130fdc8d8SChris Lattner //===-- StackID.cpp ---------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner // C Includes
1130fdc8d8SChris Lattner // C++ Includes
1230fdc8d8SChris Lattner // Other libraries and framework includes
1330fdc8d8SChris Lattner // Project includes
14d70a6e71SEugene Zelenko #include "lldb/Target/StackID.h"
1559e8fc1cSGreg Clayton #include "lldb/Symbol/Block.h"
1659e8fc1cSGreg Clayton #include "lldb/Symbol/Symbol.h"
1759e8fc1cSGreg Clayton #include "lldb/Symbol/SymbolContext.h"
18*bf9a7730SZachary Turner #include "lldb/Utility/Stream.h"
1930fdc8d8SChris Lattner 
2030fdc8d8SChris Lattner using namespace lldb_private;
2130fdc8d8SChris Lattner 
22b9c1b51eSKate Stone void StackID::Dump(Stream *s) {
23b9c1b51eSKate Stone   s->Printf("StackID (pc = 0x%16.16" PRIx64 ", cfa = 0x%16.16" PRIx64
24b9c1b51eSKate Stone             ", symbol_scope = %p",
25324a1036SSaleem Abdulrasool             m_pc, m_cfa, static_cast<void *>(m_symbol_scope));
26b9c1b51eSKate Stone   if (m_symbol_scope) {
2759e8fc1cSGreg Clayton     SymbolContext sc;
2859e8fc1cSGreg Clayton 
2959e8fc1cSGreg Clayton     m_symbol_scope->CalculateSymbolContext(&sc);
3059e8fc1cSGreg Clayton     if (sc.block)
31d01b2953SDaniel Malea       s->Printf(" (Block {0x%8.8" PRIx64 "})", sc.block->GetID());
3259e8fc1cSGreg Clayton     else if (sc.symbol)
3359e8fc1cSGreg Clayton       s->Printf(" (Symbol{0x%8.8x})", sc.symbol->GetID());
3459e8fc1cSGreg Clayton   }
3559e8fc1cSGreg Clayton   s->PutCString(") ");
3659e8fc1cSGreg Clayton }
3759e8fc1cSGreg Clayton 
38b9c1b51eSKate Stone bool lldb_private::operator==(const StackID &lhs, const StackID &rhs) {
396dadd508SGreg Clayton   if (lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress())
406dadd508SGreg Clayton     return false;
416dadd508SGreg Clayton 
426dadd508SGreg Clayton   SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope();
436dadd508SGreg Clayton   SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope();
446dadd508SGreg Clayton 
45d70a6e71SEugene Zelenko   // Only compare the PC values if both symbol context scopes are nullptr
46d70a6e71SEugene Zelenko   if (lhs_scope == nullptr && rhs_scope == nullptr)
476dadd508SGreg Clayton     return lhs.GetPC() == rhs.GetPC();
486dadd508SGreg Clayton 
496dadd508SGreg Clayton   return lhs_scope == rhs_scope;
5030fdc8d8SChris Lattner }
5130fdc8d8SChris Lattner 
52b9c1b51eSKate Stone bool lldb_private::operator!=(const StackID &lhs, const StackID &rhs) {
536dadd508SGreg Clayton   if (lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress())
546dadd508SGreg Clayton     return true;
556dadd508SGreg Clayton 
566dadd508SGreg Clayton   SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope();
576dadd508SGreg Clayton   SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope();
586dadd508SGreg Clayton 
59d70a6e71SEugene Zelenko   if (lhs_scope == nullptr && rhs_scope == nullptr)
606dadd508SGreg Clayton     return lhs.GetPC() != rhs.GetPC();
616dadd508SGreg Clayton 
626dadd508SGreg Clayton   return lhs_scope != rhs_scope;
6330fdc8d8SChris Lattner }
6430fdc8d8SChris Lattner 
65b9c1b51eSKate Stone bool lldb_private::operator<(const StackID &lhs, const StackID &rhs) {
666dadd508SGreg Clayton   const lldb::addr_t lhs_cfa = lhs.GetCallFrameAddress();
676dadd508SGreg Clayton   const lldb::addr_t rhs_cfa = rhs.GetCallFrameAddress();
686dadd508SGreg Clayton 
69b9c1b51eSKate Stone   // FIXME: We are assuming that the stacks grow downward in memory.  That's not
70b9c1b51eSKate Stone   // necessary, but true on
71b9c1b51eSKate Stone   // all the machines we care about at present.  If this changes, we'll have to
72b9c1b51eSKate Stone   // deal with that.  The ABI is the
73b9c1b51eSKate Stone   // agent who knows this ordering, but the StackID has no access to the ABI.
74b9c1b51eSKate Stone   // The most straightforward way
75b9c1b51eSKate Stone   // to handle this is to add a "m_grows_downward" bool to the StackID, and set
76b9c1b51eSKate Stone   // it in the constructor.
77b5c0d1ccSJim Ingham   // But I'm not going to waste a bool per StackID on this till we need it.
78b5c0d1ccSJim Ingham 
796dadd508SGreg Clayton   if (lhs_cfa != rhs_cfa)
806dadd508SGreg Clayton     return lhs_cfa < rhs_cfa;
816dadd508SGreg Clayton 
826dadd508SGreg Clayton   SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope();
836dadd508SGreg Clayton   SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope();
846dadd508SGreg Clayton 
85b9c1b51eSKate Stone   if (lhs_scope != nullptr && rhs_scope != nullptr) {
866dadd508SGreg Clayton     // Same exact scope, lhs is not less than (younger than rhs)
876dadd508SGreg Clayton     if (lhs_scope == rhs_scope)
886dadd508SGreg Clayton       return false;
896dadd508SGreg Clayton 
906dadd508SGreg Clayton     SymbolContext lhs_sc;
916dadd508SGreg Clayton     SymbolContext rhs_sc;
926dadd508SGreg Clayton     lhs_scope->CalculateSymbolContext(&lhs_sc);
936dadd508SGreg Clayton     rhs_scope->CalculateSymbolContext(&rhs_sc);
946dadd508SGreg Clayton 
956dadd508SGreg Clayton     // Items with the same function can only be compared
96b9c1b51eSKate Stone     if (lhs_sc.function == rhs_sc.function && lhs_sc.function != nullptr &&
97b9c1b51eSKate Stone         lhs_sc.block != nullptr && rhs_sc.function != nullptr &&
98b9c1b51eSKate Stone         rhs_sc.block != nullptr) {
996dadd508SGreg Clayton       return rhs_sc.block->Contains(lhs_sc.block);
1006dadd508SGreg Clayton     }
1016dadd508SGreg Clayton   }
1026dadd508SGreg Clayton   return false;
10330fdc8d8SChris Lattner }
104