Coverage Report

Created: 2022-01-15 10:30

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Symbol/Symbol.h
Line
Count
Source (jump to first uncovered line)
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
348M
  Address &GetAddressRef() { return m_addr_range.GetBaseAddress(); }
58
59
296M
  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
141M
  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
141M
    if (ValueIsAddress())
83
141M
      return m_addr_range.GetBaseAddress();
84
131
    else
85
131
      return Address();
86
141M
  }
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
2.08k
  uint64_t GetIntegerValue(uint64_t fail_value = 0) const {
93
2.08k
    if (ValueIsAddress()) {
94
      // This symbol's value is an address. Use Symbol::GetAddress() to get the
95
      // address.
96
0
      return fail_value;
97
2.08k
    } else {
98
      // The value is stored in the base address' offset
99
2.08k
      return m_addr_range.GetBaseAddress().GetOffset();
100
2.08k
    }
101
2.08k
  }
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
147M
  uint32_t GetID() const { return m_uid; }
112
113
33.0k
  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
33.0k
    return GetMangled().GuessLanguage();
117
33.0k
  }
118
119
172M
  void SetID(uint32_t uid) { m_uid = uid; }
120
121
362M
  Mangled &GetMangled() {
122
362M
    SynthesizeNameIfNeeded();
123
362M
    return m_mangled;
124
362M
  }
125
126
4.41M
  const Mangled &GetMangled() const {
127
4.41M
    SynthesizeNameIfNeeded();
128
4.41M
    return m_mangled;
129
4.41M
  }
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
1.05G
  lldb::SymbolType GetType() const { return (lldb::SymbolType)m_type; }
144
145
187M
  void SetType(lldb::SymbolType type) { m_type = (lldb::SymbolType)type; }
146
147
  const char *GetTypeAsString() const;
148
149
2.08k
  uint32_t GetFlags() const { return m_flags; }
150
151
158M
  void SetFlags(uint32_t flags) { m_flags = flags; }
152
153
  void GetDescription(Stream *s, lldb::DescriptionLevel level,
154
                      Target *target) const;
155
156
158M
  bool IsSynthetic() const { return m_is_synthetic; }
157
158
  bool IsSyntheticWithAutoGeneratedName() const;
159
160
13.9M
  void SetIsSynthetic(bool b) { m_is_synthetic = b; }
161
162
0
  bool GetSizeIsSynthesized() const { return m_size_is_synthesized; }
163
164
51.9M
  void SetSizeIsSynthesized(bool b) { m_size_is_synthesized = b; }
165
166
214M
  bool IsDebug() const { return m_is_debug; }
167
168
159M
  void SetDebug(bool b) { m_is_debug = b; }
169
170
15.2M
  bool IsExternal() const { return m_is_external; }
171
172
173M
  void SetExternal(bool b) { m_is_external = b; }
173
174
  bool IsTrampoline() const;
175
176
  bool IsIndirect() const;
177
178
1.47M
  bool IsWeak() const { return m_is_weak; }
179
180
106k
  void SetIsWeak (bool b) { m_is_weak = b; }
181
182
159
  bool GetByteSizeIsValid() const { return m_size_is_valid; }
183
184
  lldb::addr_t GetByteSize() const;
185
186
169M
  void SetByteSize(lldb::addr_t size) {
187
169M
    m_size_is_valid = size > 0;
188
169M
    m_addr_range.SetByteSize(size);
189
169M
  }
190
191
0
  bool GetSizeIsSibling() const { return m_size_is_sibling; }
192
193
3.48k
  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
691
  bool GetDemangledNameIsSynthesized() const {
200
691
    return m_demangled_is_synthesized;
201
691
  }
202
203
3.50M
  void SetDemangledNameIsSynthesized(bool b) { m_demangled_is_synthesized = b; }
204
205
179M
  bool ContainsLinkerAnnotations() const {
206
179M
    return m_contains_linker_annotations;
207
179M
  }
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
5.84M
  static llvm::StringRef GetSyntheticSymbolPrefix() {
235
5.84M
    return "___lldb_unnamed_symbol";
236
5.84M
  }
237
238
  /// Decode a serialized version of this object from data.
239
  ///
240
  /// \param data
241
  ///   The decoder object that references the serialized data.
242
  ///
243
  /// \param offset_ptr
244
  ///   A pointer that contains the offset from which the data will be decoded
245
  ///   from that gets updated as data gets decoded.
246
  ///
247
  /// \param section_list
248
  ///   A section list that allows lldb_private::Address objects to be filled
249
  ///   in. The address information for symbols are serilized as file addresses
250
  ///   and must be converted into Address objects with the right section and
251
  ///   offset.
252
  ///
253
  /// \param strtab
254
  ///   All strings in cache files are put into string tables for efficiency
255
  ///   and cache file size reduction. Strings are stored as uint32_t string
256
  ///   table offsets in the cache data.
257
  ///
258
  /// \return
259
  ///   True if the symbol is successfully decoded, false otherwise.
260
  bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
261
              const SectionList *section_list, const StringTableReader &strtab);
262
263
  /// Encode this object into a data encoder object.
264
  ///
265
  /// This allows this object to be serialized to disk.
266
  ///
267
  /// \param encoder
268
  ///   A data encoder object that serialized bytes will be encoded into.
269
  ///
270
  /// \param strtab
271
  ///   All strings in cache files are put into string tables for efficiency
272
  ///   and cache file size reduction. Strings are stored as uint32_t string
273
  ///   table offsets in the cache data.
274
  void Encode(DataEncoder &encoder, ConstStringTable &strtab) const;
275
276
  bool operator==(const Symbol &rhs) const;
277
278
protected:
279
  // This is the internal guts of ResolveReExportedSymbol, it assumes
280
  // reexport_name is not null, and that module_spec is valid.  We track the
281
  // modules we've already seen to make sure we don't get caught in a cycle.
282
283
  Symbol *ResolveReExportedSymbolInModuleSpec(
284
      Target &target, ConstString &reexport_name,
285
      lldb_private::ModuleSpec &module_spec,
286
      lldb_private::ModuleList &seen_modules) const;
287
288
  void SynthesizeNameIfNeeded() const;
289
290
  uint32_t m_uid =
291
      UINT32_MAX;           // User ID (usually the original symbol table index)
292
  uint16_t m_type_data = 0; // data specific to m_type
293
  uint16_t m_type_data_resolved : 1, // True if the data in m_type_data has
294
                                     // already been calculated
295
      m_is_synthetic : 1, // non-zero if this symbol is not actually in the
296
                          // symbol table, but synthesized from other info in
297
                          // the object file.
298
      m_is_debug : 1,     // non-zero if this symbol is debug information in a
299
                          // symbol
300
      m_is_external : 1,  // non-zero if this symbol is globally visible
301
      m_size_is_sibling : 1,     // m_size contains the index of this symbol's
302
                                 // sibling
303
      m_size_is_synthesized : 1, // non-zero if this symbol's size was
304
                                 // calculated using a delta between this
305
                                 // symbol and the next
306
      m_size_is_valid : 1,
307
      m_demangled_is_synthesized : 1, // The demangled name was created should
308
                                      // not be used for expressions or other
309
                                      // lookups
310
      m_contains_linker_annotations : 1, // The symbol name contains linker
311
                                         // annotations, which are optional when
312
                                         // doing name lookups
313
      m_is_weak : 1,
314
      m_type : 6;            // Values from the lldb::SymbolType enum.
315
  mutable Mangled m_mangled; // uniqued symbol name/mangled name pair
316
  AddressRange m_addr_range; // Contains the value, or the section offset
317
                             // address when the value is an address in a
318
                             // section, and the size (if any)
319
  uint32_t m_flags = 0; // A copy of the flags from the original symbol table,
320
                        // the ObjectFile plug-in can interpret these
321
};
322
323
} // namespace lldb_private
324
325
#endif // LLDB_SYMBOL_SYMBOL_H