stacktrace.cc revision 13884
15086Sgblack@eecs.umich.edu/* 25086Sgblack@eecs.umich.edu * Copyright (c) 2005 The Regents of The University of Michigan 35086Sgblack@eecs.umich.edu * All rights reserved. 45086Sgblack@eecs.umich.edu * 55086Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 65086Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 75086Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 85086Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 95086Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 105086Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 115086Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 125086Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 135086Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 145086Sgblack@eecs.umich.edu * this software without specific prior written permission. 155086Sgblack@eecs.umich.edu * 165086Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175086Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185086Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195086Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205086Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215086Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225086Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235086Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245086Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255086Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265086Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275086Sgblack@eecs.umich.edu * 285086Sgblack@eecs.umich.edu * Authors: Nathan Binkert 295086Sgblack@eecs.umich.edu */ 305086Sgblack@eecs.umich.edu 3111793Sbrandon.potter@amd.com#include "arch/x86/stacktrace.hh" 3211793Sbrandon.potter@amd.com 335086Sgblack@eecs.umich.edu#include <string> 345086Sgblack@eecs.umich.edu 355086Sgblack@eecs.umich.edu#include "arch/x86/isa_traits.hh" 365086Sgblack@eecs.umich.edu#include "arch/x86/vtophys.hh" 375086Sgblack@eecs.umich.edu#include "base/bitfield.hh" 385086Sgblack@eecs.umich.edu#include "base/trace.hh" 395086Sgblack@eecs.umich.edu#include "cpu/base.hh" 405086Sgblack@eecs.umich.edu#include "cpu/thread_context.hh" 418706Sandreas.hansson@arm.com#include "mem/fs_translating_port_proxy.hh" 425086Sgblack@eecs.umich.edu#include "sim/system.hh" 435086Sgblack@eecs.umich.edu 445086Sgblack@eecs.umich.eduusing namespace std; 455086Sgblack@eecs.umich.edunamespace X86ISA 465086Sgblack@eecs.umich.edu{ 475086Sgblack@eecs.umich.edu 4813884Sgabeblack@google.comProcessInfo::ProcessInfo(ThreadContext *_tc) 4913884Sgabeblack@google.com : tc(_tc) 5013884Sgabeblack@google.com{ 5113884Sgabeblack@google.com Addr addr = 0; 525086Sgblack@eecs.umich.edu 5313884Sgabeblack@google.com FSTranslatingPortProxy &vp = tc->getVirtProxy(); 545086Sgblack@eecs.umich.edu 5513884Sgabeblack@google.com if (!tc->getSystemPtr()->kernelSymtab->findAddress( 5613884Sgabeblack@google.com "thread_info_size", addr)) { 5713884Sgabeblack@google.com panic("thread info not compiled into kernel\n"); 5813884Sgabeblack@google.com } 5913884Sgabeblack@google.com thread_info_size = vp.readGtoH<int32_t>(addr); 605086Sgblack@eecs.umich.edu 6113884Sgabeblack@google.com if (!tc->getSystemPtr()->kernelSymtab->findAddress( 6213884Sgabeblack@google.com "task_struct_size", addr)) { 6313884Sgabeblack@google.com panic("thread info not compiled into kernel\n"); 6413884Sgabeblack@google.com } 6513884Sgabeblack@google.com task_struct_size = vp.readGtoH<int32_t>(addr); 665086Sgblack@eecs.umich.edu 6713884Sgabeblack@google.com if (!tc->getSystemPtr()->kernelSymtab->findAddress( 6813884Sgabeblack@google.com "thread_info_task", addr)) { 6913884Sgabeblack@google.com panic("thread info not compiled into kernel\n"); 7013884Sgabeblack@google.com } 7113884Sgabeblack@google.com task_off = vp.readGtoH<int32_t>(addr); 725086Sgblack@eecs.umich.edu 7313884Sgabeblack@google.com if (!tc->getSystemPtr()->kernelSymtab->findAddress( 7413884Sgabeblack@google.com "task_struct_pid", addr)) { 7513884Sgabeblack@google.com panic("thread info not compiled into kernel\n"); 765086Sgblack@eecs.umich.edu } 7713884Sgabeblack@google.com pid_off = vp.readGtoH<int32_t>(addr); 785086Sgblack@eecs.umich.edu 7913884Sgabeblack@google.com if (!tc->getSystemPtr()->kernelSymtab->findAddress( 8013884Sgabeblack@google.com "task_struct_comm", addr)) { 8113884Sgabeblack@google.com panic("thread info not compiled into kernel\n"); 8213884Sgabeblack@google.com } 8313884Sgabeblack@google.com name_off = vp.readGtoH<int32_t>(addr); 8413884Sgabeblack@google.com} 855086Sgblack@eecs.umich.edu 8613884Sgabeblack@google.comAddr 8713884Sgabeblack@google.comProcessInfo::task(Addr ksp) const 8813884Sgabeblack@google.com{ 8913884Sgabeblack@google.com Addr base = ksp & ~0x3fff; 9013884Sgabeblack@google.com if (base == ULL(0xfffffc0000000000)) 9113884Sgabeblack@google.com return 0; 925086Sgblack@eecs.umich.edu 9313884Sgabeblack@google.com Addr tsk; 945086Sgblack@eecs.umich.edu 9513884Sgabeblack@google.com FSTranslatingPortProxy &vp = tc->getVirtProxy(); 9613884Sgabeblack@google.com tsk = vp.readGtoH<Addr>(base + task_off); 975086Sgblack@eecs.umich.edu 9813884Sgabeblack@google.com return tsk; 9913884Sgabeblack@google.com} 1005086Sgblack@eecs.umich.edu 10113884Sgabeblack@google.comint 10213884Sgabeblack@google.comProcessInfo::pid(Addr ksp) const 10313884Sgabeblack@google.com{ 10413884Sgabeblack@google.com Addr task = this->task(ksp); 10513884Sgabeblack@google.com if (!task) 10613884Sgabeblack@google.com return -1; 1075086Sgblack@eecs.umich.edu 10813884Sgabeblack@google.com uint16_t pd; 1095086Sgblack@eecs.umich.edu 11013884Sgabeblack@google.com FSTranslatingPortProxy &vp = tc->getVirtProxy(); 11113884Sgabeblack@google.com pd = vp.readGtoH<uint16_t>(task + pid_off); 1125086Sgblack@eecs.umich.edu 11313884Sgabeblack@google.com return pd; 11413884Sgabeblack@google.com} 1155086Sgblack@eecs.umich.edu 11613884Sgabeblack@google.comstring 11713884Sgabeblack@google.comProcessInfo::name(Addr ksp) const 11813884Sgabeblack@google.com{ 11913884Sgabeblack@google.com Addr task = this->task(ksp); 12013884Sgabeblack@google.com if (!task) 12113884Sgabeblack@google.com return "console"; 1225086Sgblack@eecs.umich.edu 12313884Sgabeblack@google.com char comm[256]; 12413884Sgabeblack@google.com CopyStringOut(tc, comm, task + name_off, sizeof(comm)); 12513884Sgabeblack@google.com if (!comm[0]) 12613884Sgabeblack@google.com return "startup"; 1275086Sgblack@eecs.umich.edu 12813884Sgabeblack@google.com return comm; 12913884Sgabeblack@google.com} 1305086Sgblack@eecs.umich.edu 13113884Sgabeblack@google.comStackTrace::StackTrace() 13213884Sgabeblack@google.com : tc(0), stack(64) 13313884Sgabeblack@google.com{ 13413884Sgabeblack@google.com} 1355086Sgblack@eecs.umich.edu 13613884Sgabeblack@google.comStackTrace::StackTrace(ThreadContext *_tc, const StaticInstPtr &inst) 13713884Sgabeblack@google.com : tc(0), stack(64) 13813884Sgabeblack@google.com{ 13913884Sgabeblack@google.com trace(_tc, inst); 14013884Sgabeblack@google.com} 1415086Sgblack@eecs.umich.edu 14213884Sgabeblack@google.comStackTrace::~StackTrace() 14313884Sgabeblack@google.com{ 14413884Sgabeblack@google.com} 1455086Sgblack@eecs.umich.edu 14613884Sgabeblack@google.comvoid 14713884Sgabeblack@google.comStackTrace::trace(ThreadContext *_tc, bool is_call) 14813884Sgabeblack@google.com{ 14913884Sgabeblack@google.com} 1505086Sgblack@eecs.umich.edu 15113884Sgabeblack@google.combool 15213884Sgabeblack@google.comStackTrace::isEntry(Addr addr) 15313884Sgabeblack@google.com{ 15413884Sgabeblack@google.com return false; 15513884Sgabeblack@google.com} 1565086Sgblack@eecs.umich.edu 15713884Sgabeblack@google.combool 15813884Sgabeblack@google.comStackTrace::decodeStack(MachInst inst, int &disp) 15913884Sgabeblack@google.com{ 16013884Sgabeblack@google.com disp = 0; 16113884Sgabeblack@google.com return true; 16213884Sgabeblack@google.com} 1635086Sgblack@eecs.umich.edu 16413884Sgabeblack@google.combool 16513884Sgabeblack@google.comStackTrace::decodeSave(MachInst inst, int ®, int &disp) 16613884Sgabeblack@google.com{ 16713884Sgabeblack@google.com reg = 0; 16813884Sgabeblack@google.com disp = 0; 16913884Sgabeblack@google.com return true; 17013884Sgabeblack@google.com} 1715086Sgblack@eecs.umich.edu 17213884Sgabeblack@google.com/* 17313884Sgabeblack@google.com * Decode the function prologue for the function we're in, and note 17413884Sgabeblack@google.com * which registers are stored where, and how large the stack frame is. 17513884Sgabeblack@google.com */ 17613884Sgabeblack@google.combool 17713884Sgabeblack@google.comStackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, 17813884Sgabeblack@google.com int &size, Addr &ra) 17913884Sgabeblack@google.com{ 18013884Sgabeblack@google.com size = 0; 18113884Sgabeblack@google.com ra = 0; 1825086Sgblack@eecs.umich.edu 18313884Sgabeblack@google.com for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) { 18413884Sgabeblack@google.com MachInst inst; 18513884Sgabeblack@google.com CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst)); 18613884Sgabeblack@google.com 18713884Sgabeblack@google.com int reg, disp; 18813884Sgabeblack@google.com if (decodeStack(inst, disp)) { 18913884Sgabeblack@google.com if (size) { 19013884Sgabeblack@google.com // panic("decoding frame size again"); 19113884Sgabeblack@google.com return true; 19213884Sgabeblack@google.com } 19313884Sgabeblack@google.com size += disp; 19413884Sgabeblack@google.com } else if (decodeSave(inst, reg, disp)) { 19513884Sgabeblack@google.com if (!ra && reg == ReturnAddressReg) { 19613884Sgabeblack@google.com CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr)); 19713884Sgabeblack@google.com if (!ra) { 19813884Sgabeblack@google.com // panic("no return address value pc=%#x\n", pc); 19913884Sgabeblack@google.com return false; 2005086Sgblack@eecs.umich.edu } 2015086Sgblack@eecs.umich.edu } 2025086Sgblack@eecs.umich.edu } 2035086Sgblack@eecs.umich.edu } 2045086Sgblack@eecs.umich.edu 20513884Sgabeblack@google.com return true; 20613884Sgabeblack@google.com} 20713884Sgabeblack@google.com 2085086Sgblack@eecs.umich.edu#if TRACING_ON 20913884Sgabeblack@google.comvoid 21013884Sgabeblack@google.comStackTrace::dump() 21113884Sgabeblack@google.com{ 21213884Sgabeblack@google.com StringWrap name(tc->getCpuPtr()->name()); 21313884Sgabeblack@google.com SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; 2145086Sgblack@eecs.umich.edu 21513884Sgabeblack@google.com DPRINTFN("------ Stack ------\n"); 2165086Sgblack@eecs.umich.edu 21713884Sgabeblack@google.com string symbol; 21813884Sgabeblack@google.com for (int i = 0, size = stack.size(); i < size; ++i) { 21913884Sgabeblack@google.com Addr addr = stack[size - i - 1]; 22013884Sgabeblack@google.com if (addr == user) 22113884Sgabeblack@google.com symbol = "user"; 22213884Sgabeblack@google.com else if (addr == console) 22313884Sgabeblack@google.com symbol = "console"; 22413884Sgabeblack@google.com else if (addr == unknown) 22513884Sgabeblack@google.com symbol = "unknown"; 22613884Sgabeblack@google.com else 22713884Sgabeblack@google.com symtab->findSymbol(addr, symbol); 2285086Sgblack@eecs.umich.edu 22913884Sgabeblack@google.com DPRINTFN("%#x: %s\n", addr, symbol); 2305086Sgblack@eecs.umich.edu } 23113884Sgabeblack@google.com} 23213884Sgabeblack@google.com 2335086Sgblack@eecs.umich.edu#endif 2345086Sgblack@eecs.umich.edu} 235