stacktrace.hh revision 13915:24ae4ea846c9
12379SN/A/*
22379SN/A * Copyright (c) 2005 The Regents of The University of Michigan
32379SN/A * Copyright (c) 2007-2008 The Florida State University
42379SN/A * Copyright (c) 2009 The University of Edinburgh
52379SN/A * All rights reserved.
62379SN/A *
72379SN/A * Redistribution and use in source and binary forms, with or without
82379SN/A * modification, are permitted provided that the following conditions are
92379SN/A * met: redistributions of source code must retain the above copyright
102379SN/A * notice, this list of conditions and the following disclaimer;
112379SN/A * redistributions in binary form must reproduce the above copyright
122379SN/A * notice, this list of conditions and the following disclaimer in the
132379SN/A * documentation and/or other materials provided with the distribution;
142379SN/A * neither the name of the copyright holders nor the names of its
152379SN/A * contributors may be used to endorse or promote products derived from
162379SN/A * this software without specific prior written permission.
172379SN/A *
182379SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
192379SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
202379SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
212379SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
222379SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
232379SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
242379SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
252379SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
262379SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
272665Ssaidi@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
282665Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
292665Ssaidi@eecs.umich.edu *
302379SN/A * Authors: Ali Saidi
312379SN/A *          Stephen Hines
322379SN/A *          Timothy M. Jones
332379SN/A */
342379SN/A
352379SN/A#ifndef __ARCH_RISCV_STACKTRACE_HH__
362379SN/A#define __ARCH_RISCV_STACKTRACE_HH__
372379SN/A
382379SN/A#include "base/trace.hh"
392379SN/A#include "cpu/static_inst.hh"
402423SN/A#include "debug/Stack.hh"
412399SN/A
422379SN/Aclass ThreadContext;
432379SN/Aclass StackTrace;
442379SN/A
452379SN/Anamespace RiscvISA
462379SN/A{
472399SN/A
482379SN/Aclass ProcessInfo
492399SN/A{
502423SN/A  public:
512399SN/A    ProcessInfo(ThreadContext *_tc);
522399SN/A
532399SN/A    Addr task(Addr ksp) const;
542399SN/A    int pid(Addr ksp) const;
552379SN/A    std::string name(Addr ksp) const;
562399SN/A};
572379SN/A
582379SN/Aclass StackTrace
592379SN/A{
602379SN/A  private:
612379SN/A    ThreadContext *tc;
622379SN/A    std::vector<Addr> stack;
632379SN/A
642423SN/A  private:
652379SN/A    bool isEntry(Addr addr);
662379SN/A    bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
672394SN/A    bool decodeSave(MachInst inst, int &reg, int &disp);
682379SN/A    bool decodeStack(MachInst inst, int &disp);
692423SN/A
702379SN/A    void trace(ThreadContext *tc, bool is_call);
712379SN/A
722423SN/A  public:
732423SN/A    StackTrace();
742379SN/A    StackTrace(ThreadContext *tc, const StaticInstPtr &inst);
752379SN/A    ~StackTrace();
762379SN/A
772379SN/A    void
782423SN/A    clear()
792379SN/A    {
802379SN/A        tc = 0;
812423SN/A        stack.clear();
822423SN/A    }
832379SN/A
842379SN/A    bool
852423SN/A    valid() const
862379SN/A    {
872379SN/A        return tc != nullptr;
882379SN/A    }
892399SN/A
902399SN/A    bool trace(ThreadContext *tc, const StaticInstPtr &inst);
912399SN/A
922399SN/A  public:
932399SN/A    const std::vector<Addr> &
942399SN/A    getstack() const
952399SN/A    {
962399SN/A        return stack;
972399SN/A    }
982399SN/A
992399SN/A    static const int user = 1;
1002399SN/A    static const int console = 2;
1012399SN/A    static const int unknown = 3;
1022399SN/A
1032399SN/A#if TRACING_ON
1042399SN/A  private:
1052399SN/A    void dump();
1062399SN/A
1072399SN/A  public:
1082399SN/A    void
1092399SN/A    dprintf()
1102399SN/A    {
1112399SN/A        if (DTRACE(Stack))
1122399SN/A            dump();
1132399SN/A    }
1142399SN/A#else
1152399SN/A  public:
1162399SN/A    void
1172399SN/A    dprintf()
1182399SN/A    {
1192399SN/A    }
1202399SN/A#endif
1212399SN/A};
1222399SN/A
1232399SN/Ainline bool
1242399SN/AStackTrace::trace(ThreadContext *tc, const StaticInstPtr &inst)
1252399SN/A{
1262394SN/A    if (!inst->isCall() && !inst->isReturn())
1272532SN/A        return false;
1282394SN/A
1292532SN/A    if (valid())
1302532SN/A        clear();
1312532SN/A
1322532SN/A    trace(tc, !inst->isReturn());
1332423SN/A    return true;
1342399SN/A}
1352532SN/A
1362532SN/A} // namespace RiscvISA
1372394SN/A
138#endif // __ARCH_RISCV_STACKTRACE_HH__
139