Coverage Report

Created: 2023-11-11 10:31

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
Line
Count
Source (jump to first uncovered line)
1
//===-- DynamicLoaderDarwinKernel.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_SOURCE_PLUGINS_DYNAMICLOADER_DARWIN_KERNEL_DYNAMICLOADERDARWINKERNEL_H
10
#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_DARWIN_KERNEL_DYNAMICLOADERDARWINKERNEL_H
11
12
#include <mutex>
13
#include <string>
14
#include <vector>
15
16
17
#include "lldb/Host/SafeMachO.h"
18
19
#include "lldb/Target/DynamicLoader.h"
20
#include "lldb/Target/Process.h"
21
#include "lldb/Utility/FileSpec.h"
22
#include "lldb/Utility/UUID.h"
23
24
class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader {
25
public:
26
  DynamicLoaderDarwinKernel(lldb_private::Process *process,
27
                            lldb::addr_t kernel_addr);
28
29
  ~DynamicLoaderDarwinKernel() override;
30
31
  // Static Functions
32
  static void Initialize();
33
34
  static void Terminate();
35
36
3.95k
  static llvm::StringRef GetPluginNameStatic() { return "darwin-kernel"; }
37
38
  static llvm::StringRef GetPluginDescriptionStatic();
39
40
  static lldb_private::DynamicLoader *
41
  CreateInstance(lldb_private::Process *process, bool force);
42
43
  static void DebuggerInitialize(lldb_private::Debugger &debugger);
44
45
  static lldb::addr_t SearchForDarwinKernel(lldb_private::Process *process);
46
47
  /// Called after attaching a process.
48
  ///
49
  /// Allow DynamicLoader plug-ins to execute some code after
50
  /// attaching to a process.
51
  void DidAttach() override;
52
53
  void DidLaunch() override;
54
55
  lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
56
                                                  bool stop_others) override;
57
58
  lldb_private::Status CanLoadImage() override;
59
60
  // PluginInterface protocol
61
0
  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
62
63
protected:
64
  void PrivateInitialize(lldb_private::Process *process);
65
66
  void PrivateProcessStateChanged(lldb_private::Process *process,
67
                                  lldb::StateType state);
68
69
  void UpdateIfNeeded();
70
71
  void LoadKernelModuleIfNeeded();
72
73
  void Clear(bool clear_process);
74
75
  void PutToLog(lldb_private::Log *log) const;
76
77
  static bool
78
  BreakpointHitCallback(void *baton,
79
                        lldb_private::StoppointCallbackContext *context,
80
                        lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
81
82
  bool BreakpointHit(lldb_private::StoppointCallbackContext *context,
83
                     lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
84
0
  uint32_t GetAddrByteSize() { return m_kernel.GetAddressByteSize(); }
85
86
  static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic);
87
88
  enum {
89
    KERNEL_MODULE_MAX_NAME = 64u,
90
    // Versions less than 2 didn't have an entry size,
91
    // they had a 64 bit name, 16 byte UUID, 8 byte addr,
92
    // 8 byte size, 8 byte version, 4 byte load tag, and
93
    // 4 byte flags
94
    KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
95
  };
96
97
  // class KextImageInfo represents a single kext or kernel binary image.
98
  // The class was designed to hold the information from the
99
  // OSKextLoadedKextSummary
100
  // structure (in libkern/libkern/OSKextLibPrivate.h from xnu).  The kernel
101
  // maintains
102
  // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader
103
  // structure,
104
  // which points to an array of OSKextLoadedKextSummary's).
105
  //
106
  // A KextImageInfos may have -
107
  //
108
  // 1. The load address, name, UUID, and size of a kext/kernel binary in memory
109
  //    (read straight out of the kernel's list-of-kexts loaded)
110
  // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory
111
  //    (very unlikely to have any symbolic information)
112
  // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug
113
  // info
114
  //    or a dSYM
115
  //
116
  // For performance reasons, the developer may prefer that lldb not load the
117
  // kexts out
118
  // of memory at the start of a kernel session.  But we should build up /
119
  // maintain a
120
  // list of kexts that the kernel has told us about so we can relocate a kext
121
  // module
122
  // later if the user explicitly adds it to the target.
123
124
  class KextImageInfo {
125
  public:
126
0
    KextImageInfo() : m_name(), m_module_sp(), m_memory_module_sp(), m_uuid() {}
127
128
0
    void Clear() {
129
0
      m_load_address = LLDB_INVALID_ADDRESS;
130
0
      m_size = 0;
131
0
      m_name.clear();
132
0
      m_uuid.Clear();
133
0
      m_module_sp.reset();
134
0
      m_memory_module_sp.reset();
135
0
      m_load_process_stop_id = UINT32_MAX;
136
0
    }
137
138
    bool LoadImageAtFileAddress(lldb_private::Process *process);
139
140
    bool LoadImageUsingMemoryModule(lldb_private::Process *process);
141
142
0
    bool IsLoaded() { return m_load_process_stop_id != UINT32_MAX; }
143
144
    void SetLoadAddress(
145
        lldb::addr_t load_addr); // Address of the Mach-O header for this binary
146
147
    lldb::addr_t
148
    GetLoadAddress() const; // Address of the Mach-O header for this binary
149
150
    lldb_private::UUID GetUUID() const;
151
152
    void SetUUID(const lldb_private::UUID &uuid);
153
154
    void SetName(const char *);
155
156
    std::string GetName() const;
157
158
    void SetModule(lldb::ModuleSP module);
159
160
    lldb::ModuleSP GetModule();
161
162
    // try to fill in m_memory_module_sp from memory based on the m_load_address
163
    bool ReadMemoryModule(lldb_private::Process *process);
164
165
    bool IsKernel()
166
        const; // true if this is the mach_kernel; false if this is a kext
167
168
    void SetIsKernel(bool is_kernel);
169
170
    uint64_t GetSize() const;
171
172
    void SetSize(uint64_t size);
173
174
    uint32_t
175
    GetProcessStopId() const; // the stop-id when this binary was first noticed
176
177
    void SetProcessStopId(uint32_t stop_id);
178
179
    bool operator==(const KextImageInfo &rhs) const;
180
181
    uint32_t GetAddressByteSize(); // as determined by Mach-O header
182
183
    lldb::ByteOrder GetByteOrder(); // as determined by Mach-O header
184
185
    lldb_private::ArchSpec
186
    GetArchitecture() const; // as determined by Mach-O header
187
188
    void PutToLog(lldb_private::Log *log) const;
189
190
    typedef std::vector<KextImageInfo> collection;
191
    typedef collection::iterator iterator;
192
    typedef collection::const_iterator const_iterator;
193
194
  private:
195
    std::string m_name;
196
    lldb::ModuleSP m_module_sp;
197
    lldb::ModuleSP m_memory_module_sp;
198
    uint32_t m_load_process_stop_id =
199
        UINT32_MAX; // the stop-id when this module was added
200
                    // to the Target
201
    lldb_private::UUID
202
        m_uuid; // UUID for this dylib if it has one, else all zeros
203
    lldb::addr_t m_load_address = LLDB_INVALID_ADDRESS;
204
    uint64_t m_size = 0;
205
    bool m_kernel_image =
206
        false; // true if this is the kernel, false if this is a kext
207
  };
208
209
  struct OSKextLoadedKextSummaryHeader {
210
    uint32_t version = 0;
211
    uint32_t entry_size = 0;
212
    uint32_t entry_count = 0;
213
    lldb::addr_t image_infos_addr = LLDB_INVALID_ADDRESS;
214
215
0
    OSKextLoadedKextSummaryHeader() = default;
216
217
0
    uint32_t GetSize() {
218
0
      switch (version) {
219
0
      case 0:
220
0
        return 0; // Can't know the size without a valid version
221
0
      case 1:
222
0
        return 8; // Version 1 only had a version + entry_count
223
0
      default:
224
0
        break;
225
0
      }
226
      // Version 2 and above has version, entry_size, entry_count, and reserved
227
0
      return 16;
228
0
    }
229
230
0
    void Clear() {
231
0
      version = 0;
232
0
      entry_size = 0;
233
0
      entry_count = 0;
234
0
      image_infos_addr = LLDB_INVALID_ADDRESS;
235
0
    }
236
237
0
    bool IsValid() const { return version >= 1 && version <= 2; }
238
  };
239
240
  void RegisterNotificationCallbacks();
241
242
  void UnregisterNotificationCallbacks();
243
244
  void SetNotificationBreakpointIfNeeded();
245
246
  bool ReadAllKextSummaries();
247
248
  bool ReadKextSummaryHeader();
249
250
  bool ParseKextSummaries(const lldb_private::Address &kext_summary_addr,
251
                          uint32_t count);
252
253
  void
254
  UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos,
255
                                        uint32_t infos_count,
256
                                        bool update_executable);
257
258
  uint32_t ReadKextSummaries(const lldb_private::Address &kext_summary_addr,
259
                             uint32_t image_infos_count,
260
                             KextImageInfo::collection &image_infos);
261
262
  static lldb::addr_t
263
  SearchForKernelAtSameLoadAddr(lldb_private::Process *process);
264
265
  static lldb::addr_t
266
  SearchForKernelWithDebugHints(lldb_private::Process *process);
267
268
  static lldb::addr_t SearchForKernelNearPC(lldb_private::Process *process);
269
270
  static lldb::addr_t
271
  SearchForKernelViaExhaustiveSearch(lldb_private::Process *process);
272
273
  static bool
274
  ReadMachHeader(lldb::addr_t addr, lldb_private::Process *process, llvm::MachO::mach_header &mh,
275
                 bool *read_error = nullptr);
276
277
  static lldb_private::UUID
278
  CheckForKernelImageAtAddress(lldb::addr_t addr,
279
                               lldb_private::Process *process,
280
                               bool *read_error = nullptr);
281
282
  lldb::addr_t m_kernel_load_address;
283
  KextImageInfo m_kernel; // Info about the current kernel image being used
284
285
  lldb_private::Address m_kext_summary_header_ptr_addr;
286
  lldb_private::Address m_kext_summary_header_addr;
287
  OSKextLoadedKextSummaryHeader m_kext_summary_header;
288
  KextImageInfo::collection m_known_kexts;
289
  mutable std::recursive_mutex m_mutex;
290
  lldb::user_id_t m_break_id;
291
292
private:
293
  DynamicLoaderDarwinKernel(const DynamicLoaderDarwinKernel &) = delete;
294
  const DynamicLoaderDarwinKernel &
295
  operator=(const DynamicLoaderDarwinKernel &) = delete;
296
};
297
298
#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_DARWIN_KERNEL_DYNAMICLOADERDARWINKERNEL_H