LLDB mainline
Symbol.h
Go to the documentation of this file.
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
13#include "lldb/Core/Mangled.h"
14#include "lldb/Core/Section.h"
17#include "lldb/Utility/Stream.h"
18#include "lldb/Utility/UserID.h"
20#include "lldb/lldb-private.h"
21#include "llvm/Support/JSON.h"
22
23#include <optional>
24
25namespace lldb_private {
26
27struct JSONSymbol {
28 std::optional<uint64_t> address;
29 std::optional<uint64_t> value;
30 std::optional<uint64_t> size;
31 std::optional<uint64_t> id;
32 std::optional<lldb::SymbolType> type;
33 std::string name;
34};
35
36class Symbol : public SymbolContextScope {
37public:
38 // ObjectFile readers can classify their symbol table entries and searches
39 // can be made on specific types where the symbol values will have
40 // drastically different meanings and sorting requirements.
41 Symbol();
42
43 Symbol(uint32_t symID, llvm::StringRef name, lldb::SymbolType type,
44 bool external, bool is_debug, bool is_trampoline, bool is_artificial,
45 const lldb::SectionSP &section_sp, lldb::addr_t value,
46 lldb::addr_t size, bool size_is_valid,
47 bool contains_linker_annotations, uint32_t flags);
48
49 Symbol(uint32_t symID, const Mangled &mangled, lldb::SymbolType type,
50 bool external, bool is_debug, bool is_trampoline, bool is_artificial,
51 const AddressRange &range, bool size_is_valid,
52 bool contains_linker_annotations, uint32_t flags);
53
54 Symbol(const Symbol &rhs);
55
59 m_addr_or_reexport.GetAddressRange(*this).Clear();
60 }
61
62 const Symbol &operator=(const Symbol &rhs);
63
64 static llvm::Expected<Symbol> FromJSON(const JSONSymbol &symbol,
65 SectionList *section_list);
66
67 void Clear();
68
69 bool Compare(ConstString name, lldb::SymbolType type) const;
70
71 void Dump(Stream *s, Target *target, uint32_t index,
72 Mangled::NamePreference name_preference =
74
75 bool ValueIsAddress() const;
76
77 // The GetAddressRef() accessor functions should only be called if you
78 // previously call ValueIsAddress() otherwise you might get an reference to
79 // an Address object that contains an constant integer value in
80 // m_addr_range.m_base_addr.m_offset which could be incorrectly used to
81 // represent an absolute address since it has no section.
83 return m_addr_or_reexport.GetAddressRange(*this).GetBaseAddress();
84 }
85
86 const Address &GetAddressRef() const {
87 return m_addr_or_reexport.GetAddressRange(*this).GetBaseAddress();
88 }
89
90 // Makes sure the symbol's value is an address and returns the file address.
91 // Returns LLDB_INVALID_ADDRESS if the symbol's value isn't an address.
93
94 // Makes sure the symbol's value is an address and gets the load address
95 // using \a target if it is. Returns LLDB_INVALID_ADDRESS if the symbol's
96 // value isn't an address or if the section isn't loaded in \a target.
97 lldb::addr_t GetLoadAddress(Target *target) const;
98
99 // Access the address value. Do NOT hand out the AddressRange as an object as
100 // the byte size of the address range may not be filled in and it should be
101 // accessed via GetByteSize().
103 // Make sure the our value is an address before we hand a copy out. We use
104 // the Address inside m_addr_range to contain the value for symbols that
105 // are not address based symbols so we are using it for more than just
106 // addresses. For example undefined symbols on MacOSX have a nlist.n_value
107 // of 0 (zero) and this will get placed into
108 // m_addr_range.m_base_addr.m_offset and it will have no section. So in the
109 // GetAddress() accessor, we need to hand out an invalid address if the
110 // symbol's value isn't an address.
111 if (ValueIsAddress())
112 return m_addr_or_reexport.GetAddressRange(*this).GetBaseAddress();
113 else
114 return Address();
115 }
116
117 /// Get the raw value of the symbol from the symbol table.
118 ///
119 /// If the symbol's value is an address, return the file address, else return
120 /// the raw value that is stored in the m_addr_range. If the base address has
121 /// no section, then getting the file address will return the correct value
122 /// as it will return the offset in the base address which is the value.
123 uint64_t GetRawValue() const {
124 return m_addr_or_reexport.GetAddressRange(*this)
125 .GetBaseAddress()
126 .GetFileAddress();
127 }
128
129 // When a symbol's value isn't an address, we need to access the raw value.
130 // This function will ensure this symbol's value isn't an address and return
131 // the integer value if this checks out, otherwise it will return
132 // "fail_value" if the symbol is an address value.
133 uint64_t GetIntegerValue(uint64_t fail_value = 0) const {
134 if (ValueIsAddress()) {
135 // This symbol's value is an address. Use Symbol::GetAddress() to get the
136 // address.
137 return fail_value;
138 } else {
139 // The value is stored in the base address' offset
140 return m_addr_or_reexport.GetAddressRange(*this)
141 .GetBaseAddress()
142 .GetOffset();
143 }
144 }
145
147
148 ConstString GetName() const;
149
151
153
154 uint32_t GetID() const { return m_uid; }
155
157 // TODO: See if there is a way to determine the language for a symbol
158 // somehow, for now just return our best guess
159 return GetMangled().GuessLanguage();
160 }
161
162 void SetID(uint32_t uid) { m_uid = uid; }
163
166 return m_mangled;
167 }
168
169 const Mangled &GetMangled() const {
171 return m_mangled;
172 }
173
175
177
179
181
182 Symbol *ResolveReExportedSymbol(Target &target) const;
183
184 uint32_t GetSiblingIndex() const;
185
187
188 void SetType(lldb::SymbolType type) { m_type = type; }
189
190 const char *GetTypeAsString() const;
191
192 uint32_t GetFlags() const { return m_flags; }
193
194 void SetFlags(uint32_t flags) { m_flags = flags; }
195
196 void GetDescription(
197 Stream *s, lldb::DescriptionLevel level, Target *target,
198 std::optional<Stream::HighlightSettings> settings = std::nullopt) const;
199
200 bool IsSynthetic() const { return m_is_synthetic; }
201
203
204 void SetIsSynthetic(bool b) { m_is_synthetic = b; }
205
207
209
210 bool IsDebug() const { return m_is_debug; }
211
212 void SetDebug(bool b) { m_is_debug = b; }
213
214 bool IsExternal() const { return m_is_external; }
215
216 void SetExternal(bool b) { m_is_external = b; }
217
218 bool IsTrampoline() const;
219
220 bool IsIndirect() const;
221
222 bool IsWeak() const { return m_is_weak; }
223
224 void SetIsWeak(bool b) { m_is_weak = b; }
225
226 bool GetByteSizeIsValid() const { return m_size_is_valid; }
227
229
231 m_size_is_valid = size > 0;
232 m_addr_or_reexport.GetAddressRange(*this).SetByteSize(size);
233 }
234
235 bool GetSizeIsSibling() const { return m_size_is_sibling; }
236
238
239 // If m_type is "Code" or "Function" then this will return the prologue size
240 // in bytes, else it will return zero.
241 uint32_t GetPrologueByteSize();
242
243 void SetPrologueByteSize(uint32_t prologue_byte_size) {
244 assert(m_type == lldb::eSymbolTypeCode ||
246 m_type_data = prologue_byte_size;
248 }
249
253
255
262 /// \copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
263 ///
264 /// \see SymbolContextScope
265 void CalculateSymbolContext(SymbolContext *sc) override;
266
268
270
271 /// \copydoc SymbolContextScope::DumpSymbolContext(Stream*)
272 ///
273 /// \see SymbolContextScope
274 void DumpSymbolContext(Stream *s) override;
275
277 const char *flavor,
278 bool prefer_file_cache);
279
280 bool GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor,
281 bool prefer_file_cache, Stream &strm);
282
283 bool ContainsFileAddress(lldb::addr_t file_addr) const;
284
285 static llvm::StringRef GetSyntheticSymbolPrefix() {
286 return "___lldb_unnamed_symbol_";
287 }
288
289 /// Decode a serialized version of this object from data.
290 ///
291 /// \param data
292 /// The decoder object that references the serialized data.
293 ///
294 /// \param offset_ptr
295 /// A pointer that contains the offset from which the data will be decoded
296 /// from. The offset_ptr offset value will be updated as data is read.
297 ///
298 /// \param section_list
299 /// A section list that allows lldb_private::Address objects to be filled
300 /// in. The address information for symbols are serialized as file addresses
301 /// and must be converted into Address objects with the right section and
302 /// offset.
303 ///
304 /// \param strtab
305 /// All strings in cache files are put into string tables for efficiency
306 /// and cache file size reduction. Strings are stored as uint32_t string
307 /// table offsets in the cache data.
308 ///
309 /// \return
310 /// True if the symbol is successfully decoded, false otherwise.
311 bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
312 const SectionList *section_list, const StringTableReader &strtab);
313
314 /// Encode this object into a data encoder object.
315 ///
316 /// This allows this object to be serialized to disk.
317 ///
318 /// \param encoder
319 /// A data encoder object that serialized bytes will be encoded into.
320 ///
321 /// \param strtab
322 /// All strings in cache files are put into string tables for efficiency
323 /// and cache file size reduction. Strings are stored as uint32_t string
324 /// table offsets in the cache data.
325 void Encode(DataEncoder &encoder, ConstStringTable &strtab) const;
326
327 bool operator==(const Symbol &rhs) const;
328
329 static const char *GetTypeAsString(lldb::SymbolType symbol_type);
330
331 static lldb::SymbolType GetTypeFromString(const char *str);
332
333protected:
334 // This is the internal guts of ResolveReExportedSymbol, it assumes
335 // reexport_name is not null, and that module_spec is valid. We track the
336 // modules we've already seen to make sure we don't get caught in a cycle.
337
339 Target &target, ConstString reexport_name,
340 lldb_private::ModuleSpec &module_spec,
341 lldb_private::ModuleList &seen_modules) const;
342
343 void SynthesizeNameIfNeeded() const;
344
345 // Initially, a ReExportInfo will only have a name: the symbol name
346 // that this Symbol will remap to, at runtime.
347 // We won't have the library that this symbol is defined in,
348 // until later, when we have other binaries loaded in the Target.
351 std::unique_ptr<FileSpec> library_up;
354 name = rhs.name;
355 if (rhs.library_up)
356 library_up = std::make_unique<FileSpec>(*rhs.library_up);
357 else
358 library_up.reset();
359 }
361 if (this != &rhs) {
362 name = rhs.name;
363 if (rhs.library_up)
364 library_up = std::make_unique<FileSpec>(*rhs.library_up);
365 else
366 library_up.reset();
367 }
368 return *this;
369 }
370 void Clear() {
371 name.Clear();
372 library_up.reset();
373 }
374 };
375
376 uint32_t m_uid = LLDB_INVALID_SYMBOL_ID; // User ID (usually the original
377 // symbol table index)
378 uint16_t m_type_data = 0; // data specific to m_type
379 uint16_t m_type_data_resolved : 1, // True if the data in m_type_data has
380 // already been calculated
381 m_is_synthetic : 1, // non-zero if this symbol is not actually in the
382 // symbol table, but synthesized from other info in
383 // the object file.
384 m_is_debug : 1, // non-zero if this symbol is debug information in a
385 // symbol
386 m_is_external : 1, // non-zero if this symbol is globally visible
387 m_size_is_sibling : 1, // m_size contains the index of this symbol's
388 // sibling
389 m_size_is_synthesized : 1, // non-zero if this symbol's size was
390 // calculated using a delta between this
391 // symbol and the next
393 m_demangled_is_synthesized : 1, // The demangled name was created should
394 // not be used for expressions or other
395 // lookups
396 m_contains_linker_annotations : 1, // The symbol name contains linker
397 // annotations, which are optional when
398 // doing name lookups
400 m_type : 6; // Values from the lldb::SymbolType enum.
401 mutable Mangled m_mangled; // uniqued symbol name/mangled name pair
402
403 // A wrapper around a `union {AddressRange, ReExportInfo}` to
404 // enforce the types being get/set match the Symbol's m_type,
405 // assert if there is a type mismatch.
408 const AddressRange &GetAddressRange(const Symbol &sym) const;
410 const ReExportInfo &GetReExportInfo(const Symbol &sym) const;
411 void SetAddressRange(Symbol &sym, const AddressRange addr_range);
412 void SetReExportInfo(Symbol &sym, const ReExportInfo reexport_info);
413
416 m_reexport_info.Clear();
417 }
418 // Proper destruction is handled by Symbol's dtor; supply a no-op
419 // impl to let the compiler know it's handled.
421
422 private:
423 union {
424 // Contains the value, or the section offset address when the value is an
425 // address in a section, and the size (if known). For non-re-export
426 // symbols.
428
429 // Stores re-export information if this symbol is of type
430 // eSymbolTypeReExported; no address information for these symbols.
432 };
434
435 uint32_t m_flags = 0; // A copy of the flags from the original symbol table,
436 // the ObjectFile plug-in can interpret these
437};
438
439} // namespace lldb_private
440
441#if __SIZEOF_POINTER__ == 8
442static_assert(
443 sizeof(lldb_private::Symbol) == 80,
444 "Symbol is a high volume data type, size must be increased with care");
445#endif
446
447namespace llvm {
448namespace json {
449
450bool fromJSON(const llvm::json::Value &value, lldb_private::JSONSymbol &symbol,
451 llvm::json::Path path);
452
453bool fromJSON(const llvm::json::Value &value, lldb::SymbolType &type,
454 llvm::json::Path path);
455
456} // namespace json
457} // namespace llvm
458
459#endif // LLDB_SYMBOL_SYMBOL_H
A section + offset based address range class.
A section + offset based address class.
Definition Address.h:62
Many cache files require string tables to store data efficiently.
A uniqued constant string class.
Definition ConstString.h:40
An binary data encoding class.
Definition DataEncoder.h:42
An data extractor class.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
A file utility class.
Definition FileSpec.h:56
A class that handles mangled names.
Definition Mangled.h:34
lldb::LanguageType GuessLanguage() const
Try to guess the language from the mangling.
Definition Mangled.cpp:416
A collection class for Module objects.
Definition ModuleList.h:125
A stream class that can stream formatted output to a file.
Definition Stream.h:28
Many cache files require string tables to store data efficiently.
"lldb/Symbol/SymbolContextScope.h" Inherit from this if your object is part of a symbol context and c...
Defines a symbol context baton that can be handed other debug core functions.
bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr, const SectionList *section_list, const StringTableReader &strtab)
Decode a serialized version of this object from data.
Definition Symbol.cpp:660
uint32_t GetSiblingIndex() const
Definition Symbol.cpp:241
uint16_t m_is_external
Definition Symbol.h:386
uint64_t GetIntegerValue(uint64_t fail_value=0) const
Definition Symbol.h:133
uint32_t GetID() const
Definition Symbol.h:154
lldb::addr_t GetLoadAddress(Target *target) const
Definition Symbol.cpp:547
bool ValueIsAddress() const
Definition Symbol.cpp:191
bool IsExternal() const
Definition Symbol.h:214
uint16_t m_type_data_resolved
Definition Symbol.h:379
void SetReExportedSymbolName(ConstString name)
Definition Symbol.cpp:221
void SetType(lldb::SymbolType type)
Definition Symbol.h:188
void SetSizeIsSynthesized(bool b)
Definition Symbol.h:208
void SetSizeIsSibling(bool b)
Definition Symbol.h:237
void CalculateSymbolContext(SymbolContext *sc) override
Reconstruct the object's symbol context into sc.
Definition Symbol.cpp:437
bool IsIndirect() const
Definition Symbol.cpp:249
bool IsDebug() const
Definition Symbol.h:210
void SynthesizeNameIfNeeded() const
Definition Symbol.cpp:638
const char * GetTypeAsString() const
Definition Symbol.cpp:433
bool IsSynthetic() const
Definition Symbol.h:200
uint16_t m_is_synthetic
Definition Symbol.h:381
uint16_t m_demangled_is_synthesized
Definition Symbol.h:393
lldb::DisassemblerSP GetInstructions(const ExecutionContext &exe_ctx, const char *flavor, bool prefer_file_cache)
Definition Symbol.cpp:595
bool ContainsLinkerAnnotations() const
Definition Symbol.h:256
lldb::addr_t GetFileAddress() const
Definition Symbol.cpp:540
void DumpSymbolContext(Stream *s) override
Dump the object's symbol context to the stream s.
Definition Symbol.cpp:454
lldb::ModuleSP CalculateSymbolContextModule() override
Definition Symbol.cpp:446
bool ContainsFileAddress(lldb::addr_t file_addr) const
Definition Symbol.cpp:624
bool GetDemangledNameIsSynthesized() const
Definition Symbol.h:250
bool GetByteSizeIsValid() const
Definition Symbol.h:226
Mangled & GetMangled()
Definition Symbol.h:164
static lldb::SymbolType GetTypeFromString(const char *str)
Definition Symbol.cpp:865
uint16_t m_contains_linker_annotations
Definition Symbol.h:396
uint16_t m_size_is_valid
Definition Symbol.h:392
lldb::LanguageType GetLanguage() const
Definition Symbol.h:156
bool IsTrampoline() const
Definition Symbol.cpp:247
Address & GetAddressRef()
Definition Symbol.h:82
const Symbol & operator=(const Symbol &rhs)
Definition Symbol.cpp:97
void SetContainsLinkerAnnotations(bool b)
Definition Symbol.h:259
void SetIsWeak(bool b)
Definition Symbol.h:224
bool IsSyntheticWithAutoGeneratedName() const
Definition Symbol.cpp:629
void Encode(DataEncoder &encoder, ConstStringTable &strtab) const
Encode this object into a data encoder object.
Definition Symbol.cpp:736
uint32_t GetFlags() const
Definition Symbol.h:192
bool GetSizeIsSibling() const
Definition Symbol.h:235
const Mangled & GetMangled() const
Definition Symbol.h:169
void SetPrologueByteSize(uint32_t prologue_byte_size)
Definition Symbol.h:243
ConstString GetReExportedSymbolName() const
Definition Symbol.cpp:203
bool Compare(ConstString name, lldb::SymbolType type) const
Definition Symbol.cpp:424
uint16_t m_is_debug
Definition Symbol.h:384
bool SetReExportedSymbolSharedLibrary(const FileSpec &fspec)
Definition Symbol.cpp:230
void GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target, std::optional< Stream::HighlightSettings > settings=std::nullopt) const
Definition Symbol.cpp:251
bool operator==(const Symbol &rhs) const
Definition Symbol.cpp:786
static llvm::StringRef GetSyntheticSymbolPrefix()
Definition Symbol.h:285
lldb::addr_t GetByteSize() const
Definition Symbol.cpp:469
ConstString GetName() const
Definition Symbol.cpp:554
lldb::SymbolType GetType() const
Definition Symbol.h:186
void SetFlags(uint32_t flags)
Definition Symbol.h:194
struct lldb_private::Symbol::AddrRangeOrReExport m_addr_or_reexport
Address GetAddress() const
Definition Symbol.h:102
ConstString GetNameNoArguments() const
Definition Symbol.cpp:556
uint16_t m_size_is_sibling
Definition Symbol.h:387
Symbol * ResolveReExportedSymbol(Target &target) const
Definition Symbol.cpp:526
FileSpec GetReExportedSymbolSharedLibrary() const
Definition Symbol.cpp:210
uint16_t m_is_weak
Definition Symbol.h:399
bool IsWeak() const
Definition Symbol.h:222
void SetIsSynthetic(bool b)
Definition Symbol.h:204
bool GetSizeIsSynthesized() const
Definition Symbol.h:206
Symbol * ResolveReExportedSymbolInModuleSpec(Target &target, ConstString reexport_name, lldb_private::ModuleSpec &module_spec, lldb_private::ModuleList &seen_modules) const
Definition Symbol.cpp:476
void SetByteSize(lldb::addr_t size)
Definition Symbol.h:230
uint32_t GetPrologueByteSize()
Definition Symbol.cpp:348
uint16_t m_type_data
Definition Symbol.h:378
void SetDemangledNameIsSynthesized(bool b)
Definition Symbol.h:254
ConstString GetDisplayName() const
Definition Symbol.cpp:199
bool GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor, bool prefer_file_cache, Stream &strm)
Definition Symbol.cpp:609
lldb::addr_t ResolveCallableAddress(Target &target) const
Definition Symbol.cpp:560
void SetExternal(bool b)
Definition Symbol.h:216
uint16_t m_size_is_synthesized
Definition Symbol.h:389
Symbol * CalculateSymbolContextSymbol() override
Definition Symbol.cpp:452
void SetDebug(bool b)
Definition Symbol.h:212
uint64_t GetRawValue() const
Get the raw value of the symbol from the symbol table.
Definition Symbol.h:123
const Address & GetAddressRef() const
Definition Symbol.h:86
void SetID(uint32_t uid)
Definition Symbol.h:162
static llvm::Expected< Symbol > FromJSON(const JSONSymbol &symbol, SectionList *section_list)
Definition Symbol.cpp:127
void Dump(Stream *s, Target *target, uint32_t index, Mangled::NamePreference name_preference=Mangled::ePreferDemangled) const
Definition Symbol.cpp:299
#define LLDB_INVALID_SYMBOL_ID
A class that represents a running process on the host machine.
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
uint64_t offset_t
Definition lldb-types.h:86
LanguageType
Programming language type.
SymbolType
Symbol types.
@ eSymbolTypeReExported
@ eSymbolTypeResolver
std::shared_ptr< lldb_private::Disassembler > DisassemblerSP
std::shared_ptr< lldb_private::Section > SectionSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::Module > ModuleSP
bool fromJSON(const llvm::json::Value &value, lldb_private::JSONSection &section, llvm::json::Path path)
Definition Section.cpp:720
std::optional< uint64_t > address
Definition Symbol.h:28
std::optional< uint64_t > id
Definition Symbol.h:31
std::optional< lldb::SymbolType > type
Definition Symbol.h:32
std::optional< uint64_t > value
Definition Symbol.h:29
std::optional< uint64_t > size
Definition Symbol.h:30
void SetReExportInfo(Symbol &sym, const ReExportInfo reexport_info)
Definition Symbol.cpp:931
void SetAddressRange(Symbol &sym, const AddressRange addr_range)
Definition Symbol.cpp:922
ReExportInfo & GetReExportInfo(Symbol &sym)
Definition Symbol.cpp:911
AddressRange & GetAddressRange(Symbol &sym)
Definition Symbol.cpp:899
const ReExportInfo & operator=(const ReExportInfo &rhs)
Definition Symbol.h:360
ReExportInfo(const ReExportInfo &rhs)
Definition Symbol.h:353
std::unique_ptr< FileSpec > library_up
Definition Symbol.h:351