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