Coverage Report

Created: 2023-09-30 09:22

/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/Core/Section.h"
15
#include "lldb/Symbol/SymbolContextScope.h"
16
#include "lldb/Utility/UserID.h"
17
#include "lldb/lldb-private.h"
18
#include "llvm/Support/JSON.h"
19
20
namespace lldb_private {
21
22
struct JSONSymbol {
23
  std::optional<uint64_t> address;
24
  std::optional<uint64_t> value;
25
  std::optional<uint64_t> size;
26
  std::optional<uint64_t> id;
27
  std::optional<lldb::SymbolType> type;
28
  std::string name;
29
};
30
31
class Symbol : public SymbolContextScope {
32
public:
33
  // ObjectFile readers can classify their symbol table entries and searches
34
  // can be made on specific types where the symbol values will have
35
  // drastically different meanings and sorting requirements.
36
  Symbol();
37
38
  Symbol(uint32_t symID, llvm::StringRef name, lldb::SymbolType type,
39
         bool external, bool is_debug, bool is_trampoline, bool is_artificial,
40
         const lldb::SectionSP &section_sp, lldb::addr_t value,
41
         lldb::addr_t size, bool size_is_valid,
42
         bool contains_linker_annotations, uint32_t flags);
43
44
  Symbol(uint32_t symID, const Mangled &mangled, lldb::SymbolType type,
45
         bool external, bool is_debug, bool is_trampoline, bool is_artificial,
46
         const AddressRange &range, bool size_is_valid,
47
         bool contains_linker_annotations, uint32_t flags);
48
49
  Symbol(const Symbol &rhs);
50
51
  const Symbol &operator=(const Symbol &rhs);
52
53
  static llvm::Expected<Symbol> FromJSON(const JSONSymbol &symbol,
54
                                         SectionList *section_list);
55
56
  void Clear();
57
58
  bool Compare(ConstString name, lldb::SymbolType type) const;
59
60
  void Dump(Stream *s, Target *target, uint32_t index,
61
            Mangled::NamePreference name_preference =
62
                Mangled::ePreferDemangled) const;
63
64
  bool ValueIsAddress() const;
65
66
  // The GetAddressRef() accessor functions should only be called if you
67
  // previously call ValueIsAddress() otherwise you might get an reference to
68
  // an Address object that contains an constant integer value in
69
  // m_addr_range.m_base_addr.m_offset which could be incorrectly used to
70
  // represent an absolute address since it has no section.
71
274M
  Address &GetAddressRef() { return m_addr_range.GetBaseAddress(); }
72
73
237M
  const Address &GetAddressRef() const { return m_addr_range.GetBaseAddress(); }
74
75
  // Makes sure the symbol's value is an address and returns the file address.
76
  // Returns LLDB_INVALID_ADDRESS if the symbol's value isn't an address.
77
  lldb::addr_t GetFileAddress() const;
78
79
  // Makes sure the symbol's value is an address and gets the load address
80
  // using \a target if it is. Returns LLDB_INVALID_ADDRESS if the symbol's
81
  // value isn't an address or if the section isn't loaded in \a target.
82
  lldb::addr_t GetLoadAddress(Target *target) const;
83
84
  // Access the address value. Do NOT hand out the AddressRange as an object as
85
  // the byte size of the address range may not be filled in and it should be
86
  // accessed via GetByteSize().
87
110M
  Address GetAddress() const {
88
    // Make sure the our value is an address before we hand a copy out. We use
89
    // the Address inside m_addr_range to contain the value for symbols that
90
    // are not address based symbols so we are using it for more than just
91
    // addresses. For example undefined symbols on MacOSX have a nlist.n_value
92
    // of 0 (zero) and this will get placed into
93
    // m_addr_range.m_base_addr.m_offset and it will have no section. So in the
94
    // GetAddress() accessor, we need to hand out an invalid address if the
95
    // symbol's value isn't an address.
96
110M
    if (ValueIsAddress())
97
110M
      return m_addr_range.GetBaseAddress();
98
79
    else
99
79
      return Address();
100
110M
  }
101
102
  /// Get the raw value of the symbol from the symbol table.
103
  ///
104
  /// If the symbol's value is an address, return the file address, else return
105
  /// the raw value that is stored in the m_addr_range. If the base address has
106
  /// no section, then getting the file address will return the correct value
107
  /// as it will return the offset in the base address which is the value.
108
6
  uint64_t GetRawValue() const {
109
6
    return m_addr_range.GetBaseAddress().GetFileAddress();
110
6
  }
111
112
  // When a symbol's value isn't an address, we need to access the raw value.
113
  // This function will ensure this symbol's value isn't an address and return
114
  // the integer value if this checks out, otherwise it will return
115
  // "fail_value" if the symbol is an address value.
116
1.34k
  uint64_t GetIntegerValue(uint64_t fail_value = 0) const {
117
1.34k
    if (ValueIsAddress()) {
118
      // This symbol's value is an address. Use Symbol::GetAddress() to get the
119
      // address.
120
0
      return fail_value;
121
1.34k
    } else {
122
      // The value is stored in the base address' offset
123
1.34k
      return m_addr_range.GetBaseAddress().GetOffset();
124
1.34k
    }
125
1.34k
  }
126
127
  lldb::addr_t ResolveCallableAddress(Target &target) const;
128
129
  ConstString GetName() const;
130
131
  ConstString GetNameNoArguments() const;
132
133
  ConstString GetDisplayName() const;
134
135
117M
  uint32_t GetID() const { return m_uid; }
136
137
53.0k
  lldb::LanguageType GetLanguage() const {
138
    // TODO: See if there is a way to determine the language for a symbol
139
    // somehow, for now just return our best guess
140
53.0k
    return GetMangled().GuessLanguage();
141
53.0k
  }
142
143
135M
  void SetID(uint32_t uid) { m_uid = uid; }
144
145
282M
  Mangled &GetMangled() {
146
282M
    SynthesizeNameIfNeeded();
147
282M
    return m_mangled;
148
282M
  }
149
150
4.01M
  const Mangled &GetMangled() const {
151
4.01M
    SynthesizeNameIfNeeded();
152
4.01M
    return m_mangled;
153
4.01M
  }
154
155
  ConstString GetReExportedSymbolName() const;
156
157
  FileSpec GetReExportedSymbolSharedLibrary() const;
158
159
  void SetReExportedSymbolName(ConstString name);
160
161
  bool SetReExportedSymbolSharedLibrary(const FileSpec &fspec);
162
163
  Symbol *ResolveReExportedSymbol(Target &target) const;
164
165
  uint32_t GetSiblingIndex() const;
166
167
824M
  lldb::SymbolType GetType() const { return (lldb::SymbolType)m_type; }
168
169
147M
  void SetType(lldb::SymbolType type) { m_type = (lldb::SymbolType)type; }
170
171
  const char *GetTypeAsString() const;
172
173
1.34k
  uint32_t GetFlags() const { return m_flags; }
174
175
125M
  void SetFlags(uint32_t flags) { m_flags = flags; }
176
177
  void GetDescription(Stream *s, lldb::DescriptionLevel level,
178
                      Target *target) const;
179
180
123M
  bool IsSynthetic() const { return m_is_synthetic; }
181
182
  bool IsSyntheticWithAutoGeneratedName() const;
183
184
9.96M
  void SetIsSynthetic(bool b) { m_is_synthetic = b; }
185
186
0
  bool GetSizeIsSynthesized() const { return m_size_is_synthesized; }
187
188
35.4M
  void SetSizeIsSynthesized(bool b) { m_size_is_synthesized = b; }
189
190
169M
  bool IsDebug() const { return m_is_debug; }
191
192
126M
  void SetDebug(bool b) { m_is_debug = b; }
193
194
11.4M
  bool IsExternal() const { return m_is_external; }
195
196
137M
  void SetExternal(bool b) { m_is_external = b; }
197
198
  bool IsTrampoline() const;
199
200
  bool IsIndirect() const;
201
202
1.17M
  bool IsWeak() const { return m_is_weak; }
203
204
80.7k
  void SetIsWeak(bool b) { m_is_weak = b; }
205
206
297
  bool GetByteSizeIsValid() const { return m_size_is_valid; }
207
208
  lldb::addr_t GetByteSize() const;
209
210
131M
  void SetByteSize(lldb::addr_t size) {
211
131M
    m_size_is_valid = size > 0;
212
131M
    m_addr_range.SetByteSize(size);
213
131M
  }
214
215
0
  bool GetSizeIsSibling() const { return m_size_is_sibling; }
216
217
2.91k
  void SetSizeIsSibling(bool b) { m_size_is_sibling = b; }
218
219
  // If m_type is "Code" or "Function" then this will return the prologue size
220
  // in bytes, else it will return zero.
221
  uint32_t GetPrologueByteSize();
222
223
451
  bool GetDemangledNameIsSynthesized() const {
224
451
    return m_demangled_is_synthesized;
225
451
  }
226
227
2.64M
  void SetDemangledNameIsSynthesized(bool b) { m_demangled_is_synthesized = b; }
228
229
126M
  bool ContainsLinkerAnnotations() const {
230
126M
    return m_contains_linker_annotations;
231
126M
  }
232
  void SetContainsLinkerAnnotations(bool b) {
233
    m_contains_linker_annotations = b;
234
  }
235
  /// \copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
236
  ///
237
  /// \see SymbolContextScope
238
  void CalculateSymbolContext(SymbolContext *sc) override;
239
240
  lldb::ModuleSP CalculateSymbolContextModule() override;
241
242
  Symbol *CalculateSymbolContextSymbol() override;
243
244
  /// \copydoc SymbolContextScope::DumpSymbolContext(Stream*)
245
  ///
246
  /// \see SymbolContextScope
247
  void DumpSymbolContext(Stream *s) override;
248
249
  lldb::DisassemblerSP GetInstructions(const ExecutionContext &exe_ctx,
250
                                       const char *flavor,
251
                                       bool prefer_file_cache);
252
253
  bool GetDisassembly(const ExecutionContext &exe_ctx, const char *flavor,
254
                      bool prefer_file_cache, Stream &strm);
255
256
  bool ContainsFileAddress(lldb::addr_t file_addr) const;
257
258
5.46M
  static llvm::StringRef GetSyntheticSymbolPrefix() {
259
5.46M
    return "___lldb_unnamed_symbol";
260
5.46M
  }
261
262
  /// Decode a serialized version of this object from data.
263
  ///
264
  /// \param data
265
  ///   The decoder object that references the serialized data.
266
  ///
267
  /// \param offset_ptr
268
  ///   A pointer that contains the offset from which the data will be decoded
269
  ///   from that gets updated as data gets decoded.
270
  ///
271
  /// \param section_list
272
  ///   A section list that allows lldb_private::Address objects to be filled
273
  ///   in. The address information for symbols are serilized as file addresses
274
  ///   and must be converted into Address objects with the right section and
275
  ///   offset.
276
  ///
277
  /// \param strtab
278
  ///   All strings in cache files are put into string tables for efficiency
279
  ///   and cache file size reduction. Strings are stored as uint32_t string
280
  ///   table offsets in the cache data.
281
  ///
282
  /// \return
283
  ///   True if the symbol is successfully decoded, false otherwise.
284
  bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
285
              const SectionList *section_list, const StringTableReader &strtab);
286
287
  /// Encode this object into a data encoder object.
288
  ///
289
  /// This allows this object to be serialized to disk.
290
  ///
291
  /// \param encoder
292
  ///   A data encoder object that serialized bytes will be encoded into.
293
  ///
294
  /// \param strtab
295
  ///   All strings in cache files are put into string tables for efficiency
296
  ///   and cache file size reduction. Strings are stored as uint32_t string
297
  ///   table offsets in the cache data.
298
  void Encode(DataEncoder &encoder, ConstStringTable &strtab) const;
299
300
  bool operator==(const Symbol &rhs) const;
301
302
protected:
303
  // This is the internal guts of ResolveReExportedSymbol, it assumes
304
  // reexport_name is not null, and that module_spec is valid.  We track the
305
  // modules we've already seen to make sure we don't get caught in a cycle.
306
307
  Symbol *ResolveReExportedSymbolInModuleSpec(
308
      Target &target, ConstString &reexport_name,
309
      lldb_private::ModuleSpec &module_spec,
310
      lldb_private::ModuleList &seen_modules) const;
311
312
  void SynthesizeNameIfNeeded() const;
313
314
  uint32_t m_uid =
315
      UINT32_MAX;           // User ID (usually the original symbol table index)
316
  uint16_t m_type_data = 0; // data specific to m_type
317
  uint16_t m_type_data_resolved : 1, // True if the data in m_type_data has
318
                                     // already been calculated
319
      m_is_synthetic : 1, // non-zero if this symbol is not actually in the
320
                          // symbol table, but synthesized from other info in
321
                          // the object file.
322
      m_is_debug : 1,     // non-zero if this symbol is debug information in a
323
                          // symbol
324
      m_is_external : 1,  // non-zero if this symbol is globally visible
325
      m_size_is_sibling : 1,     // m_size contains the index of this symbol's
326
                                 // sibling
327
      m_size_is_synthesized : 1, // non-zero if this symbol's size was
328
                                 // calculated using a delta between this
329
                                 // symbol and the next
330
      m_size_is_valid : 1,
331
      m_demangled_is_synthesized : 1, // The demangled name was created should
332
                                      // not be used for expressions or other
333
                                      // lookups
334
      m_contains_linker_annotations : 1, // The symbol name contains linker
335
                                         // annotations, which are optional when
336
                                         // doing name lookups
337
      m_is_weak : 1,
338
      m_type : 6;            // Values from the lldb::SymbolType enum.
339
  mutable Mangled m_mangled; // uniqued symbol name/mangled name pair
340
  AddressRange m_addr_range; // Contains the value, or the section offset
341
                             // address when the value is an address in a
342
                             // section, and the size (if any)
343
  uint32_t m_flags = 0; // A copy of the flags from the original symbol table,
344
                        // the ObjectFile plug-in can interpret these
345
};
346
347
} // namespace lldb_private
348
349
namespace llvm {
350
namespace json {
351
352
bool fromJSON(const llvm::json::Value &value, lldb_private::JSONSymbol &symbol,
353
              llvm::json::Path path);
354
355
bool fromJSON(const llvm::json::Value &value, lldb::SymbolType &type,
356
              llvm::json::Path path);
357
358
} // namespace json
359
} // namespace llvm
360
361
#endif // LLDB_SYMBOL_SYMBOL_H