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