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 17 using namespace lldb; 18 using namespace lldb_private; 19 20 21 Symbol::Symbol() : 22 UserID (), 23 m_mangled (), 24 m_type (eSymbolTypeInvalid), 25 m_type_data (0), 26 m_type_data_resolved (false), 27 m_is_synthetic (false), 28 m_is_debug (false), 29 m_is_external (false), 30 m_size_is_sibling (false), 31 m_size_is_synthesized (false), 32 m_searched_for_function (false), 33 m_addr_range (), 34 m_flags (), 35 m_function (NULL) 36 { 37 } 38 39 Symbol::Symbol 40 ( 41 user_id_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 UserID (symID), 55 m_mangled (name, name_is_mangled), 56 m_type (type), 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_searched_for_function (false), 65 m_addr_range (section, offset, size), 66 m_flags (flags), 67 m_function (NULL) 68 { 69 } 70 71 Symbol::Symbol 72 ( 73 user_id_t symID, 74 const char *name, 75 bool name_is_mangled, 76 SymbolType type, 77 bool external, 78 bool is_debug, 79 bool is_trampoline, 80 bool is_artificial, 81 const AddressRange &range, 82 uint32_t flags 83 ) : 84 UserID (symID), 85 m_mangled (name, name_is_mangled), 86 m_type (type), 87 m_type_data (0), 88 m_type_data_resolved (false), 89 m_is_synthetic (is_artificial), 90 m_is_debug (is_debug), 91 m_is_external (external), 92 m_size_is_sibling (false), 93 m_size_is_synthesized (false), 94 m_searched_for_function (false), 95 m_addr_range (range), 96 m_flags (flags), 97 m_function (NULL) 98 { 99 } 100 101 Symbol::Symbol(const Symbol& rhs): 102 UserID (rhs), 103 m_mangled (rhs.m_mangled), 104 m_type (rhs.m_type), 105 m_type_data (rhs.m_type_data), 106 m_type_data_resolved (rhs.m_type_data_resolved), 107 m_is_synthetic (rhs.m_is_synthetic), 108 m_is_debug (rhs.m_is_debug), 109 m_is_external (rhs.m_is_external), 110 m_size_is_sibling (rhs.m_size_is_sibling), 111 m_size_is_synthesized (false), 112 m_searched_for_function (false), 113 m_addr_range (rhs.m_addr_range), 114 m_flags (rhs.m_flags), 115 m_function (NULL) 116 { 117 } 118 119 const Symbol& 120 Symbol::operator= (const Symbol& rhs) 121 { 122 if (this != &rhs) 123 { 124 UserID::operator= (rhs); 125 m_mangled = rhs.m_mangled; 126 m_type = rhs.m_type; 127 m_type_data = rhs.m_type_data; 128 m_type_data_resolved = rhs.m_type_data_resolved; 129 m_is_synthetic = rhs.m_is_synthetic; 130 m_is_debug = rhs.m_is_debug; 131 m_is_external = rhs.m_is_external; 132 m_size_is_sibling = rhs.m_size_is_sibling; 133 m_size_is_synthesized = rhs.m_size_is_sibling; 134 m_searched_for_function = rhs.m_searched_for_function; 135 m_addr_range = rhs.m_addr_range; 136 m_flags = rhs.m_flags; 137 m_function = rhs.m_function; 138 } 139 return *this; 140 } 141 142 AddressRange & 143 Symbol::GetAddressRangeRef() 144 { 145 return m_addr_range; 146 } 147 148 const AddressRange & 149 Symbol::GetAddressRangeRef() const 150 { 151 return m_addr_range; 152 } 153 154 AddressRange * 155 Symbol::GetAddressRangePtr() 156 { 157 if (m_addr_range.GetBaseAddress().GetSection()) 158 return &m_addr_range; 159 return NULL; 160 } 161 162 const AddressRange * 163 Symbol::GetAddressRangePtr() const 164 { 165 if (m_addr_range.GetBaseAddress().GetSection()) 166 return &m_addr_range; 167 return NULL; 168 } 169 170 bool 171 Symbol::GetSizeIsSibling() const 172 { 173 return m_size_is_sibling; 174 } 175 176 bool 177 Symbol::GetSizeIsSynthesized() const 178 { 179 return m_size_is_synthesized; 180 } 181 182 uint32_t 183 Symbol::GetSiblingIndex() const 184 { 185 return m_size_is_sibling ? m_addr_range.GetByteSize() : 0; 186 } 187 188 uint32_t 189 Symbol::GetFlags() const 190 { 191 return m_flags; 192 } 193 194 void 195 Symbol::SetFlags (uint32_t flags) 196 { 197 m_flags = flags; 198 } 199 200 SymbolType 201 Symbol::GetType() const 202 { 203 return m_type; 204 } 205 206 void 207 Symbol::SetType(SymbolType type) 208 { 209 m_type = type; 210 } 211 212 bool 213 Symbol::IsSynthetic () const 214 { 215 return m_is_synthetic; 216 } 217 218 void 219 Symbol::SetIsSynthetic (bool b) 220 { 221 m_is_synthetic = b; 222 } 223 224 void 225 Symbol::SetSizeIsSynthesized(bool b) 226 { 227 m_size_is_synthesized = b; 228 } 229 230 231 bool 232 Symbol::IsDebug() const 233 { 234 return m_is_debug; 235 } 236 237 void 238 Symbol::SetDebug (bool b) 239 { 240 m_is_debug = b; 241 } 242 243 bool 244 Symbol::IsExternal() const 245 { 246 return m_is_external; 247 } 248 249 void 250 Symbol::SetExternal(bool b) 251 { 252 m_is_external = b; 253 } 254 255 bool 256 Symbol::IsTrampoline () const 257 { 258 return m_type == eSymbolTypeTrampoline; 259 } 260 261 uint32_t 262 Symbol::GetByteSize() const 263 { 264 return m_addr_range.GetByteSize(); 265 } 266 267 void 268 Symbol::SetByteSize (uint32_t size) 269 { 270 m_addr_range.SetByteSize(size); 271 } 272 273 void 274 Symbol::SetSizeIsSibling (bool b) 275 { 276 m_size_is_sibling = b; 277 } 278 279 void 280 Symbol::Dump(Stream *s, Process *process, uint32_t index) const 281 { 282 // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 283 // s->Indent(); 284 // s->Printf("Symbol[%5u] %6u %c%c %-12s ", 285 s->Printf("[%5u] %6u %c%c%c %-12s ", 286 index, 287 GetID(), 288 m_is_debug ? 'D' : ' ', 289 m_is_synthetic ? 'S' : ' ', 290 m_is_external ? 'X' : ' ', 291 GetTypeAsString()); 292 293 const Section *section = m_addr_range.GetBaseAddress().GetSection(); 294 if (section != NULL) 295 { 296 if (!m_addr_range.GetBaseAddress().Dump(s, NULL, Address::DumpStyleFileAddress)) 297 s->Printf("%*s", 18, ""); 298 299 s->PutChar(' '); 300 301 if (!m_addr_range.GetBaseAddress().Dump(s, process, Address::DumpStyleLoadAddress)) 302 s->Printf("%*s", 18, ""); 303 304 const char *format = m_size_is_sibling ? 305 " Sibling -> [%5llu] 0x%8.8x %s\n": 306 " 0x%16.16llx 0x%8.8x %s\n"; 307 s->Printf( format, 308 m_addr_range.GetByteSize(), 309 m_flags, 310 m_mangled.GetName().AsCString("")); 311 } 312 else 313 { 314 const char *format = m_size_is_sibling ? 315 "0x%16.16llx Sibling -> [%5llu] 0x%8.8x %s\n": 316 "0x%16.16llx 0x%16.16llx 0x%8.8x %s\n"; 317 s->Printf( format, 318 m_addr_range.GetBaseAddress().GetOffset(), 319 m_addr_range.GetByteSize(), 320 m_flags, 321 m_mangled.GetName().AsCString("")); 322 } 323 } 324 325 const Mangled& 326 Symbol::GetMangled() const 327 { 328 return m_mangled; 329 } 330 331 Mangled& 332 Symbol::GetMangled() 333 { 334 return m_mangled; 335 } 336 337 Address & 338 Symbol::GetValue() 339 { 340 return m_addr_range.GetBaseAddress(); 341 } 342 343 const Address & 344 Symbol::GetValue() const 345 { 346 return m_addr_range.GetBaseAddress(); 347 } 348 349 void 350 Symbol::SetValue (Address &value) 351 { 352 m_addr_range.GetBaseAddress() = value; 353 } 354 355 Function * 356 Symbol::GetFunction () 357 { 358 if (m_function == NULL && !m_searched_for_function) 359 { 360 m_searched_for_function = true; 361 Module *module = m_addr_range.GetBaseAddress().GetModule(); 362 if (module) 363 { 364 SymbolContext sc; 365 if (module->ResolveSymbolContextForAddress(m_addr_range.GetBaseAddress(), eSymbolContextFunction, sc)) 366 m_function = sc.function; 367 } 368 } 369 return m_function; 370 } 371 372 uint32_t 373 Symbol::GetPrologueByteSize () 374 { 375 if (m_type == eSymbolTypeCode || m_type == eSymbolTypeFunction) 376 { 377 if (!m_type_data_resolved) 378 { 379 m_type_data_resolved = true; 380 Module *module = m_addr_range.GetBaseAddress().GetModule(); 381 SymbolContext sc; 382 if (module && module->ResolveSymbolContextForAddress (m_addr_range.GetBaseAddress(), 383 eSymbolContextLineEntry, 384 sc)) 385 { 386 m_type_data = sc.line_entry.range.GetByteSize(); 387 } 388 else 389 { 390 // TODO: expose something in Process to figure out the 391 // size of a function prologue. 392 } 393 } 394 return m_type_data; 395 } 396 return 0; 397 } 398 399 void 400 Symbol::SetValue (const AddressRange &range) 401 { 402 m_addr_range = range; 403 } 404 405 406 void 407 Symbol::SetValue(addr_t value) 408 { 409 m_addr_range.GetBaseAddress().SetSection(NULL); 410 m_addr_range.GetBaseAddress().SetOffset(value); 411 } 412 413 414 bool 415 Symbol::Compare(const ConstString& name, SymbolType type) const 416 { 417 if (m_type == eSymbolTypeAny || m_type == type) 418 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName() == name; 419 return false; 420 } 421 422 #define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x; 423 424 const char * 425 Symbol::GetTypeAsString() const 426 { 427 switch (m_type) 428 { 429 ENUM_TO_CSTRING(Invalid); 430 ENUM_TO_CSTRING(Absolute); 431 ENUM_TO_CSTRING(Extern); 432 ENUM_TO_CSTRING(Code); 433 ENUM_TO_CSTRING(Data); 434 ENUM_TO_CSTRING(Trampoline); 435 ENUM_TO_CSTRING(Runtime); 436 ENUM_TO_CSTRING(Exception); 437 ENUM_TO_CSTRING(SourceFile); 438 ENUM_TO_CSTRING(HeaderFile); 439 ENUM_TO_CSTRING(ObjectFile); 440 ENUM_TO_CSTRING(Function); 441 ENUM_TO_CSTRING(FunctionEnd); 442 ENUM_TO_CSTRING(CommonBlock); 443 ENUM_TO_CSTRING(Block); 444 ENUM_TO_CSTRING(Static); 445 ENUM_TO_CSTRING(Global); 446 ENUM_TO_CSTRING(Local); 447 ENUM_TO_CSTRING(Param); 448 ENUM_TO_CSTRING(Variable); 449 ENUM_TO_CSTRING(VariableType); 450 ENUM_TO_CSTRING(LineEntry); 451 ENUM_TO_CSTRING(LineHeader); 452 ENUM_TO_CSTRING(ScopeBegin); 453 ENUM_TO_CSTRING(ScopeEnd); 454 ENUM_TO_CSTRING(Additional); 455 ENUM_TO_CSTRING(Compiler); 456 ENUM_TO_CSTRING(Instrumentation); 457 ENUM_TO_CSTRING(Undefined); 458 default: 459 break; 460 } 461 return "<unknown SymbolType>"; 462 } 463 464