LLDB  mainline
DynamicLoaderDarwinKernel.h
Go to the documentation of this file.
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 liblldb_DynamicLoaderDarwinKernel_h_
10 #define liblldb_DynamicLoaderDarwinKernel_h_
11 
12 #include <mutex>
13 #include <string>
14 #include <vector>
15 
16 
17 #include "lldb/Host/SafeMachO.h"
18 
20 #include "lldb/Target/Process.h"
21 #include "lldb/Utility/FileSpec.h"
22 #include "lldb/Utility/UUID.h"
23 
25 public:
27  lldb::addr_t kernel_addr);
28 
29  ~DynamicLoaderDarwinKernel() override;
30 
31  // Static Functions
32  static void Initialize();
33 
34  static void Terminate();
35 
37 
38  static const char *GetPluginDescriptionStatic();
39 
41  CreateInstance(lldb_private::Process *process, bool force);
42 
43  static void DebuggerInitialize(lldb_private::Debugger &debugger);
44 
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 
59 
60  // PluginInterface protocol
62 
63  uint32_t GetPluginVersion() override;
64 
65 protected:
67 
69  lldb::StateType state);
70 
71  void UpdateIfNeeded();
72 
74 
75  void Clear(bool clear_process);
76 
77  void PutToLog(lldb_private::Log *log) const;
78 
79  static bool
80  BreakpointHitCallback(void *baton,
82  lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
83 
85  lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
87 
89 
90  enum {
92  // Versions less than 2 didn't have an entry size,
93  // they had a 64 bit name, 16 byte UUID, 8 byte addr,
94  // 8 byte size, 8 byte version, 4 byte load tag, and
95  // 4 byte flags
96  KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
97  };
98 
99  // class KextImageInfo represents a single kext or kernel binary image.
100  // The class was designed to hold the information from the
101  // OSKextLoadedKextSummary
102  // structure (in libkern/libkern/OSKextLibPrivate.h from xnu). The kernel
103  // maintains
104  // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader
105  // structure,
106  // which points to an array of OSKextLoadedKextSummary's).
107  //
108  // A KextImageInfos may have -
109  //
110  // 1. The load address, name, UUID, and size of a kext/kernel binary in memory
111  // (read straight out of the kernel's list-of-kexts loaded)
112  // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory
113  // (very unlikely to have any symbolic information)
114  // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug
115  // info
116  // or a dSYM
117  //
118  // For performance reasons, the developer may prefer that lldb not load the
119  // kexts out
120  // of memory at the start of a kernel session. But we should build up /
121  // maintain a
122  // list of kexts that the kernel has told us about so we can relocate a kext
123  // module
124  // later if the user explicitly adds it to the target.
125 
127  public:
129  : m_name(), m_module_sp(), m_memory_module_sp(),
130  m_load_process_stop_id(UINT32_MAX), m_uuid(),
131  m_load_address(LLDB_INVALID_ADDRESS), m_size(0),
132  m_kernel_image(false) {}
133 
134  void Clear() {
135  m_load_address = LLDB_INVALID_ADDRESS;
136  m_size = 0;
137  m_name.clear();
138  m_uuid.Clear();
139  m_module_sp.reset();
140  m_memory_module_sp.reset();
141  m_load_process_stop_id = UINT32_MAX;
142  }
143 
145 
147 
148  bool IsLoaded() { return m_load_process_stop_id != UINT32_MAX; }
149 
150  void SetLoadAddress(
151  lldb::addr_t load_addr); // Address of the Mach-O header for this binary
152 
154  GetLoadAddress() const; // Address of the Mach-O header for this binary
155 
156  lldb_private::UUID GetUUID() const;
157 
158  void SetUUID(const lldb_private::UUID &uuid);
159 
160  void SetName(const char *);
161 
162  std::string GetName() const;
163 
164  void SetModule(lldb::ModuleSP module);
165 
166  lldb::ModuleSP GetModule();
167 
168  // try to fill in m_memory_module_sp from memory based on the m_load_address
170 
171  bool IsKernel()
172  const; // true if this is the mach_kernel; false if this is a kext
173 
174  void SetIsKernel(bool is_kernel);
175 
176  uint64_t GetSize() const;
177 
178  void SetSize(uint64_t size);
179 
180  uint32_t
181  GetProcessStopId() const; // the stop-id when this binary was first noticed
182 
183  void SetProcessStopId(uint32_t stop_id);
184 
185  bool operator==(const KextImageInfo &rhs);
186 
187  uint32_t GetAddressByteSize(); // as determined by Mach-O header
188 
189  lldb::ByteOrder GetByteOrder(); // as determined by Mach-O header
190 
192  GetArchitecture() const; // as determined by Mach-O header
193 
194  void PutToLog(lldb_private::Log *log) const;
195 
196  typedef std::vector<KextImageInfo> collection;
197  typedef collection::iterator iterator;
198  typedef collection::const_iterator const_iterator;
199 
200  private:
201  std::string m_name;
202  lldb::ModuleSP m_module_sp;
203  lldb::ModuleSP m_memory_module_sp;
204  uint32_t m_load_process_stop_id; // the stop-id when this module was added
205  // to the Target
207  m_uuid; // UUID for this dylib if it has one, else all zeros
208  lldb::addr_t m_load_address;
209  uint64_t m_size;
210  bool m_kernel_image; // true if this is the kernel, false if this is a kext
211  };
212 
218 
220  : version(0), entry_size(0), entry_count(0),
221  image_infos_addr(LLDB_INVALID_ADDRESS) {}
222 
224  switch (version) {
225  case 0:
226  return 0; // Can't know the size without a valid version
227  case 1:
228  return 8; // Version 1 only had a version + entry_count
229  default:
230  break;
231  }
232  // Version 2 and above has version, entry_size, entry_count, and reserved
233  return 16;
234  }
235 
236  void Clear() {
237  version = 0;
238  entry_size = 0;
239  entry_count = 0;
240  image_infos_addr = LLDB_INVALID_ADDRESS;
241  }
242 
243  bool IsValid() const { return version >= 1 || version <= 2; }
244  };
245 
247 
249 
251 
252  bool ReadAllKextSummaries();
253 
254  bool ReadKextSummaryHeader();
255 
256  bool ParseKextSummaries(const lldb_private::Address &kext_summary_addr,
257  uint32_t count);
258 
259  void
261  uint32_t infos_count,
262  bool update_executable);
263 
264  uint32_t ReadKextSummaries(const lldb_private::Address &kext_summary_addr,
265  uint32_t image_infos_count,
266  KextImageInfo::collection &image_infos);
267 
268  static lldb::addr_t
270 
271  static lldb::addr_t
273 
275 
276  static lldb::addr_t
278 
279  static bool
280  ReadMachHeader(lldb::addr_t addr, lldb_private::Process *process, llvm::MachO::mach_header &mh,
281  bool *read_error = nullptr);
282 
283  static lldb_private::UUID
285  lldb_private::Process *process,
286  bool *read_error = nullptr);
287 
289  KextImageInfo m_kernel; // Info about the current kernel image being used
290 
295  mutable std::recursive_mutex m_mutex;
297 
298 private:
299  DISALLOW_COPY_AND_ASSIGN(DynamicLoaderDarwinKernel);
300 };
301 
302 #endif // liblldb_DynamicLoaderDarwinKernel_h_
A class to manage flag bits.
Definition: Debugger.h:82
void PrivateInitialize(lldb_private::Process *process)
DynamicLoaderDarwinKernel(lldb_private::Process *process, lldb::addr_t kernel_addr)
static lldb::addr_t SearchForKernelWithDebugHints(lldb_private::Process *process)
static lldb_private::UUID CheckForKernelImageAtAddress(lldb::addr_t addr, lldb_private::Process *process, bool *read_error=nullptr)
static lldb::addr_t SearchForKernelAtSameLoadAddr(lldb_private::Process *process)
An architecture specification class.
Definition: ArchSpec.h:32
void UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos, uint32_t infos_count, bool update_executable)
bool BreakpointHit(lldb_private::StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
lldb_private::Address m_kext_summary_header_ptr_addr
bool LoadImageUsingMemoryModule(lldb_private::Process *process)
bool ParseKextSummaries(const lldb_private::Address &kext_summary_addr, uint32_t count)
#define UINT32_MAX
Definition: lldb-defines.h:31
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
uint64_t user_id_t
Definition: lldb-types.h:84
KextImageInfo::collection m_known_kexts
bool LoadImageAtFileAddress(lldb_private::Process *process)
static lldb_private::DynamicLoader * CreateInstance(lldb_private::Process *process, bool force)
lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread, bool stop_others) override
Provides a plan to step through the dynamic loader trampoline for the current state of thread...
static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic)
void PutToLog(lldb_private::Log *log) const
A plug-in interface definition class for debugging a process.
Definition: Process.h:353
lldb_private::ConstString GetPluginName() override
OSKextLoadedKextSummaryHeader m_kext_summary_header
A section + offset based address class.
Definition: Address.h:80
static lldb_private::ConstString GetPluginNameStatic()
bool ReadMemoryModule(lldb_private::Process *process)
A plug-in interface definition class for dynamic loaders.
Definition: DynamicLoader.h:64
uint32_t ReadKextSummaries(const lldb_private::Address &kext_summary_addr, uint32_t image_infos_count, KextImageInfo::collection &image_infos)
static lldb::addr_t SearchForKernelNearPC(lldb_private::Process *process)
void DidAttach() override
Called after attaching a process.
uint64_t addr_t
Definition: lldb-types.h:83
void Clear()
Definition: UUID.h:58
A uniqued constant string class.
Definition: ConstString.h:38
static lldb::addr_t SearchForDarwinKernel(lldb_private::Process *process)
static bool ReadMachHeader(lldb::addr_t addr, lldb_private::Process *process, llvm::MachO::mach_header &mh, bool *read_error=nullptr)
void SetUUID(const lldb_private::UUID &uuid)
void DidLaunch() override
Called after attaching a process.
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
static bool BreakpointHitCallback(void *baton, lldb_private::StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
lldb_private::Status CanLoadImage() override
Ask if it is ok to try and load or unload an shared library (image).
static lldb::addr_t SearchForKernelViaExhaustiveSearch(lldb_private::Process *process)
lldb_private::Address m_kext_summary_header_addr
static const char * GetPluginDescriptionStatic()
static void DebuggerInitialize(lldb_private::Debugger &debugger)
An error handling class.
Definition: Status.h:44
void PrivateProcessStateChanged(lldb_private::Process *process, lldb::StateType state)