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