blob: db0d0644f09a497db6c28c133027022a7f62218c [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;
242 addr_t addr = LLDB_INVALID_ADDRESS;
243 addr_t kernel_addresses_64[] = {
244 0xfffffff000004010ULL, // newest arm64 devices
245 0xffffff8000004010ULL, // 2014-2015-ish arm64 devices
246 0xffffff8000002010ULL, // oldest arm64 devices
247 LLDB_INVALID_ADDRESS};
248 addr_t kernel_addresses_32[] = {0xffff0110, LLDB_INVALID_ADDRESS};
249 for (size_t i = 0; kernel_addresses_64[i] != LLDB_INVALID_ADDRESS; i++) {
250 addr = process->ReadUnsignedIntegerFromMemory(
251 kernel_addresses_64[i], 8, LLDB_INVALID_ADDRESS, read_err);
252 if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
253 return addr;
254 }
255 }
256
257 for (size_t i = 0; kernel_addresses_32[i] != LLDB_INVALID_ADDRESS; i++) {
258 addr = process->ReadUnsignedIntegerFromMemory(
259 kernel_addresses_32[i], 4, LLDB_INVALID_ADDRESS, read_err);
260 if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
261 return addr;
262 }
263 }
264
265 return LLDB_INVALID_ADDRESS;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000266}
267
268//----------------------------------------------------------------------
269// If the kernel is currently executing when lldb attaches, and we don't have
270// a better way of finding the kernel's load address, try searching backwards
271// from the current pc value looking for the kernel's Mach header in memory.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000272// Returns the address of the kernel if one was found, else
273// LLDB_INVALID_ADDRESS.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000274//----------------------------------------------------------------------
275lldb::addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000276DynamicLoaderDarwinKernel::SearchForKernelNearPC(Process *process) {
277 if (GetGlobalProperties()->GetScanType() == eKASLRScanNone ||
278 GetGlobalProperties()->GetScanType() == eKASLRScanLowgloAddresses) {
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000279 return LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000280 }
281
282 ThreadSP thread = process->GetThreadList().GetSelectedThread();
283 if (thread.get() == NULL)
284 return LLDB_INVALID_ADDRESS;
285 addr_t pc = thread->GetRegisterContext()->GetPC(LLDB_INVALID_ADDRESS);
286
287 if (pc == LLDB_INVALID_ADDRESS)
288 return LLDB_INVALID_ADDRESS;
289
290 // The kernel will load at at one megabyte boundary (0x100000), or at that
291 // boundary plus
292 // an offset of one page (0x1000) or two, or four (0x4000), depending on the
293 // device.
294
295 // Round the current pc down to the nearest one megabyte boundary - the place
296 // where we will start searching.
297 addr_t addr = pc & ~0xfffff;
298
299 // Search backwards 32 megabytes, looking for the start of the kernel at each
300 // one-megabyte boundary.
301 for (int i = 0; i < 32; i++, addr -= 0x100000) {
302 if (CheckForKernelImageAtAddress(addr, process).IsValid())
303 return addr;
304 if (CheckForKernelImageAtAddress(addr + 0x1000, process).IsValid())
305 return addr + 0x1000;
306 if (CheckForKernelImageAtAddress(addr + 0x2000, process).IsValid())
307 return addr + 0x2000;
308 if (CheckForKernelImageAtAddress(addr + 0x4000, process).IsValid())
309 return addr + 0x4000;
310 }
311
312 return LLDB_INVALID_ADDRESS;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000313}
314
315//----------------------------------------------------------------------
316// Scan through the valid address range for a kernel binary.
317// This is uselessly slow in 64-bit environments so we don't even try it.
318// This scan is not enabled by default even for 32-bit targets.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000319// Returns the address of the kernel if one was found, else
320// LLDB_INVALID_ADDRESS.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000321//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000322lldb::addr_t DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch(
323 Process *process) {
324 if (GetGlobalProperties()->GetScanType() != eKASLRScanExhaustiveScan) {
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000325 return LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000326 }
327
328 addr_t kernel_range_low, kernel_range_high;
329 if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8) {
330 kernel_range_low = 1ULL << 63;
331 kernel_range_high = UINT64_MAX;
332 } else {
333 kernel_range_low = 1ULL << 31;
334 kernel_range_high = UINT32_MAX;
335 }
336
337 // Stepping through memory at one-megabyte resolution looking for a kernel
338 // rarely works (fast enough) with a 64-bit address space -- for now, let's
339 // not even bother. We may be attaching to something which *isn't* a kernel
340 // and we don't want to spin for minutes on-end looking for a kernel.
341 if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
342 return LLDB_INVALID_ADDRESS;
343
344 addr_t addr = kernel_range_low;
345
346 while (addr >= kernel_range_low && addr < kernel_range_high) {
347 if (CheckForKernelImageAtAddress(addr, process).IsValid())
348 return addr;
349 if (CheckForKernelImageAtAddress(addr + 0x1000, process).IsValid())
350 return addr + 0x1000;
351 if (CheckForKernelImageAtAddress(addr + 0x2000, process).IsValid())
352 return addr + 0x2000;
353 if (CheckForKernelImageAtAddress(addr + 0x4000, process).IsValid())
354 return addr + 0x4000;
355 addr += 0x100000;
356 }
357 return LLDB_INVALID_ADDRESS;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000358}
359
360//----------------------------------------------------------------------
361// Given an address in memory, look to see if there is a kernel image at that
Kate Stoneb9c1b512016-09-06 20:57:50 +0000362// address.
363// Returns a UUID; if a kernel was not found at that address, UUID.IsValid()
364// will be false.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000365//----------------------------------------------------------------------
366lldb_private::UUID
Kate Stoneb9c1b512016-09-06 20:57:50 +0000367DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress(lldb::addr_t addr,
368 Process *process) {
369 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
370 if (addr == LLDB_INVALID_ADDRESS)
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000371 return UUID();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000372
373 if (log)
374 log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
375 "looking for kernel binary at 0x%" PRIx64,
376 addr);
377
378 // First try a quick test -- read the first 4 bytes and see if there is a
379 // valid Mach-O magic field there
380 // (the first field of the mach_header/mach_header_64 struct).
381
382 Error read_error;
383 uint64_t result = process->ReadUnsignedIntegerFromMemory(
384 addr, 4, LLDB_INVALID_ADDRESS, read_error);
385 if (result != llvm::MachO::MH_MAGIC_64 && result != llvm::MachO::MH_MAGIC &&
386 result != llvm::MachO::MH_CIGAM && result != llvm::MachO::MH_CIGAM_64) {
387 return UUID();
388 }
389
390 // Read the mach header and see whether it looks like a kernel
391 llvm::MachO::mach_header header;
392 if (process->DoReadMemory(addr, &header, sizeof(header), read_error) !=
393 sizeof(header))
394 return UUID();
395
396 if (header.magic == llvm::MachO::MH_CIGAM ||
397 header.magic == llvm::MachO::MH_CIGAM_64) {
398 header.magic = llvm::ByteSwap_32(header.magic);
399 header.cputype = llvm::ByteSwap_32(header.cputype);
400 header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
401 header.filetype = llvm::ByteSwap_32(header.filetype);
402 header.ncmds = llvm::ByteSwap_32(header.ncmds);
403 header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
404 header.flags = llvm::ByteSwap_32(header.flags);
405 }
406
407 // A kernel is an executable which does not have the dynamic link object flag
408 // set.
409 if (header.filetype == llvm::MachO::MH_EXECUTE &&
410 (header.flags & llvm::MachO::MH_DYLDLINK) == 0) {
411 // Create a full module to get the UUID
412 ModuleSP memory_module_sp = process->ReadModuleFromMemory(
413 FileSpec("temp_mach_kernel", false), addr);
414 if (!memory_module_sp.get())
415 return UUID();
416
417 ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
418 if (exe_objfile == NULL)
419 return UUID();
420
421 if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
422 exe_objfile->GetStrata() == ObjectFile::eStrataKernel) {
423 ArchSpec kernel_arch(eArchTypeMachO, header.cputype, header.cpusubtype);
424 if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(
425 kernel_arch)) {
426 process->GetTarget().SetArchitecture(kernel_arch);
427 }
428 if (log)
429 log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
430 "kernel binary image found at 0x%" PRIx64,
431 addr);
432 return memory_module_sp->GetUUID();
433 }
434 }
435
436 return UUID();
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000437}
438
439//----------------------------------------------------------------------
Greg Clayton7b242382011-07-08 00:48:09 +0000440// Constructor
441//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000442DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel(Process *process,
443 lldb::addr_t kernel_addr)
444 : DynamicLoader(process), m_kernel_load_address(kernel_addr), m_kernel(),
445 m_kext_summary_header_ptr_addr(), m_kext_summary_header_addr(),
446 m_kext_summary_header(), m_known_kexts(), m_mutex(),
447 m_break_id(LLDB_INVALID_BREAK_ID) {
448 Error error;
449 PlatformSP platform_sp(
450 Platform::Create(PlatformDarwinKernel::GetPluginNameStatic(), error));
451 // Only select the darwin-kernel Platform if we've been asked to load kexts.
452 // It can take some time to scan over all of the kext info.plists and that
453 // shouldn't be done if kext loading is explicitly disabled.
454 if (platform_sp.get() && GetGlobalProperties()->GetLoadKexts()) {
455 process->GetTarget().SetPlatform(platform_sp);
456 }
Greg Clayton7b242382011-07-08 00:48:09 +0000457}
458
459//----------------------------------------------------------------------
460// Destructor
461//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000462DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel() { Clear(true); }
Greg Clayton7b242382011-07-08 00:48:09 +0000463
Kate Stoneb9c1b512016-09-06 20:57:50 +0000464void DynamicLoaderDarwinKernel::UpdateIfNeeded() {
465 LoadKernelModuleIfNeeded();
466 SetNotificationBreakpointIfNeeded();
Greg Clayton374972e2011-07-09 17:15:55 +0000467}
Greg Clayton7b242382011-07-08 00:48:09 +0000468//------------------------------------------------------------------
469/// Called after attaching a process.
470///
471/// Allow DynamicLoader plug-ins to execute some code after
472/// attaching to a process.
473//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000474void DynamicLoaderDarwinKernel::DidAttach() {
475 PrivateInitialize(m_process);
476 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000477}
478
479//------------------------------------------------------------------
480/// Called after attaching a process.
481///
482/// Allow DynamicLoader plug-ins to execute some code after
483/// attaching to a process.
484//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000485void DynamicLoaderDarwinKernel::DidLaunch() {
486 PrivateInitialize(m_process);
487 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000488}
489
Greg Clayton7b242382011-07-08 00:48:09 +0000490//----------------------------------------------------------------------
491// Clear out the state of this class.
492//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000493void DynamicLoaderDarwinKernel::Clear(bool clear_process) {
494 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Clayton7b242382011-07-08 00:48:09 +0000495
Kate Stoneb9c1b512016-09-06 20:57:50 +0000496 if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
497 m_process->ClearBreakpointSiteByID(m_break_id);
Greg Clayton7b242382011-07-08 00:48:09 +0000498
Kate Stoneb9c1b512016-09-06 20:57:50 +0000499 if (clear_process)
500 m_process = NULL;
501 m_kernel.Clear();
502 m_known_kexts.clear();
503 m_kext_summary_header_ptr_addr.Clear();
504 m_kext_summary_header_addr.Clear();
505 m_break_id = LLDB_INVALID_BREAK_ID;
Greg Clayton7b242382011-07-08 00:48:09 +0000506}
507
Kate Stoneb9c1b512016-09-06 20:57:50 +0000508bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageAtFileAddress(
509 Process *process) {
510 if (IsLoaded())
511 return true;
Greg Clayton7b242382011-07-08 00:48:09 +0000512
Kate Stoneb9c1b512016-09-06 20:57:50 +0000513 if (m_module_sp) {
514 bool changed = false;
515 if (m_module_sp->SetLoadAddress(process->GetTarget(), 0, true, changed))
516 m_load_process_stop_id = process->GetStopID();
517 }
518 return false;
519}
Greg Clayton2af282a2012-03-21 04:25:00 +0000520
Kate Stoneb9c1b512016-09-06 20:57:50 +0000521void DynamicLoaderDarwinKernel::KextImageInfo::SetModule(ModuleSP module_sp) {
522 m_module_sp = module_sp;
523 if (module_sp.get() && module_sp->GetObjectFile()) {
524 if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable &&
525 module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel) {
526 m_kernel_image = true;
527 } else {
528 m_kernel_image = false;
529 }
530 }
531}
532
533ModuleSP DynamicLoaderDarwinKernel::KextImageInfo::GetModule() {
534 return m_module_sp;
535}
536
537void DynamicLoaderDarwinKernel::KextImageInfo::SetLoadAddress(
538 addr_t load_addr) {
539 m_load_address = load_addr;
540}
541
542addr_t DynamicLoaderDarwinKernel::KextImageInfo::GetLoadAddress() const {
543 return m_load_address;
544}
545
546uint64_t DynamicLoaderDarwinKernel::KextImageInfo::GetSize() const {
547 return m_size;
548}
549
550void DynamicLoaderDarwinKernel::KextImageInfo::SetSize(uint64_t size) {
551 m_size = size;
552}
553
554uint32_t DynamicLoaderDarwinKernel::KextImageInfo::GetProcessStopId() const {
555 return m_load_process_stop_id;
556}
557
558void DynamicLoaderDarwinKernel::KextImageInfo::SetProcessStopId(
559 uint32_t stop_id) {
560 m_load_process_stop_id = stop_id;
561}
562
563bool DynamicLoaderDarwinKernel::KextImageInfo::
564operator==(const KextImageInfo &rhs) {
565 if (m_uuid.IsValid() || rhs.GetUUID().IsValid()) {
566 if (m_uuid == rhs.GetUUID()) {
567 return true;
Greg Clayton2af282a2012-03-21 04:25:00 +0000568 }
569 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000570 }
571
572 if (m_name == rhs.GetName() && m_load_address == rhs.GetLoadAddress())
573 return true;
574
575 return false;
Greg Clayton2af282a2012-03-21 04:25:00 +0000576}
577
Kate Stoneb9c1b512016-09-06 20:57:50 +0000578void DynamicLoaderDarwinKernel::KextImageInfo::SetName(const char *name) {
579 m_name = name;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000580}
581
Kate Stoneb9c1b512016-09-06 20:57:50 +0000582std::string DynamicLoaderDarwinKernel::KextImageInfo::GetName() const {
583 return m_name;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000584}
585
Kate Stoneb9c1b512016-09-06 20:57:50 +0000586void DynamicLoaderDarwinKernel::KextImageInfo::SetUUID(const UUID &uuid) {
587 m_uuid = uuid;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000588}
589
Kate Stoneb9c1b512016-09-06 20:57:50 +0000590UUID DynamicLoaderDarwinKernel::KextImageInfo::GetUUID() const {
591 return m_uuid;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000592}
593
Kate Stoneb9c1b512016-09-06 20:57:50 +0000594// Given the m_load_address from the kext summaries, and a UUID, try to create
595// an in-memory
596// Module at that address. Require that the MemoryModule have a matching UUID
597// and detect
Jason Molenda306bd0a2013-02-19 05:42:46 +0000598// if this MemoryModule is a kernel or a kext.
599//
Kate Stoneb9c1b512016-09-06 20:57:50 +0000600// Returns true if m_memory_module_sp is now set to a valid Module.
Jason Molenda306bd0a2013-02-19 05:42:46 +0000601
Kate Stoneb9c1b512016-09-06 20:57:50 +0000602bool DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule(
603 Process *process) {
604 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
605 if (m_memory_module_sp.get() != NULL)
Jason Molenda306bd0a2013-02-19 05:42:46 +0000606 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000607 if (m_load_address == LLDB_INVALID_ADDRESS)
608 return false;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000609
Kate Stoneb9c1b512016-09-06 20:57:50 +0000610 FileSpec file_spec;
611 file_spec.SetFile(m_name.c_str(), false);
Jason Molenda306bd0a2013-02-19 05:42:46 +0000612
Kate Stoneb9c1b512016-09-06 20:57:50 +0000613 ModuleSP memory_module_sp =
614 process->ReadModuleFromMemory(file_spec, m_load_address);
Jason Molenda306bd0a2013-02-19 05:42:46 +0000615
Kate Stoneb9c1b512016-09-06 20:57:50 +0000616 if (memory_module_sp.get() == NULL)
617 return false;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000618
Kate Stoneb9c1b512016-09-06 20:57:50 +0000619 bool is_kernel = false;
620 if (memory_module_sp->GetObjectFile()) {
621 if (memory_module_sp->GetObjectFile()->GetType() ==
622 ObjectFile::eTypeExecutable &&
623 memory_module_sp->GetObjectFile()->GetStrata() ==
624 ObjectFile::eStrataKernel) {
625 is_kernel = true;
626 } else if (memory_module_sp->GetObjectFile()->GetType() ==
627 ObjectFile::eTypeSharedLibrary) {
628 is_kernel = false;
Jason Molenda87a04b22012-10-19 03:40:45 +0000629 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000630 }
Jason Molenda87a04b22012-10-19 03:40:45 +0000631
Kate Stoneb9c1b512016-09-06 20:57:50 +0000632 // If this is a kext, and the kernel specified what UUID we should find at
633 // this
634 // load address, require that the memory module have a matching UUID or
635 // something
636 // has gone wrong and we should discard it.
637 if (m_uuid.IsValid()) {
638 if (m_uuid != memory_module_sp->GetUUID()) {
639 if (log) {
640 log->Printf("KextImageInfo::ReadMemoryModule the kernel said to find "
641 "uuid %s at 0x%" PRIx64
642 " but instead we found uuid %s, throwing it away",
643 m_uuid.GetAsString().c_str(), m_load_address,
644 memory_module_sp->GetUUID().GetAsString().c_str());
645 }
646 return false;
647 }
648 }
Jason Molenda306bd0a2013-02-19 05:42:46 +0000649
Kate Stoneb9c1b512016-09-06 20:57:50 +0000650 // If the in-memory Module has a UUID, let's use that.
651 if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid()) {
652 m_uuid = memory_module_sp->GetUUID();
653 }
654
655 m_memory_module_sp = memory_module_sp;
656 m_kernel_image = is_kernel;
657 if (is_kernel) {
658 if (log) {
659 // This is unusual and probably not intended
660 log->Printf("KextImageInfo::ReadMemoryModule read the kernel binary out "
661 "of memory");
662 }
663 if (memory_module_sp->GetArchitecture().IsValid()) {
664 process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture());
665 }
666 if (m_uuid.IsValid()) {
667 ModuleSP exe_module_sp = process->GetTarget().GetExecutableModule();
668 if (exe_module_sp.get() && exe_module_sp->GetUUID().IsValid()) {
669 if (m_uuid != exe_module_sp->GetUUID()) {
670 // The user specified a kernel binary that has a different UUID than
671 // the kernel actually running in memory. This never ends well;
672 // clear the user specified kernel binary from the Target.
673
674 m_module_sp.reset();
675
676 ModuleList user_specified_kernel_list;
677 user_specified_kernel_list.Append(exe_module_sp);
678 process->GetTarget().GetImages().Remove(user_specified_kernel_list);
679 }
680 }
681 }
682 }
683
684 return true;
685}
686
687bool DynamicLoaderDarwinKernel::KextImageInfo::IsKernel() const {
688 return m_kernel_image == true;
689}
690
691void DynamicLoaderDarwinKernel::KextImageInfo::SetIsKernel(bool is_kernel) {
692 m_kernel_image = is_kernel;
693}
694
695bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
696 Process *process) {
697 if (IsLoaded())
698 return true;
699
700 Target &target = process->GetTarget();
701
702 // If we don't have / can't create a memory module for this kext, don't try to
703 // load it - we won't
704 // have the correct segment load addresses.
705 if (!ReadMemoryModule(process)) {
706 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
707 if (log)
708 log->Printf("Unable to read '%s' from memory at address 0x%" PRIx64
709 " to get the segment load addresses.",
710 m_name.c_str(), m_load_address);
711 return false;
712 }
713
714 bool uuid_is_valid = m_uuid.IsValid();
715
716 if (IsKernel() && uuid_is_valid && m_memory_module_sp.get()) {
717 Stream *s = target.GetDebugger().GetOutputFile().get();
718 if (s) {
719 s->Printf("Kernel UUID: %s\n",
720 m_memory_module_sp->GetUUID().GetAsString().c_str());
721 s->Printf("Load Address: 0x%" PRIx64 "\n", m_load_address);
722 }
723 }
724
725 if (!m_module_sp) {
726 // See if the kext has already been loaded into the target, probably by the
727 // user doing target modules add.
728 const ModuleList &target_images = target.GetImages();
729 m_module_sp = target_images.FindModule(m_uuid);
730
731 // Search for the kext on the local filesystem via the UUID
732 if (!m_module_sp && uuid_is_valid) {
733 ModuleSpec module_spec;
734 module_spec.GetUUID() = m_uuid;
735 module_spec.GetArchitecture() = target.GetArchitecture();
736
737 // For the kernel, we really do need an on-disk file copy of the binary to
738 // do anything useful.
739 // This will force a clal to
740 if (IsKernel()) {
741 if (Symbols::DownloadObjectAndSymbolFile(module_spec, true)) {
742 if (module_spec.GetFileSpec().Exists()) {
743 m_module_sp.reset(new Module(module_spec.GetFileSpec(),
744 target.GetArchitecture()));
745 if (m_module_sp.get() &&
746 m_module_sp->MatchesModuleSpec(module_spec)) {
747 ModuleList loaded_module_list;
748 loaded_module_list.Append(m_module_sp);
749 target.ModulesDidLoad(loaded_module_list);
750 }
751 }
752 }
753 }
754
755 // If the current platform is PlatformDarwinKernel, create a ModuleSpec
756 // with the filename set
757 // to be the bundle ID for this kext, e.g.
758 // "com.apple.filesystems.msdosfs", and ask the platform
759 // to find it.
760 PlatformSP platform_sp(target.GetPlatform());
761 if (!m_module_sp && platform_sp) {
762 ConstString platform_name(platform_sp->GetPluginName());
763 static ConstString g_platform_name(
764 PlatformDarwinKernel::GetPluginNameStatic());
765 if (platform_name == g_platform_name) {
766 ModuleSpec kext_bundle_module_spec(module_spec);
767 FileSpec kext_filespec(m_name.c_str(), false);
768 kext_bundle_module_spec.GetFileSpec() = kext_filespec;
769 platform_sp->GetSharedModule(
770 kext_bundle_module_spec, process, m_module_sp,
771 &target.GetExecutableSearchPaths(), NULL, NULL);
772 }
773 }
774
775 // Ask the Target to find this file on the local system, if possible.
776 // This will search in the list of currently-loaded files, look in the
777 // standard search paths on the system, and on a Mac it will try calling
778 // the DebugSymbols framework with the UUID to find the binary via its
779 // search methods.
780 if (!m_module_sp) {
781 m_module_sp = target.GetSharedModule(module_spec);
782 }
783
784 if (IsKernel() && !m_module_sp) {
Greg Clayton44d93782014-01-27 23:43:24 +0000785 Stream *s = target.GetDebugger().GetOutputFile().get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000786 if (s) {
787 s->Printf("WARNING: Unable to locate kernel binary on the debugger "
788 "system.\n");
Jason Molendae575e7b2013-02-19 06:11:13 +0000789 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000790 }
Jason Molendae575e7b2013-02-19 06:11:13 +0000791 }
792
Kate Stoneb9c1b512016-09-06 20:57:50 +0000793 // If we managed to find a module, append it to the target's list of images.
794 // If we also have a memory module, require that they have matching UUIDs
795 if (m_module_sp) {
796 bool uuid_match_ok = true;
797 if (m_memory_module_sp) {
798 if (m_module_sp->GetUUID() != m_memory_module_sp->GetUUID()) {
799 uuid_match_ok = false;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000800 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000801 }
802 if (uuid_match_ok) {
803 target.GetImages().AppendIfNeeded(m_module_sp);
804 if (IsKernel() &&
805 target.GetExecutableModulePointer() != m_module_sp.get()) {
806 target.SetExecutableModule(m_module_sp, false);
Greg Claytonc859e2d2012-02-13 23:10:39 +0000807 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000808 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000809 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000810 }
811
812 if (!m_module_sp && !IsKernel() && m_uuid.IsValid() && !m_name.empty()) {
813 Stream *s = target.GetDebugger().GetOutputFile().get();
814 if (s) {
815 s->Printf("warning: Can't find binary/dSYM for %s (%s)\n", m_name.c_str(),
816 m_uuid.GetAsString().c_str());
Jason Molenda56c23282013-02-19 06:39:56 +0000817 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000818 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000819
Kate Stoneb9c1b512016-09-06 20:57:50 +0000820 static ConstString g_section_name_LINKEDIT("__LINKEDIT");
Greg Clayton67408532012-12-11 01:20:51 +0000821
Kate Stoneb9c1b512016-09-06 20:57:50 +0000822 if (m_memory_module_sp && m_module_sp) {
823 if (m_module_sp->GetUUID() == m_memory_module_sp->GetUUID()) {
824 ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();
825 ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile();
Jason Molendabb860bd2012-10-09 01:17:11 +0000826
Kate Stoneb9c1b512016-09-06 20:57:50 +0000827 if (memory_object_file && ondisk_object_file) {
828 // The memory_module for kexts may have an invalid __LINKEDIT seg; skip
829 // it.
830 const bool ignore_linkedit = !IsKernel();
Greg Clayton67408532012-12-11 01:20:51 +0000831
Kate Stoneb9c1b512016-09-06 20:57:50 +0000832 SectionList *ondisk_section_list = ondisk_object_file->GetSectionList();
833 SectionList *memory_section_list = memory_object_file->GetSectionList();
834 if (memory_section_list && ondisk_section_list) {
835 const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
836 // There may be CTF sections in the memory image so we can't
837 // always just compare the number of sections (which are actually
838 // segments in mach-o parlance)
839 uint32_t sect_idx = 0;
840
841 // Use the memory_module's addresses for each section to set the
842 // file module's load address as appropriate. We don't want to use
843 // a single slide value for the entire kext - different segments may
844 // be slid different amounts by the kext loader.
845
846 uint32_t num_sections_loaded = 0;
847 for (sect_idx = 0; sect_idx < num_ondisk_sections; ++sect_idx) {
848 SectionSP ondisk_section_sp(
849 ondisk_section_list->GetSectionAtIndex(sect_idx));
850 if (ondisk_section_sp) {
851 // Don't ever load __LINKEDIT as it may or may not be actually
852 // mapped into memory and there is no current way to tell.
853 // I filed rdar://problem/12851706 to track being able to tell
854 // if the __LINKEDIT is actually mapped, but until then, we need
855 // to not load the __LINKEDIT
856 if (ignore_linkedit &&
857 ondisk_section_sp->GetName() == g_section_name_LINKEDIT)
858 continue;
859
860 const Section *memory_section =
861 memory_section_list
862 ->FindSectionByName(ondisk_section_sp->GetName())
863 .get();
864 if (memory_section) {
865 target.SetSectionLoadAddress(ondisk_section_sp,
866 memory_section->GetFileAddress());
867 ++num_sections_loaded;
868 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000869 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000870 }
871 if (num_sections_loaded > 0)
872 m_load_process_stop_id = process->GetStopID();
873 else
874 m_module_sp.reset(); // No sections were loaded
875 } else
876 m_module_sp.reset(); // One or both section lists
877 } else
878 m_module_sp.reset(); // One or both object files missing
879 } else
880 m_module_sp.reset(); // UUID mismatch
881 }
882
883 bool is_loaded = IsLoaded();
884
885 if (is_loaded && m_module_sp && IsKernel()) {
886 Stream *s = target.GetDebugger().GetOutputFile().get();
887 if (s) {
888 ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
889 if (kernel_object_file) {
890 addr_t file_address =
891 kernel_object_file->GetHeaderAddress().GetFileAddress();
892 if (m_load_address != LLDB_INVALID_ADDRESS &&
893 file_address != LLDB_INVALID_ADDRESS) {
894 s->Printf("Kernel slid 0x%" PRIx64 " in memory.\n",
895 m_load_address - file_address);
Greg Claytonc859e2d2012-02-13 23:10:39 +0000896 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000897 }
898 {
899 s->Printf("Loaded kernel file %s\n",
900 m_module_sp->GetFileSpec().GetPath().c_str());
901 }
902 s->Flush();
Greg Claytonc859e2d2012-02-13 23:10:39 +0000903 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000904 }
905 return is_loaded;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000906}
907
Kate Stoneb9c1b512016-09-06 20:57:50 +0000908uint32_t DynamicLoaderDarwinKernel::KextImageInfo::GetAddressByteSize() {
909 if (m_memory_module_sp)
910 return m_memory_module_sp->GetArchitecture().GetAddressByteSize();
911 if (m_module_sp)
912 return m_module_sp->GetArchitecture().GetAddressByteSize();
913 return 0;
Greg Clayton1f746072012-08-29 21:13:06 +0000914}
915
Kate Stoneb9c1b512016-09-06 20:57:50 +0000916lldb::ByteOrder DynamicLoaderDarwinKernel::KextImageInfo::GetByteOrder() {
917 if (m_memory_module_sp)
918 return m_memory_module_sp->GetArchitecture().GetByteOrder();
919 if (m_module_sp)
920 return m_module_sp->GetArchitecture().GetByteOrder();
921 return endian::InlHostByteOrder();
Greg Clayton1f746072012-08-29 21:13:06 +0000922}
923
924lldb_private::ArchSpec
Kate Stoneb9c1b512016-09-06 20:57:50 +0000925DynamicLoaderDarwinKernel::KextImageInfo::GetArchitecture() const {
926 if (m_memory_module_sp)
927 return m_memory_module_sp->GetArchitecture();
928 if (m_module_sp)
929 return m_module_sp->GetArchitecture();
930 return lldb_private::ArchSpec();
Greg Clayton1f746072012-08-29 21:13:06 +0000931}
932
Greg Clayton7b242382011-07-08 00:48:09 +0000933//----------------------------------------------------------------------
934// Load the kernel module and initialize the "m_kernel" member. Return
935// true _only_ if the kernel is loaded the first time through (subsequent
936// calls to this function should return false after the kernel has been
937// already loaded).
938//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000939void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
940 if (!m_kext_summary_header_ptr_addr.IsValid()) {
941 m_kernel.Clear();
942 m_kernel.SetModule(m_process->GetTarget().GetExecutableModule());
943 m_kernel.SetIsKernel(true);
Jason Molenda4bd4e7e2012-09-29 04:02:01 +0000944
Kate Stoneb9c1b512016-09-06 20:57:50 +0000945 ConstString kernel_name("mach_kernel");
946 if (m_kernel.GetModule().get() && m_kernel.GetModule()->GetObjectFile() &&
947 !m_kernel.GetModule()
948 ->GetObjectFile()
949 ->GetFileSpec()
950 .GetFilename()
951 .IsEmpty()) {
952 kernel_name =
953 m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename();
Greg Clayton7b242382011-07-08 00:48:09 +0000954 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000955 m_kernel.SetName(kernel_name.AsCString());
956
957 if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS) {
958 m_kernel.SetLoadAddress(m_kernel_load_address);
959 if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS &&
960 m_kernel.GetModule()) {
961 // We didn't get a hint from the process, so we will
962 // try the kernel at the address that it exists at in
963 // the file if we have one
964 ObjectFile *kernel_object_file = m_kernel.GetModule()->GetObjectFile();
965 if (kernel_object_file) {
966 addr_t load_address =
967 kernel_object_file->GetHeaderAddress().GetLoadAddress(
968 &m_process->GetTarget());
969 addr_t file_address =
970 kernel_object_file->GetHeaderAddress().GetFileAddress();
971 if (load_address != LLDB_INVALID_ADDRESS && load_address != 0) {
972 m_kernel.SetLoadAddress(load_address);
973 if (load_address != file_address) {
974 // Don't accidentally relocate the kernel to the File address --
975 // the Load address has already been set to its actual in-memory
976 // address.
977 // Mark it as IsLoaded.
978 m_kernel.SetProcessStopId(m_process->GetStopID());
979 }
980 } else {
981 m_kernel.SetLoadAddress(file_address);
982 }
983 }
984 }
985 }
986
987 if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS) {
988 if (!m_kernel.LoadImageUsingMemoryModule(m_process)) {
989 m_kernel.LoadImageAtFileAddress(m_process);
990 }
991 }
992
993 if (m_kernel.IsLoaded() && m_kernel.GetModule()) {
994 static ConstString kext_summary_symbol("gLoadedKextSummaries");
995 const Symbol *symbol =
996 m_kernel.GetModule()->FindFirstSymbolWithNameAndType(
997 kext_summary_symbol, eSymbolTypeData);
998 if (symbol) {
999 m_kext_summary_header_ptr_addr = symbol->GetAddress();
1000 // Update all image infos
1001 ReadAllKextSummaries();
1002 }
1003 } else {
1004 m_kernel.Clear();
1005 }
1006 }
Greg Clayton7b242382011-07-08 00:48:09 +00001007}
1008
Greg Clayton7b242382011-07-08 00:48:09 +00001009//----------------------------------------------------------------------
1010// Static callback function that gets called when our DYLD notification
1011// breakpoint gets hit. We update all of our image infos and then
1012// let our super class DynamicLoader class decide if we should stop
1013// or not (based on global preference).
1014//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001015bool DynamicLoaderDarwinKernel::BreakpointHitCallback(
1016 void *baton, StoppointCallbackContext *context, user_id_t break_id,
1017 user_id_t break_loc_id) {
1018 return static_cast<DynamicLoaderDarwinKernel *>(baton)->BreakpointHit(
1019 context, break_id, break_loc_id);
Greg Clayton7b242382011-07-08 00:48:09 +00001020}
1021
Kate Stoneb9c1b512016-09-06 20:57:50 +00001022bool DynamicLoaderDarwinKernel::BreakpointHit(StoppointCallbackContext *context,
1023 user_id_t break_id,
1024 user_id_t break_loc_id) {
1025 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
1026 if (log)
1027 log->Printf("DynamicLoaderDarwinKernel::BreakpointHit (...)\n");
Greg Claytond16e1e52011-07-12 17:06:17 +00001028
Kate Stoneb9c1b512016-09-06 20:57:50 +00001029 ReadAllKextSummaries();
Greg Claytond16e1e52011-07-12 17:06:17 +00001030
Kate Stoneb9c1b512016-09-06 20:57:50 +00001031 if (log)
1032 PutToLog(log);
1033
1034 return GetStopWhenImagesChange();
Greg Clayton374972e2011-07-09 17:15:55 +00001035}
1036
Kate Stoneb9c1b512016-09-06 20:57:50 +00001037bool DynamicLoaderDarwinKernel::ReadKextSummaryHeader() {
1038 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Clayton374972e2011-07-09 17:15:55 +00001039
Kate Stoneb9c1b512016-09-06 20:57:50 +00001040 // the all image infos is already valid for this process stop ID
Greg Clayton7b242382011-07-08 00:48:09 +00001041
Kate Stoneb9c1b512016-09-06 20:57:50 +00001042 if (m_kext_summary_header_ptr_addr.IsValid()) {
1043 const uint32_t addr_size = m_kernel.GetAddressByteSize();
1044 const ByteOrder byte_order = m_kernel.GetByteOrder();
1045 Error error;
1046 // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure
1047 // which is currently 4 uint32_t and a pointer.
1048 uint8_t buf[24];
1049 DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
1050 const size_t count = 4 * sizeof(uint32_t) + addr_size;
1051 const bool prefer_file_cache = false;
1052 if (m_process->GetTarget().ReadPointerFromMemory(
1053 m_kext_summary_header_ptr_addr, prefer_file_cache, error,
1054 m_kext_summary_header_addr)) {
1055 // We got a valid address for our kext summary header and make sure it
1056 // isn't NULL
1057 if (m_kext_summary_header_addr.IsValid() &&
1058 m_kext_summary_header_addr.GetFileAddress() != 0) {
1059 const size_t bytes_read = m_process->GetTarget().ReadMemory(
1060 m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
1061 if (bytes_read == count) {
1062 lldb::offset_t offset = 0;
1063 m_kext_summary_header.version = data.GetU32(&offset);
1064 if (m_kext_summary_header.version > 128) {
1065 Stream *s =
1066 m_process->GetTarget().GetDebugger().GetOutputFile().get();
1067 s->Printf("WARNING: Unable to read kext summary header, got "
1068 "improbable version number %u\n",
1069 m_kext_summary_header.version);
1070 // If we get an improbably large version number, we're probably
1071 // getting bad memory.
1072 m_kext_summary_header_addr.Clear();
1073 return false;
1074 }
1075 if (m_kext_summary_header.version >= 2) {
1076 m_kext_summary_header.entry_size = data.GetU32(&offset);
1077 if (m_kext_summary_header.entry_size > 4096) {
1078 // If we get an improbably large entry_size, we're probably
1079 // getting bad memory.
1080 Stream *s =
1081 m_process->GetTarget().GetDebugger().GetOutputFile().get();
1082 s->Printf("WARNING: Unable to read kext summary header, got "
1083 "improbable entry_size %u\n",
1084 m_kext_summary_header.entry_size);
1085 m_kext_summary_header_addr.Clear();
1086 return false;
Greg Claytond16e1e52011-07-12 17:06:17 +00001087 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001088 } else {
1089 // Versions less than 2 didn't have an entry size, it was hard coded
1090 m_kext_summary_header.entry_size =
1091 KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
1092 }
1093 m_kext_summary_header.entry_count = data.GetU32(&offset);
1094 if (m_kext_summary_header.entry_count > 10000) {
1095 // If we get an improbably large number of kexts, we're probably
1096 // getting bad memory.
1097 Stream *s =
1098 m_process->GetTarget().GetDebugger().GetOutputFile().get();
1099 s->Printf("WARNING: Unable to read kext summary header, got "
1100 "improbable number of kexts %u\n",
1101 m_kext_summary_header.entry_count);
1102 m_kext_summary_header_addr.Clear();
1103 return false;
1104 }
1105 return true;
Greg Clayton7b242382011-07-08 00:48:09 +00001106 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001107 }
Greg Clayton7b242382011-07-08 00:48:09 +00001108 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001109 }
1110 m_kext_summary_header_addr.Clear();
1111 return false;
Greg Clayton7b242382011-07-08 00:48:09 +00001112}
1113
Kate Stoneb9c1b512016-09-06 20:57:50 +00001114// We've either (a) just attached to a new kernel, or (b) the kexts-changed
1115// breakpoint was hit
Jason Molenda306bd0a2013-02-19 05:42:46 +00001116// and we need to figure out what kexts have been added or removed.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001117// Read the kext summaries from the inferior kernel memory, compare them against
1118// the
1119// m_known_kexts vector and update the m_known_kexts vector as needed to keep in
1120// sync with the
Jason Molenda306bd0a2013-02-19 05:42:46 +00001121// inferior.
Greg Clayton7b242382011-07-08 00:48:09 +00001122
Kate Stoneb9c1b512016-09-06 20:57:50 +00001123bool DynamicLoaderDarwinKernel::ParseKextSummaries(
1124 const Address &kext_summary_addr, uint32_t count) {
1125 KextImageInfo::collection kext_summaries;
1126 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
1127 if (log)
1128 log->Printf("Kexts-changed breakpoint hit, there are %d kexts currently.\n",
1129 count);
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001130
Kate Stoneb9c1b512016-09-06 20:57:50 +00001131 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Clayton7b242382011-07-08 00:48:09 +00001132
Kate Stoneb9c1b512016-09-06 20:57:50 +00001133 if (!ReadKextSummaries(kext_summary_addr, count, kext_summaries))
Greg Clayton7b242382011-07-08 00:48:09 +00001134 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001135
1136 // read the plugin.dynamic-loader.darwin-kernel.load-kexts setting -- if the
1137 // user requested no
1138 // kext loading, don't print any messages about kexts & don't try to read
1139 // them.
1140 const bool load_kexts = GetGlobalProperties()->GetLoadKexts();
1141
1142 // By default, all kexts we've loaded in the past are marked as "remove" and
1143 // all of the kexts
1144 // we just found out about from ReadKextSummaries are marked as "add".
1145 std::vector<bool> to_be_removed(m_known_kexts.size(), true);
1146 std::vector<bool> to_be_added(count, true);
1147
1148 int number_of_new_kexts_being_added = 0;
1149 int number_of_old_kexts_being_removed = m_known_kexts.size();
1150
1151 const uint32_t new_kexts_size = kext_summaries.size();
1152 const uint32_t old_kexts_size = m_known_kexts.size();
1153
1154 // The m_known_kexts vector may have entries that have been Cleared,
1155 // or are a kernel.
1156 for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++) {
1157 bool ignore = false;
1158 KextImageInfo &image_info = m_known_kexts[old_kext];
1159 if (image_info.IsKernel()) {
1160 ignore = true;
1161 } else if (image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS &&
1162 !image_info.GetModule()) {
1163 ignore = true;
1164 }
1165
1166 if (ignore) {
1167 number_of_old_kexts_being_removed--;
1168 to_be_removed[old_kext] = false;
1169 }
1170 }
1171
1172 // Scan over the list of kexts we just read from the kernel, note those that
1173 // need to be added and those already loaded.
1174 for (uint32_t new_kext = 0; new_kext < new_kexts_size; new_kext++) {
1175 bool add_this_one = true;
1176 for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++) {
1177 if (m_known_kexts[old_kext] == kext_summaries[new_kext]) {
1178 // We already have this kext, don't re-load it.
1179 to_be_added[new_kext] = false;
1180 // This kext is still present, do not remove it.
1181 to_be_removed[old_kext] = false;
1182
1183 number_of_old_kexts_being_removed--;
1184 add_this_one = false;
1185 break;
1186 }
1187 }
1188 if (add_this_one) {
1189 number_of_new_kexts_being_added++;
1190 }
1191 }
1192
1193 if (number_of_new_kexts_being_added == 0 &&
1194 number_of_old_kexts_being_removed == 0)
1195 return true;
1196
1197 Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
1198 if (s && load_kexts) {
1199 if (number_of_new_kexts_being_added > 0 &&
1200 number_of_old_kexts_being_removed > 0) {
1201 s->Printf("Loading %d kext modules and unloading %d kext modules ",
1202 number_of_new_kexts_being_added,
1203 number_of_old_kexts_being_removed);
1204 } else if (number_of_new_kexts_being_added > 0) {
1205 s->Printf("Loading %d kext modules ", number_of_new_kexts_being_added);
1206 } else if (number_of_old_kexts_being_removed > 0) {
1207 s->Printf("Unloading %d kext modules ",
1208 number_of_old_kexts_being_removed);
1209 }
1210 }
1211
1212 if (log) {
1213 if (load_kexts) {
1214 log->Printf("DynamicLoaderDarwinKernel::ParseKextSummaries: %d kexts "
1215 "added, %d kexts removed",
1216 number_of_new_kexts_being_added,
1217 number_of_old_kexts_being_removed);
1218 } else {
1219 log->Printf(
1220 "DynamicLoaderDarwinKernel::ParseKextSummaries kext loading is "
1221 "disabled, else would have %d kexts added, %d kexts removed",
1222 number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
1223 }
1224 }
1225
1226 if (number_of_new_kexts_being_added > 0) {
1227 ModuleList loaded_module_list;
1228
1229 const uint32_t num_of_new_kexts = kext_summaries.size();
1230 for (uint32_t new_kext = 0; new_kext < num_of_new_kexts; new_kext++) {
1231 if (to_be_added[new_kext] == true) {
1232 KextImageInfo &image_info = kext_summaries[new_kext];
1233 if (load_kexts) {
1234 if (!image_info.LoadImageUsingMemoryModule(m_process)) {
1235 image_info.LoadImageAtFileAddress(m_process);
1236 }
1237 }
1238
1239 m_known_kexts.push_back(image_info);
1240
1241 if (image_info.GetModule() &&
1242 m_process->GetStopID() == image_info.GetProcessStopId())
1243 loaded_module_list.AppendIfNeeded(image_info.GetModule());
1244
1245 if (s && load_kexts)
1246 s->Printf(".");
1247
1248 if (log)
1249 kext_summaries[new_kext].PutToLog(log);
1250 }
1251 }
1252 m_process->GetTarget().ModulesDidLoad(loaded_module_list);
1253 }
1254
1255 if (number_of_old_kexts_being_removed > 0) {
1256 ModuleList loaded_module_list;
1257 const uint32_t num_of_old_kexts = m_known_kexts.size();
1258 for (uint32_t old_kext = 0; old_kext < num_of_old_kexts; old_kext++) {
1259 ModuleList unloaded_module_list;
1260 if (to_be_removed[old_kext]) {
1261 KextImageInfo &image_info = m_known_kexts[old_kext];
1262 // You can't unload the kernel.
1263 if (!image_info.IsKernel()) {
1264 if (image_info.GetModule()) {
1265 unloaded_module_list.AppendIfNeeded(image_info.GetModule());
1266 }
1267 if (s)
1268 s->Printf(".");
1269 image_info.Clear();
1270 // should pull it out of the KextImageInfos vector but that would
1271 // mutate the list and invalidate
1272 // the to_be_removed bool vector; leaving it in place once Cleared()
1273 // is relatively harmless.
1274 }
1275 }
1276 m_process->GetTarget().ModulesDidUnload(unloaded_module_list, false);
1277 }
1278 }
1279
1280 if (s && load_kexts) {
1281 s->Printf(" done.\n");
1282 s->Flush();
1283 }
1284
1285 return true;
1286}
1287
1288uint32_t DynamicLoaderDarwinKernel::ReadKextSummaries(
1289 const Address &kext_summary_addr, uint32_t image_infos_count,
1290 KextImageInfo::collection &image_infos) {
1291 const ByteOrder endian = m_kernel.GetByteOrder();
1292 const uint32_t addr_size = m_kernel.GetAddressByteSize();
1293
1294 image_infos.resize(image_infos_count);
1295 const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
1296 DataBufferHeap data(count, 0);
1297 Error error;
1298
1299 const bool prefer_file_cache = false;
1300 const size_t bytes_read = m_process->GetTarget().ReadMemory(
1301 kext_summary_addr, prefer_file_cache, data.GetBytes(), data.GetByteSize(),
1302 error);
1303 if (bytes_read == count) {
1304
1305 DataExtractor extractor(data.GetBytes(), data.GetByteSize(), endian,
1306 addr_size);
1307 uint32_t i = 0;
1308 for (uint32_t kext_summary_offset = 0;
1309 i < image_infos.size() &&
1310 extractor.ValidOffsetForDataOfSize(kext_summary_offset,
1311 m_kext_summary_header.entry_size);
1312 ++i, kext_summary_offset += m_kext_summary_header.entry_size) {
1313 lldb::offset_t offset = kext_summary_offset;
1314 const void *name_data =
1315 extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
1316 if (name_data == NULL)
1317 break;
1318 image_infos[i].SetName((const char *)name_data);
1319 UUID uuid(extractor.GetData(&offset, 16), 16);
1320 image_infos[i].SetUUID(uuid);
1321 image_infos[i].SetLoadAddress(extractor.GetU64(&offset));
1322 image_infos[i].SetSize(extractor.GetU64(&offset));
1323 }
1324 if (i < image_infos.size())
1325 image_infos.resize(i);
1326 } else {
1327 image_infos.clear();
1328 }
1329 return image_infos.size();
1330}
1331
1332bool DynamicLoaderDarwinKernel::ReadAllKextSummaries() {
1333 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1334
1335 if (ReadKextSummaryHeader()) {
1336 if (m_kext_summary_header.entry_count > 0 &&
1337 m_kext_summary_header_addr.IsValid()) {
1338 Address summary_addr(m_kext_summary_header_addr);
1339 summary_addr.Slide(m_kext_summary_header.GetSize());
1340 if (!ParseKextSummaries(summary_addr,
1341 m_kext_summary_header.entry_count)) {
1342 m_known_kexts.clear();
1343 }
1344 return true;
1345 }
1346 }
1347 return false;
Greg Clayton7b242382011-07-08 00:48:09 +00001348}
1349
1350//----------------------------------------------------------------------
Greg Clayton7b242382011-07-08 00:48:09 +00001351// Dump an image info structure to the file handle provided.
1352//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001353void DynamicLoaderDarwinKernel::KextImageInfo::PutToLog(Log *log) const {
1354 if (log == NULL)
1355 return;
1356 const uint8_t *u = (uint8_t *)m_uuid.GetBytes();
Greg Clayton7b242382011-07-08 00:48:09 +00001357
Kate Stoneb9c1b512016-09-06 20:57:50 +00001358 if (m_load_address == LLDB_INVALID_ADDRESS) {
1359 if (u) {
1360 log->Printf("\tuuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2."
1361 "2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\" (UNLOADED)",
1362 u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7], u[8], u[9],
1363 u[10], u[11], u[12], u[13], u[14], u[15], m_name.c_str());
1364 } else
1365 log->Printf("\tname=\"%s\" (UNLOADED)", m_name.c_str());
1366 } else {
1367 if (u) {
1368 log->Printf("\taddr=0x%16.16" PRIx64 " size=0x%16.16" PRIx64
1369 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-"
1370 "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\"",
1371 m_load_address, m_size, u[0], u[1], u[2], u[3], u[4], u[5],
1372 u[6], u[7], u[8], u[9], u[10], u[11], u[12], u[13], u[14],
1373 u[15], m_name.c_str());
1374 } else {
1375 log->Printf("\t[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") name=\"%s\"",
1376 m_load_address, m_load_address + m_size, m_name.c_str());
Greg Clayton7b242382011-07-08 00:48:09 +00001377 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001378 }
Greg Clayton7b242382011-07-08 00:48:09 +00001379}
1380
1381//----------------------------------------------------------------------
1382// Dump the _dyld_all_image_infos members and all current image infos
1383// that we have parsed to the file handle provided.
1384//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001385void DynamicLoaderDarwinKernel::PutToLog(Log *log) const {
1386 if (log == NULL)
1387 return;
Greg Clayton7b242382011-07-08 00:48:09 +00001388
Kate Stoneb9c1b512016-09-06 20:57:50 +00001389 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1390 log->Printf("gLoadedKextSummaries = 0x%16.16" PRIx64
1391 " { version=%u, entry_size=%u, entry_count=%u }",
1392 m_kext_summary_header_addr.GetFileAddress(),
1393 m_kext_summary_header.version, m_kext_summary_header.entry_size,
1394 m_kext_summary_header.entry_count);
Greg Clayton7b242382011-07-08 00:48:09 +00001395
Kate Stoneb9c1b512016-09-06 20:57:50 +00001396 size_t i;
1397 const size_t count = m_known_kexts.size();
1398 if (count > 0) {
1399 log->PutCString("Loaded:");
1400 for (i = 0; i < count; i++)
1401 m_known_kexts[i].PutToLog(log);
1402 }
Greg Clayton7b242382011-07-08 00:48:09 +00001403}
1404
Kate Stoneb9c1b512016-09-06 20:57:50 +00001405void DynamicLoaderDarwinKernel::PrivateInitialize(Process *process) {
1406 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n",
1407 __FUNCTION__, StateAsCString(m_process->GetState()));
1408 Clear(true);
1409 m_process = process;
Greg Clayton7b242382011-07-08 00:48:09 +00001410}
1411
Kate Stoneb9c1b512016-09-06 20:57:50 +00001412void DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded() {
1413 if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.GetModule()) {
1414 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n",
1415 __FUNCTION__, StateAsCString(m_process->GetState()));
Greg Clayton374972e2011-07-09 17:15:55 +00001416
Kate Stoneb9c1b512016-09-06 20:57:50 +00001417 const bool internal_bp = true;
1418 const bool hardware = false;
1419 const LazyBool skip_prologue = eLazyBoolNo;
1420 FileSpecList module_spec_list;
1421 module_spec_list.Append(m_kernel.GetModule()->GetFileSpec());
1422 Breakpoint *bp =
1423 m_process->GetTarget()
1424 .CreateBreakpoint(&module_spec_list, NULL,
1425 "OSKextLoadedKextSummariesUpdated",
1426 eFunctionNameTypeFull, eLanguageTypeUnknown, 0,
1427 skip_prologue, internal_bp, hardware)
1428 .get();
Greg Clayton374972e2011-07-09 17:15:55 +00001429
Kate Stoneb9c1b512016-09-06 20:57:50 +00001430 bp->SetCallback(DynamicLoaderDarwinKernel::BreakpointHitCallback, this,
1431 true);
1432 m_break_id = bp->GetID();
1433 }
Greg Clayton7b242382011-07-08 00:48:09 +00001434}
1435
1436//----------------------------------------------------------------------
1437// Member function that gets called when the process state changes.
1438//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001439void DynamicLoaderDarwinKernel::PrivateProcessStateChanged(Process *process,
1440 StateType state) {
1441 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__,
1442 StateAsCString(state));
1443 switch (state) {
1444 case eStateConnected:
1445 case eStateAttaching:
1446 case eStateLaunching:
1447 case eStateInvalid:
1448 case eStateUnloaded:
1449 case eStateExited:
1450 case eStateDetached:
1451 Clear(false);
1452 break;
Greg Clayton7b242382011-07-08 00:48:09 +00001453
Kate Stoneb9c1b512016-09-06 20:57:50 +00001454 case eStateStopped:
1455 UpdateIfNeeded();
1456 break;
Greg Clayton7b242382011-07-08 00:48:09 +00001457
Kate Stoneb9c1b512016-09-06 20:57:50 +00001458 case eStateRunning:
1459 case eStateStepping:
1460 case eStateCrashed:
1461 case eStateSuspended:
1462 break;
1463 }
Greg Clayton7b242382011-07-08 00:48:09 +00001464}
1465
1466ThreadPlanSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00001467DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan(Thread &thread,
1468 bool stop_others) {
1469 ThreadPlanSP thread_plan_sp;
1470 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
1471 if (log)
1472 log->Printf("Could not find symbol for step through.");
1473 return thread_plan_sp;
Greg Clayton7b242382011-07-08 00:48:09 +00001474}
1475
Kate Stoneb9c1b512016-09-06 20:57:50 +00001476Error DynamicLoaderDarwinKernel::CanLoadImage() {
1477 Error error;
1478 error.SetErrorString(
1479 "always unsafe to load or unload shared libraries in the darwin kernel");
1480 return error;
Greg Clayton7b242382011-07-08 00:48:09 +00001481}
1482
Kate Stoneb9c1b512016-09-06 20:57:50 +00001483void DynamicLoaderDarwinKernel::Initialize() {
1484 PluginManager::RegisterPlugin(GetPluginNameStatic(),
1485 GetPluginDescriptionStatic(), CreateInstance,
1486 DebuggerInitialize);
Greg Clayton7b242382011-07-08 00:48:09 +00001487}
1488
Kate Stoneb9c1b512016-09-06 20:57:50 +00001489void DynamicLoaderDarwinKernel::Terminate() {
1490 PluginManager::UnregisterPlugin(CreateInstance);
Greg Clayton7b242382011-07-08 00:48:09 +00001491}
1492
Kate Stoneb9c1b512016-09-06 20:57:50 +00001493void DynamicLoaderDarwinKernel::DebuggerInitialize(
1494 lldb_private::Debugger &debugger) {
1495 if (!PluginManager::GetSettingForDynamicLoaderPlugin(
1496 debugger, DynamicLoaderDarwinKernelProperties::GetSettingName())) {
1497 const bool is_global_setting = true;
1498 PluginManager::CreateSettingForDynamicLoaderPlugin(
1499 debugger, GetGlobalProperties()->GetValueProperties(),
1500 ConstString("Properties for the DynamicLoaderDarwinKernel plug-in."),
1501 is_global_setting);
1502 }
Greg Claytone8cd0c92012-10-19 18:02:49 +00001503}
Greg Clayton7b242382011-07-08 00:48:09 +00001504
Kate Stoneb9c1b512016-09-06 20:57:50 +00001505lldb_private::ConstString DynamicLoaderDarwinKernel::GetPluginNameStatic() {
1506 static ConstString g_name("darwin-kernel");
1507 return g_name;
Greg Clayton7b242382011-07-08 00:48:09 +00001508}
1509
Kate Stoneb9c1b512016-09-06 20:57:50 +00001510const char *DynamicLoaderDarwinKernel::GetPluginDescriptionStatic() {
1511 return "Dynamic loader plug-in that watches for shared library loads/unloads "
1512 "in the MacOSX kernel.";
Greg Clayton7b242382011-07-08 00:48:09 +00001513}
1514
Greg Clayton7b242382011-07-08 00:48:09 +00001515//------------------------------------------------------------------
1516// PluginInterface protocol
1517//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001518lldb_private::ConstString DynamicLoaderDarwinKernel::GetPluginName() {
1519 return GetPluginNameStatic();
Greg Clayton7b242382011-07-08 00:48:09 +00001520}
1521
Kate Stoneb9c1b512016-09-06 20:57:50 +00001522uint32_t DynamicLoaderDarwinKernel::GetPluginVersion() { return 1; }
Greg Clayton7b242382011-07-08 00:48:09 +00001523
Greg Clayton1f746072012-08-29 21:13:06 +00001524lldb::ByteOrder
Kate Stoneb9c1b512016-09-06 20:57:50 +00001525DynamicLoaderDarwinKernel::GetByteOrderFromMagic(uint32_t magic) {
1526 switch (magic) {
1527 case llvm::MachO::MH_MAGIC:
1528 case llvm::MachO::MH_MAGIC_64:
1529 return endian::InlHostByteOrder();
Greg Clayton1f746072012-08-29 21:13:06 +00001530
Kate Stoneb9c1b512016-09-06 20:57:50 +00001531 case llvm::MachO::MH_CIGAM:
1532 case llvm::MachO::MH_CIGAM_64:
1533 if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
1534 return lldb::eByteOrderLittle;
1535 else
1536 return lldb::eByteOrderBig;
1537
1538 default:
1539 break;
1540 }
1541 return lldb::eByteOrderInvalid;
1542}