1 //===-- Symbol.h ------------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_Symbol_h_
11 #define liblldb_Symbol_h_
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"
19 namespace lldb_private {
21 class Symbol : public SymbolContextScope {
23 // ObjectFile readers can classify their symbol table entries and searches can
25 // on specific types where the symbol values will have drastically different
27 // and sorting requirements.
30 Symbol(uint32_t symID, const char *name, bool name_is_mangled,
31 lldb::SymbolType type, bool external, bool is_debug,
32 bool is_trampoline, bool is_artificial,
33 const lldb::SectionSP §ion_sp, lldb::addr_t value,
34 lldb::addr_t size, bool size_is_valid,
35 bool contains_linker_annotations, uint32_t flags);
37 Symbol(uint32_t symID, const Mangled &mangled, lldb::SymbolType type,
38 bool external, bool is_debug, bool is_trampoline, bool is_artificial,
39 const AddressRange &range, bool size_is_valid,
40 bool contains_linker_annotations, uint32_t flags);
42 Symbol(const Symbol &rhs);
44 const Symbol &operator=(const Symbol &rhs);
48 bool Compare(const ConstString &name, lldb::SymbolType type) const;
50 void Dump(Stream *s, Target *target, uint32_t index) const;
52 bool ValueIsAddress() const;
54 //------------------------------------------------------------------
55 // The GetAddressRef() accessor functions should only be called if
56 // you previously call ValueIsAddress() otherwise you might get an
57 // reference to an Address object that contains an constant integer
58 // value in m_addr_range.m_base_addr.m_offset which could be
59 // incorrectly used to represent an absolute address since it has
61 //------------------------------------------------------------------
62 Address &GetAddressRef() { return m_addr_range.GetBaseAddress(); }
64 const Address &GetAddressRef() const { return m_addr_range.GetBaseAddress(); }
66 //------------------------------------------------------------------
67 // Makes sure the symbol's value is an address and returns the file
68 // address. Returns LLDB_INVALID_ADDRESS if the symbol's value isn't
70 //------------------------------------------------------------------
71 lldb::addr_t GetFileAddress() const;
73 //------------------------------------------------------------------
74 // Makes sure the symbol's value is an address and gets the load
75 // address using \a target if it is. Returns LLDB_INVALID_ADDRESS
76 // if the symbol's value isn't an address or if the section isn't
77 // loaded in \a target.
78 //------------------------------------------------------------------
79 lldb::addr_t GetLoadAddress(Target *target) const;
81 //------------------------------------------------------------------
82 // Access the address value. Do NOT hand out the AddressRange as an
83 // object as the byte size of the address range may not be filled in
84 // and it should be accessed via GetByteSize().
85 //------------------------------------------------------------------
86 Address GetAddress() const {
87 // Make sure the our value is an address before we hand a copy out.
88 // We use the Address inside m_addr_range to contain the value for
89 // symbols that are not address based symbols so we are using it
90 // for more than just addresses. For example undefined symbols on
91 // MacOSX have a nlist.n_value of 0 (zero) and this will get placed
92 // into m_addr_range.m_base_addr.m_offset and it will have no section.
93 // So in the GetAddress() accessor, we need to hand out an invalid
94 // address if the symbol's value isn't an address.
96 return m_addr_range.GetBaseAddress();
101 // When a symbol's value isn't an address, we need to access the raw
102 // value. This function will ensure this symbol's value isn't an address
103 // and return the integer value if this checks out, otherwise it will
104 // return "fail_value" if the symbol is an address value.
105 uint64_t GetIntegerValue(uint64_t fail_value = 0) const {
106 if (ValueIsAddress()) {
107 // This symbol's value is an address. Use Symbol::GetAddress() to get the
111 // The value is stored in the base address' offset
112 return m_addr_range.GetBaseAddress().GetOffset();
116 lldb::addr_t ResolveCallableAddress(Target &target) const;
118 ConstString GetName() const;
120 ConstString GetNameNoArguments() const;
122 ConstString GetDisplayName() const;
124 uint32_t GetID() const { return m_uid; }
126 lldb::LanguageType GetLanguage() const {
127 // TODO: See if there is a way to determine the language for a symbol
128 // somehow, for now just return our best guess
129 return m_mangled.GuessLanguage();
132 void SetID(uint32_t uid) { m_uid = uid; }
134 Mangled &GetMangled() { return m_mangled; }
136 const Mangled &GetMangled() const { return m_mangled; }
138 ConstString GetReExportedSymbolName() const;
140 FileSpec GetReExportedSymbolSharedLibrary() const;
142 void SetReExportedSymbolName(const ConstString &name);
144 bool SetReExportedSymbolSharedLibrary(const FileSpec &fspec);
146 Symbol *ResolveReExportedSymbol(Target &target) const;
148 uint32_t GetSiblingIndex() const;
150 lldb::SymbolType GetType() const { return (lldb::SymbolType)m_type; }
152 void SetType(lldb::SymbolType type) { m_type = (lldb::SymbolType)type; }
154 const char *GetTypeAsString() const;
156 uint32_t GetFlags() const { return m_flags; }
158 void SetFlags(uint32_t flags) { m_flags = flags; }
160 void GetDescription(Stream *s, lldb::DescriptionLevel level,
161 Target *target) const;
163 bool IsSynthetic() const { return m_is_synthetic; }
165 void SetIsSynthetic(bool b) { m_is_synthetic = b; }
167 bool GetSizeIsSynthesized() const { return m_size_is_synthesized; }
169 void SetSizeIsSynthesized(bool b) { m_size_is_synthesized = b; }
171 bool IsDebug() const { return m_is_debug; }
173 void SetDebug(bool b) { m_is_debug = b; }
175 bool IsExternal() const { return m_is_external; }
177 void SetExternal(bool b) { m_is_external = b; }
179 bool IsTrampoline() const;
181 bool IsIndirect() const;
183 bool GetByteSizeIsValid() const { return m_size_is_valid; }
185 lldb::addr_t GetByteSize() const;
187 void SetByteSize(lldb::addr_t size) {
188 m_size_is_valid = size > 0;
189 m_addr_range.SetByteSize(size);
192 bool GetSizeIsSibling() const { return m_size_is_sibling; }
194 void SetSizeIsSibling(bool b) { m_size_is_sibling = b; }
196 // If m_type is "Code" or "Function" then this will return the prologue size
197 // in bytes, else it will return zero.
198 uint32_t GetPrologueByteSize();
200 bool GetDemangledNameIsSynthesized() const {
201 return m_demangled_is_synthesized;
204 void SetDemangledNameIsSynthesized(bool b) { m_demangled_is_synthesized = b; }
206 bool ContainsLinkerAnnotations() const {
207 return m_contains_linker_annotations;
209 void SetContainsLinkerAnnotations(bool b) {
210 m_contains_linker_annotations = b;
212 //------------------------------------------------------------------
213 /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
215 /// @see SymbolContextScope
216 //------------------------------------------------------------------
217 void CalculateSymbolContext(SymbolContext *sc) override;
219 lldb::ModuleSP CalculateSymbolContextModule() override;
221 Symbol *CalculateSymbolContextSymbol() override;
223 //------------------------------------------------------------------
224 /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*)
226 /// @see SymbolContextScope
227 //------------------------------------------------------------------
228 void DumpSymbolContext(Stream *s) override;
230 lldb::DisassemblerSP GetInstructions(const ExecutionContext &exe_ctx,
232 bool prefer_file_cache);
234 bool GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor,
235 bool prefer_file_cache, Stream &strm);
237 bool ContainsFileAddress(lldb::addr_t file_addr) const;
240 // This is the internal guts of ResolveReExportedSymbol, it assumes
241 // reexport_name is not null, and that module_spec
242 // is valid. We track the modules we've already seen to make sure we don't
243 // get caught in a cycle.
245 Symbol *ResolveReExportedSymbolInModuleSpec(
246 Target &target, ConstString &reexport_name,
247 lldb_private::ModuleSpec &module_spec,
248 lldb_private::ModuleList &seen_modules) const;
250 uint32_t m_uid; // User ID (usually the original symbol table index)
251 uint16_t m_type_data; // data specific to m_type
252 uint16_t m_type_data_resolved : 1, // True if the data in m_type_data has
253 // already been calculated
254 m_is_synthetic : 1, // non-zero if this symbol is not actually in the
255 // symbol table, but synthesized from other info in
257 m_is_debug : 1, // non-zero if this symbol is debug information in a
259 m_is_external : 1, // non-zero if this symbol is globally visible
260 m_size_is_sibling : 1, // m_size contains the index of this symbol's
262 m_size_is_synthesized : 1, // non-zero if this symbol's size was
263 // calculated using a delta between this symbol
266 m_demangled_is_synthesized : 1, // The demangled name was created should
267 // not be used for expressions or other
269 m_contains_linker_annotations : 1, // The symbol name contains linker
270 // annotations, which are optional when
271 // doing name lookups
273 Mangled m_mangled; // uniqued symbol name/mangled name pair
274 AddressRange m_addr_range; // Contains the value, or the section offset
275 // address when the value is an address in a
276 // section, and the size (if any)
277 uint32_t m_flags; // A copy of the flags from the original symbol table, the
278 // ObjectFile plug-in can interpret these
281 } // namespace lldb_private
283 #endif // liblldb_Symbol_h_