stacktrace.cc revision 8706
14276Sgblack@eecs.umich.edu/* 24276Sgblack@eecs.umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan 34276Sgblack@eecs.umich.edu * All rights reserved. 44276Sgblack@eecs.umich.edu * 54276Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 64276Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 74276Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 84276Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 94276Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 104276Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 114276Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 124276Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 134276Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 144276Sgblack@eecs.umich.edu * this software without specific prior written permission. 154276Sgblack@eecs.umich.edu * 164276Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 174276Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 184276Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 194276Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 204276Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 214276Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 224276Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 234276Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 244276Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 254276Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 264276Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 274276Sgblack@eecs.umich.edu * 284276Sgblack@eecs.umich.edu * Authors: Nathan Binkert 294276Sgblack@eecs.umich.edu */ 304276Sgblack@eecs.umich.edu 314276Sgblack@eecs.umich.edu#include <string> 324276Sgblack@eecs.umich.edu 334276Sgblack@eecs.umich.edu#include "arch/mips/isa_traits.hh" 344276Sgblack@eecs.umich.edu#include "arch/mips/stacktrace.hh" 354276Sgblack@eecs.umich.edu#include "arch/mips/vtophys.hh" 364276Sgblack@eecs.umich.edu#include "base/bitfield.hh" 374276Sgblack@eecs.umich.edu#include "base/trace.hh" 384276Sgblack@eecs.umich.edu#include "cpu/base.hh" 394276Sgblack@eecs.umich.edu#include "cpu/thread_context.hh" 404276Sgblack@eecs.umich.edu#include "sim/system.hh" 414276Sgblack@eecs.umich.edu 424276Sgblack@eecs.umich.eduusing namespace std; 434276Sgblack@eecs.umich.eduusing namespace MipsISA; 444276Sgblack@eecs.umich.edu 454276Sgblack@eecs.umich.eduProcessInfo::ProcessInfo(ThreadContext *_tc) : tc(_tc) 464276Sgblack@eecs.umich.edu{} 474276Sgblack@eecs.umich.edu 484276Sgblack@eecs.umich.eduAddr 494276Sgblack@eecs.umich.eduProcessInfo::task(Addr ksp) const 504276Sgblack@eecs.umich.edu{ 514276Sgblack@eecs.umich.edu Addr base = ksp & ~0x3fff; 524276Sgblack@eecs.umich.edu if (base == ULL(0xfffffc0000000000)) 534276Sgblack@eecs.umich.edu return 0; 544276Sgblack@eecs.umich.edu 554276Sgblack@eecs.umich.edu Addr tsk; 564276Sgblack@eecs.umich.edu 574276Sgblack@eecs.umich.edu FSTranslatingPortProxy* vp; 584276Sgblack@eecs.umich.edu 594276Sgblack@eecs.umich.edu vp = tc->getVirtProxy(); 604276Sgblack@eecs.umich.edu tsk = vp->readGtoH<Addr>(base + task_off); 614276Sgblack@eecs.umich.edu 624276Sgblack@eecs.umich.edu return tsk; 634276Sgblack@eecs.umich.edu} 644519Sgblack@eecs.umich.edu 654519Sgblack@eecs.umich.eduint 664592Sgblack@eecs.umich.eduProcessInfo::pid(Addr ksp) const 674592Sgblack@eecs.umich.edu{ 684592Sgblack@eecs.umich.edu Addr task = this->task(ksp); 694592Sgblack@eecs.umich.edu if (!task) 704592Sgblack@eecs.umich.edu return -1; 714592Sgblack@eecs.umich.edu 724592Sgblack@eecs.umich.edu uint16_t pd; 734592Sgblack@eecs.umich.edu 744519Sgblack@eecs.umich.edu FSTranslatingPortProxy* vp; 754276Sgblack@eecs.umich.edu 764276Sgblack@eecs.umich.edu vp = tc->getVirtProxy(); 774276Sgblack@eecs.umich.edu pd = vp->readGtoH<uint16_t>(task + pid_off); 784276Sgblack@eecs.umich.edu 794276Sgblack@eecs.umich.edu return pd; 804276Sgblack@eecs.umich.edu} 814276Sgblack@eecs.umich.edu 824276Sgblack@eecs.umich.edustring 834592Sgblack@eecs.umich.eduProcessInfo::name(Addr ksp) const 844592Sgblack@eecs.umich.edu{ 854592Sgblack@eecs.umich.edu Addr task = this->task(ksp); 864592Sgblack@eecs.umich.edu if (!task) 874276Sgblack@eecs.umich.edu return "console"; 884276Sgblack@eecs.umich.edu 894276Sgblack@eecs.umich.edu char comm[256]; 904276Sgblack@eecs.umich.edu CopyStringOut(tc, comm, task + name_off, sizeof(comm)); 914276Sgblack@eecs.umich.edu if (!comm[0]) 924276Sgblack@eecs.umich.edu return "startup"; 934276Sgblack@eecs.umich.edu 944276Sgblack@eecs.umich.edu return comm; 954276Sgblack@eecs.umich.edu} 964276Sgblack@eecs.umich.edu 974276Sgblack@eecs.umich.eduStackTrace::StackTrace() 984592Sgblack@eecs.umich.edu : tc(0), stack(64) 994592Sgblack@eecs.umich.edu{ 1004592Sgblack@eecs.umich.edu} 1014592Sgblack@eecs.umich.edu 1024592Sgblack@eecs.umich.eduStackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst) 1034592Sgblack@eecs.umich.edu : tc(0), stack(64) 1044592Sgblack@eecs.umich.edu{ 1054592Sgblack@eecs.umich.edu trace(_tc, inst); 1064276Sgblack@eecs.umich.edu} 1074276Sgblack@eecs.umich.edu 1084276Sgblack@eecs.umich.eduStackTrace::~StackTrace() 1094276Sgblack@eecs.umich.edu{ 1104276Sgblack@eecs.umich.edu} 1114276Sgblack@eecs.umich.edu 1124276Sgblack@eecs.umich.eduvoid 1134276Sgblack@eecs.umich.eduStackTrace::trace(ThreadContext *_tc, bool is_call) 1144592Sgblack@eecs.umich.edu{ 1154592Sgblack@eecs.umich.edu tc = _tc; 1164592Sgblack@eecs.umich.edu bool usermode = 0; 1174592Sgblack@eecs.umich.edu 1184592Sgblack@eecs.umich.edu if (usermode) { 1194592Sgblack@eecs.umich.edu stack.push_back(user); 1204592Sgblack@eecs.umich.edu return; 1214592Sgblack@eecs.umich.edu } 1224276Sgblack@eecs.umich.edu} 1234276Sgblack@eecs.umich.edu 1244276Sgblack@eecs.umich.edubool 1254276Sgblack@eecs.umich.eduStackTrace::isEntry(Addr addr) 1264276Sgblack@eecs.umich.edu{ 1274276Sgblack@eecs.umich.edu return false; 1284276Sgblack@eecs.umich.edu} 1294276Sgblack@eecs.umich.edu 1304276Sgblack@eecs.umich.edubool 1314276Sgblack@eecs.umich.eduStackTrace::decodeStack(MachInst inst, int &disp) 1324592Sgblack@eecs.umich.edu{ 1334592Sgblack@eecs.umich.edu // lda $sp, -disp($sp) 1344592Sgblack@eecs.umich.edu // 1354592Sgblack@eecs.umich.edu // Opcode<31:26> == 0x08 1364276Sgblack@eecs.umich.edu // RA<25:21> == 30 1374276Sgblack@eecs.umich.edu // RB<20:16> == 30 1384276Sgblack@eecs.umich.edu // Disp<15:0> 1394276Sgblack@eecs.umich.edu const MachInst mem_mask = 0xffff0000; 1404276Sgblack@eecs.umich.edu const MachInst lda_pattern = 0x23de0000; 1414276Sgblack@eecs.umich.edu const MachInst lda_disp_mask = 0x0000ffff; 1424276Sgblack@eecs.umich.edu 1434276Sgblack@eecs.umich.edu // subq $sp, disp, $sp 1444276Sgblack@eecs.umich.edu // addq $sp, disp, $sp 1454276Sgblack@eecs.umich.edu // 1464276Sgblack@eecs.umich.edu // Opcode<31:26> == 0x10 1474276Sgblack@eecs.umich.edu // RA<25:21> == 30 1484276Sgblack@eecs.umich.edu // Lit<20:13> 1494527Sgblack@eecs.umich.edu // One<12> = 1 1504527Sgblack@eecs.umich.edu // Func<11:5> == 0x20 (addq) 1514276Sgblack@eecs.umich.edu // Func<11:5> == 0x29 (subq) 1524276Sgblack@eecs.umich.edu // RC<4:0> == 30 1534592Sgblack@eecs.umich.edu const MachInst intop_mask = 0xffe01fff; 1544592Sgblack@eecs.umich.edu const MachInst addq_pattern = 0x43c0141e; 1554592Sgblack@eecs.umich.edu const MachInst subq_pattern = 0x43c0153e; 1564592Sgblack@eecs.umich.edu const MachInst intop_disp_mask = 0x001fe000; 1574527Sgblack@eecs.umich.edu const int intop_disp_shift = 13; 1584527Sgblack@eecs.umich.edu 1594527Sgblack@eecs.umich.edu if ((inst & mem_mask) == lda_pattern) 1604276Sgblack@eecs.umich.edu disp = -sext<16>(inst & lda_disp_mask); 1614276Sgblack@eecs.umich.edu else if ((inst & intop_mask) == addq_pattern) 1624276Sgblack@eecs.umich.edu disp = -int((inst & intop_disp_mask) >> intop_disp_shift); 1634276Sgblack@eecs.umich.edu else if ((inst & intop_mask) == subq_pattern) 1644276Sgblack@eecs.umich.edu disp = int((inst & intop_disp_mask) >> intop_disp_shift); 1654276Sgblack@eecs.umich.edu else 1664276Sgblack@eecs.umich.edu return false; 1674276Sgblack@eecs.umich.edu 1684276Sgblack@eecs.umich.edu return true; 1694276Sgblack@eecs.umich.edu} 1704592Sgblack@eecs.umich.edu 1714592Sgblack@eecs.umich.edubool 1724592Sgblack@eecs.umich.eduStackTrace::decodeSave(MachInst inst, int ®, int &disp) 1734592Sgblack@eecs.umich.edu{ 1744276Sgblack@eecs.umich.edu // lda $stq, disp($sp) 1754595Sgblack@eecs.umich.edu // 1764595Sgblack@eecs.umich.edu // Opcode<31:26> == 0x08 1774595Sgblack@eecs.umich.edu // RA<25:21> == ? 1784595Sgblack@eecs.umich.edu // RB<20:16> == 30 1794595Sgblack@eecs.umich.edu // Disp<15:0> 1804595Sgblack@eecs.umich.edu const MachInst stq_mask = 0xfc1f0000; 1814595Sgblack@eecs.umich.edu const MachInst stq_pattern = 0xb41e0000; 1824595Sgblack@eecs.umich.edu const MachInst stq_disp_mask = 0x0000ffff; 1834595Sgblack@eecs.umich.edu const MachInst reg_mask = 0x03e00000; 1844595Sgblack@eecs.umich.edu const int reg_shift = 21; 1854595Sgblack@eecs.umich.edu 1864595Sgblack@eecs.umich.edu if ((inst & stq_mask) == stq_pattern) { 1874595Sgblack@eecs.umich.edu reg = (inst & reg_mask) >> reg_shift; 1884276Sgblack@eecs.umich.edu disp = sext<16>(inst & stq_disp_mask); 1894595Sgblack@eecs.umich.edu } else { 1904595Sgblack@eecs.umich.edu return false; 1914595Sgblack@eecs.umich.edu } 1924595Sgblack@eecs.umich.edu 1934595Sgblack@eecs.umich.edu return true; 1944595Sgblack@eecs.umich.edu} 1954595Sgblack@eecs.umich.edu 1964595Sgblack@eecs.umich.edu/* 1974595Sgblack@eecs.umich.edu * Decode the function prologue for the function we're in, and note 1984595Sgblack@eecs.umich.edu * which registers are stored where, and how large the stack frame is. 1994595Sgblack@eecs.umich.edu */ 2004595Sgblack@eecs.umich.edubool 2014595Sgblack@eecs.umich.eduStackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, 2024276Sgblack@eecs.umich.edu int &size, Addr &ra) 2034592Sgblack@eecs.umich.edu{ 2044592Sgblack@eecs.umich.edu size = 0; 2054592Sgblack@eecs.umich.edu ra = 0; 2064592Sgblack@eecs.umich.edu 2074592Sgblack@eecs.umich.edu for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) { 2084592Sgblack@eecs.umich.edu MachInst inst; 2094592Sgblack@eecs.umich.edu CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst)); 2104592Sgblack@eecs.umich.edu 2114592Sgblack@eecs.umich.edu int reg, disp; 2124592Sgblack@eecs.umich.edu if (decodeStack(inst, disp)) { 2134592Sgblack@eecs.umich.edu if (size) { 2144592Sgblack@eecs.umich.edu return true; 2154592Sgblack@eecs.umich.edu } 2164592Sgblack@eecs.umich.edu size += disp; 2174592Sgblack@eecs.umich.edu } else if (decodeSave(inst, reg, disp)) { 2184592Sgblack@eecs.umich.edu if (!ra && reg == ReturnAddressReg) { 2194592Sgblack@eecs.umich.edu CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr)); 2204592Sgblack@eecs.umich.edu if (!ra) { 2214592Sgblack@eecs.umich.edu return false; 2224592Sgblack@eecs.umich.edu } 2234592Sgblack@eecs.umich.edu } 2244276Sgblack@eecs.umich.edu } 2254276Sgblack@eecs.umich.edu } 2264592Sgblack@eecs.umich.edu 2274592Sgblack@eecs.umich.edu return true; 2284592Sgblack@eecs.umich.edu} 2294592Sgblack@eecs.umich.edu 2304592Sgblack@eecs.umich.edu#if TRACING_ON 2314592Sgblack@eecs.umich.eduvoid 2324592Sgblack@eecs.umich.eduStackTrace::dump() 2334592Sgblack@eecs.umich.edu{ 2344592Sgblack@eecs.umich.edu panic("Stack trace dump not implemented.\n"); 2354592Sgblack@eecs.umich.edu} 2364592Sgblack@eecs.umich.edu#endif 2374592Sgblack@eecs.umich.edu