xref: /openbsd/gnu/llvm/lldb/include/lldb/Symbol/Symbol.h (revision f6aab3d8)
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.
GetAddressRef()57   Address &GetAddressRef() { return m_addr_range.GetBaseAddress(); }
58 
GetAddressRef()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().
GetAddress()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   /// Get the raw value of the symbol from the symbol table.
89   ///
90   /// If the symbol's value is an address, return the file address, else return
91   /// the raw value that is stored in the m_addr_range. If the base address has
92   /// no section, then getting the file address will return the correct value
93   /// as it will return the offset in the base address which is the value.
GetRawValue()94   uint64_t GetRawValue() const {
95     return m_addr_range.GetBaseAddress().GetFileAddress();
96   }
97 
98   // When a symbol's value isn't an address, we need to access the raw value.
99   // This function will ensure this symbol's value isn't an address and return
100   // the integer value if this checks out, otherwise it will return
101   // "fail_value" if the symbol is an address value.
102   uint64_t GetIntegerValue(uint64_t fail_value = 0) const {
103     if (ValueIsAddress()) {
104       // This symbol's value is an address. Use Symbol::GetAddress() to get the
105       // address.
106       return fail_value;
107     } else {
108       // The value is stored in the base address' offset
109       return m_addr_range.GetBaseAddress().GetOffset();
110     }
111   }
112 
113   lldb::addr_t ResolveCallableAddress(Target &target) const;
114 
115   ConstString GetName() const;
116 
117   ConstString GetNameNoArguments() const;
118 
119   ConstString GetDisplayName() const;
120 
GetID()121   uint32_t GetID() const { return m_uid; }
122 
GetLanguage()123   lldb::LanguageType GetLanguage() const {
124     // TODO: See if there is a way to determine the language for a symbol
125     // somehow, for now just return our best guess
126     return GetMangled().GuessLanguage();
127   }
128 
SetID(uint32_t uid)129   void SetID(uint32_t uid) { m_uid = uid; }
130 
GetMangled()131   Mangled &GetMangled() {
132     SynthesizeNameIfNeeded();
133     return m_mangled;
134   }
135 
GetMangled()136   const Mangled &GetMangled() const {
137     SynthesizeNameIfNeeded();
138     return m_mangled;
139   }
140 
141   ConstString GetReExportedSymbolName() const;
142 
143   FileSpec GetReExportedSymbolSharedLibrary() const;
144 
145   void SetReExportedSymbolName(ConstString name);
146 
147   bool SetReExportedSymbolSharedLibrary(const FileSpec &fspec);
148 
149   Symbol *ResolveReExportedSymbol(Target &target) const;
150 
151   uint32_t GetSiblingIndex() const;
152 
GetType()153   lldb::SymbolType GetType() const { return (lldb::SymbolType)m_type; }
154 
SetType(lldb::SymbolType type)155   void SetType(lldb::SymbolType type) { m_type = (lldb::SymbolType)type; }
156 
157   const char *GetTypeAsString() const;
158 
GetFlags()159   uint32_t GetFlags() const { return m_flags; }
160 
SetFlags(uint32_t flags)161   void SetFlags(uint32_t flags) { m_flags = flags; }
162 
163   void GetDescription(Stream *s, lldb::DescriptionLevel level,
164                       Target *target) const;
165 
IsSynthetic()166   bool IsSynthetic() const { return m_is_synthetic; }
167 
168   bool IsSyntheticWithAutoGeneratedName() const;
169 
SetIsSynthetic(bool b)170   void SetIsSynthetic(bool b) { m_is_synthetic = b; }
171 
GetSizeIsSynthesized()172   bool GetSizeIsSynthesized() const { return m_size_is_synthesized; }
173 
SetSizeIsSynthesized(bool b)174   void SetSizeIsSynthesized(bool b) { m_size_is_synthesized = b; }
175 
IsDebug()176   bool IsDebug() const { return m_is_debug; }
177 
SetDebug(bool b)178   void SetDebug(bool b) { m_is_debug = b; }
179 
IsExternal()180   bool IsExternal() const { return m_is_external; }
181 
SetExternal(bool b)182   void SetExternal(bool b) { m_is_external = b; }
183 
184   bool IsTrampoline() const;
185 
186   bool IsIndirect() const;
187 
IsWeak()188   bool IsWeak() const { return m_is_weak; }
189 
SetIsWeak(bool b)190   void SetIsWeak (bool b) { m_is_weak = b; }
191 
GetByteSizeIsValid()192   bool GetByteSizeIsValid() const { return m_size_is_valid; }
193 
194   lldb::addr_t GetByteSize() const;
195 
SetByteSize(lldb::addr_t size)196   void SetByteSize(lldb::addr_t size) {
197     m_size_is_valid = size > 0;
198     m_addr_range.SetByteSize(size);
199   }
200 
GetSizeIsSibling()201   bool GetSizeIsSibling() const { return m_size_is_sibling; }
202 
SetSizeIsSibling(bool b)203   void SetSizeIsSibling(bool b) { m_size_is_sibling = b; }
204 
205   // If m_type is "Code" or "Function" then this will return the prologue size
206   // in bytes, else it will return zero.
207   uint32_t GetPrologueByteSize();
208 
GetDemangledNameIsSynthesized()209   bool GetDemangledNameIsSynthesized() const {
210     return m_demangled_is_synthesized;
211   }
212 
SetDemangledNameIsSynthesized(bool b)213   void SetDemangledNameIsSynthesized(bool b) { m_demangled_is_synthesized = b; }
214 
ContainsLinkerAnnotations()215   bool ContainsLinkerAnnotations() const {
216     return m_contains_linker_annotations;
217   }
SetContainsLinkerAnnotations(bool b)218   void SetContainsLinkerAnnotations(bool b) {
219     m_contains_linker_annotations = b;
220   }
221   /// \copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
222   ///
223   /// \see SymbolContextScope
224   void CalculateSymbolContext(SymbolContext *sc) override;
225 
226   lldb::ModuleSP CalculateSymbolContextModule() override;
227 
228   Symbol *CalculateSymbolContextSymbol() override;
229 
230   /// \copydoc SymbolContextScope::DumpSymbolContext(Stream*)
231   ///
232   /// \see SymbolContextScope
233   void DumpSymbolContext(Stream *s) override;
234 
235   lldb::DisassemblerSP GetInstructions(const ExecutionContext &exe_ctx,
236                                        const char *flavor,
237                                        bool prefer_file_cache);
238 
239   bool GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor,
240                       bool prefer_file_cache, Stream &strm);
241 
242   bool ContainsFileAddress(lldb::addr_t file_addr) const;
243 
GetSyntheticSymbolPrefix()244   static llvm::StringRef GetSyntheticSymbolPrefix() {
245     return "___lldb_unnamed_symbol";
246   }
247 
248   /// Decode a serialized version of this object from data.
249   ///
250   /// \param data
251   ///   The decoder object that references the serialized data.
252   ///
253   /// \param offset_ptr
254   ///   A pointer that contains the offset from which the data will be decoded
255   ///   from that gets updated as data gets decoded.
256   ///
257   /// \param section_list
258   ///   A section list that allows lldb_private::Address objects to be filled
259   ///   in. The address information for symbols are serilized as file addresses
260   ///   and must be converted into Address objects with the right section and
261   ///   offset.
262   ///
263   /// \param strtab
264   ///   All strings in cache files are put into string tables for efficiency
265   ///   and cache file size reduction. Strings are stored as uint32_t string
266   ///   table offsets in the cache data.
267   ///
268   /// \return
269   ///   True if the symbol is successfully decoded, false otherwise.
270   bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
271               const SectionList *section_list, const StringTableReader &strtab);
272 
273   /// Encode this object into a data encoder object.
274   ///
275   /// This allows this object to be serialized to disk.
276   ///
277   /// \param encoder
278   ///   A data encoder object that serialized bytes will be encoded into.
279   ///
280   /// \param strtab
281   ///   All strings in cache files are put into string tables for efficiency
282   ///   and cache file size reduction. Strings are stored as uint32_t string
283   ///   table offsets in the cache data.
284   void Encode(DataEncoder &encoder, ConstStringTable &strtab) const;
285 
286   bool operator==(const Symbol &rhs) const;
287 
288 protected:
289   // This is the internal guts of ResolveReExportedSymbol, it assumes
290   // reexport_name is not null, and that module_spec is valid.  We track the
291   // modules we've already seen to make sure we don't get caught in a cycle.
292 
293   Symbol *ResolveReExportedSymbolInModuleSpec(
294       Target &target, ConstString &reexport_name,
295       lldb_private::ModuleSpec &module_spec,
296       lldb_private::ModuleList &seen_modules) const;
297 
298   void SynthesizeNameIfNeeded() const;
299 
300   uint32_t m_uid =
301       UINT32_MAX;           // User ID (usually the original symbol table index)
302   uint16_t m_type_data = 0; // data specific to m_type
303   uint16_t m_type_data_resolved : 1, // True if the data in m_type_data has
304                                      // already been calculated
305       m_is_synthetic : 1, // non-zero if this symbol is not actually in the
306                           // symbol table, but synthesized from other info in
307                           // the object file.
308       m_is_debug : 1,     // non-zero if this symbol is debug information in a
309                           // symbol
310       m_is_external : 1,  // non-zero if this symbol is globally visible
311       m_size_is_sibling : 1,     // m_size contains the index of this symbol's
312                                  // sibling
313       m_size_is_synthesized : 1, // non-zero if this symbol's size was
314                                  // calculated using a delta between this
315                                  // symbol and the next
316       m_size_is_valid : 1,
317       m_demangled_is_synthesized : 1, // The demangled name was created should
318                                       // not be used for expressions or other
319                                       // lookups
320       m_contains_linker_annotations : 1, // The symbol name contains linker
321                                          // annotations, which are optional when
322                                          // doing name lookups
323       m_is_weak : 1,
324       m_type : 6;            // Values from the lldb::SymbolType enum.
325   mutable Mangled m_mangled; // uniqued symbol name/mangled name pair
326   AddressRange m_addr_range; // Contains the value, or the section offset
327                              // address when the value is an address in a
328                              // section, and the size (if any)
329   uint32_t m_flags = 0; // A copy of the flags from the original symbol table,
330                         // the ObjectFile plug-in can interpret these
331 };
332 
333 } // namespace lldb_private
334 
335 #endif // LLDB_SYMBOL_SYMBOL_H
336