diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript index 3f34216471..4aec933eb6 100644 --- a/src/arch/arm/SConscript +++ b/src/arch/arm/SConscript @@ -82,7 +82,6 @@ if env['TARGET_ISA'] == 'arm': Source('qarma.cc') Source('remote_gdb.cc') Source('semihosting.cc') - Source('stacktrace.cc') Source('system.cc') Source('table_walker.cc') Source('self_debug.cc') diff --git a/src/arch/arm/stacktrace.cc b/src/arch/arm/stacktrace.cc deleted file mode 100644 index a9f79e8640..0000000000 --- a/src/arch/arm/stacktrace.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "arch/arm/stacktrace.hh" - -#include - -#include "arch/arm/isa_traits.hh" -#include "base/bitfield.hh" -#include "base/trace.hh" -#include "cpu/base.hh" -#include "cpu/thread_context.hh" -#include "mem/port_proxy.hh" -#include "sim/system.hh" - -namespace ArmISA -{ - -StackTrace::StackTrace() - : tc(0), stack(64) -{ -} - -StackTrace::StackTrace(ThreadContext *_tc, const StaticInstPtr &inst) - : tc(0), stack(64) -{ - trace(_tc, inst); -} - -StackTrace::~StackTrace() -{ -} - -void -StackTrace::trace(ThreadContext *_tc, bool is_call) -{ -} - -bool -StackTrace::isEntry(Addr addr) -{ - return false; -} - -bool -StackTrace::decodeStack(MachInst inst, int &disp) -{ - return false; -} - -bool -StackTrace::decodeSave(MachInst inst, int ®, int &disp) -{ - return false; -} - -/* - * Decode the function prologue for the function we're in, and note - * which registers are stored where, and how large the stack frame is. - */ -bool -StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, - int &size, Addr &ra) -{ - return false; -} - -#if TRACING_ON -void -StackTrace::dump() -{ - DPRINTFN("------ Stack ------\n"); - - DPRINTFN(" Not implemented\n"); -} -#endif -} diff --git a/src/arch/arm/stacktrace.hh b/src/arch/arm/stacktrace.hh index 61bea299c2..6a83fcec82 100644 --- a/src/arch/arm/stacktrace.hh +++ b/src/arch/arm/stacktrace.hh @@ -29,72 +29,17 @@ #ifndef __ARCH_ARM_STACKTRACE_HH__ #define __ARCH_ARM_STACKTRACE_HH__ -#include "base/trace.hh" -#include "cpu/static_inst.hh" -#include "debug/Stack.hh" +#include "cpu/profile.hh" -class ThreadContext; namespace ArmISA { -class StackTrace +class StackTrace : public BaseStackTrace { protected: - typedef ArmISA::MachInst MachInst; - private: - ThreadContext *tc; - std::vector stack; - - private: - bool isEntry(Addr addr); - bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); - bool decodeSave(MachInst inst, int ®, int &disp); - bool decodeStack(MachInst inst, int &disp); - - void trace(ThreadContext *tc, bool is_call); - - public: - StackTrace(); - StackTrace(ThreadContext *tc, const StaticInstPtr &inst); - ~StackTrace(); - - void clear() - { - tc = 0; - stack.clear(); - } - - bool valid() const { return tc != NULL; } - bool trace(ThreadContext *tc, const StaticInstPtr &inst); - - public: - const std::vector &getstack() const { return stack; } - -#if TRACING_ON - private: - void dump(); - - public: - void dprintf() { if (DTRACE(Stack)) dump(); } -#else - public: - void dprintf() {} -#endif + void trace(ThreadContext *tc, bool is_call) override {}; }; -inline bool -StackTrace::trace(ThreadContext *tc, const StaticInstPtr &inst) -{ - if (!inst->isCall() && !inst->isReturn()) - return false; - - if (valid()) - clear(); - - trace(tc, !inst->isReturn()); - return true; -} - } // Namespace ArmISA #endif // __ARCH_ARM_STACKTRACE_HH__ diff --git a/src/arch/mips/SConscript b/src/arch/mips/SConscript index 0e4fcf286f..cac589f8ec 100644 --- a/src/arch/mips/SConscript +++ b/src/arch/mips/SConscript @@ -40,7 +40,6 @@ if env['TARGET_ISA'] == 'mips': Source('pagetable.cc') Source('process.cc') Source('remote_gdb.cc') - Source('stacktrace.cc') Source('tlb.cc') Source('utility.cc') diff --git a/src/arch/mips/stacktrace.cc b/src/arch/mips/stacktrace.cc deleted file mode 100644 index 0384e2bd05..0000000000 --- a/src/arch/mips/stacktrace.cc +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "arch/mips/stacktrace.hh" - -#include - -#include "arch/mips/isa_traits.hh" -#include "base/bitfield.hh" -#include "base/trace.hh" -#include "cpu/base.hh" -#include "cpu/thread_context.hh" -#include "mem/port_proxy.hh" -#include "sim/system.hh" - -using namespace MipsISA; - -StackTrace::StackTrace() - : tc(0), stack(64) -{ -} - -StackTrace::StackTrace(ThreadContext *_tc, const StaticInstPtr &inst) - : tc(0), stack(64) -{ - trace(_tc, inst); -} - -StackTrace::~StackTrace() -{ -} - -void -StackTrace::trace(ThreadContext *_tc, bool is_call) -{ - tc = _tc; - bool usermode = 0; - - if (usermode) { - stack.push_back(user); - return; - } -} - -bool -StackTrace::isEntry(Addr addr) -{ - return false; -} - -bool -StackTrace::decodeStack(MachInst inst, int &disp) -{ - // lda $sp, -disp($sp) - // - // Opcode<31:26> == 0x08 - // RA<25:21> == 30 - // RB<20:16> == 30 - // Disp<15:0> - const MachInst mem_mask = 0xffff0000; - const MachInst lda_pattern = 0x23de0000; - const MachInst lda_disp_mask = 0x0000ffff; - - // subq $sp, disp, $sp - // addq $sp, disp, $sp - // - // Opcode<31:26> == 0x10 - // RA<25:21> == 30 - // Lit<20:13> - // One<12> = 1 - // Func<11:5> == 0x20 (addq) - // Func<11:5> == 0x29 (subq) - // RC<4:0> == 30 - const MachInst intop_mask = 0xffe01fff; - const MachInst addq_pattern = 0x43c0141e; - const MachInst subq_pattern = 0x43c0153e; - const MachInst intop_disp_mask = 0x001fe000; - const int intop_disp_shift = 13; - - if ((inst & mem_mask) == lda_pattern) - disp = -sext<16>(inst & lda_disp_mask); - else if ((inst & intop_mask) == addq_pattern) - disp = -int((inst & intop_disp_mask) >> intop_disp_shift); - else if ((inst & intop_mask) == subq_pattern) - disp = int((inst & intop_disp_mask) >> intop_disp_shift); - else - return false; - - return true; -} - -bool -StackTrace::decodeSave(MachInst inst, int ®, int &disp) -{ - // lda $stq, disp($sp) - // - // Opcode<31:26> == 0x08 - // RA<25:21> == ? - // RB<20:16> == 30 - // Disp<15:0> - const MachInst stq_mask = 0xfc1f0000; - const MachInst stq_pattern = 0xb41e0000; - const MachInst stq_disp_mask = 0x0000ffff; - const MachInst reg_mask = 0x03e00000; - const int reg_shift = 21; - - if ((inst & stq_mask) == stq_pattern) { - reg = (inst & reg_mask) >> reg_shift; - disp = sext<16>(inst & stq_disp_mask); - } else { - return false; - } - - return true; -} - -/* - * Decode the function prologue for the function we're in, and note - * which registers are stored where, and how large the stack frame is. - */ -bool -StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, - int &size, Addr &ra) -{ - size = 0; - ra = 0; - - for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) { - MachInst inst = tc->getVirtProxy().read(pc); - - int reg, disp; - if (decodeStack(inst, disp)) { - if (size) { - return true; - } - size += disp; - } else if (decodeSave(inst, reg, disp)) { - if (!ra && reg == ReturnAddressReg) { - ra = tc->getVirtProxy().read(sp + disp); - if (!ra) { - return false; - } - } - } - } - - return true; -} - -#if TRACING_ON -void -StackTrace::dump() -{ - panic("Stack trace dump not implemented.\n"); -} -#endif diff --git a/src/arch/mips/stacktrace.hh b/src/arch/mips/stacktrace.hh index 9c0217055b..8612e0687d 100644 --- a/src/arch/mips/stacktrace.hh +++ b/src/arch/mips/stacktrace.hh @@ -29,77 +29,17 @@ #ifndef __ARCH_MIPS_STACKTRACE_HH__ #define __ARCH_MIPS_STACKTRACE_HH__ -#include "base/trace.hh" -#include "cpu/static_inst.hh" -#include "debug/Stack.hh" - -class ThreadContext; +#include "cpu/profile.hh" namespace MipsISA { -class StackTrace +class StackTrace : public BaseStackTrace { protected: - typedef MipsISA::MachInst MachInst; - private: - ThreadContext *tc; - std::vector stack; - - private: - bool isEntry(Addr addr); - bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); - bool decodeSave(MachInst inst, int ®, int &disp); - bool decodeStack(MachInst inst, int &disp); - - void trace(ThreadContext *tc, bool is_call); - - public: - StackTrace(); - StackTrace(ThreadContext *tc, const StaticInstPtr &inst); - ~StackTrace(); - - void clear() - { - tc = 0; - stack.clear(); - } - - bool valid() const { return tc != NULL; } - bool trace(ThreadContext *tc, const StaticInstPtr &inst); - - public: - const std::vector &getstack() const { return stack; } - - static const int user = 1; - static const int console = 2; - static const int unknown = 3; - -#if TRACING_ON - private: - void dump(); - - public: - void dprintf() { if (DTRACE(Stack)) dump(); } -#else - public: - void dprintf() {} -#endif + void trace(ThreadContext *tc, bool is_call) override {}; }; -inline bool -StackTrace::trace(ThreadContext *tc, const StaticInstPtr &inst) -{ - if (!inst->isCall() && !inst->isReturn()) - return false; - - if (valid()) - clear(); - - trace(tc, !inst->isReturn()); - return true; -} - } #endif // __ARCH_MIPS_STACKTRACE_HH__ diff --git a/src/arch/power/SConscript b/src/arch/power/SConscript index 93be38c4c8..a91b5d985e 100644 --- a/src/arch/power/SConscript +++ b/src/arch/power/SConscript @@ -46,7 +46,6 @@ if env['TARGET_ISA'] == 'power': Source('pagetable.cc') Source('process.cc') Source('remote_gdb.cc') - Source('stacktrace.cc') Source('tlb.cc') Source('utility.cc') diff --git a/src/arch/power/stacktrace.cc b/src/arch/power/stacktrace.cc deleted file mode 100644 index 84f1b65472..0000000000 --- a/src/arch/power/stacktrace.cc +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "arch/power/stacktrace.hh" - -#include - -#include "base/trace.hh" - -using namespace std; - -namespace PowerISA { - -StackTrace::StackTrace() - : tc(0), stack(64) -{ - panic("StackTrace constructor not implemented.\n"); -} - -StackTrace::StackTrace(ThreadContext *_tc, const StaticInstPtr &inst) - : tc(0), stack(64) -{ - panic("StackTrace constructor not implemented.\n"); -} - -StackTrace::~StackTrace() -{ - panic("StackTrace destructor not implemented.\n"); -} - -void -StackTrace::trace(ThreadContext *_tc, bool is_call) -{ - panic("StackTrace::trace not implemented.\n"); -} - -bool -StackTrace::isEntry(Addr addr) -{ - panic("StackTrace::isEntry not implemented.\n"); - return false; -} - -bool -StackTrace::decodeStack(MachInst inst, int &disp) -{ - panic("StackTrace::decodeStack not implemented.\n"); - return false; -} - -bool -StackTrace::decodeSave(MachInst inst, int ®, int &disp) -{ - panic("StackTrace::decodeSave not implemented.\n"); - return true; -} - -/* - * Decode the function prologue for the function we're in, and note - * which registers are stored where, and how large the stack frame is. - */ -bool -StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, int &size, - Addr &ra) -{ - panic("StackTrace::decodePrologue not implemented.\n"); - return true; -} - -#if TRACING_ON -void -StackTrace::dump() -{ - panic("StackTrace::dump not implemented.\n"); -} -#endif - -} // namespace PowerISA diff --git a/src/arch/power/stacktrace.hh b/src/arch/power/stacktrace.hh index d67569ff94..729daf1a97 100644 --- a/src/arch/power/stacktrace.hh +++ b/src/arch/power/stacktrace.hh @@ -31,94 +31,22 @@ #ifndef __ARCH_POWER_STACKTRACE_HH__ #define __ARCH_POWER_STACKTRACE_HH__ -#include "base/trace.hh" -#include "cpu/static_inst.hh" -#include "debug/Stack.hh" - -class ThreadContext; -class StackTrace; +#include "base/logging.hh" +#include "cpu/profile.hh" namespace PowerISA { -class StackTrace +class StackTrace : public BaseStackTrace { - private: - ThreadContext *tc; - std::vector stack; - - private: - bool isEntry(Addr addr); - bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); - bool decodeSave(MachInst inst, int ®, int &disp); - bool decodeStack(MachInst inst, int &disp); - - void trace(ThreadContext *tc, bool is_call); - - public: - StackTrace(); - StackTrace(ThreadContext *tc, const StaticInstPtr &inst); - ~StackTrace(); - + protected: void - clear() + trace(ThreadContext *tc, bool is_call) override { - tc = 0; - stack.clear(); + panic("StackTrace::trace not implemented."); } - - bool - valid() const - { - return tc != NULL; - } - - bool trace(ThreadContext *tc, const StaticInstPtr &inst); - - public: - const std::vector & - getstack() const - { - return stack; - } - - static const int user = 1; - static const int console = 2; - static const int unknown = 3; - -#if TRACING_ON - private: - void dump(); - - public: - void - dprintf() - { - if (DTRACE(Stack)) - dump(); - } -#else - public: - void - dprintf() - { - } -#endif }; -inline bool -StackTrace::trace(ThreadContext *tc, const StaticInstPtr &inst) -{ - if (!inst->isCall() && !inst->isReturn()) - return false; - - if (valid()) - clear(); - - trace(tc, !inst->isReturn()); - return true; -} - } // namespace PowerISA #endif // __ARCH_POWER_STACKTRACE_HH__ diff --git a/src/arch/riscv/SConscript b/src/arch/riscv/SConscript index 8a363f5797..f991520974 100644 --- a/src/arch/riscv/SConscript +++ b/src/arch/riscv/SConscript @@ -52,7 +52,6 @@ if env['TARGET_ISA'] == 'riscv': Source('pagetable.cc') Source('pagetable_walker.cc') Source('remote_gdb.cc') - Source('stacktrace.cc') Source('tlb.cc') Source('linux/process.cc') diff --git a/src/arch/riscv/stacktrace.cc b/src/arch/riscv/stacktrace.cc deleted file mode 100644 index f495b60ee9..0000000000 --- a/src/arch/riscv/stacktrace.cc +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "arch/riscv/stacktrace.hh" - -#include - -#include "base/trace.hh" - -using namespace std; - -namespace RiscvISA { - -StackTrace::StackTrace() - : tc(0), stack(64) -{ - panic("StackTrace constructor not implemented.\n"); -} - -StackTrace::StackTrace(ThreadContext *_tc, const StaticInstPtr &inst) - : tc(0), stack(64) -{ - panic("StackTrace constructor not implemented.\n"); -} - -StackTrace::~StackTrace() -{ - panic("StackTrace destructor not implemented.\n"); -} - -void -StackTrace::trace(ThreadContext *_tc, bool is_call) -{ - panic("StackTrace::trace not implemented.\n"); -} - -bool -StackTrace::isEntry(Addr addr) -{ - panic("StackTrace::isEntry not implemented.\n"); - return false; -} - -bool -StackTrace::decodeStack(MachInst inst, int &disp) -{ - panic("StackTrace::decodeStack not implemented.\n"); - return false; -} - -bool -StackTrace::decodeSave(MachInst inst, int ®, int &disp) -{ - panic("StackTrace::decodeSave not implemented.\n"); - return true; -} - -/* - * Decode the function prologue for the function we're in, and note - * which registers are stored where, and how large the stack frame is. - */ -bool -StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, int &size, - Addr &ra) -{ - panic("StackTrace::decodePrologue not implemented.\n"); - return true; -} - -#if TRACING_ON -void -StackTrace::dump() -{ - panic("StackTrace::dump not implemented.\n"); -} -#endif - -} // namespace RiscvISA diff --git a/src/arch/riscv/stacktrace.hh b/src/arch/riscv/stacktrace.hh index 28134126bb..34a608b11d 100644 --- a/src/arch/riscv/stacktrace.hh +++ b/src/arch/riscv/stacktrace.hh @@ -31,94 +31,22 @@ #ifndef __ARCH_RISCV_STACKTRACE_HH__ #define __ARCH_RISCV_STACKTRACE_HH__ -#include "base/trace.hh" -#include "cpu/static_inst.hh" -#include "debug/Stack.hh" - -class ThreadContext; -class StackTrace; +#include "base/logging.hh" +#include "cpu/profile.hh" namespace RiscvISA { -class StackTrace +class StackTrace : public BaseStackTrace { - private: - ThreadContext *tc; - std::vector stack; - - private: - bool isEntry(Addr addr); - bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); - bool decodeSave(MachInst inst, int ®, int &disp); - bool decodeStack(MachInst inst, int &disp); - - void trace(ThreadContext *tc, bool is_call); - - public: - StackTrace(); - StackTrace(ThreadContext *tc, const StaticInstPtr &inst); - ~StackTrace(); - + protected: void - clear() + trace(ThreadContext *tc, bool is_call) override { - tc = 0; - stack.clear(); + panic("StackTrace::trace not implemented."); } - - bool - valid() const - { - return tc != nullptr; - } - - bool trace(ThreadContext *tc, const StaticInstPtr &inst); - - public: - const std::vector & - getstack() const - { - return stack; - } - - static const int user = 1; - static const int console = 2; - static const int unknown = 3; - -#if TRACING_ON - private: - void dump(); - - public: - void - dprintf() - { - if (DTRACE(Stack)) - dump(); - } -#else - public: - void - dprintf() - { - } -#endif }; -inline bool -StackTrace::trace(ThreadContext *tc, const StaticInstPtr &inst) -{ - if (!inst->isCall() && !inst->isReturn()) - return false; - - if (valid()) - clear(); - - trace(tc, !inst->isReturn()); - return true; -} - } // namespace RiscvISA #endif // __ARCH_RISCV_STACKTRACE_HH__ diff --git a/src/arch/sparc/stacktrace.hh b/src/arch/sparc/stacktrace.hh index de931aaed3..a40859d845 100644 --- a/src/arch/sparc/stacktrace.hh +++ b/src/arch/sparc/stacktrace.hh @@ -29,33 +29,19 @@ #ifndef __ARCH_SPARC_STACKTRACE_HH__ #define __ARCH_SPARC_STACKTRACE_HH__ -#include +#include "cpu/profile.hh" -#include "base/types.hh" -#include "cpu/static_inst.hh" -#include "debug/Stack.hh" - -class ThreadContext; namespace SparcISA { -class StackTrace +class StackTrace : public BaseStackTrace { - private: - std::vector stack; - - public: - bool - trace(ThreadContext *tc, const StaticInstPtr &inst) + protected: + void + trace(ThreadContext *tc, bool is_call) override { - panic("StackTrace::trace not implemented for SPARC.\n"); - return false; + panic("StackTrace::trace not implemented for SPARC."); } - - const std::vector &getstack() const { return stack; } - - public: - void dprintf() {} }; } diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index 9bf4fb87ea..1be41ed7a9 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -65,7 +65,6 @@ if env['TARGET_ISA'] == 'x86': Source('process.cc') Source('pseudo_inst.cc') Source('remote_gdb.cc') - Source('stacktrace.cc') Source('tlb.cc') Source('types.cc') Source('utility.cc') diff --git a/src/arch/x86/stacktrace.cc b/src/arch/x86/stacktrace.cc deleted file mode 100644 index 2d4e8fbe06..0000000000 --- a/src/arch/x86/stacktrace.cc +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "arch/x86/stacktrace.hh" - -#include - -#include "arch/x86/isa_traits.hh" -#include "base/bitfield.hh" -#include "base/trace.hh" -#include "cpu/base.hh" -#include "cpu/thread_context.hh" -#include "mem/port_proxy.hh" -#include "sim/system.hh" - -namespace X86ISA -{ - -StackTrace::StackTrace() - : tc(0), stack(64) -{ -} - -StackTrace::StackTrace(ThreadContext *_tc, const StaticInstPtr &inst) - : tc(0), stack(64) -{ - trace(_tc, inst); -} - -StackTrace::~StackTrace() -{ -} - -void -StackTrace::trace(ThreadContext *_tc, bool is_call) -{ -} - -bool -StackTrace::isEntry(Addr addr) -{ - return false; -} - -bool -StackTrace::decodeStack(MachInst inst, int &disp) -{ - disp = 0; - return true; -} - -bool -StackTrace::decodeSave(MachInst inst, int ®, int &disp) -{ - reg = 0; - disp = 0; - return true; -} - -/* - * Decode the function prologue for the function we're in, and note - * which registers are stored where, and how large the stack frame is. - */ -bool -StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, - int &size, Addr &ra) -{ - size = 0; - ra = 0; - - for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) { - MachInst inst = tc->getVirtProxy().read(pc); - - int reg, disp; - if (decodeStack(inst, disp)) { - if (size) { - // panic("decoding frame size again"); - return true; - } - size += disp; - } else if (decodeSave(inst, reg, disp)) { - if (!ra && reg == ReturnAddressReg) { - ra = tc->getVirtProxy().read(sp + disp); - if (!ra) { - // panic("no return address value pc=%#x\n", pc); - return false; - } - } - } - } - - return true; -} - -#if TRACING_ON -void -StackTrace::dump() -{ - StringWrap name(tc->getCpuPtr()->name()); - const auto &symtab = tc->getSystemPtr()->workload->symtab(tc); - - DPRINTFN("------ Stack ------\n"); - - std::string symbol; - for (int i = 0, size = stack.size(); i < size; ++i) { - Addr addr = stack[size - i - 1]; - Loader::SymbolTable::const_iterator it; - if (addr == user) - symbol = "user"; - else if (addr == console) - symbol = "console"; - else if (addr == unknown) - symbol = "unknown"; - else if ((it = symtab.find(addr)) != symtab.end()) - symbol = it->name; - - DPRINTFN("%#x: %s\n", addr, symbol); - } -} - -#endif -} diff --git a/src/arch/x86/stacktrace.hh b/src/arch/x86/stacktrace.hh index c53362d08e..8fa3b65d6c 100644 --- a/src/arch/x86/stacktrace.hh +++ b/src/arch/x86/stacktrace.hh @@ -29,74 +29,17 @@ #ifndef __ARCH_X86_STACKTRACE_HH__ #define __ARCH_X86_STACKTRACE_HH__ -#include "base/trace.hh" -#include "cpu/static_inst.hh" -#include "debug/Stack.hh" +#include "cpu/profile.hh" -class ThreadContext; namespace X86ISA { -class StackTrace +class StackTrace : public BaseStackTrace { - private: - ThreadContext *tc; - std::vector stack; - - private: - bool isEntry(Addr addr); - bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); - bool decodeSave(MachInst inst, int ®, int &disp); - bool decodeStack(MachInst inst, int &disp); - - void trace(ThreadContext *tc, bool is_call); - - public: - StackTrace(); - StackTrace(ThreadContext *tc, const StaticInstPtr &inst); - ~StackTrace(); - - void clear() - { - tc = 0; - stack.clear(); - } - - bool valid() const { return tc != NULL; } - bool trace(ThreadContext *tc, const StaticInstPtr &inst); - - public: - const std::vector &getstack() const { return stack; } - - static const int user = 1; - static const int console = 2; - static const int unknown = 3; - -#if TRACING_ON - private: - void dump(); - - public: - void dprintf() { if (DTRACE(Stack)) dump(); } -#else - public: - void dprintf() {} -#endif + protected: + void trace(ThreadContext *tc, bool is_call) override {}; }; -inline bool -StackTrace::trace(ThreadContext *tc, const StaticInstPtr &inst) -{ - if (!inst->isCall() && !inst->isReturn()) - return false; - - if (valid()) - clear(); - - trace(tc, !inst->isReturn()); - return true; -} - } // namespace X86ISA #endif // __ARCH_X86_STACKTRACE_HH__ diff --git a/src/cpu/o3/thread_state.hh b/src/cpu/o3/thread_state.hh index 833b2b809c..30320bc529 100644 --- a/src/cpu/o3/thread_state.hh +++ b/src/cpu/o3/thread_state.hh @@ -41,7 +41,9 @@ #ifndef __CPU_O3_THREAD_STATE_HH__ #define __CPU_O3_THREAD_STATE_HH__ +#include "arch/stacktrace.hh" #include "base/callback.hh" +#include "base/compiler.hh" #include "base/output.hh" #include "cpu/thread_context.hh" #include "cpu/thread_state.hh" @@ -103,6 +105,7 @@ struct O3ThreadState : public ThreadState { if (cpu->params()->profile) { profile = new FunctionProfile( + m5::make_unique(), cpu->params()->system->workload->symtab(tc)); Callback *cb = new MakeCallbackgetCpuPtr()->name()); + auto *symtab = &tc->getSystemPtr()->workload->symtab(tc); + + DPRINTFN("------ Stack ------\n"); + + std::string symbol; + for (int i = 0, size = stack.size(); i < size; ++i) { + Addr addr = stack[size - i - 1]; + getSymbol(symbol, addr, symtab); + DPRINTFN("%#x: %s\n", addr, symbol); + } +} + +bool +BaseStackTrace::tryGetSymbol(std::string &symbol, Addr addr, + const Loader::SymbolTable *symtab) +{ + const auto it = symtab->find(addr); + if (it == symtab->end()) + return false; + symbol = it->name; + return true; +} + void ProfileNode::dump(const std::string &symbol, uint64_t id, - const Loader::SymbolTable &symtab, std::ostream &os) const + const FunctionProfile &prof, std::ostream &os) const { ccprintf(os, "%#x %s %d ", id, symbol, count); for (const auto &p: children) @@ -49,21 +77,11 @@ ProfileNode::dump(const std::string &symbol, uint64_t id, for (const auto &p: children) { Addr addr = p.first; std::string symbol; - if (addr == 1) { - symbol = "user"; - } else if (addr == 2) { - symbol = "console"; - } else if (addr == 3) { - symbol = "unknown"; - } else { - const auto it = symtab.find(addr); - panic_if(it == symtab.end(), - "Could not find symbol for address %#x\n", addr); - symbol = it->name; - } + + prof.trace->getSymbol(symbol, addr, &prof.symtab); const auto *node = p.second; - node->dump(symbol, (intptr_t)node, symtab, os); + node->dump(symbol, (intptr_t)node, prof, os); } } @@ -75,8 +93,9 @@ ProfileNode::clear() p.second->clear(); } -FunctionProfile::FunctionProfile(const Loader::SymbolTable &_symtab) : - symtab(_symtab) +FunctionProfile::FunctionProfile(std::unique_ptr _trace, + const Loader::SymbolTable &_symtab) : + symtab(_symtab), trace(std::move(_trace)) { reset = new MakeCallback(this); Stats::registerResetCallback(reset); @@ -117,22 +136,15 @@ FunctionProfile::dump(std::ostream &os) const Addr pc = p.first; Counter count = p.second; - if (pc == 1) { - ccprintf(os, "user %d\n", count); - continue; - } - - const auto it = symtab.find(pc); - if (it != symtab.end() && !it->name.empty()) { - ccprintf(os, "%s %d\n", it->name, count); - continue; - } - - ccprintf(os, "%#x %d\n", pc, count); + std::string symbol; + if (trace->tryGetSymbol(symbol, pc, &symtab)) + ccprintf(os, "%s %d\n", symbol, count); + else + ccprintf(os, "%#x %d\n", pc, count); } ccprintf(os, ">>>function data\n"); - top.dump("top", 0, symtab, os); + top.dump("top", 0, *this, os); } void diff --git a/src/cpu/profile.hh b/src/cpu/profile.hh index f6b98d3f69..0f2d8a8383 100644 --- a/src/cpu/profile.hh +++ b/src/cpu/profile.hh @@ -30,13 +30,82 @@ #define __CPU_PROFILE_HH__ #include +#include -#include "arch/stacktrace.hh" +#include "base/logging.hh" #include "base/types.hh" -#include "config/the_isa.hh" #include "cpu/static_inst.hh" +#include "debug/Stack.hh" class ThreadContext; +class FunctionProfile; + +namespace Loader +{ + class SymbolTable; +} // Loader + +class BaseStackTrace +{ + private: + void dump(); + + protected: + ThreadContext *tc = nullptr; + std::vector stack; + + // Subclasses should implement this function so that it collects the + // the current and return addresses on the stack in the "stack" vector. + virtual void trace(ThreadContext *tc, bool is_call) = 0; + + public: + BaseStackTrace() : stack(64) {} + virtual ~BaseStackTrace() {} + + void + clear() + { + tc = nullptr; + stack.clear(); + } + + bool valid() const { return tc; } + + bool + trace(ThreadContext *tc, const StaticInstPtr &inst) + { + if (!inst->isCall() && !inst->isReturn()) + return false; + + if (valid()) + clear(); + + trace(tc, !inst->isReturn()); + return true; + } + + const std::vector &getstack() const { return stack; } + + void dprintf() { if (DTRACE(Stack)) dump(); } + + // This function can be overridden so that special addresses which don't + // actually refer to PCs can be translated into special names. For + // instance, the address 1 could translate into "user" for user level + // code when the symbol table only has kernel symbols. + // + // It should return whether addr was recognized and symbol has been set to + // something. + virtual bool tryGetSymbol(std::string &symbol, Addr addr, + const Loader::SymbolTable *symtab); + + void + getSymbol(std::string &symbol, Addr addr, + const Loader::SymbolTable *symtab) + { + panic_if(!tryGetSymbol(symbol, addr, symtab), + "Could not find symbol for address %#x\n", addr); + } +}; class ProfileNode { @@ -51,7 +120,7 @@ class ProfileNode public: void dump(const std::string &symbol, uint64_t id, - const Loader::SymbolTable &symtab, std::ostream &os) const; + const FunctionProfile &prof, std::ostream &os) const; void clear(); }; @@ -59,14 +128,17 @@ class Callback; class FunctionProfile { private: + friend class ProfileNode; + Callback *reset = nullptr; const Loader::SymbolTable &symtab; ProfileNode top; std::map pc_count; - TheISA::StackTrace trace; + std::unique_ptr trace; public: - FunctionProfile(const Loader::SymbolTable &symtab); + FunctionProfile(std::unique_ptr _trace, + const Loader::SymbolTable &symtab); ~FunctionProfile(); ProfileNode *consume(ThreadContext *tc, const StaticInstPtr &inst); @@ -79,10 +151,10 @@ class FunctionProfile inline ProfileNode * FunctionProfile::consume(ThreadContext *tc, const StaticInstPtr &inst) { - if (!trace.trace(tc, inst)) + if (!trace->trace(tc, inst)) return nullptr; - trace.dprintf(); - return consume(trace.getstack()); + trace->dprintf(); + return consume(trace->getstack()); } #endif // __CPU_PROFILE_HH__ diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index c30872c6a3..4efe6c1691 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -46,6 +46,7 @@ #include "arch/stacktrace.hh" #include "arch/utility.hh" #include "base/callback.hh" +#include "base/compiler.hh" #include "base/cprintf.hh" #include "base/output.hh" #include "base/trace.hh" @@ -92,7 +93,8 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys, clearArchRegs(); if (baseCpu->params()->profile) { - profile = new FunctionProfile(system->workload->symtab(this)); + profile = new FunctionProfile(m5::make_unique(), + system->workload->symtab(this)); Callback *cb = new MakeCallback(this);