1 //===-- Symbol.h ------------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef liblldb_Symbol_h_
10 #define liblldb_Symbol_h_
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"
18 namespace lldb_private {
20 class Symbol : public SymbolContextScope {
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.
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);
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);
39 Symbol(const Symbol &rhs);
41 const Symbol &operator=(const Symbol &rhs);
45 bool Compare(ConstString name, lldb::SymbolType type) const;
47 void Dump(Stream *s, Target *target, uint32_t index) const;
49 bool ValueIsAddress() const;
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(); }
58 const Address &GetAddressRef() const { return m_addr_range.GetBaseAddress(); }
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;
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;
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.
82 return m_addr_range.GetBaseAddress();
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
97 // The value is stored in the base address' offset
98 return m_addr_range.GetBaseAddress().GetOffset();
102 lldb::addr_t ResolveCallableAddress(Target &target) const;
104 ConstString GetName() const;
106 ConstString GetNameNoArguments() const;
108 ConstString GetDisplayName() const;
110 uint32_t GetID() const { return m_uid; }
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();
118 void SetID(uint32_t uid) { m_uid = uid; }
120 Mangled &GetMangled() { return m_mangled; }
122 const Mangled &GetMangled() const { return m_mangled; }
124 ConstString GetReExportedSymbolName() const;
126 FileSpec GetReExportedSymbolSharedLibrary() const;
128 void SetReExportedSymbolName(ConstString name);
130 bool SetReExportedSymbolSharedLibrary(const FileSpec &fspec);
132 Symbol *ResolveReExportedSymbol(Target &target) const;
134 uint32_t GetSiblingIndex() const;
136 lldb::SymbolType GetType() const { return (lldb::SymbolType)m_type; }
138 void SetType(lldb::SymbolType type) { m_type = (lldb::SymbolType)type; }
140 const char *GetTypeAsString() const;
142 uint32_t GetFlags() const { return m_flags; }
144 void SetFlags(uint32_t flags) { m_flags = flags; }
146 void GetDescription(Stream *s, lldb::DescriptionLevel level,
147 Target *target) const;
149 bool IsSynthetic() const { return m_is_synthetic; }
151 void SetIsSynthetic(bool b) { m_is_synthetic = b; }
153 bool GetSizeIsSynthesized() const { return m_size_is_synthesized; }
155 void SetSizeIsSynthesized(bool b) { m_size_is_synthesized = b; }
157 bool IsDebug() const { return m_is_debug; }
159 void SetDebug(bool b) { m_is_debug = b; }
161 bool IsExternal() const { return m_is_external; }
163 void SetExternal(bool b) { m_is_external = b; }
165 bool IsTrampoline() const;
167 bool IsIndirect() const;
169 bool IsWeak() const { return m_is_weak; }
171 void SetIsWeak (bool b) { m_is_weak = b; }
173 bool GetByteSizeIsValid() const { return m_size_is_valid; }
175 lldb::addr_t GetByteSize() const;
177 void SetByteSize(lldb::addr_t size) {
178 m_size_is_valid = size > 0;
179 m_addr_range.SetByteSize(size);
182 bool GetSizeIsSibling() const { return m_size_is_sibling; }
184 void SetSizeIsSibling(bool b) { m_size_is_sibling = b; }
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();
190 bool GetDemangledNameIsSynthesized() const {
191 return m_demangled_is_synthesized;
194 void SetDemangledNameIsSynthesized(bool b) { m_demangled_is_synthesized = b; }
196 bool ContainsLinkerAnnotations() const {
197 return m_contains_linker_annotations;
199 void SetContainsLinkerAnnotations(bool b) {
200 m_contains_linker_annotations = b;
202 /// \copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
204 /// \see SymbolContextScope
205 void CalculateSymbolContext(SymbolContext *sc) override;
207 lldb::ModuleSP CalculateSymbolContextModule() override;
209 Symbol *CalculateSymbolContextSymbol() override;
211 /// \copydoc SymbolContextScope::DumpSymbolContext(Stream*)
213 /// \see SymbolContextScope
214 void DumpSymbolContext(Stream *s) override;
216 lldb::DisassemblerSP GetInstructions(const ExecutionContext &exe_ctx,
218 bool prefer_file_cache);
220 bool GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor,
221 bool prefer_file_cache, Stream &strm);
223 bool ContainsFileAddress(lldb::addr_t file_addr) const;
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.
230 Symbol *ResolveReExportedSymbolInModuleSpec(
231 Target &target, ConstString &reexport_name,
232 lldb_private::ModuleSpec &module_spec,
233 lldb_private::ModuleList &seen_modules) const;
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
242 m_is_debug : 1, // non-zero if this symbol is debug information in a
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
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
251 m_demangled_is_synthesized : 1, // The demangled name was created should
252 // not be used for expressions or other
254 m_contains_linker_annotations : 1, // The symbol name contains linker
255 // annotations, which are optional when
256 // doing name lookups
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
267 } // namespace lldb_private
269 #endif // liblldb_Symbol_h_