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