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