blob: b7010303bcaa32d8a814d66ad5dc5b9ee7ec234e [file] [log] [blame]
Kate Stoneb9c1b512016-09-06 20:57:50 +00001//===-- DynamicLoaderDarwinKernel.cpp -----------------------------*- C++
2//-*-===//
Greg Clayton7b242382011-07-08 00:48:09 +00003//
4// The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
Jim Ingham46d005d2014-04-02 22:53:21 +000011#include "lldb/Utility/SafeMachO.h"
Greg Claytoneadcca92014-04-02 20:36:22 +000012
Kate Stoneb9c1b512016-09-06 20:57:50 +000013#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h"
Greg Clayton7b242382011-07-08 00:48:09 +000014#include "lldb/Breakpoint/StoppointCallbackContext.h"
15#include "lldb/Core/DataBuffer.h"
16#include "lldb/Core/DataBufferHeap.h"
Greg Clayton07e66e32011-07-20 03:41:06 +000017#include "lldb/Core/Debugger.h"
Greg Clayton7b242382011-07-08 00:48:09 +000018#include "lldb/Core/Log.h"
19#include "lldb/Core/Module.h"
Greg Clayton1f746072012-08-29 21:13:06 +000020#include "lldb/Core/ModuleSpec.h"
Greg Clayton7b242382011-07-08 00:48:09 +000021#include "lldb/Core/PluginManager.h"
Greg Clayton1f746072012-08-29 21:13:06 +000022#include "lldb/Core/Section.h"
Greg Clayton7b242382011-07-08 00:48:09 +000023#include "lldb/Core/State.h"
Greg Clayton44d93782014-01-27 23:43:24 +000024#include "lldb/Core/StreamFile.h"
Jason Molenda68b36072012-10-02 03:49:41 +000025#include "lldb/Host/Symbols.h"
Ilia K41204d02015-03-04 12:05:24 +000026#include "lldb/Interpreter/OptionValueProperties.h"
Greg Clayton7b242382011-07-08 00:48:09 +000027#include "lldb/Symbol/ObjectFile.h"
Greg Clayton7b242382011-07-08 00:48:09 +000028#include "lldb/Target/RegisterContext.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000029#include "lldb/Target/StackFrame.h"
Greg Clayton7b242382011-07-08 00:48:09 +000030#include "lldb/Target/Target.h"
31#include "lldb/Target/Thread.h"
32#include "lldb/Target/ThreadPlanRunToAddress.h"
Greg Clayton7b242382011-07-08 00:48:09 +000033
Greg Clayton944b8282011-08-22 22:30:57 +000034#include "DynamicLoaderDarwinKernel.h"
Greg Clayton7b242382011-07-08 00:48:09 +000035
36//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
37#ifdef ENABLE_DEBUG_PRINTF
38#include <stdio.h>
Kate Stoneb9c1b512016-09-06 20:57:50 +000039#define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
Greg Clayton7b242382011-07-08 00:48:09 +000040#else
41#define DEBUG_PRINTF(fmt, ...)
42#endif
43
44using namespace lldb;
45using namespace lldb_private;
46
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000047// Progressively greater amounts of scanning we will allow
Kate Stoneb9c1b512016-09-06 20:57:50 +000048// For some targets very early in startup, we can't do any random reads of
49// memory or we can crash the device
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000050// so a setting is needed that can completely disable the KASLR scans.
51
Kate Stoneb9c1b512016-09-06 20:57:50 +000052enum KASLRScanType {
53 eKASLRScanNone = 0, // No reading into the inferior at all
54 eKASLRScanLowgloAddresses, // Check one word of memory for a possible kernel
55 // addr, then see if a kernel is there
56 eKASLRScanNearPC, // Scan backwards from the current $pc looking for kernel;
57 // checking at 96 locations total
58 eKASLRScanExhaustiveScan // Scan through the entire possible kernel address
59 // range looking for a kernel
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000060};
61
Kate Stoneb9c1b512016-09-06 20:57:50 +000062OptionEnumValueElement g_kaslr_kernel_scan_enum_values[] = {
63 {eKASLRScanNone, "none",
64 "Do not read memory looking for a Darwin kernel when attaching."},
65 {eKASLRScanLowgloAddresses, "basic", "Check for the Darwin kernel's load "
66 "addr in the lowglo page "
67 "(boot-args=debug) only."},
68 {eKASLRScanNearPC, "fast-scan", "Scan near the pc value on attach to find "
69 "the Darwin kernel's load address."},
70 {eKASLRScanExhaustiveScan, "exhaustive-scan",
71 "Scan through the entire potential address range of Darwin kernel (only "
72 "on 32-bit targets)."},
73 {0, NULL, NULL}};
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000074
Kate Stoneb9c1b512016-09-06 20:57:50 +000075static PropertyDefinition g_properties[] = {
76 {"load-kexts", OptionValue::eTypeBoolean, true, true, NULL, NULL,
77 "Automatically loads kext images when attaching to a kernel."},
78 {"scan-type", OptionValue::eTypeEnum, true, eKASLRScanNearPC, NULL,
79 g_kaslr_kernel_scan_enum_values, "Control how many reads lldb will make "
80 "while searching for a Darwin kernel on "
81 "attach."},
82 {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}};
Greg Claytone8cd0c92012-10-19 18:02:49 +000083
Kate Stoneb9c1b512016-09-06 20:57:50 +000084enum { ePropertyLoadKexts, ePropertyScanType };
Greg Claytone8cd0c92012-10-19 18:02:49 +000085
Kate Stoneb9c1b512016-09-06 20:57:50 +000086class DynamicLoaderDarwinKernelProperties : public Properties {
Greg Claytone8cd0c92012-10-19 18:02:49 +000087public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000088 static ConstString &GetSettingName() {
89 static ConstString g_setting_name("darwin-kernel");
90 return g_setting_name;
91 }
Greg Claytone8cd0c92012-10-19 18:02:49 +000092
Kate Stoneb9c1b512016-09-06 20:57:50 +000093 DynamicLoaderDarwinKernelProperties() : Properties() {
94 m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
95 m_collection_sp->Initialize(g_properties);
96 }
Greg Claytone8cd0c92012-10-19 18:02:49 +000097
Kate Stoneb9c1b512016-09-06 20:57:50 +000098 virtual ~DynamicLoaderDarwinKernelProperties() {}
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000099
Kate Stoneb9c1b512016-09-06 20:57:50 +0000100 bool GetLoadKexts() const {
101 const uint32_t idx = ePropertyLoadKexts;
102 return m_collection_sp->GetPropertyAtIndexAsBoolean(
103 NULL, idx, g_properties[idx].default_uint_value != 0);
104 }
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000105
Kate Stoneb9c1b512016-09-06 20:57:50 +0000106 KASLRScanType GetScanType() const {
107 const uint32_t idx = ePropertyScanType;
108 return (KASLRScanType)m_collection_sp->GetPropertyAtIndexAsEnumeration(
109 NULL, idx, g_properties[idx].default_uint_value);
110 }
Greg Claytone8cd0c92012-10-19 18:02:49 +0000111};
112
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113typedef std::shared_ptr<DynamicLoaderDarwinKernelProperties>
114 DynamicLoaderDarwinKernelPropertiesSP;
Greg Claytone8cd0c92012-10-19 18:02:49 +0000115
Kate Stoneb9c1b512016-09-06 20:57:50 +0000116static const DynamicLoaderDarwinKernelPropertiesSP &GetGlobalProperties() {
117 static DynamicLoaderDarwinKernelPropertiesSP g_settings_sp;
118 if (!g_settings_sp)
119 g_settings_sp.reset(new DynamicLoaderDarwinKernelProperties());
120 return g_settings_sp;
Greg Claytone8cd0c92012-10-19 18:02:49 +0000121}
122
Greg Clayton7b242382011-07-08 00:48:09 +0000123//----------------------------------------------------------------------
124// Create an instance of this class. This function is filled into
125// the plugin info class that gets handed out by the plugin factory and
126// allows the lldb to instantiate an instance of this class.
127//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000128DynamicLoader *DynamicLoaderDarwinKernel::CreateInstance(Process *process,
129 bool force) {
130 if (!force) {
131 // If the user provided an executable binary and it is not a kernel,
132 // this plugin should not create an instance.
133 Module *exe_module = process->GetTarget().GetExecutableModulePointer();
134 if (exe_module) {
135 ObjectFile *object_file = exe_module->GetObjectFile();
136 if (object_file) {
137 if (object_file->GetStrata() != ObjectFile::eStrataKernel) {
138 return NULL;
Greg Claytondf0b7d52011-07-08 04:11:42 +0000139 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000140 }
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000141 }
142
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143 // If the target's architecture does not look like an Apple environment,
144 // this plugin should not create an instance.
145 const llvm::Triple &triple_ref =
146 process->GetTarget().GetArchitecture().GetTriple();
147 switch (triple_ref.getOS()) {
148 case llvm::Triple::Darwin:
149 case llvm::Triple::MacOSX:
150 case llvm::Triple::IOS:
151 case llvm::Triple::TvOS:
152 case llvm::Triple::WatchOS:
153 if (triple_ref.getVendor() != llvm::Triple::Apple) {
154 return NULL;
155 }
156 break;
157 // If we have triple like armv7-unknown-unknown, we should try looking for a
158 // Darwin kernel.
159 case llvm::Triple::UnknownOS:
160 break;
161 default:
162 return NULL;
163 break;
Jason Molenda503d0182013-03-02 07:19:32 +0000164 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000165 }
166
167 // At this point if there is an ExecutableModule, it is a kernel and the
168 // Target is some variant of an Apple system.
169 // If the Process hasn't provided the kernel load address, we need to look
170 // around in memory to find it.
171
172 const addr_t kernel_load_address = SearchForDarwinKernel(process);
173 if (CheckForKernelImageAtAddress(kernel_load_address, process).IsValid()) {
174 process->SetCanRunCode(false);
175 return new DynamicLoaderDarwinKernel(process, kernel_load_address);
176 }
177 return NULL;
Jason Molenda503d0182013-03-02 07:19:32 +0000178}
179
180lldb::addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000181DynamicLoaderDarwinKernel::SearchForDarwinKernel(Process *process) {
182 addr_t kernel_load_address = process->GetImageInfoAddress();
183 if (kernel_load_address == LLDB_INVALID_ADDRESS) {
184 kernel_load_address = SearchForKernelAtSameLoadAddr(process);
185 if (kernel_load_address == LLDB_INVALID_ADDRESS) {
186 kernel_load_address = SearchForKernelWithDebugHints(process);
187 if (kernel_load_address == LLDB_INVALID_ADDRESS) {
188 kernel_load_address = SearchForKernelNearPC(process);
189 if (kernel_load_address == LLDB_INVALID_ADDRESS) {
190 kernel_load_address = SearchForKernelViaExhaustiveSearch(process);
Greg Claytondf0b7d52011-07-08 04:11:42 +0000191 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000192 }
Greg Clayton7b242382011-07-08 00:48:09 +0000193 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000194 }
195 return kernel_load_address;
Greg Clayton7b242382011-07-08 00:48:09 +0000196}
197
198//----------------------------------------------------------------------
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000199// Check if the kernel binary is loaded in memory without a slide.
200// First verify that the ExecutableModule is a kernel before we proceed.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000201// Returns the address of the kernel if one was found, else
202// LLDB_INVALID_ADDRESS.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000203//----------------------------------------------------------------------
204lldb::addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000205DynamicLoaderDarwinKernel::SearchForKernelAtSameLoadAddr(Process *process) {
206 Module *exe_module = process->GetTarget().GetExecutableModulePointer();
207 if (exe_module == NULL)
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000208 return LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000209
210 ObjectFile *exe_objfile = exe_module->GetObjectFile();
211 if (exe_objfile == NULL)
212 return LLDB_INVALID_ADDRESS;
213
214 if (exe_objfile->GetType() != ObjectFile::eTypeExecutable ||
215 exe_objfile->GetStrata() != ObjectFile::eStrataKernel)
216 return LLDB_INVALID_ADDRESS;
217
218 if (!exe_objfile->GetHeaderAddress().IsValid())
219 return LLDB_INVALID_ADDRESS;
220
221 if (CheckForKernelImageAtAddress(
222 exe_objfile->GetHeaderAddress().GetFileAddress(), process) ==
223 exe_module->GetUUID())
224 return exe_objfile->GetHeaderAddress().GetFileAddress();
225
226 return LLDB_INVALID_ADDRESS;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000227}
228
229//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000230// If the debug flag is included in the boot-args nvram setting, the kernel's
231// load address
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000232// will be noted in the lowglo page at a fixed address
Kate Stoneb9c1b512016-09-06 20:57:50 +0000233// Returns the address of the kernel if one was found, else
234// LLDB_INVALID_ADDRESS.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000235//----------------------------------------------------------------------
236lldb::addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000237DynamicLoaderDarwinKernel::SearchForKernelWithDebugHints(Process *process) {
238 if (GetGlobalProperties()->GetScanType() == eKASLRScanNone)
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000239 return LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000240
241 Error read_err;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000242 addr_t kernel_addresses_64[] = {
243 0xfffffff000004010ULL, // newest arm64 devices
244 0xffffff8000004010ULL, // 2014-2015-ish arm64 devices
245 0xffffff8000002010ULL, // oldest arm64 devices
246 LLDB_INVALID_ADDRESS};
Jason Molenda61a8e532016-11-30 23:00:52 +0000247 addr_t kernel_addresses_32[] = {0xffff0110, // 2016 and earlier armv7 devices
248 0xffff1010,
249 LLDB_INVALID_ADDRESS};
Jason Molenda2b0a7be2016-11-15 01:41:27 +0000250
251 uint8_t uval[8];
252 if (process->GetAddressByteSize() == 8) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000253 for (size_t i = 0; kernel_addresses_64[i] != LLDB_INVALID_ADDRESS; i++) {
Jason Molenda2b0a7be2016-11-15 01:41:27 +0000254 if (process->ReadMemoryFromInferior (kernel_addresses_64[i], uval, 8, read_err) == 8)
255 {
256 DataExtractor data (&uval, 8, process->GetByteOrder(), process->GetAddressByteSize());
257 offset_t offset = 0;
258 uint64_t addr = data.GetU64 (&offset);
259 if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
260 return addr;
261 }
262 }
263 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000264 }
265
Jason Molenda2b0a7be2016-11-15 01:41:27 +0000266 if (process->GetAddressByteSize() == 4) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000267 for (size_t i = 0; kernel_addresses_32[i] != LLDB_INVALID_ADDRESS; i++) {
Jason Molenda2b0a7be2016-11-15 01:41:27 +0000268 if (process->ReadMemoryFromInferior (kernel_addresses_32[i], uval, 4, read_err) == 4)
269 {
270 DataExtractor data (&uval, 4, process->GetByteOrder(), process->GetAddressByteSize());
271 offset_t offset = 0;
272 uint32_t addr = data.GetU32 (&offset);
273 if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
274 return addr;
275 }
276 }
277 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000278 }
279
280 return LLDB_INVALID_ADDRESS;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000281}
282
283//----------------------------------------------------------------------
284// If the kernel is currently executing when lldb attaches, and we don't have
285// a better way of finding the kernel's load address, try searching backwards
286// from the current pc value looking for the kernel's Mach header in memory.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000287// Returns the address of the kernel if one was found, else
288// LLDB_INVALID_ADDRESS.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000289//----------------------------------------------------------------------
290lldb::addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000291DynamicLoaderDarwinKernel::SearchForKernelNearPC(Process *process) {
292 if (GetGlobalProperties()->GetScanType() == eKASLRScanNone ||
293 GetGlobalProperties()->GetScanType() == eKASLRScanLowgloAddresses) {
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000294 return LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000295 }
296
297 ThreadSP thread = process->GetThreadList().GetSelectedThread();
298 if (thread.get() == NULL)
299 return LLDB_INVALID_ADDRESS;
300 addr_t pc = thread->GetRegisterContext()->GetPC(LLDB_INVALID_ADDRESS);
301
302 if (pc == LLDB_INVALID_ADDRESS)
303 return LLDB_INVALID_ADDRESS;
304
305 // The kernel will load at at one megabyte boundary (0x100000), or at that
306 // boundary plus
307 // an offset of one page (0x1000) or two, or four (0x4000), depending on the
308 // device.
309
310 // Round the current pc down to the nearest one megabyte boundary - the place
311 // where we will start searching.
312 addr_t addr = pc & ~0xfffff;
313
314 // Search backwards 32 megabytes, looking for the start of the kernel at each
315 // one-megabyte boundary.
316 for (int i = 0; i < 32; i++, addr -= 0x100000) {
317 if (CheckForKernelImageAtAddress(addr, process).IsValid())
318 return addr;
319 if (CheckForKernelImageAtAddress(addr + 0x1000, process).IsValid())
320 return addr + 0x1000;
321 if (CheckForKernelImageAtAddress(addr + 0x2000, process).IsValid())
322 return addr + 0x2000;
323 if (CheckForKernelImageAtAddress(addr + 0x4000, process).IsValid())
324 return addr + 0x4000;
325 }
326
327 return LLDB_INVALID_ADDRESS;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000328}
329
330//----------------------------------------------------------------------
331// Scan through the valid address range for a kernel binary.
332// This is uselessly slow in 64-bit environments so we don't even try it.
333// This scan is not enabled by default even for 32-bit targets.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000334// Returns the address of the kernel if one was found, else
335// LLDB_INVALID_ADDRESS.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000336//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000337lldb::addr_t DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch(
338 Process *process) {
339 if (GetGlobalProperties()->GetScanType() != eKASLRScanExhaustiveScan) {
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000340 return LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000341 }
342
343 addr_t kernel_range_low, kernel_range_high;
344 if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8) {
345 kernel_range_low = 1ULL << 63;
346 kernel_range_high = UINT64_MAX;
347 } else {
348 kernel_range_low = 1ULL << 31;
349 kernel_range_high = UINT32_MAX;
350 }
351
352 // Stepping through memory at one-megabyte resolution looking for a kernel
353 // rarely works (fast enough) with a 64-bit address space -- for now, let's
354 // not even bother. We may be attaching to something which *isn't* a kernel
355 // and we don't want to spin for minutes on-end looking for a kernel.
356 if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
357 return LLDB_INVALID_ADDRESS;
358
359 addr_t addr = kernel_range_low;
360
361 while (addr >= kernel_range_low && addr < kernel_range_high) {
362 if (CheckForKernelImageAtAddress(addr, process).IsValid())
363 return addr;
364 if (CheckForKernelImageAtAddress(addr + 0x1000, process).IsValid())
365 return addr + 0x1000;
366 if (CheckForKernelImageAtAddress(addr + 0x2000, process).IsValid())
367 return addr + 0x2000;
368 if (CheckForKernelImageAtAddress(addr + 0x4000, process).IsValid())
369 return addr + 0x4000;
370 addr += 0x100000;
371 }
372 return LLDB_INVALID_ADDRESS;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000373}
374
375//----------------------------------------------------------------------
376// Given an address in memory, look to see if there is a kernel image at that
Kate Stoneb9c1b512016-09-06 20:57:50 +0000377// address.
378// Returns a UUID; if a kernel was not found at that address, UUID.IsValid()
379// will be false.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000380//----------------------------------------------------------------------
381lldb_private::UUID
Kate Stoneb9c1b512016-09-06 20:57:50 +0000382DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress(lldb::addr_t addr,
383 Process *process) {
384 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
385 if (addr == LLDB_INVALID_ADDRESS)
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000386 return UUID();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000387
388 if (log)
389 log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
390 "looking for kernel binary at 0x%" PRIx64,
391 addr);
392
393 // First try a quick test -- read the first 4 bytes and see if there is a
394 // valid Mach-O magic field there
395 // (the first field of the mach_header/mach_header_64 struct).
396
397 Error read_error;
Jason Molenda2b0a7be2016-11-15 01:41:27 +0000398 uint8_t magicbuf[4];
399 if (process->ReadMemoryFromInferior (addr, magicbuf, sizeof (magicbuf), read_error) != sizeof (magicbuf))
400 return UUID();
401
402 const uint32_t magicks[] = { llvm::MachO::MH_MAGIC_64, llvm::MachO::MH_MAGIC, llvm::MachO::MH_CIGAM, llvm::MachO::MH_CIGAM_64};
403
404 bool found_matching_pattern = false;
Taras Tsugrii0ca1dde2016-11-24 01:34:43 +0000405 for (size_t i = 0; i < llvm::array_lengthof (magicks); i++)
Jason Molenda2b0a7be2016-11-15 01:41:27 +0000406 if (::memcmp (magicbuf, &magicks[i], sizeof (magicbuf)) == 0)
407 found_matching_pattern = true;
408
409 if (found_matching_pattern == false)
410 return UUID();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000411
412 // Read the mach header and see whether it looks like a kernel
413 llvm::MachO::mach_header header;
414 if (process->DoReadMemory(addr, &header, sizeof(header), read_error) !=
415 sizeof(header))
416 return UUID();
417
418 if (header.magic == llvm::MachO::MH_CIGAM ||
419 header.magic == llvm::MachO::MH_CIGAM_64) {
420 header.magic = llvm::ByteSwap_32(header.magic);
421 header.cputype = llvm::ByteSwap_32(header.cputype);
422 header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
423 header.filetype = llvm::ByteSwap_32(header.filetype);
424 header.ncmds = llvm::ByteSwap_32(header.ncmds);
425 header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
426 header.flags = llvm::ByteSwap_32(header.flags);
427 }
428
429 // A kernel is an executable which does not have the dynamic link object flag
430 // set.
431 if (header.filetype == llvm::MachO::MH_EXECUTE &&
432 (header.flags & llvm::MachO::MH_DYLDLINK) == 0) {
433 // Create a full module to get the UUID
434 ModuleSP memory_module_sp = process->ReadModuleFromMemory(
435 FileSpec("temp_mach_kernel", false), addr);
436 if (!memory_module_sp.get())
437 return UUID();
438
439 ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
Jason Molendabc22c8d2016-10-21 23:45:07 +0000440 if (exe_objfile == NULL) {
441 if (log)
442 log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress "
443 "found a binary at 0x%" PRIx64
444 " but could not create an object file from memory",
445 addr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000446 return UUID();
Jason Molendabc22c8d2016-10-21 23:45:07 +0000447 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000448
449 if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
450 exe_objfile->GetStrata() == ObjectFile::eStrataKernel) {
451 ArchSpec kernel_arch(eArchTypeMachO, header.cputype, header.cpusubtype);
452 if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(
453 kernel_arch)) {
454 process->GetTarget().SetArchitecture(kernel_arch);
455 }
Jason Molendabc22c8d2016-10-21 23:45:07 +0000456 if (log) {
457 std::string uuid_str;
458 if (memory_module_sp->GetUUID().IsValid()) {
459 uuid_str = "with UUID ";
460 uuid_str += memory_module_sp->GetUUID().GetAsString();
461 } else {
462 uuid_str = "and no LC_UUID found in load commands ";
463 }
464 log->Printf(
465 "DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
466 "kernel binary image found at 0x%" PRIx64 " with arch '%s' %s",
467 addr, kernel_arch.GetTriple().str().c_str(), uuid_str.c_str());
468 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000469 return memory_module_sp->GetUUID();
470 }
471 }
472
473 return UUID();
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000474}
475
476//----------------------------------------------------------------------
Greg Clayton7b242382011-07-08 00:48:09 +0000477// Constructor
478//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000479DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel(Process *process,
480 lldb::addr_t kernel_addr)
481 : DynamicLoader(process), m_kernel_load_address(kernel_addr), m_kernel(),
482 m_kext_summary_header_ptr_addr(), m_kext_summary_header_addr(),
483 m_kext_summary_header(), m_known_kexts(), m_mutex(),
484 m_break_id(LLDB_INVALID_BREAK_ID) {
485 Error error;
486 PlatformSP platform_sp(
487 Platform::Create(PlatformDarwinKernel::GetPluginNameStatic(), error));
488 // Only select the darwin-kernel Platform if we've been asked to load kexts.
489 // It can take some time to scan over all of the kext info.plists and that
490 // shouldn't be done if kext loading is explicitly disabled.
491 if (platform_sp.get() && GetGlobalProperties()->GetLoadKexts()) {
492 process->GetTarget().SetPlatform(platform_sp);
493 }
Greg Clayton7b242382011-07-08 00:48:09 +0000494}
495
496//----------------------------------------------------------------------
497// Destructor
498//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000499DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel() { Clear(true); }
Greg Clayton7b242382011-07-08 00:48:09 +0000500
Kate Stoneb9c1b512016-09-06 20:57:50 +0000501void DynamicLoaderDarwinKernel::UpdateIfNeeded() {
502 LoadKernelModuleIfNeeded();
503 SetNotificationBreakpointIfNeeded();
Greg Clayton374972e2011-07-09 17:15:55 +0000504}
Greg Clayton7b242382011-07-08 00:48:09 +0000505//------------------------------------------------------------------
506/// Called after attaching a process.
507///
508/// Allow DynamicLoader plug-ins to execute some code after
509/// attaching to a process.
510//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000511void DynamicLoaderDarwinKernel::DidAttach() {
512 PrivateInitialize(m_process);
513 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000514}
515
516//------------------------------------------------------------------
517/// Called after attaching a process.
518///
519/// Allow DynamicLoader plug-ins to execute some code after
520/// attaching to a process.
521//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000522void DynamicLoaderDarwinKernel::DidLaunch() {
523 PrivateInitialize(m_process);
524 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000525}
526
Greg Clayton7b242382011-07-08 00:48:09 +0000527//----------------------------------------------------------------------
528// Clear out the state of this class.
529//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000530void DynamicLoaderDarwinKernel::Clear(bool clear_process) {
531 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Clayton7b242382011-07-08 00:48:09 +0000532
Kate Stoneb9c1b512016-09-06 20:57:50 +0000533 if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
534 m_process->ClearBreakpointSiteByID(m_break_id);
Greg Clayton7b242382011-07-08 00:48:09 +0000535
Kate Stoneb9c1b512016-09-06 20:57:50 +0000536 if (clear_process)
537 m_process = NULL;
538 m_kernel.Clear();
539 m_known_kexts.clear();
540 m_kext_summary_header_ptr_addr.Clear();
541 m_kext_summary_header_addr.Clear();
542 m_break_id = LLDB_INVALID_BREAK_ID;
Greg Clayton7b242382011-07-08 00:48:09 +0000543}
544
Kate Stoneb9c1b512016-09-06 20:57:50 +0000545bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageAtFileAddress(
546 Process *process) {
547 if (IsLoaded())
548 return true;
Greg Clayton7b242382011-07-08 00:48:09 +0000549
Kate Stoneb9c1b512016-09-06 20:57:50 +0000550 if (m_module_sp) {
551 bool changed = false;
552 if (m_module_sp->SetLoadAddress(process->GetTarget(), 0, true, changed))
553 m_load_process_stop_id = process->GetStopID();
554 }
555 return false;
556}
Greg Clayton2af282a2012-03-21 04:25:00 +0000557
Kate Stoneb9c1b512016-09-06 20:57:50 +0000558void DynamicLoaderDarwinKernel::KextImageInfo::SetModule(ModuleSP module_sp) {
559 m_module_sp = module_sp;
560 if (module_sp.get() && module_sp->GetObjectFile()) {
561 if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable &&
562 module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel) {
563 m_kernel_image = true;
564 } else {
565 m_kernel_image = false;
566 }
567 }
568}
569
570ModuleSP DynamicLoaderDarwinKernel::KextImageInfo::GetModule() {
571 return m_module_sp;
572}
573
574void DynamicLoaderDarwinKernel::KextImageInfo::SetLoadAddress(
575 addr_t load_addr) {
576 m_load_address = load_addr;
577}
578
579addr_t DynamicLoaderDarwinKernel::KextImageInfo::GetLoadAddress() const {
580 return m_load_address;
581}
582
583uint64_t DynamicLoaderDarwinKernel::KextImageInfo::GetSize() const {
584 return m_size;
585}
586
587void DynamicLoaderDarwinKernel::KextImageInfo::SetSize(uint64_t size) {
588 m_size = size;
589}
590
591uint32_t DynamicLoaderDarwinKernel::KextImageInfo::GetProcessStopId() const {
592 return m_load_process_stop_id;
593}
594
595void DynamicLoaderDarwinKernel::KextImageInfo::SetProcessStopId(
596 uint32_t stop_id) {
597 m_load_process_stop_id = stop_id;
598}
599
600bool DynamicLoaderDarwinKernel::KextImageInfo::
601operator==(const KextImageInfo &rhs) {
602 if (m_uuid.IsValid() || rhs.GetUUID().IsValid()) {
603 if (m_uuid == rhs.GetUUID()) {
604 return true;
Greg Clayton2af282a2012-03-21 04:25:00 +0000605 }
606 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000607 }
608
609 if (m_name == rhs.GetName() && m_load_address == rhs.GetLoadAddress())
610 return true;
611
612 return false;
Greg Clayton2af282a2012-03-21 04:25:00 +0000613}
614
Kate Stoneb9c1b512016-09-06 20:57:50 +0000615void DynamicLoaderDarwinKernel::KextImageInfo::SetName(const char *name) {
616 m_name = name;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000617}
618
Kate Stoneb9c1b512016-09-06 20:57:50 +0000619std::string DynamicLoaderDarwinKernel::KextImageInfo::GetName() const {
620 return m_name;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000621}
622
Kate Stoneb9c1b512016-09-06 20:57:50 +0000623void DynamicLoaderDarwinKernel::KextImageInfo::SetUUID(const UUID &uuid) {
624 m_uuid = uuid;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000625}
626
Kate Stoneb9c1b512016-09-06 20:57:50 +0000627UUID DynamicLoaderDarwinKernel::KextImageInfo::GetUUID() const {
628 return m_uuid;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000629}
630
Kate Stoneb9c1b512016-09-06 20:57:50 +0000631// Given the m_load_address from the kext summaries, and a UUID, try to create
632// an in-memory
633// Module at that address. Require that the MemoryModule have a matching UUID
634// and detect
Jason Molenda306bd0a2013-02-19 05:42:46 +0000635// if this MemoryModule is a kernel or a kext.
636//
Kate Stoneb9c1b512016-09-06 20:57:50 +0000637// Returns true if m_memory_module_sp is now set to a valid Module.
Jason Molenda306bd0a2013-02-19 05:42:46 +0000638
Kate Stoneb9c1b512016-09-06 20:57:50 +0000639bool DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule(
640 Process *process) {
641 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
642 if (m_memory_module_sp.get() != NULL)
Jason Molenda306bd0a2013-02-19 05:42:46 +0000643 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000644 if (m_load_address == LLDB_INVALID_ADDRESS)
645 return false;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000646
Kate Stoneb9c1b512016-09-06 20:57:50 +0000647 FileSpec file_spec;
648 file_spec.SetFile(m_name.c_str(), false);
Jason Molenda306bd0a2013-02-19 05:42:46 +0000649
Kate Stoneb9c1b512016-09-06 20:57:50 +0000650 ModuleSP memory_module_sp =
651 process->ReadModuleFromMemory(file_spec, m_load_address);
Jason Molenda306bd0a2013-02-19 05:42:46 +0000652
Kate Stoneb9c1b512016-09-06 20:57:50 +0000653 if (memory_module_sp.get() == NULL)
654 return false;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000655
Kate Stoneb9c1b512016-09-06 20:57:50 +0000656 bool is_kernel = false;
657 if (memory_module_sp->GetObjectFile()) {
658 if (memory_module_sp->GetObjectFile()->GetType() ==
659 ObjectFile::eTypeExecutable &&
660 memory_module_sp->GetObjectFile()->GetStrata() ==
661 ObjectFile::eStrataKernel) {
662 is_kernel = true;
663 } else if (memory_module_sp->GetObjectFile()->GetType() ==
664 ObjectFile::eTypeSharedLibrary) {
665 is_kernel = false;
Jason Molenda87a04b22012-10-19 03:40:45 +0000666 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000667 }
Jason Molenda87a04b22012-10-19 03:40:45 +0000668
Kate Stoneb9c1b512016-09-06 20:57:50 +0000669 // If this is a kext, and the kernel specified what UUID we should find at
670 // this
671 // load address, require that the memory module have a matching UUID or
672 // something
673 // has gone wrong and we should discard it.
674 if (m_uuid.IsValid()) {
675 if (m_uuid != memory_module_sp->GetUUID()) {
676 if (log) {
677 log->Printf("KextImageInfo::ReadMemoryModule the kernel said to find "
678 "uuid %s at 0x%" PRIx64
679 " but instead we found uuid %s, throwing it away",
680 m_uuid.GetAsString().c_str(), m_load_address,
681 memory_module_sp->GetUUID().GetAsString().c_str());
682 }
683 return false;
684 }
685 }
Jason Molenda306bd0a2013-02-19 05:42:46 +0000686
Kate Stoneb9c1b512016-09-06 20:57:50 +0000687 // If the in-memory Module has a UUID, let's use that.
688 if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid()) {
689 m_uuid = memory_module_sp->GetUUID();
690 }
691
692 m_memory_module_sp = memory_module_sp;
693 m_kernel_image = is_kernel;
694 if (is_kernel) {
695 if (log) {
696 // This is unusual and probably not intended
697 log->Printf("KextImageInfo::ReadMemoryModule read the kernel binary out "
698 "of memory");
699 }
700 if (memory_module_sp->GetArchitecture().IsValid()) {
701 process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture());
702 }
703 if (m_uuid.IsValid()) {
704 ModuleSP exe_module_sp = process->GetTarget().GetExecutableModule();
705 if (exe_module_sp.get() && exe_module_sp->GetUUID().IsValid()) {
706 if (m_uuid != exe_module_sp->GetUUID()) {
707 // The user specified a kernel binary that has a different UUID than
708 // the kernel actually running in memory. This never ends well;
709 // clear the user specified kernel binary from the Target.
710
711 m_module_sp.reset();
712
713 ModuleList user_specified_kernel_list;
714 user_specified_kernel_list.Append(exe_module_sp);
715 process->GetTarget().GetImages().Remove(user_specified_kernel_list);
716 }
717 }
718 }
719 }
720
721 return true;
722}
723
724bool DynamicLoaderDarwinKernel::KextImageInfo::IsKernel() const {
725 return m_kernel_image == true;
726}
727
728void DynamicLoaderDarwinKernel::KextImageInfo::SetIsKernel(bool is_kernel) {
729 m_kernel_image = is_kernel;
730}
731
732bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
733 Process *process) {
734 if (IsLoaded())
735 return true;
736
737 Target &target = process->GetTarget();
738
739 // If we don't have / can't create a memory module for this kext, don't try to
740 // load it - we won't
741 // have the correct segment load addresses.
742 if (!ReadMemoryModule(process)) {
743 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
744 if (log)
745 log->Printf("Unable to read '%s' from memory at address 0x%" PRIx64
746 " to get the segment load addresses.",
747 m_name.c_str(), m_load_address);
748 return false;
749 }
750
751 bool uuid_is_valid = m_uuid.IsValid();
752
753 if (IsKernel() && uuid_is_valid && m_memory_module_sp.get()) {
754 Stream *s = target.GetDebugger().GetOutputFile().get();
755 if (s) {
756 s->Printf("Kernel UUID: %s\n",
757 m_memory_module_sp->GetUUID().GetAsString().c_str());
758 s->Printf("Load Address: 0x%" PRIx64 "\n", m_load_address);
759 }
760 }
761
762 if (!m_module_sp) {
763 // See if the kext has already been loaded into the target, probably by the
764 // user doing target modules add.
765 const ModuleList &target_images = target.GetImages();
766 m_module_sp = target_images.FindModule(m_uuid);
767
768 // Search for the kext on the local filesystem via the UUID
769 if (!m_module_sp && uuid_is_valid) {
770 ModuleSpec module_spec;
771 module_spec.GetUUID() = m_uuid;
772 module_spec.GetArchitecture() = target.GetArchitecture();
773
774 // For the kernel, we really do need an on-disk file copy of the binary to
775 // do anything useful.
776 // This will force a clal to
777 if (IsKernel()) {
778 if (Symbols::DownloadObjectAndSymbolFile(module_spec, true)) {
779 if (module_spec.GetFileSpec().Exists()) {
780 m_module_sp.reset(new Module(module_spec.GetFileSpec(),
781 target.GetArchitecture()));
782 if (m_module_sp.get() &&
783 m_module_sp->MatchesModuleSpec(module_spec)) {
784 ModuleList loaded_module_list;
785 loaded_module_list.Append(m_module_sp);
786 target.ModulesDidLoad(loaded_module_list);
787 }
788 }
789 }
790 }
791
792 // If the current platform is PlatformDarwinKernel, create a ModuleSpec
793 // with the filename set
794 // to be the bundle ID for this kext, e.g.
795 // "com.apple.filesystems.msdosfs", and ask the platform
796 // to find it.
797 PlatformSP platform_sp(target.GetPlatform());
798 if (!m_module_sp && platform_sp) {
799 ConstString platform_name(platform_sp->GetPluginName());
800 static ConstString g_platform_name(
801 PlatformDarwinKernel::GetPluginNameStatic());
802 if (platform_name == g_platform_name) {
803 ModuleSpec kext_bundle_module_spec(module_spec);
804 FileSpec kext_filespec(m_name.c_str(), false);
805 kext_bundle_module_spec.GetFileSpec() = kext_filespec;
806 platform_sp->GetSharedModule(
807 kext_bundle_module_spec, process, m_module_sp,
808 &target.GetExecutableSearchPaths(), NULL, NULL);
809 }
810 }
811
812 // Ask the Target to find this file on the local system, if possible.
813 // This will search in the list of currently-loaded files, look in the
814 // standard search paths on the system, and on a Mac it will try calling
815 // the DebugSymbols framework with the UUID to find the binary via its
816 // search methods.
817 if (!m_module_sp) {
818 m_module_sp = target.GetSharedModule(module_spec);
819 }
820
821 if (IsKernel() && !m_module_sp) {
Greg Clayton44d93782014-01-27 23:43:24 +0000822 Stream *s = target.GetDebugger().GetOutputFile().get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000823 if (s) {
824 s->Printf("WARNING: Unable to locate kernel binary on the debugger "
825 "system.\n");
Jason Molendae575e7b2013-02-19 06:11:13 +0000826 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000827 }
Jason Molendae575e7b2013-02-19 06:11:13 +0000828 }
829
Kate Stoneb9c1b512016-09-06 20:57:50 +0000830 // If we managed to find a module, append it to the target's list of images.
831 // If we also have a memory module, require that they have matching UUIDs
832 if (m_module_sp) {
833 bool uuid_match_ok = true;
834 if (m_memory_module_sp) {
835 if (m_module_sp->GetUUID() != m_memory_module_sp->GetUUID()) {
836 uuid_match_ok = false;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000837 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000838 }
839 if (uuid_match_ok) {
840 target.GetImages().AppendIfNeeded(m_module_sp);
841 if (IsKernel() &&
842 target.GetExecutableModulePointer() != m_module_sp.get()) {
843 target.SetExecutableModule(m_module_sp, false);
Greg Claytonc859e2d2012-02-13 23:10:39 +0000844 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000845 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000846 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000847 }
848
849 if (!m_module_sp && !IsKernel() && m_uuid.IsValid() && !m_name.empty()) {
850 Stream *s = target.GetDebugger().GetOutputFile().get();
851 if (s) {
852 s->Printf("warning: Can't find binary/dSYM for %s (%s)\n", m_name.c_str(),
853 m_uuid.GetAsString().c_str());
Jason Molenda56c23282013-02-19 06:39:56 +0000854 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000855 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000856
Kate Stoneb9c1b512016-09-06 20:57:50 +0000857 static ConstString g_section_name_LINKEDIT("__LINKEDIT");
Greg Clayton67408532012-12-11 01:20:51 +0000858
Kate Stoneb9c1b512016-09-06 20:57:50 +0000859 if (m_memory_module_sp && m_module_sp) {
860 if (m_module_sp->GetUUID() == m_memory_module_sp->GetUUID()) {
861 ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();
862 ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile();
Jason Molendabb860bd2012-10-09 01:17:11 +0000863
Kate Stoneb9c1b512016-09-06 20:57:50 +0000864 if (memory_object_file && ondisk_object_file) {
865 // The memory_module for kexts may have an invalid __LINKEDIT seg; skip
866 // it.
867 const bool ignore_linkedit = !IsKernel();
Greg Clayton67408532012-12-11 01:20:51 +0000868
Kate Stoneb9c1b512016-09-06 20:57:50 +0000869 SectionList *ondisk_section_list = ondisk_object_file->GetSectionList();
870 SectionList *memory_section_list = memory_object_file->GetSectionList();
871 if (memory_section_list && ondisk_section_list) {
872 const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
873 // There may be CTF sections in the memory image so we can't
874 // always just compare the number of sections (which are actually
875 // segments in mach-o parlance)
876 uint32_t sect_idx = 0;
877
878 // Use the memory_module's addresses for each section to set the
879 // file module's load address as appropriate. We don't want to use
880 // a single slide value for the entire kext - different segments may
881 // be slid different amounts by the kext loader.
882
883 uint32_t num_sections_loaded = 0;
884 for (sect_idx = 0; sect_idx < num_ondisk_sections; ++sect_idx) {
885 SectionSP ondisk_section_sp(
886 ondisk_section_list->GetSectionAtIndex(sect_idx));
887 if (ondisk_section_sp) {
888 // Don't ever load __LINKEDIT as it may or may not be actually
889 // mapped into memory and there is no current way to tell.
890 // I filed rdar://problem/12851706 to track being able to tell
891 // if the __LINKEDIT is actually mapped, but until then, we need
892 // to not load the __LINKEDIT
893 if (ignore_linkedit &&
894 ondisk_section_sp->GetName() == g_section_name_LINKEDIT)
895 continue;
896
897 const Section *memory_section =
898 memory_section_list
899 ->FindSectionByName(ondisk_section_sp->GetName())
900 .get();
901 if (memory_section) {
902 target.SetSectionLoadAddress(ondisk_section_sp,
903 memory_section->GetFileAddress());
904 ++num_sections_loaded;
905 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000906 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000907 }
908 if (num_sections_loaded > 0)
909 m_load_process_stop_id = process->GetStopID();
910 else
911 m_module_sp.reset(); // No sections were loaded
912 } else
913 m_module_sp.reset(); // One or both section lists
914 } else
915 m_module_sp.reset(); // One or both object files missing
916 } else
917 m_module_sp.reset(); // UUID mismatch
918 }
919
920 bool is_loaded = IsLoaded();
921
922 if (is_loaded && m_module_sp && IsKernel()) {
923 Stream *s = target.GetDebugger().GetOutputFile().get();
924 if (s) {
925 ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
926 if (kernel_object_file) {
927 addr_t file_address =
928 kernel_object_file->GetHeaderAddress().GetFileAddress();
929 if (m_load_address != LLDB_INVALID_ADDRESS &&
930 file_address != LLDB_INVALID_ADDRESS) {
931 s->Printf("Kernel slid 0x%" PRIx64 " in memory.\n",
932 m_load_address - file_address);
Greg Claytonc859e2d2012-02-13 23:10:39 +0000933 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000934 }
935 {
936 s->Printf("Loaded kernel file %s\n",
937 m_module_sp->GetFileSpec().GetPath().c_str());
938 }
939 s->Flush();
Greg Claytonc859e2d2012-02-13 23:10:39 +0000940 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000941 }
942 return is_loaded;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000943}
944
Kate Stoneb9c1b512016-09-06 20:57:50 +0000945uint32_t DynamicLoaderDarwinKernel::KextImageInfo::GetAddressByteSize() {
946 if (m_memory_module_sp)
947 return m_memory_module_sp->GetArchitecture().GetAddressByteSize();
948 if (m_module_sp)
949 return m_module_sp->GetArchitecture().GetAddressByteSize();
950 return 0;
Greg Clayton1f746072012-08-29 21:13:06 +0000951}
952
Kate Stoneb9c1b512016-09-06 20:57:50 +0000953lldb::ByteOrder DynamicLoaderDarwinKernel::KextImageInfo::GetByteOrder() {
954 if (m_memory_module_sp)
955 return m_memory_module_sp->GetArchitecture().GetByteOrder();
956 if (m_module_sp)
957 return m_module_sp->GetArchitecture().GetByteOrder();
958 return endian::InlHostByteOrder();
Greg Clayton1f746072012-08-29 21:13:06 +0000959}
960
961lldb_private::ArchSpec
Kate Stoneb9c1b512016-09-06 20:57:50 +0000962DynamicLoaderDarwinKernel::KextImageInfo::GetArchitecture() const {
963 if (m_memory_module_sp)
964 return m_memory_module_sp->GetArchitecture();
965 if (m_module_sp)
966 return m_module_sp->GetArchitecture();
967 return lldb_private::ArchSpec();
Greg Clayton1f746072012-08-29 21:13:06 +0000968}
969
Greg Clayton7b242382011-07-08 00:48:09 +0000970//----------------------------------------------------------------------
971// Load the kernel module and initialize the "m_kernel" member. Return
972// true _only_ if the kernel is loaded the first time through (subsequent
973// calls to this function should return false after the kernel has been
974// already loaded).
975//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000976void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
977 if (!m_kext_summary_header_ptr_addr.IsValid()) {
978 m_kernel.Clear();
979 m_kernel.SetModule(m_process->GetTarget().GetExecutableModule());
980 m_kernel.SetIsKernel(true);
Jason Molenda4bd4e7e2012-09-29 04:02:01 +0000981
Kate Stoneb9c1b512016-09-06 20:57:50 +0000982 ConstString kernel_name("mach_kernel");
983 if (m_kernel.GetModule().get() && m_kernel.GetModule()->GetObjectFile() &&
984 !m_kernel.GetModule()
985 ->GetObjectFile()
986 ->GetFileSpec()
987 .GetFilename()
988 .IsEmpty()) {
989 kernel_name =
990 m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename();
Greg Clayton7b242382011-07-08 00:48:09 +0000991 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000992 m_kernel.SetName(kernel_name.AsCString());
993
994 if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS) {
995 m_kernel.SetLoadAddress(m_kernel_load_address);
996 if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS &&
997 m_kernel.GetModule()) {
998 // We didn't get a hint from the process, so we will
999 // try the kernel at the address that it exists at in
1000 // the file if we have one
1001 ObjectFile *kernel_object_file = m_kernel.GetModule()->GetObjectFile();
1002 if (kernel_object_file) {
1003 addr_t load_address =
1004 kernel_object_file->GetHeaderAddress().GetLoadAddress(
1005 &m_process->GetTarget());
1006 addr_t file_address =
1007 kernel_object_file->GetHeaderAddress().GetFileAddress();
1008 if (load_address != LLDB_INVALID_ADDRESS && load_address != 0) {
1009 m_kernel.SetLoadAddress(load_address);
1010 if (load_address != file_address) {
1011 // Don't accidentally relocate the kernel to the File address --
1012 // the Load address has already been set to its actual in-memory
1013 // address.
1014 // Mark it as IsLoaded.
1015 m_kernel.SetProcessStopId(m_process->GetStopID());
1016 }
1017 } else {
1018 m_kernel.SetLoadAddress(file_address);
1019 }
1020 }
1021 }
1022 }
1023
1024 if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS) {
1025 if (!m_kernel.LoadImageUsingMemoryModule(m_process)) {
1026 m_kernel.LoadImageAtFileAddress(m_process);
1027 }
1028 }
1029
1030 if (m_kernel.IsLoaded() && m_kernel.GetModule()) {
1031 static ConstString kext_summary_symbol("gLoadedKextSummaries");
1032 const Symbol *symbol =
1033 m_kernel.GetModule()->FindFirstSymbolWithNameAndType(
1034 kext_summary_symbol, eSymbolTypeData);
1035 if (symbol) {
1036 m_kext_summary_header_ptr_addr = symbol->GetAddress();
1037 // Update all image infos
1038 ReadAllKextSummaries();
1039 }
1040 } else {
1041 m_kernel.Clear();
1042 }
1043 }
Greg Clayton7b242382011-07-08 00:48:09 +00001044}
1045
Greg Clayton7b242382011-07-08 00:48:09 +00001046//----------------------------------------------------------------------
1047// Static callback function that gets called when our DYLD notification
1048// breakpoint gets hit. We update all of our image infos and then
1049// let our super class DynamicLoader class decide if we should stop
1050// or not (based on global preference).
1051//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001052bool DynamicLoaderDarwinKernel::BreakpointHitCallback(
1053 void *baton, StoppointCallbackContext *context, user_id_t break_id,
1054 user_id_t break_loc_id) {
1055 return static_cast<DynamicLoaderDarwinKernel *>(baton)->BreakpointHit(
1056 context, break_id, break_loc_id);
Greg Clayton7b242382011-07-08 00:48:09 +00001057}
1058
Kate Stoneb9c1b512016-09-06 20:57:50 +00001059bool DynamicLoaderDarwinKernel::BreakpointHit(StoppointCallbackContext *context,
1060 user_id_t break_id,
1061 user_id_t break_loc_id) {
1062 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
1063 if (log)
1064 log->Printf("DynamicLoaderDarwinKernel::BreakpointHit (...)\n");
Greg Claytond16e1e52011-07-12 17:06:17 +00001065
Kate Stoneb9c1b512016-09-06 20:57:50 +00001066 ReadAllKextSummaries();
Greg Claytond16e1e52011-07-12 17:06:17 +00001067
Kate Stoneb9c1b512016-09-06 20:57:50 +00001068 if (log)
1069 PutToLog(log);
1070
1071 return GetStopWhenImagesChange();
Greg Clayton374972e2011-07-09 17:15:55 +00001072}
1073
Kate Stoneb9c1b512016-09-06 20:57:50 +00001074bool DynamicLoaderDarwinKernel::ReadKextSummaryHeader() {
1075 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Clayton374972e2011-07-09 17:15:55 +00001076
Kate Stoneb9c1b512016-09-06 20:57:50 +00001077 // the all image infos is already valid for this process stop ID
Greg Clayton7b242382011-07-08 00:48:09 +00001078
Kate Stoneb9c1b512016-09-06 20:57:50 +00001079 if (m_kext_summary_header_ptr_addr.IsValid()) {
1080 const uint32_t addr_size = m_kernel.GetAddressByteSize();
1081 const ByteOrder byte_order = m_kernel.GetByteOrder();
1082 Error error;
1083 // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure
1084 // which is currently 4 uint32_t and a pointer.
1085 uint8_t buf[24];
1086 DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
1087 const size_t count = 4 * sizeof(uint32_t) + addr_size;
1088 const bool prefer_file_cache = false;
1089 if (m_process->GetTarget().ReadPointerFromMemory(
1090 m_kext_summary_header_ptr_addr, prefer_file_cache, error,
1091 m_kext_summary_header_addr)) {
1092 // We got a valid address for our kext summary header and make sure it
1093 // isn't NULL
1094 if (m_kext_summary_header_addr.IsValid() &&
1095 m_kext_summary_header_addr.GetFileAddress() != 0) {
1096 const size_t bytes_read = m_process->GetTarget().ReadMemory(
1097 m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
1098 if (bytes_read == count) {
1099 lldb::offset_t offset = 0;
1100 m_kext_summary_header.version = data.GetU32(&offset);
1101 if (m_kext_summary_header.version > 128) {
1102 Stream *s =
1103 m_process->GetTarget().GetDebugger().GetOutputFile().get();
1104 s->Printf("WARNING: Unable to read kext summary header, got "
1105 "improbable version number %u\n",
1106 m_kext_summary_header.version);
1107 // If we get an improbably large version number, we're probably
1108 // getting bad memory.
1109 m_kext_summary_header_addr.Clear();
1110 return false;
1111 }
1112 if (m_kext_summary_header.version >= 2) {
1113 m_kext_summary_header.entry_size = data.GetU32(&offset);
1114 if (m_kext_summary_header.entry_size > 4096) {
1115 // If we get an improbably large entry_size, we're probably
1116 // getting bad memory.
1117 Stream *s =
1118 m_process->GetTarget().GetDebugger().GetOutputFile().get();
1119 s->Printf("WARNING: Unable to read kext summary header, got "
1120 "improbable entry_size %u\n",
1121 m_kext_summary_header.entry_size);
1122 m_kext_summary_header_addr.Clear();
1123 return false;
Greg Claytond16e1e52011-07-12 17:06:17 +00001124 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001125 } else {
1126 // Versions less than 2 didn't have an entry size, it was hard coded
1127 m_kext_summary_header.entry_size =
1128 KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
1129 }
1130 m_kext_summary_header.entry_count = data.GetU32(&offset);
1131 if (m_kext_summary_header.entry_count > 10000) {
1132 // If we get an improbably large number of kexts, we're probably
1133 // getting bad memory.
1134 Stream *s =
1135 m_process->GetTarget().GetDebugger().GetOutputFile().get();
1136 s->Printf("WARNING: Unable to read kext summary header, got "
1137 "improbable number of kexts %u\n",
1138 m_kext_summary_header.entry_count);
1139 m_kext_summary_header_addr.Clear();
1140 return false;
1141 }
1142 return true;
Greg Clayton7b242382011-07-08 00:48:09 +00001143 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001144 }
Greg Clayton7b242382011-07-08 00:48:09 +00001145 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001146 }
1147 m_kext_summary_header_addr.Clear();
1148 return false;
Greg Clayton7b242382011-07-08 00:48:09 +00001149}
1150
Kate Stoneb9c1b512016-09-06 20:57:50 +00001151// We've either (a) just attached to a new kernel, or (b) the kexts-changed
1152// breakpoint was hit
Jason Molenda306bd0a2013-02-19 05:42:46 +00001153// and we need to figure out what kexts have been added or removed.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001154// Read the kext summaries from the inferior kernel memory, compare them against
1155// the
1156// m_known_kexts vector and update the m_known_kexts vector as needed to keep in
1157// sync with the
Jason Molenda306bd0a2013-02-19 05:42:46 +00001158// inferior.
Greg Clayton7b242382011-07-08 00:48:09 +00001159
Kate Stoneb9c1b512016-09-06 20:57:50 +00001160bool DynamicLoaderDarwinKernel::ParseKextSummaries(
1161 const Address &kext_summary_addr, uint32_t count) {
1162 KextImageInfo::collection kext_summaries;
1163 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
1164 if (log)
1165 log->Printf("Kexts-changed breakpoint hit, there are %d kexts currently.\n",
1166 count);
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001167
Kate Stoneb9c1b512016-09-06 20:57:50 +00001168 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Clayton7b242382011-07-08 00:48:09 +00001169
Kate Stoneb9c1b512016-09-06 20:57:50 +00001170 if (!ReadKextSummaries(kext_summary_addr, count, kext_summaries))
Greg Clayton7b242382011-07-08 00:48:09 +00001171 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001172
1173 // read the plugin.dynamic-loader.darwin-kernel.load-kexts setting -- if the
1174 // user requested no
1175 // kext loading, don't print any messages about kexts & don't try to read
1176 // them.
1177 const bool load_kexts = GetGlobalProperties()->GetLoadKexts();
1178
1179 // By default, all kexts we've loaded in the past are marked as "remove" and
1180 // all of the kexts
1181 // we just found out about from ReadKextSummaries are marked as "add".
1182 std::vector<bool> to_be_removed(m_known_kexts.size(), true);
1183 std::vector<bool> to_be_added(count, true);
1184
1185 int number_of_new_kexts_being_added = 0;
1186 int number_of_old_kexts_being_removed = m_known_kexts.size();
1187
1188 const uint32_t new_kexts_size = kext_summaries.size();
1189 const uint32_t old_kexts_size = m_known_kexts.size();
1190
1191 // The m_known_kexts vector may have entries that have been Cleared,
1192 // or are a kernel.
1193 for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++) {
1194 bool ignore = false;
1195 KextImageInfo &image_info = m_known_kexts[old_kext];
1196 if (image_info.IsKernel()) {
1197 ignore = true;
1198 } else if (image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS &&
1199 !image_info.GetModule()) {
1200 ignore = true;
1201 }
1202
1203 if (ignore) {
1204 number_of_old_kexts_being_removed--;
1205 to_be_removed[old_kext] = false;
1206 }
1207 }
1208
1209 // Scan over the list of kexts we just read from the kernel, note those that
1210 // need to be added and those already loaded.
1211 for (uint32_t new_kext = 0; new_kext < new_kexts_size; new_kext++) {
1212 bool add_this_one = true;
1213 for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++) {
1214 if (m_known_kexts[old_kext] == kext_summaries[new_kext]) {
1215 // We already have this kext, don't re-load it.
1216 to_be_added[new_kext] = false;
1217 // This kext is still present, do not remove it.
1218 to_be_removed[old_kext] = false;
1219
1220 number_of_old_kexts_being_removed--;
1221 add_this_one = false;
1222 break;
1223 }
1224 }
1225 if (add_this_one) {
1226 number_of_new_kexts_being_added++;
1227 }
1228 }
1229
1230 if (number_of_new_kexts_being_added == 0 &&
1231 number_of_old_kexts_being_removed == 0)
1232 return true;
1233
1234 Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
1235 if (s && load_kexts) {
1236 if (number_of_new_kexts_being_added > 0 &&
1237 number_of_old_kexts_being_removed > 0) {
1238 s->Printf("Loading %d kext modules and unloading %d kext modules ",
1239 number_of_new_kexts_being_added,
1240 number_of_old_kexts_being_removed);
1241 } else if (number_of_new_kexts_being_added > 0) {
1242 s->Printf("Loading %d kext modules ", number_of_new_kexts_being_added);
1243 } else if (number_of_old_kexts_being_removed > 0) {
1244 s->Printf("Unloading %d kext modules ",
1245 number_of_old_kexts_being_removed);
1246 }
1247 }
1248
1249 if (log) {
1250 if (load_kexts) {
1251 log->Printf("DynamicLoaderDarwinKernel::ParseKextSummaries: %d kexts "
1252 "added, %d kexts removed",
1253 number_of_new_kexts_being_added,
1254 number_of_old_kexts_being_removed);
1255 } else {
1256 log->Printf(
1257 "DynamicLoaderDarwinKernel::ParseKextSummaries kext loading is "
1258 "disabled, else would have %d kexts added, %d kexts removed",
1259 number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
1260 }
1261 }
1262
1263 if (number_of_new_kexts_being_added > 0) {
1264 ModuleList loaded_module_list;
1265
1266 const uint32_t num_of_new_kexts = kext_summaries.size();
1267 for (uint32_t new_kext = 0; new_kext < num_of_new_kexts; new_kext++) {
1268 if (to_be_added[new_kext] == true) {
1269 KextImageInfo &image_info = kext_summaries[new_kext];
1270 if (load_kexts) {
1271 if (!image_info.LoadImageUsingMemoryModule(m_process)) {
1272 image_info.LoadImageAtFileAddress(m_process);
1273 }
1274 }
1275
1276 m_known_kexts.push_back(image_info);
1277
1278 if (image_info.GetModule() &&
1279 m_process->GetStopID() == image_info.GetProcessStopId())
1280 loaded_module_list.AppendIfNeeded(image_info.GetModule());
1281
1282 if (s && load_kexts)
1283 s->Printf(".");
1284
1285 if (log)
1286 kext_summaries[new_kext].PutToLog(log);
1287 }
1288 }
1289 m_process->GetTarget().ModulesDidLoad(loaded_module_list);
1290 }
1291
1292 if (number_of_old_kexts_being_removed > 0) {
1293 ModuleList loaded_module_list;
1294 const uint32_t num_of_old_kexts = m_known_kexts.size();
1295 for (uint32_t old_kext = 0; old_kext < num_of_old_kexts; old_kext++) {
1296 ModuleList unloaded_module_list;
1297 if (to_be_removed[old_kext]) {
1298 KextImageInfo &image_info = m_known_kexts[old_kext];
1299 // You can't unload the kernel.
1300 if (!image_info.IsKernel()) {
1301 if (image_info.GetModule()) {
1302 unloaded_module_list.AppendIfNeeded(image_info.GetModule());
1303 }
1304 if (s)
1305 s->Printf(".");
1306 image_info.Clear();
1307 // should pull it out of the KextImageInfos vector but that would
1308 // mutate the list and invalidate
1309 // the to_be_removed bool vector; leaving it in place once Cleared()
1310 // is relatively harmless.
1311 }
1312 }
1313 m_process->GetTarget().ModulesDidUnload(unloaded_module_list, false);
1314 }
1315 }
1316
1317 if (s && load_kexts) {
1318 s->Printf(" done.\n");
1319 s->Flush();
1320 }
1321
1322 return true;
1323}
1324
1325uint32_t DynamicLoaderDarwinKernel::ReadKextSummaries(
1326 const Address &kext_summary_addr, uint32_t image_infos_count,
1327 KextImageInfo::collection &image_infos) {
1328 const ByteOrder endian = m_kernel.GetByteOrder();
1329 const uint32_t addr_size = m_kernel.GetAddressByteSize();
1330
1331 image_infos.resize(image_infos_count);
1332 const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
1333 DataBufferHeap data(count, 0);
1334 Error error;
1335
1336 const bool prefer_file_cache = false;
1337 const size_t bytes_read = m_process->GetTarget().ReadMemory(
1338 kext_summary_addr, prefer_file_cache, data.GetBytes(), data.GetByteSize(),
1339 error);
1340 if (bytes_read == count) {
1341
1342 DataExtractor extractor(data.GetBytes(), data.GetByteSize(), endian,
1343 addr_size);
1344 uint32_t i = 0;
1345 for (uint32_t kext_summary_offset = 0;
1346 i < image_infos.size() &&
1347 extractor.ValidOffsetForDataOfSize(kext_summary_offset,
1348 m_kext_summary_header.entry_size);
1349 ++i, kext_summary_offset += m_kext_summary_header.entry_size) {
1350 lldb::offset_t offset = kext_summary_offset;
1351 const void *name_data =
1352 extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
1353 if (name_data == NULL)
1354 break;
1355 image_infos[i].SetName((const char *)name_data);
1356 UUID uuid(extractor.GetData(&offset, 16), 16);
1357 image_infos[i].SetUUID(uuid);
1358 image_infos[i].SetLoadAddress(extractor.GetU64(&offset));
1359 image_infos[i].SetSize(extractor.GetU64(&offset));
1360 }
1361 if (i < image_infos.size())
1362 image_infos.resize(i);
1363 } else {
1364 image_infos.clear();
1365 }
1366 return image_infos.size();
1367}
1368
1369bool DynamicLoaderDarwinKernel::ReadAllKextSummaries() {
1370 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1371
1372 if (ReadKextSummaryHeader()) {
1373 if (m_kext_summary_header.entry_count > 0 &&
1374 m_kext_summary_header_addr.IsValid()) {
1375 Address summary_addr(m_kext_summary_header_addr);
1376 summary_addr.Slide(m_kext_summary_header.GetSize());
1377 if (!ParseKextSummaries(summary_addr,
1378 m_kext_summary_header.entry_count)) {
1379 m_known_kexts.clear();
1380 }
1381 return true;
1382 }
1383 }
1384 return false;
Greg Clayton7b242382011-07-08 00:48:09 +00001385}
1386
1387//----------------------------------------------------------------------
Greg Clayton7b242382011-07-08 00:48:09 +00001388// Dump an image info structure to the file handle provided.
1389//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001390void DynamicLoaderDarwinKernel::KextImageInfo::PutToLog(Log *log) const {
1391 if (log == NULL)
1392 return;
1393 const uint8_t *u = (uint8_t *)m_uuid.GetBytes();
Greg Clayton7b242382011-07-08 00:48:09 +00001394
Kate Stoneb9c1b512016-09-06 20:57:50 +00001395 if (m_load_address == LLDB_INVALID_ADDRESS) {
1396 if (u) {
1397 log->Printf("\tuuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2."
1398 "2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\" (UNLOADED)",
1399 u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7], u[8], u[9],
1400 u[10], u[11], u[12], u[13], u[14], u[15], m_name.c_str());
1401 } else
1402 log->Printf("\tname=\"%s\" (UNLOADED)", m_name.c_str());
1403 } else {
1404 if (u) {
1405 log->Printf("\taddr=0x%16.16" PRIx64 " size=0x%16.16" PRIx64
1406 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-"
1407 "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\"",
1408 m_load_address, m_size, u[0], u[1], u[2], u[3], u[4], u[5],
1409 u[6], u[7], u[8], u[9], u[10], u[11], u[12], u[13], u[14],
1410 u[15], m_name.c_str());
1411 } else {
1412 log->Printf("\t[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") name=\"%s\"",
1413 m_load_address, m_load_address + m_size, m_name.c_str());
Greg Clayton7b242382011-07-08 00:48:09 +00001414 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001415 }
Greg Clayton7b242382011-07-08 00:48:09 +00001416}
1417
1418//----------------------------------------------------------------------
1419// Dump the _dyld_all_image_infos members and all current image infos
1420// that we have parsed to the file handle provided.
1421//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001422void DynamicLoaderDarwinKernel::PutToLog(Log *log) const {
1423 if (log == NULL)
1424 return;
Greg Clayton7b242382011-07-08 00:48:09 +00001425
Kate Stoneb9c1b512016-09-06 20:57:50 +00001426 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1427 log->Printf("gLoadedKextSummaries = 0x%16.16" PRIx64
1428 " { version=%u, entry_size=%u, entry_count=%u }",
1429 m_kext_summary_header_addr.GetFileAddress(),
1430 m_kext_summary_header.version, m_kext_summary_header.entry_size,
1431 m_kext_summary_header.entry_count);
Greg Clayton7b242382011-07-08 00:48:09 +00001432
Kate Stoneb9c1b512016-09-06 20:57:50 +00001433 size_t i;
1434 const size_t count = m_known_kexts.size();
1435 if (count > 0) {
1436 log->PutCString("Loaded:");
1437 for (i = 0; i < count; i++)
1438 m_known_kexts[i].PutToLog(log);
1439 }
Greg Clayton7b242382011-07-08 00:48:09 +00001440}
1441
Kate Stoneb9c1b512016-09-06 20:57:50 +00001442void DynamicLoaderDarwinKernel::PrivateInitialize(Process *process) {
1443 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n",
1444 __FUNCTION__, StateAsCString(m_process->GetState()));
1445 Clear(true);
1446 m_process = process;
Greg Clayton7b242382011-07-08 00:48:09 +00001447}
1448
Kate Stoneb9c1b512016-09-06 20:57:50 +00001449void DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded() {
1450 if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.GetModule()) {
1451 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n",
1452 __FUNCTION__, StateAsCString(m_process->GetState()));
Greg Clayton374972e2011-07-09 17:15:55 +00001453
Kate Stoneb9c1b512016-09-06 20:57:50 +00001454 const bool internal_bp = true;
1455 const bool hardware = false;
1456 const LazyBool skip_prologue = eLazyBoolNo;
1457 FileSpecList module_spec_list;
1458 module_spec_list.Append(m_kernel.GetModule()->GetFileSpec());
1459 Breakpoint *bp =
1460 m_process->GetTarget()
1461 .CreateBreakpoint(&module_spec_list, NULL,
1462 "OSKextLoadedKextSummariesUpdated",
1463 eFunctionNameTypeFull, eLanguageTypeUnknown, 0,
1464 skip_prologue, internal_bp, hardware)
1465 .get();
Greg Clayton374972e2011-07-09 17:15:55 +00001466
Kate Stoneb9c1b512016-09-06 20:57:50 +00001467 bp->SetCallback(DynamicLoaderDarwinKernel::BreakpointHitCallback, this,
1468 true);
1469 m_break_id = bp->GetID();
1470 }
Greg Clayton7b242382011-07-08 00:48:09 +00001471}
1472
1473//----------------------------------------------------------------------
1474// Member function that gets called when the process state changes.
1475//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001476void DynamicLoaderDarwinKernel::PrivateProcessStateChanged(Process *process,
1477 StateType state) {
1478 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__,
1479 StateAsCString(state));
1480 switch (state) {
1481 case eStateConnected:
1482 case eStateAttaching:
1483 case eStateLaunching:
1484 case eStateInvalid:
1485 case eStateUnloaded:
1486 case eStateExited:
1487 case eStateDetached:
1488 Clear(false);
1489 break;
Greg Clayton7b242382011-07-08 00:48:09 +00001490
Kate Stoneb9c1b512016-09-06 20:57:50 +00001491 case eStateStopped:
1492 UpdateIfNeeded();
1493 break;
Greg Clayton7b242382011-07-08 00:48:09 +00001494
Kate Stoneb9c1b512016-09-06 20:57:50 +00001495 case eStateRunning:
1496 case eStateStepping:
1497 case eStateCrashed:
1498 case eStateSuspended:
1499 break;
1500 }
Greg Clayton7b242382011-07-08 00:48:09 +00001501}
1502
1503ThreadPlanSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00001504DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan(Thread &thread,
1505 bool stop_others) {
1506 ThreadPlanSP thread_plan_sp;
1507 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
1508 if (log)
1509 log->Printf("Could not find symbol for step through.");
1510 return thread_plan_sp;
Greg Clayton7b242382011-07-08 00:48:09 +00001511}
1512
Kate Stoneb9c1b512016-09-06 20:57:50 +00001513Error DynamicLoaderDarwinKernel::CanLoadImage() {
1514 Error error;
1515 error.SetErrorString(
1516 "always unsafe to load or unload shared libraries in the darwin kernel");
1517 return error;
Greg Clayton7b242382011-07-08 00:48:09 +00001518}
1519
Kate Stoneb9c1b512016-09-06 20:57:50 +00001520void DynamicLoaderDarwinKernel::Initialize() {
1521 PluginManager::RegisterPlugin(GetPluginNameStatic(),
1522 GetPluginDescriptionStatic(), CreateInstance,
1523 DebuggerInitialize);
Greg Clayton7b242382011-07-08 00:48:09 +00001524}
1525
Kate Stoneb9c1b512016-09-06 20:57:50 +00001526void DynamicLoaderDarwinKernel::Terminate() {
1527 PluginManager::UnregisterPlugin(CreateInstance);
Greg Clayton7b242382011-07-08 00:48:09 +00001528}
1529
Kate Stoneb9c1b512016-09-06 20:57:50 +00001530void DynamicLoaderDarwinKernel::DebuggerInitialize(
1531 lldb_private::Debugger &debugger) {
1532 if (!PluginManager::GetSettingForDynamicLoaderPlugin(
1533 debugger, DynamicLoaderDarwinKernelProperties::GetSettingName())) {
1534 const bool is_global_setting = true;
1535 PluginManager::CreateSettingForDynamicLoaderPlugin(
1536 debugger, GetGlobalProperties()->GetValueProperties(),
1537 ConstString("Properties for the DynamicLoaderDarwinKernel plug-in."),
1538 is_global_setting);
1539 }
Greg Claytone8cd0c92012-10-19 18:02:49 +00001540}
Greg Clayton7b242382011-07-08 00:48:09 +00001541
Kate Stoneb9c1b512016-09-06 20:57:50 +00001542lldb_private::ConstString DynamicLoaderDarwinKernel::GetPluginNameStatic() {
1543 static ConstString g_name("darwin-kernel");
1544 return g_name;
Greg Clayton7b242382011-07-08 00:48:09 +00001545}
1546
Kate Stoneb9c1b512016-09-06 20:57:50 +00001547const char *DynamicLoaderDarwinKernel::GetPluginDescriptionStatic() {
1548 return "Dynamic loader plug-in that watches for shared library loads/unloads "
1549 "in the MacOSX kernel.";
Greg Clayton7b242382011-07-08 00:48:09 +00001550}
1551
Greg Clayton7b242382011-07-08 00:48:09 +00001552//------------------------------------------------------------------
1553// PluginInterface protocol
1554//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001555lldb_private::ConstString DynamicLoaderDarwinKernel::GetPluginName() {
1556 return GetPluginNameStatic();
Greg Clayton7b242382011-07-08 00:48:09 +00001557}
1558
Kate Stoneb9c1b512016-09-06 20:57:50 +00001559uint32_t DynamicLoaderDarwinKernel::GetPluginVersion() { return 1; }
Greg Clayton7b242382011-07-08 00:48:09 +00001560
Greg Clayton1f746072012-08-29 21:13:06 +00001561lldb::ByteOrder
Kate Stoneb9c1b512016-09-06 20:57:50 +00001562DynamicLoaderDarwinKernel::GetByteOrderFromMagic(uint32_t magic) {
1563 switch (magic) {
1564 case llvm::MachO::MH_MAGIC:
1565 case llvm::MachO::MH_MAGIC_64:
1566 return endian::InlHostByteOrder();
Greg Clayton1f746072012-08-29 21:13:06 +00001567
Kate Stoneb9c1b512016-09-06 20:57:50 +00001568 case llvm::MachO::MH_CIGAM:
1569 case llvm::MachO::MH_CIGAM_64:
1570 if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
1571 return lldb::eByteOrderLittle;
1572 else
1573 return lldb::eByteOrderBig;
1574
1575 default:
1576 break;
1577 }
1578 return lldb::eByteOrderInvalid;
1579}