11917SN/A/*
21917SN/A * Copyright (c) 2005 The Regents of The University of Michigan
31917SN/A * All rights reserved.
41917SN/A *
51917SN/A * Redistribution and use in source and binary forms, with or without
61917SN/A * modification, are permitted provided that the following conditions are
71917SN/A * met: redistributions of source code must retain the above copyright
81917SN/A * notice, this list of conditions and the following disclaimer;
91917SN/A * redistributions in binary form must reproduce the above copyright
101917SN/A * notice, this list of conditions and the following disclaimer in the
111917SN/A * documentation and/or other materials provided with the distribution;
121917SN/A * neither the name of the copyright holders nor the names of its
131917SN/A * contributors may be used to endorse or promote products derived from
141917SN/A * this software without specific prior written permission.
151917SN/A *
161917SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171917SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181917SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191917SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201917SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211917SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221917SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231917SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241917SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251917SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261917SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
291917SN/A */
301917SN/A
311917SN/A#ifndef __ARCH_ALPHA_STACKTRACE_HH__
321917SN/A#define __ARCH_ALPHA_STACKTRACE_HH__
331917SN/A
341917SN/A#include "base/trace.hh"
351917SN/A#include "cpu/static_inst.hh"
368232Snate@binkert.org#include "debug/Stack.hh"
371917SN/A
382680Sktlim@umich.educlass ThreadContext;
391917SN/A
405569Snate@binkert.orgnamespace AlphaISA {
415569Snate@binkert.org
425569Snate@binkert.orgclass StackTrace;
435569Snate@binkert.org
445569Snate@binkert.orgclass ProcessInfo
451917SN/A{
465569Snate@binkert.org  private:
475569Snate@binkert.org    ThreadContext *tc;
481917SN/A
495569Snate@binkert.org    int thread_info_size;
505569Snate@binkert.org    int task_struct_size;
515569Snate@binkert.org    int task_off;
525569Snate@binkert.org    int pid_off;
535569Snate@binkert.org    int name_off;
545569Snate@binkert.org
555569Snate@binkert.org  public:
565569Snate@binkert.org    ProcessInfo(ThreadContext *_tc);
575569Snate@binkert.org
585569Snate@binkert.org    Addr task(Addr ksp) const;
595569Snate@binkert.org    int pid(Addr ksp) const;
605569Snate@binkert.org    std::string name(Addr ksp) const;
615569Snate@binkert.org};
625569Snate@binkert.org
635569Snate@binkert.orgclass StackTrace
645569Snate@binkert.org{
655569Snate@binkert.org  private:
665569Snate@binkert.org    ThreadContext *tc;
675569Snate@binkert.org    std::vector<Addr> stack;
685569Snate@binkert.org
695569Snate@binkert.org  private:
705569Snate@binkert.org    bool isEntry(Addr addr);
715569Snate@binkert.org    bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
725569Snate@binkert.org    bool decodeSave(MachInst inst, int &reg, int &disp);
735569Snate@binkert.org    bool decodeStack(MachInst inst, int &disp);
745569Snate@binkert.org
755569Snate@binkert.org    void trace(ThreadContext *tc, bool is_call);
765569Snate@binkert.org
775569Snate@binkert.org  public:
785569Snate@binkert.org    StackTrace();
7910417Sandreas.hansson@arm.com    StackTrace(ThreadContext *tc, const StaticInstPtr &inst);
805569Snate@binkert.org    ~StackTrace();
815569Snate@binkert.org
825569Snate@binkert.org    void
835569Snate@binkert.org    clear()
843570Sgblack@eecs.umich.edu    {
855569Snate@binkert.org        tc = 0;
865569Snate@binkert.org        stack.clear();
875569Snate@binkert.org    }
881917SN/A
895569Snate@binkert.org    bool valid() const { return tc != NULL; }
9010417Sandreas.hansson@arm.com    bool trace(ThreadContext *tc, const StaticInstPtr &inst);
911917SN/A
925569Snate@binkert.org  public:
935569Snate@binkert.org    const std::vector<Addr> &getstack() const { return stack; }
941917SN/A
956227Snate@binkert.org    enum {
966227Snate@binkert.org        user = 1,
976227Snate@binkert.org        console = 2,
986227Snate@binkert.org        unknown = 3
996227Snate@binkert.org    };
1001917SN/A
1011917SN/A#if TRACING_ON
1025569Snate@binkert.org  private:
1035569Snate@binkert.org    void dump();
1041917SN/A
1055569Snate@binkert.org  public:
1065569Snate@binkert.org    void dprintf() { if (DTRACE(Stack)) dump(); }
1071917SN/A#else
1085569Snate@binkert.org  public:
1095569Snate@binkert.org    void dprintf() {}
1101917SN/A#endif
1115569Snate@binkert.org};
1121917SN/A
1135569Snate@binkert.orginline bool
11410417Sandreas.hansson@arm.comStackTrace::trace(ThreadContext *tc, const StaticInstPtr &inst)
1155569Snate@binkert.org{
1165569Snate@binkert.org    if (!inst->isCall() && !inst->isReturn())
1175569Snate@binkert.org        return false;
1181917SN/A
1195569Snate@binkert.org    if (valid())
1205569Snate@binkert.org        clear();
1211977SN/A
1225569Snate@binkert.org    trace(tc, !inst->isReturn());
1235569Snate@binkert.org    return true;
1241917SN/A}
1251917SN/A
1265569Snate@binkert.org} // namespace AlphaISA
1275569Snate@binkert.org
1281917SN/A#endif // __ARCH_ALPHA_STACKTRACE_HH__
129