stacktrace.cc revision 8706
18839Sandreas.hansson@arm.com/* 28839Sandreas.hansson@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 38839Sandreas.hansson@arm.com * All rights reserved. 48839Sandreas.hansson@arm.com * 58839Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 68839Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 78839Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 88839Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 98839Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 108839Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 118839Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 128839Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 135335Shines@cs.fsu.edu * contributors may be used to endorse or promote products derived from 147897Shestness@cs.utexas.edu * this software without specific prior written permission. 154486Sbinkertn@umich.edu * 164486Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 174486Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 184486Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 194486Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 204486Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 214486Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 224486Sbinkertn@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 234486Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 244486Sbinkertn@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 254486Sbinkertn@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 264486Sbinkertn@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 274486Sbinkertn@umich.edu * 284486Sbinkertn@umich.edu * Authors: Nathan Binkert 294486Sbinkertn@umich.edu */ 304486Sbinkertn@umich.edu 314486Sbinkertn@umich.edu#include <string> 324486Sbinkertn@umich.edu 334486Sbinkertn@umich.edu#include "arch/mips/isa_traits.hh" 344486Sbinkertn@umich.edu#include "arch/mips/stacktrace.hh" 354486Sbinkertn@umich.edu#include "arch/mips/vtophys.hh" 364486Sbinkertn@umich.edu#include "base/bitfield.hh" 374486Sbinkertn@umich.edu#include "base/trace.hh" 384486Sbinkertn@umich.edu#include "cpu/base.hh" 394486Sbinkertn@umich.edu#include "cpu/thread_context.hh" 404486Sbinkertn@umich.edu#include "sim/system.hh" 417897Shestness@cs.utexas.edu 428839Sandreas.hansson@arm.comusing namespace std; 434486Sbinkertn@umich.eduusing namespace MipsISA; 446654Snate@binkert.org 456654Snate@binkert.orgProcessInfo::ProcessInfo(ThreadContext *_tc) : tc(_tc) 466654Snate@binkert.org{} 473102SN/A 483102SN/AAddr 496654Snate@binkert.orgProcessInfo::task(Addr ksp) const 509036Sandreas.hansson@arm.com{ 514776Sgblack@eecs.umich.edu Addr base = ksp & ~0x3fff; 524776Sgblack@eecs.umich.edu if (base == ULL(0xfffffc0000000000)) 536654Snate@binkert.org return 0; 549480Snilay@cs.wisc.edu 552667SN/A Addr tsk; 564776Sgblack@eecs.umich.edu 574776Sgblack@eecs.umich.edu FSTranslatingPortProxy* vp; 586654Snate@binkert.org 596023Snate@binkert.org vp = tc->getVirtProxy(); 608745Sgblack@eecs.umich.edu tsk = vp->readGtoH<Addr>(base + task_off); 619384SAndreas.Sandberg@arm.com 629384SAndreas.Sandberg@arm.com return tsk; 636654Snate@binkert.org} 646022Sgblack@eecs.umich.edu 658745Sgblack@eecs.umich.eduint 669384SAndreas.Sandberg@arm.comProcessInfo::pid(Addr ksp) const 679384SAndreas.Sandberg@arm.com{ 686654Snate@binkert.org Addr task = this->task(ksp); 696022Sgblack@eecs.umich.edu if (!task) 708745Sgblack@eecs.umich.edu return -1; 719384SAndreas.Sandberg@arm.com 729384SAndreas.Sandberg@arm.com uint16_t pd; 736654Snate@binkert.org 746022Sgblack@eecs.umich.edu FSTranslatingPortProxy* vp; 758745Sgblack@eecs.umich.edu 769384SAndreas.Sandberg@arm.com vp = tc->getVirtProxy(); 779384SAndreas.Sandberg@arm.com pd = vp->readGtoH<uint16_t>(task + pid_off); 786654Snate@binkert.org 796116Snate@binkert.org return pd; 808745Sgblack@eecs.umich.edu} 819384SAndreas.Sandberg@arm.com 829384SAndreas.Sandberg@arm.comstring 836691Stjones1@inf.ed.ac.ukProcessInfo::name(Addr ksp) const 846691Stjones1@inf.ed.ac.uk{ 858745Sgblack@eecs.umich.edu Addr task = this->task(ksp); 869384SAndreas.Sandberg@arm.com if (!task) 879384SAndreas.Sandberg@arm.com return "console"; 884486Sbinkertn@umich.edu 895529Snate@binkert.org char comm[256]; 901366SN/A CopyStringOut(tc, comm, task + name_off, sizeof(comm)); 911310SN/A if (!comm[0]) 929338SAndreas.Sandberg@arm.com return "startup"; 939254SAndreas.Sandberg@arm.com 949254SAndreas.Sandberg@arm.com return comm; 959254SAndreas.Sandberg@arm.com} 969254SAndreas.Sandberg@arm.com 979254SAndreas.Sandberg@arm.comStackTrace::StackTrace() 989254SAndreas.Sandberg@arm.com : tc(0), stack(64) 999430SAndreas.Sandberg@ARM.com{ 1009446SAndreas.Sandberg@ARM.com} 1019650Stimothy.jones@arm.com 1029254SAndreas.Sandberg@arm.comStackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst) 1039254SAndreas.Sandberg@arm.com : tc(0), stack(64) 1049518SAndreas.Sandberg@ARM.com{ 1059518SAndreas.Sandberg@ARM.com trace(_tc, inst); 1069518SAndreas.Sandberg@ARM.com} 1079518SAndreas.Sandberg@ARM.com 1089518SAndreas.Sandberg@ARM.comStackTrace::~StackTrace() 1099518SAndreas.Sandberg@ARM.com{ 1109518SAndreas.Sandberg@ARM.com} 1119518SAndreas.Sandberg@ARM.com 1129518SAndreas.Sandberg@ARM.comvoid 1139518SAndreas.Sandberg@ARM.comStackTrace::trace(ThreadContext *_tc, bool is_call) 1149518SAndreas.Sandberg@ARM.com{ 1159518SAndreas.Sandberg@ARM.com tc = _tc; 1169518SAndreas.Sandberg@ARM.com bool usermode = 0; 1179518SAndreas.Sandberg@ARM.com 1189518SAndreas.Sandberg@ARM.com if (usermode) { 1199518SAndreas.Sandberg@ARM.com stack.push_back(user); 1209518SAndreas.Sandberg@ARM.com return; 1219518SAndreas.Sandberg@ARM.com } 1229518SAndreas.Sandberg@ARM.com} 1239254SAndreas.Sandberg@arm.com 1249254SAndreas.Sandberg@arm.combool 1259254SAndreas.Sandberg@arm.comStackTrace::isEntry(Addr addr) 1269254SAndreas.Sandberg@arm.com{ 1272901SN/A return false; 1285712Shsul@eecs.umich.edu} 1295529Snate@binkert.org 1305529Snate@binkert.orgbool 1315529Snate@binkert.orgStackTrace::decodeStack(MachInst inst, int &disp) 1329161Sandreas.hansson@arm.com{ 1335529Snate@binkert.org // lda $sp, -disp($sp) 1345821Ssaidi@eecs.umich.edu // 1353170SN/A // Opcode<31:26> == 0x08 1365780Ssteve.reinhardt@amd.com // RA<25:21> == 30 1375780Ssteve.reinhardt@amd.com // RB<20:16> == 30 1385780Ssteve.reinhardt@amd.com // Disp<15:0> 1395780Ssteve.reinhardt@amd.com const MachInst mem_mask = 0xffff0000; 1405780Ssteve.reinhardt@amd.com const MachInst lda_pattern = 0x23de0000; 1418784Sgblack@eecs.umich.edu const MachInst lda_disp_mask = 0x0000ffff; 1428784Sgblack@eecs.umich.edu 1438784Sgblack@eecs.umich.edu // subq $sp, disp, $sp 1448793Sgblack@eecs.umich.edu // addq $sp, disp, $sp 1451310SN/A // 1466654Snate@binkert.org // Opcode<31:26> == 0x10 1476022Sgblack@eecs.umich.edu // RA<25:21> == 30 1486022Sgblack@eecs.umich.edu // Lit<20:13> 1498745Sgblack@eecs.umich.edu // One<12> = 1 1508863Snilay@cs.wisc.edu // Func<11:5> == 0x20 (addq) 1519384SAndreas.Sandberg@arm.com // Func<11:5> == 0x29 (subq) 1526654Snate@binkert.org // RC<4:0> == 30 1536023Snate@binkert.org const MachInst intop_mask = 0xffe01fff; 1546023Snate@binkert.org const MachInst addq_pattern = 0x43c0141e; 1558745Sgblack@eecs.umich.edu const MachInst subq_pattern = 0x43c0153e; 1568863Snilay@cs.wisc.edu const MachInst intop_disp_mask = 0x001fe000; 1579384SAndreas.Sandberg@arm.com const int intop_disp_shift = 13; 1586654Snate@binkert.org 1596022Sgblack@eecs.umich.edu if ((inst & mem_mask) == lda_pattern) 1606022Sgblack@eecs.umich.edu disp = -sext<16>(inst & lda_disp_mask); 1618863Snilay@cs.wisc.edu else if ((inst & intop_mask) == addq_pattern) 1629384SAndreas.Sandberg@arm.com disp = -int((inst & intop_disp_mask) >> intop_disp_shift); 1636654Snate@binkert.org else if ((inst & intop_mask) == subq_pattern) 1646022Sgblack@eecs.umich.edu disp = int((inst & intop_disp_mask) >> intop_disp_shift); 1656022Sgblack@eecs.umich.edu else 1668745Sgblack@eecs.umich.edu return false; 1678863Snilay@cs.wisc.edu 1689384SAndreas.Sandberg@arm.com return true; 1696654Snate@binkert.org} 1706116Snate@binkert.org 1716116Snate@binkert.orgbool 1728745Sgblack@eecs.umich.eduStackTrace::decodeSave(MachInst inst, int ®, int &disp) 1738863Snilay@cs.wisc.edu{ 1749384SAndreas.Sandberg@arm.com // lda $stq, disp($sp) 1756691Stjones1@inf.ed.ac.uk // 1766691Stjones1@inf.ed.ac.uk // Opcode<31:26> == 0x08 1776691Stjones1@inf.ed.ac.uk // RA<25:21> == ? 1786691Stjones1@inf.ed.ac.uk // RB<20:16> == 30 1798745Sgblack@eecs.umich.edu // Disp<15:0> 1808863Snilay@cs.wisc.edu const MachInst stq_mask = 0xfc1f0000; 1819384SAndreas.Sandberg@arm.com const MachInst stq_pattern = 0xb41e0000; 1824997Sgblack@eecs.umich.edu const MachInst stq_disp_mask = 0x0000ffff; 1834997Sgblack@eecs.umich.edu const MachInst reg_mask = 0x03e00000; 1846654Snate@binkert.org const int reg_shift = 21; 1854997Sgblack@eecs.umich.edu 1864997Sgblack@eecs.umich.edu if ((inst & stq_mask) == stq_pattern) { 1871310SN/A reg = (inst & reg_mask) >> reg_shift; 1881310SN/A disp = sext<16>(inst & stq_disp_mask); 1891310SN/A } else { 1901310SN/A return false; 1919647Sdam.sunwoo@arm.com } 1929647Sdam.sunwoo@arm.com 1931310SN/A return true; 1941310SN/A} 1951310SN/A 1961310SN/A/* 1979180Sandreas.hansson@arm.com * Decode the function prologue for the function we're in, and note 1989180Sandreas.hansson@arm.com * which registers are stored where, and how large the stack frame is. 1991310SN/A */ 2009433SAndreas.Sandberg@ARM.combool 2019433SAndreas.Sandberg@ARM.comStackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, 2029433SAndreas.Sandberg@ARM.com int &size, Addr &ra) 2031634SN/A{ 2044776Sgblack@eecs.umich.edu size = 0; 2054776Sgblack@eecs.umich.edu ra = 0; 2068839Sandreas.hansson@arm.com 2078839Sandreas.hansson@arm.com for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) { 2088707Sandreas.hansson@arm.com MachInst inst; 2098707Sandreas.hansson@arm.com CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst)); 2109480Snilay@cs.wisc.edu 2119480Snilay@cs.wisc.edu int reg, disp; 2128756Sgblack@eecs.umich.edu if (decodeStack(inst, disp)) { 2138707Sandreas.hansson@arm.com if (size) { 2147876Sgblack@eecs.umich.edu return true; 2158839Sandreas.hansson@arm.com } 2168839Sandreas.hansson@arm.com size += disp; 2178745Sgblack@eecs.umich.edu } else if (decodeSave(inst, reg, disp)) { 2188839Sandreas.hansson@arm.com if (!ra && reg == ReturnAddressReg) { 2198839Sandreas.hansson@arm.com CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr)); 2202998SN/A if (!ra) { 2218863Snilay@cs.wisc.edu return false; 2228863Snilay@cs.wisc.edu } 2238863Snilay@cs.wisc.edu } 2248863Snilay@cs.wisc.edu } 2258863Snilay@cs.wisc.edu } 2268863Snilay@cs.wisc.edu 2279544Sandreas.hansson@arm.com return true; 2289544Sandreas.hansson@arm.com} 2299544Sandreas.hansson@arm.com 2308863Snilay@cs.wisc.edu#if TRACING_ON 2318863Snilay@cs.wisc.eduvoid 2328863Snilay@cs.wisc.eduStackTrace::dump() 2338863Snilay@cs.wisc.edu{ 2348863Snilay@cs.wisc.edu panic("Stack trace dump not implemented.\n"); 2358863Snilay@cs.wisc.edu} 2368863Snilay@cs.wisc.edu#endif 2378863Snilay@cs.wisc.edu