Coverage Report

Created: 2023-09-21 18:56

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Expression/IRExecutionUnit.h
Line
Count
Source (jump to first uncovered line)
1
//===-- IRExecutionUnit.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_EXPRESSION_IREXECUTIONUNIT_H
10
#define LLDB_EXPRESSION_IREXECUTIONUNIT_H
11
12
#include <atomic>
13
#include <memory>
14
#include <string>
15
#include <vector>
16
17
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
18
#include "llvm/IR/Module.h"
19
20
#include "lldb/Expression/IRMemoryMap.h"
21
#include "lldb/Expression/ObjectFileJIT.h"
22
#include "lldb/Symbol/SymbolContext.h"
23
#include "lldb/Utility/DataBufferHeap.h"
24
#include "lldb/lldb-forward.h"
25
#include "lldb/lldb-private.h"
26
27
namespace llvm {
28
29
class Module;
30
class ExecutionEngine;
31
class ObjectCache;
32
33
} // namespace llvm
34
35
namespace lldb_private {
36
37
class Status;
38
39
/// \class IRExecutionUnit IRExecutionUnit.h
40
/// "lldb/Expression/IRExecutionUnit.h" Contains the IR and, optionally, JIT-
41
/// compiled code for a module.
42
///
43
/// This class encapsulates the compiled version of an expression, in IR form
44
/// (for interpretation purposes) and in raw machine code form (for execution
45
/// in the target).
46
///
47
/// This object wraps an IR module that comes from the expression parser, and
48
/// knows how to use the JIT to make it into executable code.  It can then be
49
/// used as input to the IR interpreter, or the address of the executable code
50
/// can be passed to a thread plan to run in the target.
51
///
52
/// This class creates a subclass of LLVM's SectionMemoryManager, because that
53
/// is how the JIT emits code.  Because LLDB needs to move JIT-compiled code
54
/// into the target process, the IRExecutionUnit knows how to copy the emitted
55
/// code into the target process.
56
class IRExecutionUnit : public std::enable_shared_from_this<IRExecutionUnit>,
57
                        public IRMemoryMap,
58
                        public ObjectFileJITDelegate {
59
public:
60
  /// Constructor
61
  IRExecutionUnit(std::unique_ptr<llvm::LLVMContext> &context_up,
62
                  std::unique_ptr<llvm::Module> &module_up, ConstString &name,
63
                  const lldb::TargetSP &target_sp, const SymbolContext &sym_ctx,
64
                  std::vector<std::string> &cpu_features);
65
66
  /// Destructor
67
  ~IRExecutionUnit() override;
68
69
2.96k
  ConstString GetFunctionName() { return m_name; }
70
71
23.5k
  llvm::Module *GetModule() { return m_module; }
72
73
12.6k
  llvm::Function *GetFunction() {
74
12.6k
    return ((m_module != nullptr) ? m_module->getFunction(m_name.GetStringRef())
75
12.6k
                                  : 
nullptr0
);
76
12.6k
  }
77
78
  void GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
79
                       lldb::addr_t &func_end);
80
81
  /// Accessors for IRForTarget and other clients that may want binary data
82
  /// placed on their behalf.  The binary data is owned by the IRExecutionUnit
83
  /// unless the client explicitly chooses to free it.
84
85
  lldb::addr_t WriteNow(const uint8_t *bytes, size_t size, Status &error);
86
87
  void FreeNow(lldb::addr_t allocation);
88
89
  /// ObjectFileJITDelegate overrides
90
  lldb::ByteOrder GetByteOrder() const override;
91
92
  uint32_t GetAddressByteSize() const override;
93
94
  void PopulateSymtab(lldb_private::ObjectFile *obj_file,
95
                      lldb_private::Symtab &symtab) override;
96
97
  void PopulateSectionList(lldb_private::ObjectFile *obj_file,
98
                           lldb_private::SectionList &section_list) override;
99
100
  ArchSpec GetArchitecture() override;
101
102
  lldb::ModuleSP GetJITModule();
103
104
  lldb::addr_t FindSymbol(ConstString name, bool &missing_weak);
105
106
  void GetStaticInitializers(std::vector<lldb::addr_t> &static_initializers);
107
108
  /// \class JittedFunction IRExecutionUnit.h
109
  /// "lldb/Expression/IRExecutionUnit.h"
110
  /// Encapsulates a single function that has been generated by the JIT.
111
  ///
112
  /// Functions that have been generated by the JIT are first resident in the
113
  /// local process, and then placed in the target process.  JittedFunction
114
  /// represents a function possibly resident in both.
115
  struct JittedEntity {
116
    ConstString m_name;        ///< The function's name
117
    lldb::addr_t m_local_addr; ///< The address of the function in LLDB's memory
118
    lldb::addr_t
119
        m_remote_addr; ///< The address of the function in the target's memory
120
121
    /// Constructor
122
    ///
123
    /// Initializes class variabes.
124
    ///
125
    /// \param[in] name
126
    ///     The name of the function.
127
    ///
128
    /// \param[in] local_addr
129
    ///     The address of the function in LLDB, or LLDB_INVALID_ADDRESS if
130
    ///     it is not present in LLDB's memory.
131
    ///
132
    /// \param[in] remote_addr
133
    ///     The address of the function in the target, or LLDB_INVALID_ADDRESS
134
    ///     if it is not present in the target's memory.
135
    JittedEntity(const char *name,
136
                 lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
137
                 lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS)
138
9.77k
        : m_name(name), m_local_addr(local_addr), m_remote_addr(remote_addr) {}
139
  };
140
141
  struct JittedFunction : JittedEntity {
142
    bool m_external;
143
    JittedFunction(const char *name, bool external,
144
                   lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
145
                   lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS)
146
8.80k
        : JittedEntity(name, local_addr, remote_addr), m_external(external) {}
147
  };
148
149
  struct JittedGlobalVariable : JittedEntity {
150
    JittedGlobalVariable(const char *name,
151
                         lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
152
                         lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS)
153
969
        : JittedEntity(name, local_addr, remote_addr) {}
154
  };
155
156
7.22k
  const std::vector<JittedFunction> &GetJittedFunctions() {
157
7.22k
    return m_jitted_functions;
158
7.22k
  }
159
160
329
  const std::vector<JittedGlobalVariable> &GetJittedGlobalVariables() {
161
329
    return m_jitted_global_variables;
162
329
  }
163
164
private:
165
  /// Look up the object in m_address_map that contains a given address, find
166
  /// where it was copied to, and return the remote address at the same offset
167
  /// into the copied entity
168
  ///
169
  /// \param[in] local_address
170
  ///     The address in the debugger.
171
  ///
172
  /// \return
173
  ///     The address in the target process.
174
  lldb::addr_t GetRemoteAddressForLocal(lldb::addr_t local_address);
175
176
  typedef std::pair<lldb::addr_t, uintptr_t> AddrRange;
177
178
  /// Look up the object in m_address_map that contains a given address, find
179
  /// where it was copied to, and return its address range in the target
180
  /// process
181
  ///
182
  /// \param[in] local_address
183
  ///     The address in the debugger.
184
  ///
185
  /// \return
186
  ///     The range of the containing object in the target process.
187
  AddrRange GetRemoteRangeForLocal(lldb::addr_t local_address);
188
189
  /// Commit all allocations to the process and record where they were stored.
190
  ///
191
  /// \param[in] process_sp
192
  ///     The process to allocate memory in.
193
  ///
194
  /// \return
195
  ///     True <=> all allocations were performed successfully.
196
  ///     This method will attempt to free allocated memory if the
197
  ///     operation fails.
198
  bool CommitAllocations(lldb::ProcessSP &process_sp);
199
200
  /// Report all committed allocations to the execution engine.
201
  ///
202
  /// \param[in] engine
203
  ///     The execution engine to notify.
204
  void ReportAllocations(llvm::ExecutionEngine &engine);
205
206
  /// Write the contents of all allocations to the process.
207
  ///
208
  /// \param[in] process_sp
209
  ///     The process containing the allocations.
210
  ///
211
  /// \return
212
  ///     True <=> all allocations were performed successfully.
213
  bool WriteData(lldb::ProcessSP &process_sp);
214
215
  Status DisassembleFunction(Stream &stream, lldb::ProcessSP &process_sp);
216
217
  void CollectCandidateCNames(std::vector<ConstString> &C_names,
218
                              ConstString name);
219
220
  void CollectCandidateCPlusPlusNames(std::vector<ConstString> &CPP_names,
221
                                      const std::vector<ConstString> &C_names,
222
                                      const SymbolContext &sc);
223
224
  lldb::addr_t FindInSymbols(const std::vector<ConstString> &names,
225
                             const lldb_private::SymbolContext &sc,
226
                             bool &symbol_was_missing_weak);
227
228
  lldb::addr_t FindInRuntimes(const std::vector<ConstString> &names,
229
                              const lldb_private::SymbolContext &sc);
230
231
  lldb::addr_t FindInUserDefinedSymbols(const std::vector<ConstString> &names,
232
                                        const lldb_private::SymbolContext &sc);
233
234
  void ReportSymbolLookupError(ConstString name);
235
236
  class MemoryManager : public llvm::SectionMemoryManager {
237
  public:
238
    MemoryManager(IRExecutionUnit &parent);
239
240
    ~MemoryManager() override;
241
242
    /// Allocate space for executable code, and add it to the m_spaceBlocks
243
    /// map
244
    ///
245
    /// \param[in] Size
246
    ///     The size of the area.
247
    ///
248
    /// \param[in] Alignment
249
    ///     The required alignment of the area.
250
    ///
251
    /// \param[in] SectionID
252
    ///     A unique identifier for the section.
253
    ///
254
    /// \return
255
    ///     Allocated space.
256
    uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
257
                                 unsigned SectionID,
258
                                 llvm::StringRef SectionName) override;
259
260
    /// Allocate space for data, and add it to the m_spaceBlocks map
261
    ///
262
    /// \param[in] Size
263
    ///     The size of the area.
264
    ///
265
    /// \param[in] Alignment
266
    ///     The required alignment of the area.
267
    ///
268
    /// \param[in] SectionID
269
    ///     A unique identifier for the section.
270
    ///
271
    /// \param[in] IsReadOnly
272
    ///     Flag indicating the section is read-only.
273
    ///
274
    /// \return
275
    ///     Allocated space.
276
    uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
277
                                 unsigned SectionID,
278
                                 llvm::StringRef SectionName,
279
                                 bool IsReadOnly) override;
280
281
    /// Called when object loading is complete and section page permissions
282
    /// can be applied. Currently unimplemented for LLDB.
283
    ///
284
    /// \param[out] ErrMsg
285
    ///     The error that prevented the page protection from succeeding.
286
    ///
287
    /// \return
288
    ///     True in case of failure, false in case of success.
289
6.90k
    bool finalizeMemory(std::string *ErrMsg) override {
290
      // TODO: Ensure that the instruction cache is flushed because
291
      // relocations are updated by dy-load.  See:
292
      //   sys::Memory::InvalidateInstructionCache
293
      //   llvm::SectionMemoryManager
294
6.90k
      return false;
295
6.90k
    }
296
297
    // Ignore any EHFrame registration.
298
    void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
299
0
                          size_t Size) override {}
300
5.90k
    void deregisterEHFrames() override {}
301
302
    uint64_t getSymbolAddress(const std::string &Name) override;
303
304
    // Find the address of the symbol Name.  If Name is a missing weak symbol
305
    // then missing_weak will be true.
306
    uint64_t GetSymbolAddressAndPresence(const std::string &Name,
307
                                         bool &missing_weak);
308
309
    llvm::JITSymbol findSymbol(const std::string &Name) override;
310
311
    void *getPointerToNamedFunction(const std::string &Name,
312
                                    bool AbortOnFailure = true) override;
313
314
  private:
315
    std::unique_ptr<SectionMemoryManager> m_default_mm_up; ///< The memory
316
                                                           /// allocator to use
317
                                                           /// in actually
318
                                                           /// creating space.
319
                                                           /// All calls are
320
                                                           /// passed through to
321
                                                           /// it.
322
    IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for.
323
  };
324
325
  static const unsigned eSectionIDInvalid = (unsigned)-1;
326
327
  enum class AllocationKind { Stub, Code, Data, Global, Bytes };
328
329
  static lldb::SectionType
330
  GetSectionTypeFromSectionName(const llvm::StringRef &name,
331
                                AllocationKind alloc_kind);
332
333
  /// Encapsulates a single allocation request made by the JIT.
334
  ///
335
  /// Allocations made by the JIT are first queued up and then applied in bulk
336
  /// to the underlying process.
337
  struct AllocationRecord {
338
    std::string m_name;
339
    lldb::addr_t m_process_address;
340
    uintptr_t m_host_address;
341
    uint32_t m_permissions;
342
    lldb::SectionType m_sect_type;
343
    size_t m_size;
344
    unsigned m_alignment;
345
    unsigned m_section_id;
346
347
    AllocationRecord(uintptr_t host_address, uint32_t permissions,
348
                     lldb::SectionType sect_type, size_t size,
349
                     unsigned alignment, unsigned section_id, const char *name)
350
62.0k
        : m_process_address(LLDB_INVALID_ADDRESS), m_host_address(host_address),
351
62.0k
          m_permissions(permissions), m_sect_type(sect_type), m_size(size),
352
62.0k
          m_alignment(alignment), m_section_id(section_id) {
353
62.0k
      if (name && name[0])
354
62.0k
        m_name = name;
355
62.0k
    }
356
357
    void dump(Log *log);
358
  };
359
360
  bool CommitOneAllocation(lldb::ProcessSP &process_sp, Status &error,
361
                           AllocationRecord &record);
362
363
  typedef std::vector<AllocationRecord> RecordVector;
364
  RecordVector m_records;
365
366
  std::unique_ptr<llvm::LLVMContext> m_context_up;
367
  std::unique_ptr<llvm::ExecutionEngine> m_execution_engine_up;
368
  std::unique_ptr<llvm::ObjectCache> m_object_cache_up;
369
  std::unique_ptr<llvm::Module>
370
      m_module_up;        ///< Holder for the module until it's been handed off
371
  llvm::Module *m_module; ///< Owned by the execution engine
372
  std::vector<std::string> m_cpu_features;
373
  std::vector<JittedFunction> m_jitted_functions; ///< A vector of all functions
374
                                                  ///that have been JITted into
375
                                                  ///machine code
376
  std::vector<JittedGlobalVariable> m_jitted_global_variables; ///< A vector of
377
                                                               ///all functions
378
                                                               ///that have been
379
                                                               ///JITted into
380
                                                               ///machine code
381
  const ConstString m_name;
382
  SymbolContext m_sym_ctx; ///< Used for symbol lookups
383
  std::vector<ConstString> m_failed_lookups;
384
385
  std::atomic<bool> m_did_jit;
386
387
  lldb::addr_t m_function_load_addr;
388
  lldb::addr_t m_function_end_load_addr;
389
390
  bool m_strip_underscore = true; ///< True for platforms where global symbols
391
                                  ///  have a _ prefix
392
  bool m_reported_allocations; ///< True after allocations have been reported.
393
                               ///It is possible that
394
  ///< sections will be allocated when this is true, in which case they weren't
395
  ///< depended on by any function.  (Top-level code defining a variable, but
396
  ///< defining no functions using that variable, would do this.)  If this
397
  ///< is true, any allocations need to be committed immediately -- no
398
  ///< opportunity for relocation.
399
};
400
401
} // namespace lldb_private
402
403
#endif // LLDB_EXPRESSION_IREXECUTIONUNIT_H