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