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