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 << "id = " << (const UserID&)*this << ", name = \"" << m_mangled.GetName() << '"'; 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 } 215 216 void 217 Symbol::Dump(Stream *s, Target *target, uint32_t index) const 218 { 219 // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 220 // s->Indent(); 221 // s->Printf("Symbol[%5u] %6u %c%c %-12s ", 222 s->Printf("[%5u] %6u %c%c%c %-12s ", 223 index, 224 GetID(), 225 m_is_debug ? 'D' : ' ', 226 m_is_synthetic ? 'S' : ' ', 227 m_is_external ? 'X' : ' ', 228 GetTypeAsString()); 229 230 const Section *section = m_addr_range.GetBaseAddress().GetSection(); 231 if (section != NULL) 232 { 233 if (!m_addr_range.GetBaseAddress().Dump(s, NULL, Address::DumpStyleFileAddress)) 234 s->Printf("%*s", 18, ""); 235 236 s->PutChar(' '); 237 238 if (!m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress)) 239 s->Printf("%*s", 18, ""); 240 241 const char *format = m_size_is_sibling ? 242 " Sibling -> [%5llu] 0x%8.8x %s\n": 243 " 0x%16.16llx 0x%8.8x %s\n"; 244 s->Printf( format, 245 m_addr_range.GetByteSize(), 246 m_flags, 247 m_mangled.GetName().AsCString("")); 248 } 249 else 250 { 251 const char *format = m_size_is_sibling ? 252 "0x%16.16llx Sibling -> [%5llu] 0x%8.8x %s\n": 253 "0x%16.16llx 0x%16.16llx 0x%8.8x %s\n"; 254 s->Printf( format, 255 m_addr_range.GetBaseAddress().GetOffset(), 256 m_addr_range.GetByteSize(), 257 m_flags, 258 m_mangled.GetName().AsCString("")); 259 } 260 } 261 262 uint32_t 263 Symbol::GetPrologueByteSize () 264 { 265 if (m_type == eSymbolTypeCode) 266 { 267 if (!m_type_data_resolved) 268 { 269 m_type_data_resolved = true; 270 Module *module = m_addr_range.GetBaseAddress().GetModule(); 271 SymbolContext sc; 272 if (module && module->ResolveSymbolContextForAddress (m_addr_range.GetBaseAddress(), 273 eSymbolContextLineEntry, 274 sc)) 275 { 276 m_type_data = sc.line_entry.range.GetByteSize(); 277 } 278 else 279 { 280 // TODO: expose something in Process to figure out the 281 // size of a function prologue. 282 } 283 } 284 return m_type_data; 285 } 286 return 0; 287 } 288 289 void 290 Symbol::SetValue(addr_t value) 291 { 292 m_addr_range.GetBaseAddress().SetSection(NULL); 293 m_addr_range.GetBaseAddress().SetOffset(value); 294 } 295 296 297 bool 298 Symbol::Compare(const ConstString& name, SymbolType type) const 299 { 300 if (type == eSymbolTypeAny || m_type == type) 301 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name; 302 return false; 303 } 304 305 #define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x; 306 307 const char * 308 Symbol::GetTypeAsString() const 309 { 310 switch (m_type) 311 { 312 ENUM_TO_CSTRING(Invalid); 313 ENUM_TO_CSTRING(Absolute); 314 ENUM_TO_CSTRING(Code); 315 ENUM_TO_CSTRING(Data); 316 ENUM_TO_CSTRING(Trampoline); 317 ENUM_TO_CSTRING(Runtime); 318 ENUM_TO_CSTRING(Exception); 319 ENUM_TO_CSTRING(SourceFile); 320 ENUM_TO_CSTRING(HeaderFile); 321 ENUM_TO_CSTRING(ObjectFile); 322 ENUM_TO_CSTRING(CommonBlock); 323 ENUM_TO_CSTRING(Block); 324 ENUM_TO_CSTRING(Local); 325 ENUM_TO_CSTRING(Param); 326 ENUM_TO_CSTRING(Variable); 327 ENUM_TO_CSTRING(VariableType); 328 ENUM_TO_CSTRING(LineEntry); 329 ENUM_TO_CSTRING(LineHeader); 330 ENUM_TO_CSTRING(ScopeBegin); 331 ENUM_TO_CSTRING(ScopeEnd); 332 ENUM_TO_CSTRING(Additional); 333 ENUM_TO_CSTRING(Compiler); 334 ENUM_TO_CSTRING(Instrumentation); 335 ENUM_TO_CSTRING(Undefined); 336 ENUM_TO_CSTRING(ObjCClass); 337 ENUM_TO_CSTRING(ObjCMetaClass); 338 ENUM_TO_CSTRING(ObjCIVar); 339 default: 340 break; 341 } 342 return "<unknown SymbolType>"; 343 } 344 345 346 void 347 Symbol::CalculateSymbolContext (SymbolContext *sc) 348 { 349 // Symbols can reconstruct the symbol and the module in the symbol context 350 sc->symbol = this; 351 const AddressRange *range = GetAddressRangePtr(); 352 if (range) 353 { 354 Module *module = range->GetBaseAddress().GetModule (); 355 if (module) 356 { 357 sc->module_sp = module; 358 return; 359 } 360 } 361 sc->module_sp.reset(); 362 } 363 364 Module * 365 Symbol::CalculateSymbolContextModule () 366 { 367 const AddressRange *range = GetAddressRangePtr(); 368 if (range) 369 return range->GetBaseAddress().GetModule (); 370 return NULL; 371 } 372 373 Symbol * 374 Symbol::CalculateSymbolContextSymbol () 375 { 376 return this; 377 } 378 379 380 void 381 Symbol::DumpSymbolContext (Stream *s) 382 { 383 bool dumped_module = false; 384 const AddressRange *range = GetAddressRangePtr(); 385 if (range) 386 { 387 Module *module = range->GetBaseAddress().GetModule (); 388 if (module) 389 { 390 dumped_module = true; 391 module->DumpSymbolContext(s); 392 } 393 } 394 if (dumped_module) 395 s->PutCString(", "); 396 397 s->Printf("Symbol{0x%8.8x}", GetID()); 398 } 399 400 401