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.edunamespace X86ISA 455086Sgblack@eecs.umich.edu{ 465086Sgblack@eecs.umich.edu 4713886Sgabeblack@google.comstatic int32_t 4813886Sgabeblack@google.comreadSymbol(ThreadContext *tc, const std::string name) 4913884Sgabeblack@google.com{ 5014020Sgabeblack@google.com PortProxy &vp = tc->getVirtProxy(); 5113886Sgabeblack@google.com SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; 525086Sgblack@eecs.umich.edu 5313886Sgabeblack@google.com Addr addr; 5413886Sgabeblack@google.com if (!symtab->findAddress(name, addr)) 5513886Sgabeblack@google.com panic("thread info not compiled into kernel\n"); 565086Sgblack@eecs.umich.edu 5713893Sgabeblack@google.com return vp.read<int32_t>(addr, GuestByteOrder); 5813886Sgabeblack@google.com} 595086Sgblack@eecs.umich.edu 6013886Sgabeblack@google.comProcessInfo::ProcessInfo(ThreadContext *_tc) : tc(_tc) 6113886Sgabeblack@google.com{ 6213886Sgabeblack@google.com thread_info_size = readSymbol(tc, "thread_info_size"); 6313886Sgabeblack@google.com task_struct_size = readSymbol(tc, "task_struct_size"); 6413886Sgabeblack@google.com task_off = readSymbol(tc, "thread_info_task"); 6513886Sgabeblack@google.com pid_off = readSymbol(tc, "task_struct_pid"); 6613886Sgabeblack@google.com name_off = readSymbol(tc, "task_struct_comm"); 6713884Sgabeblack@google.com} 685086Sgblack@eecs.umich.edu 6913884Sgabeblack@google.comAddr 7013884Sgabeblack@google.comProcessInfo::task(Addr ksp) const 7113884Sgabeblack@google.com{ 7213884Sgabeblack@google.com Addr base = ksp & ~0x3fff; 7313884Sgabeblack@google.com if (base == ULL(0xfffffc0000000000)) 7413884Sgabeblack@google.com return 0; 755086Sgblack@eecs.umich.edu 7613884Sgabeblack@google.com Addr tsk; 775086Sgblack@eecs.umich.edu 7814020Sgabeblack@google.com PortProxy &vp = tc->getVirtProxy(); 7913893Sgabeblack@google.com tsk = vp.read<Addr>(base + task_off, GuestByteOrder); 805086Sgblack@eecs.umich.edu 8113884Sgabeblack@google.com return tsk; 8213884Sgabeblack@google.com} 835086Sgblack@eecs.umich.edu 8413884Sgabeblack@google.comint 8513884Sgabeblack@google.comProcessInfo::pid(Addr ksp) const 8613884Sgabeblack@google.com{ 8713884Sgabeblack@google.com Addr task = this->task(ksp); 8813884Sgabeblack@google.com if (!task) 8913884Sgabeblack@google.com return -1; 905086Sgblack@eecs.umich.edu 9113884Sgabeblack@google.com uint16_t pd; 925086Sgblack@eecs.umich.edu 9314020Sgabeblack@google.com PortProxy &vp = tc->getVirtProxy(); 9413893Sgabeblack@google.com pd = vp.read<uint16_t>(task + pid_off, GuestByteOrder); 955086Sgblack@eecs.umich.edu 9613884Sgabeblack@google.com return pd; 9713884Sgabeblack@google.com} 985086Sgblack@eecs.umich.edu 9913886Sgabeblack@google.comstd::string 10013884Sgabeblack@google.comProcessInfo::name(Addr ksp) const 10113884Sgabeblack@google.com{ 10213884Sgabeblack@google.com Addr task = this->task(ksp); 10313884Sgabeblack@google.com if (!task) 10413884Sgabeblack@google.com return "console"; 1055086Sgblack@eecs.umich.edu 10613884Sgabeblack@google.com char comm[256]; 10714018Sgabeblack@google.com tc->getVirtProxy().readString(comm, task + name_off, sizeof(comm)); 10813884Sgabeblack@google.com if (!comm[0]) 10913884Sgabeblack@google.com return "startup"; 1105086Sgblack@eecs.umich.edu 11113884Sgabeblack@google.com return comm; 11213884Sgabeblack@google.com} 1135086Sgblack@eecs.umich.edu 11413884Sgabeblack@google.comStackTrace::StackTrace() 11513884Sgabeblack@google.com : tc(0), stack(64) 11613884Sgabeblack@google.com{ 11713884Sgabeblack@google.com} 1185086Sgblack@eecs.umich.edu 11913884Sgabeblack@google.comStackTrace::StackTrace(ThreadContext *_tc, const StaticInstPtr &inst) 12013884Sgabeblack@google.com : tc(0), stack(64) 12113884Sgabeblack@google.com{ 12213884Sgabeblack@google.com trace(_tc, inst); 12313884Sgabeblack@google.com} 1245086Sgblack@eecs.umich.edu 12513884Sgabeblack@google.comStackTrace::~StackTrace() 12613884Sgabeblack@google.com{ 12713884Sgabeblack@google.com} 1285086Sgblack@eecs.umich.edu 12913884Sgabeblack@google.comvoid 13013884Sgabeblack@google.comStackTrace::trace(ThreadContext *_tc, bool is_call) 13113884Sgabeblack@google.com{ 13213884Sgabeblack@google.com} 1335086Sgblack@eecs.umich.edu 13413884Sgabeblack@google.combool 13513884Sgabeblack@google.comStackTrace::isEntry(Addr addr) 13613884Sgabeblack@google.com{ 13713884Sgabeblack@google.com return false; 13813884Sgabeblack@google.com} 1395086Sgblack@eecs.umich.edu 14013884Sgabeblack@google.combool 14113884Sgabeblack@google.comStackTrace::decodeStack(MachInst inst, int &disp) 14213884Sgabeblack@google.com{ 14313884Sgabeblack@google.com disp = 0; 14413884Sgabeblack@google.com return true; 14513884Sgabeblack@google.com} 1465086Sgblack@eecs.umich.edu 14713884Sgabeblack@google.combool 14813884Sgabeblack@google.comStackTrace::decodeSave(MachInst inst, int ®, int &disp) 14913884Sgabeblack@google.com{ 15013884Sgabeblack@google.com reg = 0; 15113884Sgabeblack@google.com disp = 0; 15213884Sgabeblack@google.com return true; 15313884Sgabeblack@google.com} 1545086Sgblack@eecs.umich.edu 15513884Sgabeblack@google.com/* 15613884Sgabeblack@google.com * Decode the function prologue for the function we're in, and note 15713884Sgabeblack@google.com * which registers are stored where, and how large the stack frame is. 15813884Sgabeblack@google.com */ 15913884Sgabeblack@google.combool 16013884Sgabeblack@google.comStackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, 16113884Sgabeblack@google.com int &size, Addr &ra) 16213884Sgabeblack@google.com{ 16313884Sgabeblack@google.com size = 0; 16413884Sgabeblack@google.com ra = 0; 1655086Sgblack@eecs.umich.edu 16613884Sgabeblack@google.com for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) { 16714018Sgabeblack@google.com MachInst inst = tc->getVirtProxy().read<MachInst>(pc); 16813884Sgabeblack@google.com 16913884Sgabeblack@google.com int reg, disp; 17013884Sgabeblack@google.com if (decodeStack(inst, disp)) { 17113884Sgabeblack@google.com if (size) { 17213884Sgabeblack@google.com // panic("decoding frame size again"); 17313884Sgabeblack@google.com return true; 17413884Sgabeblack@google.com } 17513884Sgabeblack@google.com size += disp; 17613884Sgabeblack@google.com } else if (decodeSave(inst, reg, disp)) { 17713884Sgabeblack@google.com if (!ra && reg == ReturnAddressReg) { 17814018Sgabeblack@google.com ra = tc->getVirtProxy().read<Addr>(sp + disp); 17913884Sgabeblack@google.com if (!ra) { 18013884Sgabeblack@google.com // panic("no return address value pc=%#x\n", pc); 18113884Sgabeblack@google.com return false; 1825086Sgblack@eecs.umich.edu } 1835086Sgblack@eecs.umich.edu } 1845086Sgblack@eecs.umich.edu } 1855086Sgblack@eecs.umich.edu } 1865086Sgblack@eecs.umich.edu 18713884Sgabeblack@google.com return true; 18813884Sgabeblack@google.com} 18913884Sgabeblack@google.com 1905086Sgblack@eecs.umich.edu#if TRACING_ON 19113884Sgabeblack@google.comvoid 19213884Sgabeblack@google.comStackTrace::dump() 19313884Sgabeblack@google.com{ 19413884Sgabeblack@google.com StringWrap name(tc->getCpuPtr()->name()); 19513884Sgabeblack@google.com SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; 1965086Sgblack@eecs.umich.edu 19713884Sgabeblack@google.com DPRINTFN("------ Stack ------\n"); 1985086Sgblack@eecs.umich.edu 19913886Sgabeblack@google.com std::string symbol; 20013884Sgabeblack@google.com for (int i = 0, size = stack.size(); i < size; ++i) { 20113884Sgabeblack@google.com Addr addr = stack[size - i - 1]; 20213884Sgabeblack@google.com if (addr == user) 20313884Sgabeblack@google.com symbol = "user"; 20413884Sgabeblack@google.com else if (addr == console) 20513884Sgabeblack@google.com symbol = "console"; 20613884Sgabeblack@google.com else if (addr == unknown) 20713884Sgabeblack@google.com symbol = "unknown"; 20813884Sgabeblack@google.com else 20913884Sgabeblack@google.com symtab->findSymbol(addr, symbol); 2105086Sgblack@eecs.umich.edu 21113884Sgabeblack@google.com DPRINTFN("%#x: %s\n", addr, symbol); 2125086Sgblack@eecs.umich.edu } 21313884Sgabeblack@google.com} 21413884Sgabeblack@google.com 2155086Sgblack@eecs.umich.edu#endif 2165086Sgblack@eecs.umich.edu} 217