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