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/Target/Process.h" 16 #include "lldb/Target/Target.h" 17 18 using namespace lldb; 19 using namespace lldb_private; 20 21 22 Symbol::Symbol() : 23 SymbolContextScope (), 24 m_uid (UINT32_MAX), 25 m_mangled (), 26 m_type_data (0), 27 m_type_data_resolved (false), 28 m_is_synthetic (false), 29 m_is_debug (false), 30 m_is_external (false), 31 m_size_is_sibling (false), 32 m_size_is_synthesized (false), 33 m_type (eSymbolTypeInvalid), 34 m_flags (), 35 m_addr_range () 36 { 37 } 38 39 Symbol::Symbol 40 ( 41 uint32_t symID, 42 const char *name, 43 bool name_is_mangled, 44 SymbolType type, 45 bool external, 46 bool is_debug, 47 bool is_trampoline, 48 bool is_artificial, 49 const Section* section, 50 addr_t offset, 51 uint32_t size, 52 uint32_t flags 53 ) : 54 SymbolContextScope (), 55 m_uid (symID), 56 m_mangled (name, name_is_mangled), 57 m_type_data (0), 58 m_type_data_resolved (false), 59 m_is_synthetic (is_artificial), 60 m_is_debug (is_debug), 61 m_is_external (external), 62 m_size_is_sibling (false), 63 m_size_is_synthesized (false), 64 m_type (type), 65 m_flags (flags), 66 m_addr_range (section, offset, size) 67 { 68 } 69 70 Symbol::Symbol 71 ( 72 uint32_t symID, 73 const char *name, 74 bool name_is_mangled, 75 SymbolType type, 76 bool external, 77 bool is_debug, 78 bool is_trampoline, 79 bool is_artificial, 80 const AddressRange &range, 81 uint32_t flags 82 ) : 83 SymbolContextScope (), 84 m_uid (symID), 85 m_mangled (name, name_is_mangled), 86 m_type_data (0), 87 m_type_data_resolved (false), 88 m_is_synthetic (is_artificial), 89 m_is_debug (is_debug), 90 m_is_external (external), 91 m_size_is_sibling (false), 92 m_size_is_synthesized (false), 93 m_type (type), 94 m_flags (flags), 95 m_addr_range (range) 96 { 97 } 98 99 Symbol::Symbol(const Symbol& rhs): 100 SymbolContextScope (rhs), 101 m_uid (rhs.m_uid), 102 m_mangled (rhs.m_mangled), 103 m_type_data (rhs.m_type_data), 104 m_type_data_resolved (rhs.m_type_data_resolved), 105 m_is_synthetic (rhs.m_is_synthetic), 106 m_is_debug (rhs.m_is_debug), 107 m_is_external (rhs.m_is_external), 108 m_size_is_sibling (rhs.m_size_is_sibling), 109 m_size_is_synthesized (false), 110 m_type (rhs.m_type), 111 m_flags (rhs.m_flags), 112 m_addr_range (rhs.m_addr_range) 113 { 114 } 115 116 const Symbol& 117 Symbol::operator= (const Symbol& rhs) 118 { 119 if (this != &rhs) 120 { 121 SymbolContextScope::operator= (rhs); 122 m_uid = rhs.m_uid; 123 m_mangled = rhs.m_mangled; 124 m_type_data = rhs.m_type_data; 125 m_type_data_resolved = rhs.m_type_data_resolved; 126 m_is_synthetic = rhs.m_is_synthetic; 127 m_is_debug = rhs.m_is_debug; 128 m_is_external = rhs.m_is_external; 129 m_size_is_sibling = rhs.m_size_is_sibling; 130 m_size_is_synthesized = rhs.m_size_is_sibling; 131 m_type = rhs.m_type; 132 m_flags = rhs.m_flags; 133 m_addr_range = rhs.m_addr_range; 134 } 135 return *this; 136 } 137 138 void 139 Symbol::Clear() 140 { 141 m_uid = UINT32_MAX; 142 m_mangled.Clear(); 143 m_type_data = 0; 144 m_type_data_resolved = false; 145 m_is_synthetic = false; 146 m_is_debug = false; 147 m_is_external = false; 148 m_size_is_sibling = false; 149 m_size_is_synthesized = false; 150 m_type = eSymbolTypeInvalid; 151 m_flags = 0; 152 m_addr_range.Clear(); 153 } 154 155 AddressRange * 156 Symbol::GetAddressRangePtr() 157 { 158 if (m_addr_range.GetBaseAddress().GetSection()) 159 return &m_addr_range; 160 return NULL; 161 } 162 163 const AddressRange * 164 Symbol::GetAddressRangePtr() const 165 { 166 if (m_addr_range.GetBaseAddress().GetSection()) 167 return &m_addr_range; 168 return NULL; 169 } 170 171 uint32_t 172 Symbol::GetSiblingIndex() const 173 { 174 return m_size_is_sibling ? m_addr_range.GetByteSize() : 0; 175 } 176 177 bool 178 Symbol::IsTrampoline () const 179 { 180 return m_type == eSymbolTypeTrampoline; 181 } 182 183 void 184 Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const 185 { 186 s->Printf("uid={%6u}", m_uid); 187 188 const Section *section = m_addr_range.GetBaseAddress().GetSection(); 189 if (section != NULL) 190 { 191 if (m_addr_range.GetBaseAddress().IsSectionOffset()) 192 { 193 if (m_addr_range.GetByteSize() > 0) 194 { 195 s->PutCString (", range = "); 196 m_addr_range.Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); 197 } 198 else 199 { 200 s->PutCString (", address = "); 201 m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); 202 } 203 } 204 else 205 s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset()); 206 } 207 else 208 { 209 if (m_size_is_sibling) 210 s->Printf (", sibling = %5llu", m_addr_range.GetBaseAddress().GetOffset()); 211 else 212 s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset()); 213 } 214 if (m_mangled.GetDemangledName()) 215 s->Printf(", name=\"%s\"", m_mangled.GetDemangledName().AsCString()); 216 if (m_mangled.GetMangledName()) 217 s->Printf(", mangled=\"%s\"", m_mangled.GetMangledName().AsCString()); 218 219 } 220 221 void 222 Symbol::Dump(Stream *s, Target *target, uint32_t index) const 223 { 224 // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 225 // s->Indent(); 226 // s->Printf("Symbol[%5u] %6u %c%c %-12s ", 227 s->Printf("[%5u] %6u %c%c%c %-12s ", 228 index, 229 GetID(), 230 m_is_debug ? 'D' : ' ', 231 m_is_synthetic ? 'S' : ' ', 232 m_is_external ? 'X' : ' ', 233 GetTypeAsString()); 234 235 const Section *section = m_addr_range.GetBaseAddress().GetSection(); 236 if (section != NULL) 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 m_addr_range.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 m_addr_range.GetByteSize(), 262 m_flags, 263 m_mangled.GetName().AsCString("")); 264 } 265 } 266 267 uint32_t 268 Symbol::GetPrologueByteSize () 269 { 270 if (m_type == eSymbolTypeCode) 271 { 272 if (!m_type_data_resolved) 273 { 274 m_type_data_resolved = true; 275 Module *module = m_addr_range.GetBaseAddress().GetModulePtr(); 276 SymbolContext sc; 277 if (module && module->ResolveSymbolContextForAddress (m_addr_range.GetBaseAddress(), 278 eSymbolContextLineEntry, 279 sc)) 280 { 281 m_type_data = sc.line_entry.range.GetByteSize(); 282 } 283 else 284 { 285 // TODO: expose something in Process to figure out the 286 // size of a function prologue. 287 } 288 } 289 return m_type_data; 290 } 291 return 0; 292 } 293 294 void 295 Symbol::SetValue(addr_t value) 296 { 297 m_addr_range.GetBaseAddress().SetSection(NULL); 298 m_addr_range.GetBaseAddress().SetOffset(value); 299 } 300 301 302 bool 303 Symbol::Compare(const ConstString& name, SymbolType type) const 304 { 305 if (type == eSymbolTypeAny || m_type == type) 306 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name; 307 return false; 308 } 309 310 #define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x; 311 312 const char * 313 Symbol::GetTypeAsString() const 314 { 315 switch (m_type) 316 { 317 ENUM_TO_CSTRING(Invalid); 318 ENUM_TO_CSTRING(Absolute); 319 ENUM_TO_CSTRING(Code); 320 ENUM_TO_CSTRING(Data); 321 ENUM_TO_CSTRING(Trampoline); 322 ENUM_TO_CSTRING(Runtime); 323 ENUM_TO_CSTRING(Exception); 324 ENUM_TO_CSTRING(SourceFile); 325 ENUM_TO_CSTRING(HeaderFile); 326 ENUM_TO_CSTRING(ObjectFile); 327 ENUM_TO_CSTRING(CommonBlock); 328 ENUM_TO_CSTRING(Block); 329 ENUM_TO_CSTRING(Local); 330 ENUM_TO_CSTRING(Param); 331 ENUM_TO_CSTRING(Variable); 332 ENUM_TO_CSTRING(VariableType); 333 ENUM_TO_CSTRING(LineEntry); 334 ENUM_TO_CSTRING(LineHeader); 335 ENUM_TO_CSTRING(ScopeBegin); 336 ENUM_TO_CSTRING(ScopeEnd); 337 ENUM_TO_CSTRING(Additional); 338 ENUM_TO_CSTRING(Compiler); 339 ENUM_TO_CSTRING(Instrumentation); 340 ENUM_TO_CSTRING(Undefined); 341 ENUM_TO_CSTRING(ObjCClass); 342 ENUM_TO_CSTRING(ObjCMetaClass); 343 ENUM_TO_CSTRING(ObjCIVar); 344 default: 345 break; 346 } 347 return "<unknown SymbolType>"; 348 } 349 350 351 void 352 Symbol::CalculateSymbolContext (SymbolContext *sc) 353 { 354 // Symbols can reconstruct the symbol and the module in the symbol context 355 sc->symbol = this; 356 const AddressRange *range = GetAddressRangePtr(); 357 if (range) 358 sc->module_sp = range->GetBaseAddress().GetModuleSP (); 359 else 360 sc->module_sp.reset(); 361 } 362 363 Module * 364 Symbol::CalculateSymbolContextModule () 365 { 366 const AddressRange *range = GetAddressRangePtr(); 367 if (range) 368 return range->GetBaseAddress().GetModulePtr (); 369 return NULL; 370 } 371 372 Symbol * 373 Symbol::CalculateSymbolContextSymbol () 374 { 375 return this; 376 } 377 378 379 void 380 Symbol::DumpSymbolContext (Stream *s) 381 { 382 bool dumped_module = false; 383 const AddressRange *range = GetAddressRangePtr(); 384 if (range) 385 { 386 Module *module = range->GetBaseAddress().GetModulePtr (); 387 if (module) 388 { 389 dumped_module = true; 390 module->DumpSymbolContext(s); 391 } 392 } 393 if (dumped_module) 394 s->PutCString(", "); 395 396 s->Printf("Symbol{0x%8.8x}", GetID()); 397 } 398 399 400