1ac7ddfbfSEd Maste //===-- StackID.cpp ---------------------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste // The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste
104bb0738eSEd Maste #include "lldb/Target/StackID.h"
11ac7ddfbfSEd Maste #include "lldb/Symbol/Block.h"
12ac7ddfbfSEd Maste #include "lldb/Symbol/Symbol.h"
13ac7ddfbfSEd Maste #include "lldb/Symbol/SymbolContext.h"
14f678e45dSDimitry Andric #include "lldb/Utility/Stream.h"
15ac7ddfbfSEd Maste
16ac7ddfbfSEd Maste using namespace lldb_private;
17ac7ddfbfSEd Maste
Dump(Stream * s)18435933ddSDimitry Andric void StackID::Dump(Stream *s) {
19435933ddSDimitry Andric s->Printf("StackID (pc = 0x%16.16" PRIx64 ", cfa = 0x%16.16" PRIx64
20435933ddSDimitry Andric ", symbol_scope = %p",
210127ef0fSEd Maste m_pc, m_cfa, static_cast<void *>(m_symbol_scope));
22435933ddSDimitry Andric if (m_symbol_scope) {
23ac7ddfbfSEd Maste SymbolContext sc;
24ac7ddfbfSEd Maste
25ac7ddfbfSEd Maste m_symbol_scope->CalculateSymbolContext(&sc);
26ac7ddfbfSEd Maste if (sc.block)
27ac7ddfbfSEd Maste s->Printf(" (Block {0x%8.8" PRIx64 "})", sc.block->GetID());
28ac7ddfbfSEd Maste else if (sc.symbol)
29ac7ddfbfSEd Maste s->Printf(" (Symbol{0x%8.8x})", sc.symbol->GetID());
30ac7ddfbfSEd Maste }
31ac7ddfbfSEd Maste s->PutCString(") ");
32ac7ddfbfSEd Maste }
33ac7ddfbfSEd Maste
operator ==(const StackID & lhs,const StackID & rhs)34435933ddSDimitry Andric bool lldb_private::operator==(const StackID &lhs, const StackID &rhs) {
35ac7ddfbfSEd Maste if (lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress())
36ac7ddfbfSEd Maste return false;
37ac7ddfbfSEd Maste
38ac7ddfbfSEd Maste SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope();
39ac7ddfbfSEd Maste SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope();
40ac7ddfbfSEd Maste
414bb0738eSEd Maste // Only compare the PC values if both symbol context scopes are nullptr
424bb0738eSEd Maste if (lhs_scope == nullptr && rhs_scope == nullptr)
43ac7ddfbfSEd Maste return lhs.GetPC() == rhs.GetPC();
44ac7ddfbfSEd Maste
45ac7ddfbfSEd Maste return lhs_scope == rhs_scope;
46ac7ddfbfSEd Maste }
47ac7ddfbfSEd Maste
operator !=(const StackID & lhs,const StackID & rhs)48435933ddSDimitry Andric bool lldb_private::operator!=(const StackID &lhs, const StackID &rhs) {
49ac7ddfbfSEd Maste if (lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress())
50ac7ddfbfSEd Maste return true;
51ac7ddfbfSEd Maste
52ac7ddfbfSEd Maste SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope();
53ac7ddfbfSEd Maste SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope();
54ac7ddfbfSEd Maste
554bb0738eSEd Maste if (lhs_scope == nullptr && rhs_scope == nullptr)
56ac7ddfbfSEd Maste return lhs.GetPC() != rhs.GetPC();
57ac7ddfbfSEd Maste
58ac7ddfbfSEd Maste return lhs_scope != rhs_scope;
59ac7ddfbfSEd Maste }
60ac7ddfbfSEd Maste
operator <(const StackID & lhs,const StackID & rhs)61435933ddSDimitry Andric bool lldb_private::operator<(const StackID &lhs, const StackID &rhs) {
62ac7ddfbfSEd Maste const lldb::addr_t lhs_cfa = lhs.GetCallFrameAddress();
63ac7ddfbfSEd Maste const lldb::addr_t rhs_cfa = rhs.GetCallFrameAddress();
64ac7ddfbfSEd Maste
65435933ddSDimitry Andric // FIXME: We are assuming that the stacks grow downward in memory. That's not
66435933ddSDimitry Andric // necessary, but true on
67435933ddSDimitry Andric // all the machines we care about at present. If this changes, we'll have to
68*4ba319b5SDimitry Andric // deal with that. The ABI is the agent who knows this ordering, but the
69*4ba319b5SDimitry Andric // StackID has no access to the ABI. The most straightforward way to handle
70*4ba319b5SDimitry Andric // this is to add a "m_grows_downward" bool to the StackID, and set it in the
71*4ba319b5SDimitry Andric // constructor. But I'm not going to waste a bool per StackID on this till we
72*4ba319b5SDimitry Andric // need it.
73ac7ddfbfSEd Maste
74ac7ddfbfSEd Maste if (lhs_cfa != rhs_cfa)
75ac7ddfbfSEd Maste return lhs_cfa < rhs_cfa;
76ac7ddfbfSEd Maste
77ac7ddfbfSEd Maste SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope();
78ac7ddfbfSEd Maste SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope();
79ac7ddfbfSEd Maste
80435933ddSDimitry Andric if (lhs_scope != nullptr && rhs_scope != nullptr) {
81ac7ddfbfSEd Maste // Same exact scope, lhs is not less than (younger than rhs)
82ac7ddfbfSEd Maste if (lhs_scope == rhs_scope)
83ac7ddfbfSEd Maste return false;
84ac7ddfbfSEd Maste
85ac7ddfbfSEd Maste SymbolContext lhs_sc;
86ac7ddfbfSEd Maste SymbolContext rhs_sc;
87ac7ddfbfSEd Maste lhs_scope->CalculateSymbolContext(&lhs_sc);
88ac7ddfbfSEd Maste rhs_scope->CalculateSymbolContext(&rhs_sc);
89ac7ddfbfSEd Maste
90ac7ddfbfSEd Maste // Items with the same function can only be compared
91435933ddSDimitry Andric if (lhs_sc.function == rhs_sc.function && lhs_sc.function != nullptr &&
92435933ddSDimitry Andric lhs_sc.block != nullptr && rhs_sc.function != nullptr &&
93435933ddSDimitry Andric rhs_sc.block != nullptr) {
94ac7ddfbfSEd Maste return rhs_sc.block->Contains(lhs_sc.block);
95ac7ddfbfSEd Maste }
96ac7ddfbfSEd Maste }
97ac7ddfbfSEd Maste return false;
98ac7ddfbfSEd Maste }
99