Symbol.cpp revision 49ce8969d3154e1560106cfe530444c09410f217
1//===-- Symbol.cpp ----------------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "lldb/Symbol/Symbol.h" 11 12#include "lldb/Core/Module.h" 13#include "lldb/Core/Section.h" 14#include "lldb/Core/Stream.h" 15#include "lldb/Symbol/ObjectFile.h" 16#include "lldb/Symbol/Symtab.h" 17#include "lldb/Target/Process.h" 18#include "lldb/Target/Target.h" 19 20using namespace lldb; 21using namespace lldb_private; 22 23 24Symbol::Symbol() : 25 SymbolContextScope (), 26 m_uid (UINT32_MAX), 27 m_mangled (), 28 m_type_data (0), 29 m_type_data_resolved (false), 30 m_is_synthetic (false), 31 m_is_debug (false), 32 m_is_external (false), 33 m_size_is_sibling (false), 34 m_size_is_synthesized (false), 35 m_calculated_size (false), 36 m_type (eSymbolTypeInvalid), 37 m_flags (), 38 m_addr_range () 39{ 40} 41 42Symbol::Symbol 43( 44 uint32_t symID, 45 const char *name, 46 bool name_is_mangled, 47 SymbolType type, 48 bool external, 49 bool is_debug, 50 bool is_trampoline, 51 bool is_artificial, 52 const lldb::SectionSP §ion_sp, 53 addr_t offset, 54 uint32_t size, 55 uint32_t flags 56) : 57 SymbolContextScope (), 58 m_uid (symID), 59 m_mangled (ConstString(name), name_is_mangled), 60 m_type_data (0), 61 m_type_data_resolved (false), 62 m_is_synthetic (is_artificial), 63 m_is_debug (is_debug), 64 m_is_external (external), 65 m_size_is_sibling (false), 66 m_size_is_synthesized (false), 67 m_calculated_size (size > 0), 68 m_type (type), 69 m_flags (flags), 70 m_addr_range (section_sp, offset, size) 71{ 72} 73 74Symbol::Symbol 75( 76 uint32_t symID, 77 const char *name, 78 bool name_is_mangled, 79 SymbolType type, 80 bool external, 81 bool is_debug, 82 bool is_trampoline, 83 bool is_artificial, 84 const AddressRange &range, 85 uint32_t flags 86) : 87 SymbolContextScope (), 88 m_uid (symID), 89 m_mangled (ConstString(name), name_is_mangled), 90 m_type_data (0), 91 m_type_data_resolved (false), 92 m_is_synthetic (is_artificial), 93 m_is_debug (is_debug), 94 m_is_external (external), 95 m_size_is_sibling (false), 96 m_size_is_synthesized (false), 97 m_calculated_size (range.GetByteSize() > 0), 98 m_type (type), 99 m_flags (flags), 100 m_addr_range (range) 101{ 102} 103 104Symbol::Symbol(const Symbol& rhs): 105 SymbolContextScope (rhs), 106 m_uid (rhs.m_uid), 107 m_mangled (rhs.m_mangled), 108 m_type_data (rhs.m_type_data), 109 m_type_data_resolved (rhs.m_type_data_resolved), 110 m_is_synthetic (rhs.m_is_synthetic), 111 m_is_debug (rhs.m_is_debug), 112 m_is_external (rhs.m_is_external), 113 m_size_is_sibling (rhs.m_size_is_sibling), 114 m_size_is_synthesized (false), 115 m_calculated_size (rhs.m_calculated_size), 116 m_type (rhs.m_type), 117 m_flags (rhs.m_flags), 118 m_addr_range (rhs.m_addr_range) 119{ 120} 121 122const Symbol& 123Symbol::operator= (const Symbol& rhs) 124{ 125 if (this != &rhs) 126 { 127 SymbolContextScope::operator= (rhs); 128 m_uid = rhs.m_uid; 129 m_mangled = rhs.m_mangled; 130 m_type_data = rhs.m_type_data; 131 m_type_data_resolved = rhs.m_type_data_resolved; 132 m_is_synthetic = rhs.m_is_synthetic; 133 m_is_debug = rhs.m_is_debug; 134 m_is_external = rhs.m_is_external; 135 m_size_is_sibling = rhs.m_size_is_sibling; 136 m_size_is_synthesized = rhs.m_size_is_sibling; 137 m_calculated_size = rhs.m_calculated_size; 138 m_type = rhs.m_type; 139 m_flags = rhs.m_flags; 140 m_addr_range = rhs.m_addr_range; 141 } 142 return *this; 143} 144 145void 146Symbol::Clear() 147{ 148 m_uid = UINT32_MAX; 149 m_mangled.Clear(); 150 m_type_data = 0; 151 m_type_data_resolved = false; 152 m_is_synthetic = false; 153 m_is_debug = false; 154 m_is_external = false; 155 m_size_is_sibling = false; 156 m_size_is_synthesized = false; 157 m_calculated_size = false; 158 m_type = eSymbolTypeInvalid; 159 m_flags = 0; 160 m_addr_range.Clear(); 161} 162 163bool 164Symbol::ValueIsAddress() const 165{ 166 return m_addr_range.GetBaseAddress().GetSection().get() != NULL; 167} 168 169uint32_t 170Symbol::GetSiblingIndex() const 171{ 172 return m_size_is_sibling ? m_addr_range.GetByteSize() : 0; 173} 174 175bool 176Symbol::IsTrampoline () const 177{ 178 return m_type == eSymbolTypeTrampoline; 179} 180 181void 182Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const 183{ 184 s->Printf("id = {0x%8.8x}", m_uid); 185 186 if (m_addr_range.GetBaseAddress().GetSection()) 187 { 188 if (ValueIsAddress()) 189 { 190 const lldb::addr_t byte_size = GetByteSize(); 191 if (byte_size > 0) 192 { 193 s->PutCString (", range = "); 194 m_addr_range.Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); 195 } 196 else 197 { 198 s->PutCString (", address = "); 199 m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); 200 } 201 } 202 else 203 s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset()); 204 } 205 else 206 { 207 if (m_size_is_sibling) 208 s->Printf (", sibling = %5llu", m_addr_range.GetBaseAddress().GetOffset()); 209 else 210 s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset()); 211 } 212 if (m_mangled.GetDemangledName()) 213 s->Printf(", name=\"%s\"", m_mangled.GetDemangledName().AsCString()); 214 if (m_mangled.GetMangledName()) 215 s->Printf(", mangled=\"%s\"", m_mangled.GetMangledName().AsCString()); 216 217} 218 219void 220Symbol::Dump(Stream *s, Target *target, uint32_t index) const 221{ 222// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 223// s->Indent(); 224// s->Printf("Symbol[%5u] %6u %c%c %-12s ", 225 s->Printf("[%5u] %6u %c%c%c %-12s ", 226 index, 227 GetID(), 228 m_is_debug ? 'D' : ' ', 229 m_is_synthetic ? 'S' : ' ', 230 m_is_external ? 'X' : ' ', 231 GetTypeAsString()); 232 233 // Make sure the size of the symbol is up to date before dumping 234 GetByteSize(); 235 236 if (ValueIsAddress()) 237 { 238 if (!m_addr_range.GetBaseAddress().Dump(s, NULL, Address::DumpStyleFileAddress)) 239 s->Printf("%*s", 18, ""); 240 241 s->PutChar(' '); 242 243 if (!m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress)) 244 s->Printf("%*s", 18, ""); 245 246 const char *format = m_size_is_sibling ? 247 " Sibling -> [%5llu] 0x%8.8x %s\n": 248 " 0x%16.16llx 0x%8.8x %s\n"; 249 s->Printf( format, 250 GetByteSize(), 251 m_flags, 252 m_mangled.GetName().AsCString("")); 253 } 254 else 255 { 256 const char *format = m_size_is_sibling ? 257 "0x%16.16llx Sibling -> [%5llu] 0x%8.8x %s\n": 258 "0x%16.16llx 0x%16.16llx 0x%8.8x %s\n"; 259 s->Printf( format, 260 m_addr_range.GetBaseAddress().GetOffset(), 261 GetByteSize(), 262 m_flags, 263 m_mangled.GetName().AsCString("")); 264 } 265} 266 267uint32_t 268Symbol::GetPrologueByteSize () 269{ 270 if (m_type == eSymbolTypeCode) 271 { 272 if (!m_type_data_resolved) 273 { 274 m_type_data_resolved = true; 275 ModuleSP module_sp (m_addr_range.GetBaseAddress().GetModule()); 276 SymbolContext sc; 277 if (module_sp && module_sp->ResolveSymbolContextForAddress (m_addr_range.GetBaseAddress(), 278 eSymbolContextLineEntry, 279 sc)) 280 { 281 m_type_data = sc.line_entry.range.GetByteSize(); 282 // Sanity check - this may be a function in the middle of code that has debug information, but 283 // not for this symbol. So the line entries surrounding us won't lie inside our function. 284 // In that case, the line entry will be bigger than we are, so we do that quick check and 285 // if that is true, we just return 0. 286 if (m_type_data >= m_addr_range.GetByteSize()) 287 m_type_data = 0; 288 } 289 else 290 { 291 // TODO: expose something in Process to figure out the 292 // size of a function prologue. 293 } 294 } 295 return m_type_data; 296 } 297 return 0; 298} 299 300bool 301Symbol::Compare(const ConstString& name, SymbolType type) const 302{ 303 if (type == eSymbolTypeAny || m_type == type) 304 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name; 305 return false; 306} 307 308#define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x; 309 310const char * 311Symbol::GetTypeAsString() const 312{ 313 switch (m_type) 314 { 315 ENUM_TO_CSTRING(Invalid); 316 ENUM_TO_CSTRING(Absolute); 317 ENUM_TO_CSTRING(Code); 318 ENUM_TO_CSTRING(Data); 319 ENUM_TO_CSTRING(Trampoline); 320 ENUM_TO_CSTRING(Runtime); 321 ENUM_TO_CSTRING(Exception); 322 ENUM_TO_CSTRING(SourceFile); 323 ENUM_TO_CSTRING(HeaderFile); 324 ENUM_TO_CSTRING(ObjectFile); 325 ENUM_TO_CSTRING(CommonBlock); 326 ENUM_TO_CSTRING(Block); 327 ENUM_TO_CSTRING(Local); 328 ENUM_TO_CSTRING(Param); 329 ENUM_TO_CSTRING(Variable); 330 ENUM_TO_CSTRING(VariableType); 331 ENUM_TO_CSTRING(LineEntry); 332 ENUM_TO_CSTRING(LineHeader); 333 ENUM_TO_CSTRING(ScopeBegin); 334 ENUM_TO_CSTRING(ScopeEnd); 335 ENUM_TO_CSTRING(Additional); 336 ENUM_TO_CSTRING(Compiler); 337 ENUM_TO_CSTRING(Instrumentation); 338 ENUM_TO_CSTRING(Undefined); 339 ENUM_TO_CSTRING(ObjCClass); 340 ENUM_TO_CSTRING(ObjCMetaClass); 341 ENUM_TO_CSTRING(ObjCIVar); 342 default: 343 break; 344 } 345 return "<unknown SymbolType>"; 346} 347 348 349void 350Symbol::CalculateSymbolContext (SymbolContext *sc) 351{ 352 // Symbols can reconstruct the symbol and the module in the symbol context 353 sc->symbol = this; 354 if (ValueIsAddress()) 355 sc->module_sp = GetAddress().GetModule(); 356 else 357 sc->module_sp.reset(); 358} 359 360ModuleSP 361Symbol::CalculateSymbolContextModule () 362{ 363 if (ValueIsAddress()) 364 return GetAddress().GetModule(); 365 return ModuleSP(); 366} 367 368Symbol * 369Symbol::CalculateSymbolContextSymbol () 370{ 371 return this; 372} 373 374 375void 376Symbol::DumpSymbolContext (Stream *s) 377{ 378 bool dumped_module = false; 379 if (ValueIsAddress()) 380 { 381 ModuleSP module_sp (GetAddress().GetModule()); 382 if (module_sp) 383 { 384 dumped_module = true; 385 module_sp->DumpSymbolContext(s); 386 } 387 } 388 if (dumped_module) 389 s->PutCString(", "); 390 391 s->Printf("Symbol{0x%8.8x}", GetID()); 392} 393 394 395lldb::addr_t 396Symbol::GetByteSize () const 397{ 398 addr_t byte_size = m_addr_range.GetByteSize(); 399 if (byte_size == 0 && !m_calculated_size) 400 { 401 const_cast<Symbol*>(this)->m_calculated_size = true; 402 if (ValueIsAddress()) 403 { 404 ModuleSP module_sp (GetAddress().GetModule()); 405 if (module_sp) 406 { 407 ObjectFile *objfile = module_sp->GetObjectFile(); 408 if (objfile) 409 { 410 Symtab *symtab = objfile->GetSymtab(); 411 if (symtab) 412 { 413 const_cast<Symbol*>(this)->SetByteSize (symtab->CalculateSymbolSize (const_cast<Symbol *>(this))); 414 byte_size = m_addr_range.GetByteSize(); 415 } 416 } 417 } 418 } 419 } 420 return byte_size; 421} 422 423