1 //===-- Symbol.h ------------------------------------------------*- 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 #ifndef liblldb_Symbol_h_ 11 #define liblldb_Symbol_h_ 12 13 #include "lldb/lldb-private.h" 14 #include "lldb/Core/AddressRange.h" 15 #include "lldb/Core/Mangled.h" 16 #include "lldb/Core/UserID.h" 17 #include "lldb/Symbol/SymbolContextScope.h" 18 19 namespace lldb_private { 20 21 class Symbol : 22 public SymbolContextScope 23 { 24 public: 25 // ObjectFile readers can classify their symbol table entries and searches can be made 26 // on specific types where the symbol values will have drastically different meanings 27 // and sorting requirements. 28 Symbol(); 29 30 Symbol (uint32_t symID, 31 const char *name, 32 bool name_is_mangled, 33 lldb::SymbolType type, 34 bool external, 35 bool is_debug, 36 bool is_trampoline, 37 bool is_artificial, 38 const lldb::SectionSP §ion_sp, 39 lldb::addr_t value, 40 lldb::addr_t size, 41 bool size_is_valid, 42 bool contains_linker_annotations, 43 uint32_t flags); 44 45 Symbol (uint32_t symID, 46 const Mangled &mangled, 47 lldb::SymbolType type, 48 bool external, 49 bool is_debug, 50 bool is_trampoline, 51 bool is_artificial, 52 const AddressRange &range, 53 bool size_is_valid, 54 bool contains_linker_annotations, 55 uint32_t flags); 56 57 Symbol (const Symbol& rhs); 58 59 const Symbol& 60 operator= (const Symbol& rhs); 61 62 void 63 Clear(); 64 65 bool 66 Compare (const ConstString& name, lldb::SymbolType type) const; 67 68 void 69 Dump (Stream *s, Target *target, uint32_t index) const; 70 71 bool 72 ValueIsAddress() const; 73 74 //------------------------------------------------------------------ 75 // The GetAddressRef() accessor functions should only be called if 76 // you previously call ValueIsAddress() otherwise you might get an 77 // reference to an Address object that contains an constant integer 78 // value in m_addr_range.m_base_addr.m_offset which could be 79 // incorrectly used to represent an absolute address since it has 80 // no section. 81 //------------------------------------------------------------------ 82 Address & GetAddressRef()83 GetAddressRef() 84 { 85 return m_addr_range.GetBaseAddress(); 86 } 87 88 const Address & GetAddressRef()89 GetAddressRef() const 90 { 91 return m_addr_range.GetBaseAddress(); 92 } 93 94 //------------------------------------------------------------------ 95 // Makes sure the symbol's value is an address and returns the file 96 // address. Returns LLDB_INVALID_ADDRESS if the symbol's value isn't 97 // an address. 98 //------------------------------------------------------------------ 99 lldb::addr_t 100 GetFileAddress () const; 101 102 //------------------------------------------------------------------ 103 // Makes sure the symbol's value is an address and gets the load 104 // address using \a target if it is. Returns LLDB_INVALID_ADDRESS 105 // if the symbol's value isn't an address or if the section isn't 106 // loaded in \a target. 107 //------------------------------------------------------------------ 108 lldb::addr_t 109 GetLoadAddress (Target *target) const; 110 111 //------------------------------------------------------------------ 112 // Access the address value. Do NOT hand out the AddressRange as an 113 // object as the byte size of the address range may not be filled in 114 // and it should be accessed via GetByteSize(). 115 //------------------------------------------------------------------ 116 Address GetAddress()117 GetAddress() const 118 { 119 // Make sure the our value is an address before we hand a copy out. 120 // We use the Address inside m_addr_range to contain the value for 121 // symbols that are not address based symbols so we are using it 122 // for more than just addresses. For example undefined symbols on 123 // MacOSX have a nlist.n_value of 0 (zero) and this will get placed 124 // into m_addr_range.m_base_addr.m_offset and it will have no section. 125 // So in the GetAddress() accessor, we need to hand out an invalid 126 // address if the symbol's value isn't an address. 127 if (ValueIsAddress()) 128 return m_addr_range.GetBaseAddress(); 129 else 130 return Address(); 131 } 132 133 // When a symbol's value isn't an address, we need to access the raw 134 // value. This function will ensure this symbol's value isn't an address 135 // and return the integer value if this checks out, otherwise it will 136 // return "fail_value" if the symbol is an address value. 137 uint64_t 138 GetIntegerValue (uint64_t fail_value = 0) const 139 { 140 if (ValueIsAddress()) 141 { 142 // This symbol's value is an address. Use Symbol::GetAddress() to get the address. 143 return fail_value; 144 } 145 else 146 { 147 // The value is stored in the base address' offset 148 return m_addr_range.GetBaseAddress().GetOffset(); 149 } 150 } 151 152 lldb::addr_t 153 ResolveCallableAddress(Target &target) const; 154 155 ConstString 156 GetName () const; 157 158 ConstString 159 GetNameNoArguments () const; 160 161 ConstString 162 GetDisplayName () const; 163 164 uint32_t GetID()165 GetID() const 166 { 167 return m_uid; 168 } 169 170 lldb::LanguageType GetLanguage()171 GetLanguage() const 172 { 173 // TODO: See if there is a way to determine the language for a symbol somehow, for now just return our best guess 174 return m_mangled.GuessLanguage(); 175 } 176 177 void SetID(uint32_t uid)178 SetID(uint32_t uid) 179 { 180 m_uid = uid; 181 } 182 183 Mangled& GetMangled()184 GetMangled () 185 { 186 return m_mangled; 187 } 188 189 const Mangled& GetMangled()190 GetMangled () const 191 { 192 return m_mangled; 193 } 194 195 ConstString 196 GetReExportedSymbolName() const; 197 198 FileSpec 199 GetReExportedSymbolSharedLibrary () const; 200 201 void 202 SetReExportedSymbolName(const ConstString &name); 203 204 bool 205 SetReExportedSymbolSharedLibrary (const FileSpec &fspec); 206 207 Symbol * 208 ResolveReExportedSymbol (Target &target) const; 209 210 uint32_t 211 GetSiblingIndex () const; 212 213 lldb::SymbolType GetType()214 GetType () const 215 { 216 return (lldb::SymbolType)m_type; 217 } 218 219 void SetType(lldb::SymbolType type)220 SetType (lldb::SymbolType type) 221 { 222 m_type = (lldb::SymbolType)type; 223 } 224 225 const char * 226 GetTypeAsString () const; 227 228 uint32_t GetFlags()229 GetFlags () const 230 { 231 return m_flags; 232 } 233 234 void SetFlags(uint32_t flags)235 SetFlags (uint32_t flags) 236 { 237 m_flags = flags; 238 } 239 240 void 241 GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const; 242 243 bool IsSynthetic()244 IsSynthetic () const 245 { 246 return m_is_synthetic; 247 } 248 249 void SetIsSynthetic(bool b)250 SetIsSynthetic (bool b) 251 { 252 m_is_synthetic = b; 253 } 254 255 256 bool GetSizeIsSynthesized()257 GetSizeIsSynthesized() const 258 { 259 return m_size_is_synthesized; 260 } 261 262 void SetSizeIsSynthesized(bool b)263 SetSizeIsSynthesized(bool b) 264 { 265 m_size_is_synthesized = b; 266 } 267 268 bool IsDebug()269 IsDebug () const 270 { 271 return m_is_debug; 272 } 273 274 void SetDebug(bool b)275 SetDebug (bool b) 276 { 277 m_is_debug = b; 278 } 279 280 bool IsExternal()281 IsExternal () const 282 { 283 return m_is_external; 284 } 285 286 void SetExternal(bool b)287 SetExternal (bool b) 288 { 289 m_is_external = b; 290 } 291 292 bool 293 IsTrampoline () const; 294 295 bool 296 IsIndirect () const; 297 298 bool GetByteSizeIsValid()299 GetByteSizeIsValid () const 300 { 301 return m_size_is_valid; 302 } 303 304 lldb::addr_t 305 GetByteSize () const; 306 307 void SetByteSize(lldb::addr_t size)308 SetByteSize (lldb::addr_t size) 309 { 310 m_size_is_valid = size > 0; 311 m_addr_range.SetByteSize(size); 312 } 313 314 bool GetSizeIsSibling()315 GetSizeIsSibling () const 316 { 317 return m_size_is_sibling; 318 } 319 320 void SetSizeIsSibling(bool b)321 SetSizeIsSibling (bool b) 322 { 323 m_size_is_sibling = b; 324 } 325 326 // If m_type is "Code" or "Function" then this will return the prologue size 327 // in bytes, else it will return zero. 328 uint32_t 329 GetPrologueByteSize (); 330 331 bool GetDemangledNameIsSynthesized()332 GetDemangledNameIsSynthesized() const 333 { 334 return m_demangled_is_synthesized; 335 } 336 void SetDemangledNameIsSynthesized(bool b)337 SetDemangledNameIsSynthesized(bool b) 338 { 339 m_demangled_is_synthesized = b; 340 } 341 342 bool ContainsLinkerAnnotations()343 ContainsLinkerAnnotations() const 344 { 345 return m_contains_linker_annotations; 346 } 347 void SetContainsLinkerAnnotations(bool b)348 SetContainsLinkerAnnotations(bool b) 349 { 350 m_contains_linker_annotations = b; 351 } 352 //------------------------------------------------------------------ 353 /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) 354 /// 355 /// @see SymbolContextScope 356 //------------------------------------------------------------------ 357 virtual void 358 CalculateSymbolContext (SymbolContext *sc); 359 360 virtual lldb::ModuleSP 361 CalculateSymbolContextModule (); 362 363 virtual Symbol * 364 CalculateSymbolContextSymbol (); 365 366 //------------------------------------------------------------------ 367 /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) 368 /// 369 /// @see SymbolContextScope 370 //------------------------------------------------------------------ 371 virtual void 372 DumpSymbolContext (Stream *s); 373 374 lldb::DisassemblerSP 375 GetInstructions (const ExecutionContext &exe_ctx, 376 const char *flavor, 377 bool prefer_file_cache); 378 379 bool 380 GetDisassembly (const ExecutionContext &exe_ctx, 381 const char *flavor, 382 bool prefer_file_cache, 383 Stream &strm); 384 385 protected: 386 // This is the internal guts of ResolveReExportedSymbol, it assumes reexport_name is not null, and that module_spec 387 // is valid. We track the modules we've already seen to make sure we don't get caught in a cycle. 388 389 Symbol * 390 ResolveReExportedSymbolInModuleSpec (Target &target, 391 ConstString &reexport_name, 392 lldb_private::ModuleSpec &module_spec, 393 lldb_private::ModuleList &seen_modules) const; 394 395 uint32_t m_uid; // User ID (usually the original symbol table index) 396 uint16_t m_type_data; // data specific to m_type 397 uint16_t m_type_data_resolved:1, // True if the data in m_type_data has already been calculated 398 m_is_synthetic:1, // non-zero if this symbol is not actually in the symbol table, but synthesized from other info in the object file. 399 m_is_debug:1, // non-zero if this symbol is debug information in a symbol 400 m_is_external:1, // non-zero if this symbol is globally visible 401 m_size_is_sibling:1, // m_size contains the index of this symbol's sibling 402 m_size_is_synthesized:1,// non-zero if this symbol's size was calculated using a delta between this symbol and the next 403 m_size_is_valid:1, 404 m_demangled_is_synthesized:1, // The demangled name was created should not be used for expressions or other lookups 405 m_contains_linker_annotations:1, // The symbol name contains linker annotations, which are optional when doing name lookups 406 m_type:7; 407 Mangled m_mangled; // uniqued symbol name/mangled name pair 408 AddressRange m_addr_range; // Contains the value, or the section offset address when the value is an address in a section, and the size (if any) 409 uint32_t m_flags; // A copy of the flags from the original symbol table, the ObjectFile plug-in can interpret these 410 }; 411 412 } // namespace lldb_private 413 414 #endif // liblldb_Symbol_h_ 415