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 &reg, 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