1254721Semaste//===-- StackID.cpp ---------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Target/StackID.h" 11254721Semaste 12254721Semaste// C Includes 13254721Semaste// C++ Includes 14254721Semaste// Other libraries and framework includes 15254721Semaste// Project includes 16254721Semaste#include "lldb/Core/Stream.h" 17254721Semaste#include "lldb/Symbol/Block.h" 18254721Semaste#include "lldb/Symbol/Symbol.h" 19254721Semaste#include "lldb/Symbol/SymbolContext.h" 20254721Semaste 21254721Semasteusing namespace lldb_private; 22254721Semaste 23254721Semaste 24254721Semastevoid 25254721SemasteStackID::Dump (Stream *s) 26254721Semaste{ 27254721Semaste s->Printf("StackID (pc = 0x%16.16" PRIx64 ", cfa = 0x%16.16" PRIx64 ", symbol_scope = %p", (uint64_t)m_pc, (uint64_t)m_cfa, m_symbol_scope); 28254721Semaste if (m_symbol_scope) 29254721Semaste { 30254721Semaste SymbolContext sc; 31254721Semaste 32254721Semaste m_symbol_scope->CalculateSymbolContext (&sc); 33254721Semaste if (sc.block) 34254721Semaste s->Printf(" (Block {0x%8.8" PRIx64 "})", sc.block->GetID()); 35254721Semaste else if (sc.symbol) 36254721Semaste s->Printf(" (Symbol{0x%8.8x})", sc.symbol->GetID()); 37254721Semaste } 38254721Semaste s->PutCString(") "); 39254721Semaste} 40254721Semaste 41254721Semastebool 42254721Semastelldb_private::operator== (const StackID& lhs, const StackID& rhs) 43254721Semaste{ 44254721Semaste if (lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress()) 45254721Semaste return false; 46254721Semaste 47254721Semaste SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope(); 48254721Semaste SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope(); 49254721Semaste 50254721Semaste // Only compare the PC values if both symbol context scopes are NULL 51254721Semaste if (lhs_scope == NULL && rhs_scope == NULL) 52254721Semaste return lhs.GetPC() == rhs.GetPC(); 53254721Semaste 54254721Semaste return lhs_scope == rhs_scope; 55254721Semaste} 56254721Semaste 57254721Semastebool 58254721Semastelldb_private::operator!= (const StackID& lhs, const StackID& rhs) 59254721Semaste{ 60254721Semaste if (lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress()) 61254721Semaste return true; 62254721Semaste 63254721Semaste SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope(); 64254721Semaste SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope(); 65254721Semaste 66254721Semaste if (lhs_scope == NULL && rhs_scope == NULL) 67254721Semaste return lhs.GetPC() != rhs.GetPC(); 68254721Semaste 69254721Semaste return lhs_scope != rhs_scope; 70254721Semaste} 71254721Semaste 72254721Semastebool 73254721Semastelldb_private::operator< (const StackID& lhs, const StackID& rhs) 74254721Semaste{ 75254721Semaste const lldb::addr_t lhs_cfa = lhs.GetCallFrameAddress(); 76254721Semaste const lldb::addr_t rhs_cfa = rhs.GetCallFrameAddress(); 77254721Semaste 78254721Semaste // FIXME: We are assuming that the stacks grow downward in memory. That's not necessary, but true on 79254721Semaste // all the machines we care about at present. If this changes, we'll have to deal with that. The ABI is the 80254721Semaste // agent who knows this ordering, but the StackID has no access to the ABI. The most straightforward way 81254721Semaste // to handle this is to add a "m_grows_downward" bool to the StackID, and set it in the constructor. 82254721Semaste // But I'm not going to waste a bool per StackID on this till we need it. 83254721Semaste 84254721Semaste if (lhs_cfa != rhs_cfa) 85254721Semaste return lhs_cfa < rhs_cfa; 86254721Semaste 87254721Semaste SymbolContextScope *lhs_scope = lhs.GetSymbolContextScope(); 88254721Semaste SymbolContextScope *rhs_scope = rhs.GetSymbolContextScope(); 89254721Semaste 90254721Semaste if (lhs_scope != NULL && rhs_scope != NULL) 91254721Semaste { 92254721Semaste // Same exact scope, lhs is not less than (younger than rhs) 93254721Semaste if (lhs_scope == rhs_scope) 94254721Semaste return false; 95254721Semaste 96254721Semaste SymbolContext lhs_sc; 97254721Semaste SymbolContext rhs_sc; 98254721Semaste lhs_scope->CalculateSymbolContext (&lhs_sc); 99254721Semaste rhs_scope->CalculateSymbolContext (&rhs_sc); 100254721Semaste 101254721Semaste // Items with the same function can only be compared 102254721Semaste if (lhs_sc.function == rhs_sc.function && 103254721Semaste lhs_sc.function != NULL && lhs_sc.block != NULL && 104254721Semaste rhs_sc.function != NULL && rhs_sc.block != NULL) 105254721Semaste { 106254721Semaste return rhs_sc.block->Contains (lhs_sc.block); 107254721Semaste } 108254721Semaste } 109254721Semaste return false; 110254721Semaste} 111