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