blob: 255210b756e2c213f51166cb1d48aa6ae5e06073 [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"
Jim Ingham519b0812017-02-28 18:57:54 +000028#include "lldb/Target/OperatingSystem.h"
Greg Clayton7b242382011-07-08 00:48:09 +000029#include "lldb/Target/RegisterContext.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000030#include "lldb/Target/StackFrame.h"
Greg Clayton7b242382011-07-08 00:48:09 +000031#include "lldb/Target/Target.h"
32#include "lldb/Target/Thread.h"
33#include "lldb/Target/ThreadPlanRunToAddress.h"
Greg Clayton7b242382011-07-08 00:48:09 +000034
Greg Clayton944b8282011-08-22 22:30:57 +000035#include "DynamicLoaderDarwinKernel.h"
Greg Clayton7b242382011-07-08 00:48:09 +000036
37//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
38#ifdef ENABLE_DEBUG_PRINTF
39#include <stdio.h>
Kate Stoneb9c1b512016-09-06 20:57:50 +000040#define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
Greg Clayton7b242382011-07-08 00:48:09 +000041#else
42#define DEBUG_PRINTF(fmt, ...)
43#endif
44
45using namespace lldb;
46using namespace lldb_private;
47
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000048// Progressively greater amounts of scanning we will allow
Kate Stoneb9c1b512016-09-06 20:57:50 +000049// For some targets very early in startup, we can't do any random reads of
50// memory or we can crash the device
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000051// so a setting is needed that can completely disable the KASLR scans.
52
Kate Stoneb9c1b512016-09-06 20:57:50 +000053enum KASLRScanType {
54 eKASLRScanNone = 0, // No reading into the inferior at all
55 eKASLRScanLowgloAddresses, // Check one word of memory for a possible kernel
56 // addr, then see if a kernel is there
57 eKASLRScanNearPC, // Scan backwards from the current $pc looking for kernel;
58 // checking at 96 locations total
59 eKASLRScanExhaustiveScan // Scan through the entire possible kernel address
60 // range looking for a kernel
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000061};
62
Kate Stoneb9c1b512016-09-06 20:57:50 +000063OptionEnumValueElement g_kaslr_kernel_scan_enum_values[] = {
64 {eKASLRScanNone, "none",
65 "Do not read memory looking for a Darwin kernel when attaching."},
66 {eKASLRScanLowgloAddresses, "basic", "Check for the Darwin kernel's load "
67 "addr in the lowglo page "
68 "(boot-args=debug) only."},
69 {eKASLRScanNearPC, "fast-scan", "Scan near the pc value on attach to find "
70 "the Darwin kernel's load address."},
71 {eKASLRScanExhaustiveScan, "exhaustive-scan",
72 "Scan through the entire potential address range of Darwin kernel (only "
73 "on 32-bit targets)."},
74 {0, NULL, NULL}};
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000075
Kate Stoneb9c1b512016-09-06 20:57:50 +000076static PropertyDefinition g_properties[] = {
77 {"load-kexts", OptionValue::eTypeBoolean, true, true, NULL, NULL,
78 "Automatically loads kext images when attaching to a kernel."},
79 {"scan-type", OptionValue::eTypeEnum, true, eKASLRScanNearPC, NULL,
80 g_kaslr_kernel_scan_enum_values, "Control how many reads lldb will make "
81 "while searching for a Darwin kernel on "
82 "attach."},
83 {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}};
Greg Claytone8cd0c92012-10-19 18:02:49 +000084
Kate Stoneb9c1b512016-09-06 20:57:50 +000085enum { ePropertyLoadKexts, ePropertyScanType };
Greg Claytone8cd0c92012-10-19 18:02:49 +000086
Kate Stoneb9c1b512016-09-06 20:57:50 +000087class DynamicLoaderDarwinKernelProperties : public Properties {
Greg Claytone8cd0c92012-10-19 18:02:49 +000088public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000089 static ConstString &GetSettingName() {
90 static ConstString g_setting_name("darwin-kernel");
91 return g_setting_name;
92 }
Greg Claytone8cd0c92012-10-19 18:02:49 +000093
Kate Stoneb9c1b512016-09-06 20:57:50 +000094 DynamicLoaderDarwinKernelProperties() : Properties() {
95 m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
96 m_collection_sp->Initialize(g_properties);
97 }
Greg Claytone8cd0c92012-10-19 18:02:49 +000098
Kate Stoneb9c1b512016-09-06 20:57:50 +000099 virtual ~DynamicLoaderDarwinKernelProperties() {}
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000100
Kate Stoneb9c1b512016-09-06 20:57:50 +0000101 bool GetLoadKexts() const {
102 const uint32_t idx = ePropertyLoadKexts;
103 return m_collection_sp->GetPropertyAtIndexAsBoolean(
104 NULL, idx, g_properties[idx].default_uint_value != 0);
105 }
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000106
Kate Stoneb9c1b512016-09-06 20:57:50 +0000107 KASLRScanType GetScanType() const {
108 const uint32_t idx = ePropertyScanType;
109 return (KASLRScanType)m_collection_sp->GetPropertyAtIndexAsEnumeration(
110 NULL, idx, g_properties[idx].default_uint_value);
111 }
Greg Claytone8cd0c92012-10-19 18:02:49 +0000112};
113
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114typedef std::shared_ptr<DynamicLoaderDarwinKernelProperties>
115 DynamicLoaderDarwinKernelPropertiesSP;
Greg Claytone8cd0c92012-10-19 18:02:49 +0000116
Kate Stoneb9c1b512016-09-06 20:57:50 +0000117static const DynamicLoaderDarwinKernelPropertiesSP &GetGlobalProperties() {
118 static DynamicLoaderDarwinKernelPropertiesSP g_settings_sp;
119 if (!g_settings_sp)
120 g_settings_sp.reset(new DynamicLoaderDarwinKernelProperties());
121 return g_settings_sp;
Greg Claytone8cd0c92012-10-19 18:02:49 +0000122}
123
Greg Clayton7b242382011-07-08 00:48:09 +0000124//----------------------------------------------------------------------
125// Create an instance of this class. This function is filled into
126// the plugin info class that gets handed out by the plugin factory and
127// allows the lldb to instantiate an instance of this class.
128//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000129DynamicLoader *DynamicLoaderDarwinKernel::CreateInstance(Process *process,
130 bool force) {
131 if (!force) {
132 // If the user provided an executable binary and it is not a kernel,
133 // this plugin should not create an instance.
134 Module *exe_module = process->GetTarget().GetExecutableModulePointer();
135 if (exe_module) {
136 ObjectFile *object_file = exe_module->GetObjectFile();
137 if (object_file) {
138 if (object_file->GetStrata() != ObjectFile::eStrataKernel) {
139 return NULL;
Greg Claytondf0b7d52011-07-08 04:11:42 +0000140 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000141 }
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000142 }
143
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144 // If the target's architecture does not look like an Apple environment,
145 // this plugin should not create an instance.
146 const llvm::Triple &triple_ref =
147 process->GetTarget().GetArchitecture().GetTriple();
148 switch (triple_ref.getOS()) {
149 case llvm::Triple::Darwin:
150 case llvm::Triple::MacOSX:
151 case llvm::Triple::IOS:
152 case llvm::Triple::TvOS:
153 case llvm::Triple::WatchOS:
154 if (triple_ref.getVendor() != llvm::Triple::Apple) {
155 return NULL;
156 }
157 break;
158 // If we have triple like armv7-unknown-unknown, we should try looking for a
159 // Darwin kernel.
160 case llvm::Triple::UnknownOS:
161 break;
162 default:
163 return NULL;
164 break;
Jason Molenda503d0182013-03-02 07:19:32 +0000165 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000166 }
167
168 // At this point if there is an ExecutableModule, it is a kernel and the
169 // Target is some variant of an Apple system.
170 // If the Process hasn't provided the kernel load address, we need to look
171 // around in memory to find it.
172
173 const addr_t kernel_load_address = SearchForDarwinKernel(process);
174 if (CheckForKernelImageAtAddress(kernel_load_address, process).IsValid()) {
175 process->SetCanRunCode(false);
176 return new DynamicLoaderDarwinKernel(process, kernel_load_address);
177 }
178 return NULL;
Jason Molenda503d0182013-03-02 07:19:32 +0000179}
180
181lldb::addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000182DynamicLoaderDarwinKernel::SearchForDarwinKernel(Process *process) {
183 addr_t kernel_load_address = process->GetImageInfoAddress();
184 if (kernel_load_address == LLDB_INVALID_ADDRESS) {
185 kernel_load_address = SearchForKernelAtSameLoadAddr(process);
186 if (kernel_load_address == LLDB_INVALID_ADDRESS) {
187 kernel_load_address = SearchForKernelWithDebugHints(process);
188 if (kernel_load_address == LLDB_INVALID_ADDRESS) {
189 kernel_load_address = SearchForKernelNearPC(process);
190 if (kernel_load_address == LLDB_INVALID_ADDRESS) {
191 kernel_load_address = SearchForKernelViaExhaustiveSearch(process);
Greg Claytondf0b7d52011-07-08 04:11:42 +0000192 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193 }
Greg Clayton7b242382011-07-08 00:48:09 +0000194 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000195 }
196 return kernel_load_address;
Greg Clayton7b242382011-07-08 00:48:09 +0000197}
198
199//----------------------------------------------------------------------
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000200// Check if the kernel binary is loaded in memory without a slide.
201// First verify that the ExecutableModule is a kernel before we proceed.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202// Returns the address of the kernel if one was found, else
203// LLDB_INVALID_ADDRESS.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000204//----------------------------------------------------------------------
205lldb::addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000206DynamicLoaderDarwinKernel::SearchForKernelAtSameLoadAddr(Process *process) {
207 Module *exe_module = process->GetTarget().GetExecutableModulePointer();
208 if (exe_module == NULL)
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000209 return LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000210
211 ObjectFile *exe_objfile = exe_module->GetObjectFile();
212 if (exe_objfile == NULL)
213 return LLDB_INVALID_ADDRESS;
214
215 if (exe_objfile->GetType() != ObjectFile::eTypeExecutable ||
216 exe_objfile->GetStrata() != ObjectFile::eStrataKernel)
217 return LLDB_INVALID_ADDRESS;
218
219 if (!exe_objfile->GetHeaderAddress().IsValid())
220 return LLDB_INVALID_ADDRESS;
221
222 if (CheckForKernelImageAtAddress(
223 exe_objfile->GetHeaderAddress().GetFileAddress(), process) ==
224 exe_module->GetUUID())
225 return exe_objfile->GetHeaderAddress().GetFileAddress();
226
227 return LLDB_INVALID_ADDRESS;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000228}
229
230//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000231// If the debug flag is included in the boot-args nvram setting, the kernel's
232// load address
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000233// will be noted in the lowglo page at a fixed address
Kate Stoneb9c1b512016-09-06 20:57:50 +0000234// Returns the address of the kernel if one was found, else
235// LLDB_INVALID_ADDRESS.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000236//----------------------------------------------------------------------
237lldb::addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000238DynamicLoaderDarwinKernel::SearchForKernelWithDebugHints(Process *process) {
239 if (GetGlobalProperties()->GetScanType() == eKASLRScanNone)
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000240 return LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000241
242 Error read_err;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000243 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};
Jason Molenda61a8e532016-11-30 23:00:52 +0000248 addr_t kernel_addresses_32[] = {0xffff0110, // 2016 and earlier armv7 devices
249 0xffff1010,
250 LLDB_INVALID_ADDRESS};
Jason Molenda2b0a7be2016-11-15 01:41:27 +0000251
252 uint8_t uval[8];
253 if (process->GetAddressByteSize() == 8) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000254 for (size_t i = 0; kernel_addresses_64[i] != LLDB_INVALID_ADDRESS; i++) {
Jason Molenda2b0a7be2016-11-15 01:41:27 +0000255 if (process->ReadMemoryFromInferior (kernel_addresses_64[i], uval, 8, read_err) == 8)
256 {
257 DataExtractor data (&uval, 8, process->GetByteOrder(), process->GetAddressByteSize());
258 offset_t offset = 0;
259 uint64_t addr = data.GetU64 (&offset);
260 if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
261 return addr;
262 }
263 }
264 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265 }
266
Jason Molenda2b0a7be2016-11-15 01:41:27 +0000267 if (process->GetAddressByteSize() == 4) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000268 for (size_t i = 0; kernel_addresses_32[i] != LLDB_INVALID_ADDRESS; i++) {
Jason Molenda2b0a7be2016-11-15 01:41:27 +0000269 if (process->ReadMemoryFromInferior (kernel_addresses_32[i], uval, 4, read_err) == 4)
270 {
271 DataExtractor data (&uval, 4, process->GetByteOrder(), process->GetAddressByteSize());
272 offset_t offset = 0;
273 uint32_t addr = data.GetU32 (&offset);
274 if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
275 return addr;
276 }
277 }
278 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000279 }
280
281 return LLDB_INVALID_ADDRESS;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000282}
283
284//----------------------------------------------------------------------
285// If the kernel is currently executing when lldb attaches, and we don't have
286// a better way of finding the kernel's load address, try searching backwards
287// from the current pc value looking for the kernel's Mach header in memory.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000288// Returns the address of the kernel if one was found, else
289// LLDB_INVALID_ADDRESS.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000290//----------------------------------------------------------------------
291lldb::addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000292DynamicLoaderDarwinKernel::SearchForKernelNearPC(Process *process) {
293 if (GetGlobalProperties()->GetScanType() == eKASLRScanNone ||
294 GetGlobalProperties()->GetScanType() == eKASLRScanLowgloAddresses) {
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000295 return LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000296 }
297
298 ThreadSP thread = process->GetThreadList().GetSelectedThread();
299 if (thread.get() == NULL)
300 return LLDB_INVALID_ADDRESS;
301 addr_t pc = thread->GetRegisterContext()->GetPC(LLDB_INVALID_ADDRESS);
302
303 if (pc == LLDB_INVALID_ADDRESS)
304 return LLDB_INVALID_ADDRESS;
305
306 // The kernel will load at at one megabyte boundary (0x100000), or at that
307 // boundary plus
308 // an offset of one page (0x1000) or two, or four (0x4000), depending on the
309 // device.
310
311 // Round the current pc down to the nearest one megabyte boundary - the place
312 // where we will start searching.
313 addr_t addr = pc & ~0xfffff;
314
315 // Search backwards 32 megabytes, looking for the start of the kernel at each
316 // one-megabyte boundary.
317 for (int i = 0; i < 32; i++, addr -= 0x100000) {
318 if (CheckForKernelImageAtAddress(addr, process).IsValid())
319 return addr;
320 if (CheckForKernelImageAtAddress(addr + 0x1000, process).IsValid())
321 return addr + 0x1000;
322 if (CheckForKernelImageAtAddress(addr + 0x2000, process).IsValid())
323 return addr + 0x2000;
324 if (CheckForKernelImageAtAddress(addr + 0x4000, process).IsValid())
325 return addr + 0x4000;
326 }
327
328 return LLDB_INVALID_ADDRESS;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000329}
330
331//----------------------------------------------------------------------
332// Scan through the valid address range for a kernel binary.
333// This is uselessly slow in 64-bit environments so we don't even try it.
334// This scan is not enabled by default even for 32-bit targets.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000335// Returns the address of the kernel if one was found, else
336// LLDB_INVALID_ADDRESS.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000337//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000338lldb::addr_t DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch(
339 Process *process) {
340 if (GetGlobalProperties()->GetScanType() != eKASLRScanExhaustiveScan) {
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000341 return LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000342 }
343
344 addr_t kernel_range_low, kernel_range_high;
345 if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8) {
346 kernel_range_low = 1ULL << 63;
347 kernel_range_high = UINT64_MAX;
348 } else {
349 kernel_range_low = 1ULL << 31;
350 kernel_range_high = UINT32_MAX;
351 }
352
353 // Stepping through memory at one-megabyte resolution looking for a kernel
354 // rarely works (fast enough) with a 64-bit address space -- for now, let's
355 // not even bother. We may be attaching to something which *isn't* a kernel
356 // and we don't want to spin for minutes on-end looking for a kernel.
357 if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
358 return LLDB_INVALID_ADDRESS;
359
360 addr_t addr = kernel_range_low;
361
362 while (addr >= kernel_range_low && addr < kernel_range_high) {
363 if (CheckForKernelImageAtAddress(addr, process).IsValid())
364 return addr;
365 if (CheckForKernelImageAtAddress(addr + 0x1000, process).IsValid())
366 return addr + 0x1000;
367 if (CheckForKernelImageAtAddress(addr + 0x2000, process).IsValid())
368 return addr + 0x2000;
369 if (CheckForKernelImageAtAddress(addr + 0x4000, process).IsValid())
370 return addr + 0x4000;
371 addr += 0x100000;
372 }
373 return LLDB_INVALID_ADDRESS;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000374}
375
376//----------------------------------------------------------------------
377// Given an address in memory, look to see if there is a kernel image at that
Kate Stoneb9c1b512016-09-06 20:57:50 +0000378// address.
379// Returns a UUID; if a kernel was not found at that address, UUID.IsValid()
380// will be false.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000381//----------------------------------------------------------------------
382lldb_private::UUID
Kate Stoneb9c1b512016-09-06 20:57:50 +0000383DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress(lldb::addr_t addr,
384 Process *process) {
385 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
386 if (addr == LLDB_INVALID_ADDRESS)
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000387 return UUID();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000388
389 if (log)
390 log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
391 "looking for kernel binary at 0x%" PRIx64,
392 addr);
393
394 // First try a quick test -- read the first 4 bytes and see if there is a
395 // valid Mach-O magic field there
396 // (the first field of the mach_header/mach_header_64 struct).
397
398 Error read_error;
Jason Molenda2b0a7be2016-11-15 01:41:27 +0000399 uint8_t magicbuf[4];
400 if (process->ReadMemoryFromInferior (addr, magicbuf, sizeof (magicbuf), read_error) != sizeof (magicbuf))
401 return UUID();
402
403 const uint32_t magicks[] = { llvm::MachO::MH_MAGIC_64, llvm::MachO::MH_MAGIC, llvm::MachO::MH_CIGAM, llvm::MachO::MH_CIGAM_64};
404
405 bool found_matching_pattern = false;
Taras Tsugrii0ca1dde2016-11-24 01:34:43 +0000406 for (size_t i = 0; i < llvm::array_lengthof (magicks); i++)
Jason Molenda2b0a7be2016-11-15 01:41:27 +0000407 if (::memcmp (magicbuf, &magicks[i], sizeof (magicbuf)) == 0)
408 found_matching_pattern = true;
409
410 if (found_matching_pattern == false)
411 return UUID();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000412
413 // Read the mach header and see whether it looks like a kernel
414 llvm::MachO::mach_header header;
415 if (process->DoReadMemory(addr, &header, sizeof(header), read_error) !=
416 sizeof(header))
417 return UUID();
418
419 if (header.magic == llvm::MachO::MH_CIGAM ||
420 header.magic == llvm::MachO::MH_CIGAM_64) {
421 header.magic = llvm::ByteSwap_32(header.magic);
422 header.cputype = llvm::ByteSwap_32(header.cputype);
423 header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
424 header.filetype = llvm::ByteSwap_32(header.filetype);
425 header.ncmds = llvm::ByteSwap_32(header.ncmds);
426 header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
427 header.flags = llvm::ByteSwap_32(header.flags);
428 }
429
430 // A kernel is an executable which does not have the dynamic link object flag
431 // set.
432 if (header.filetype == llvm::MachO::MH_EXECUTE &&
433 (header.flags & llvm::MachO::MH_DYLDLINK) == 0) {
434 // Create a full module to get the UUID
435 ModuleSP memory_module_sp = process->ReadModuleFromMemory(
436 FileSpec("temp_mach_kernel", false), addr);
437 if (!memory_module_sp.get())
438 return UUID();
439
440 ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
Jason Molendabc22c8d2016-10-21 23:45:07 +0000441 if (exe_objfile == NULL) {
442 if (log)
443 log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress "
444 "found a binary at 0x%" PRIx64
445 " but could not create an object file from memory",
446 addr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000447 return UUID();
Jason Molendabc22c8d2016-10-21 23:45:07 +0000448 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000449
450 if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
451 exe_objfile->GetStrata() == ObjectFile::eStrataKernel) {
452 ArchSpec kernel_arch(eArchTypeMachO, header.cputype, header.cpusubtype);
453 if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(
454 kernel_arch)) {
455 process->GetTarget().SetArchitecture(kernel_arch);
456 }
Jason Molendabc22c8d2016-10-21 23:45:07 +0000457 if (log) {
458 std::string uuid_str;
459 if (memory_module_sp->GetUUID().IsValid()) {
460 uuid_str = "with UUID ";
461 uuid_str += memory_module_sp->GetUUID().GetAsString();
462 } else {
463 uuid_str = "and no LC_UUID found in load commands ";
464 }
465 log->Printf(
466 "DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
467 "kernel binary image found at 0x%" PRIx64 " with arch '%s' %s",
468 addr, kernel_arch.GetTriple().str().c_str(), uuid_str.c_str());
469 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000470 return memory_module_sp->GetUUID();
471 }
472 }
473
474 return UUID();
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000475}
476
477//----------------------------------------------------------------------
Greg Clayton7b242382011-07-08 00:48:09 +0000478// Constructor
479//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000480DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel(Process *process,
481 lldb::addr_t kernel_addr)
482 : DynamicLoader(process), m_kernel_load_address(kernel_addr), m_kernel(),
483 m_kext_summary_header_ptr_addr(), m_kext_summary_header_addr(),
484 m_kext_summary_header(), m_known_kexts(), m_mutex(),
485 m_break_id(LLDB_INVALID_BREAK_ID) {
486 Error error;
487 PlatformSP platform_sp(
488 Platform::Create(PlatformDarwinKernel::GetPluginNameStatic(), error));
489 // Only select the darwin-kernel Platform if we've been asked to load kexts.
490 // It can take some time to scan over all of the kext info.plists and that
491 // shouldn't be done if kext loading is explicitly disabled.
492 if (platform_sp.get() && GetGlobalProperties()->GetLoadKexts()) {
493 process->GetTarget().SetPlatform(platform_sp);
494 }
Greg Clayton7b242382011-07-08 00:48:09 +0000495}
496
497//----------------------------------------------------------------------
498// Destructor
499//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000500DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel() { Clear(true); }
Greg Clayton7b242382011-07-08 00:48:09 +0000501
Kate Stoneb9c1b512016-09-06 20:57:50 +0000502void DynamicLoaderDarwinKernel::UpdateIfNeeded() {
503 LoadKernelModuleIfNeeded();
504 SetNotificationBreakpointIfNeeded();
Greg Clayton374972e2011-07-09 17:15:55 +0000505}
Greg Clayton7b242382011-07-08 00:48:09 +0000506//------------------------------------------------------------------
507/// Called after attaching a process.
508///
509/// Allow DynamicLoader plug-ins to execute some code after
510/// attaching to a process.
511//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000512void DynamicLoaderDarwinKernel::DidAttach() {
513 PrivateInitialize(m_process);
514 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000515}
516
517//------------------------------------------------------------------
518/// Called after attaching a process.
519///
520/// Allow DynamicLoader plug-ins to execute some code after
521/// attaching to a process.
522//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000523void DynamicLoaderDarwinKernel::DidLaunch() {
524 PrivateInitialize(m_process);
525 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000526}
527
Greg Clayton7b242382011-07-08 00:48:09 +0000528//----------------------------------------------------------------------
529// Clear out the state of this class.
530//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000531void DynamicLoaderDarwinKernel::Clear(bool clear_process) {
532 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Clayton7b242382011-07-08 00:48:09 +0000533
Kate Stoneb9c1b512016-09-06 20:57:50 +0000534 if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
535 m_process->ClearBreakpointSiteByID(m_break_id);
Greg Clayton7b242382011-07-08 00:48:09 +0000536
Kate Stoneb9c1b512016-09-06 20:57:50 +0000537 if (clear_process)
538 m_process = NULL;
539 m_kernel.Clear();
540 m_known_kexts.clear();
541 m_kext_summary_header_ptr_addr.Clear();
542 m_kext_summary_header_addr.Clear();
543 m_break_id = LLDB_INVALID_BREAK_ID;
Greg Clayton7b242382011-07-08 00:48:09 +0000544}
545
Kate Stoneb9c1b512016-09-06 20:57:50 +0000546bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageAtFileAddress(
547 Process *process) {
548 if (IsLoaded())
549 return true;
Greg Clayton7b242382011-07-08 00:48:09 +0000550
Kate Stoneb9c1b512016-09-06 20:57:50 +0000551 if (m_module_sp) {
552 bool changed = false;
553 if (m_module_sp->SetLoadAddress(process->GetTarget(), 0, true, changed))
554 m_load_process_stop_id = process->GetStopID();
555 }
556 return false;
557}
Greg Clayton2af282a2012-03-21 04:25:00 +0000558
Kate Stoneb9c1b512016-09-06 20:57:50 +0000559void DynamicLoaderDarwinKernel::KextImageInfo::SetModule(ModuleSP module_sp) {
560 m_module_sp = module_sp;
561 if (module_sp.get() && module_sp->GetObjectFile()) {
562 if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable &&
563 module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel) {
564 m_kernel_image = true;
565 } else {
566 m_kernel_image = false;
567 }
568 }
569}
570
571ModuleSP DynamicLoaderDarwinKernel::KextImageInfo::GetModule() {
572 return m_module_sp;
573}
574
575void DynamicLoaderDarwinKernel::KextImageInfo::SetLoadAddress(
576 addr_t load_addr) {
577 m_load_address = load_addr;
578}
579
580addr_t DynamicLoaderDarwinKernel::KextImageInfo::GetLoadAddress() const {
581 return m_load_address;
582}
583
584uint64_t DynamicLoaderDarwinKernel::KextImageInfo::GetSize() const {
585 return m_size;
586}
587
588void DynamicLoaderDarwinKernel::KextImageInfo::SetSize(uint64_t size) {
589 m_size = size;
590}
591
592uint32_t DynamicLoaderDarwinKernel::KextImageInfo::GetProcessStopId() const {
593 return m_load_process_stop_id;
594}
595
596void DynamicLoaderDarwinKernel::KextImageInfo::SetProcessStopId(
597 uint32_t stop_id) {
598 m_load_process_stop_id = stop_id;
599}
600
601bool DynamicLoaderDarwinKernel::KextImageInfo::
602operator==(const KextImageInfo &rhs) {
603 if (m_uuid.IsValid() || rhs.GetUUID().IsValid()) {
604 if (m_uuid == rhs.GetUUID()) {
605 return true;
Greg Clayton2af282a2012-03-21 04:25:00 +0000606 }
607 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000608 }
609
610 if (m_name == rhs.GetName() && m_load_address == rhs.GetLoadAddress())
611 return true;
612
613 return false;
Greg Clayton2af282a2012-03-21 04:25:00 +0000614}
615
Kate Stoneb9c1b512016-09-06 20:57:50 +0000616void DynamicLoaderDarwinKernel::KextImageInfo::SetName(const char *name) {
617 m_name = name;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000618}
619
Kate Stoneb9c1b512016-09-06 20:57:50 +0000620std::string DynamicLoaderDarwinKernel::KextImageInfo::GetName() const {
621 return m_name;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000622}
623
Kate Stoneb9c1b512016-09-06 20:57:50 +0000624void DynamicLoaderDarwinKernel::KextImageInfo::SetUUID(const UUID &uuid) {
625 m_uuid = uuid;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000626}
627
Kate Stoneb9c1b512016-09-06 20:57:50 +0000628UUID DynamicLoaderDarwinKernel::KextImageInfo::GetUUID() const {
629 return m_uuid;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000630}
631
Kate Stoneb9c1b512016-09-06 20:57:50 +0000632// Given the m_load_address from the kext summaries, and a UUID, try to create
633// an in-memory
634// Module at that address. Require that the MemoryModule have a matching UUID
635// and detect
Jason Molenda306bd0a2013-02-19 05:42:46 +0000636// if this MemoryModule is a kernel or a kext.
637//
Kate Stoneb9c1b512016-09-06 20:57:50 +0000638// Returns true if m_memory_module_sp is now set to a valid Module.
Jason Molenda306bd0a2013-02-19 05:42:46 +0000639
Kate Stoneb9c1b512016-09-06 20:57:50 +0000640bool DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule(
641 Process *process) {
642 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
643 if (m_memory_module_sp.get() != NULL)
Jason Molenda306bd0a2013-02-19 05:42:46 +0000644 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000645 if (m_load_address == LLDB_INVALID_ADDRESS)
646 return false;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000647
Kate Stoneb9c1b512016-09-06 20:57:50 +0000648 FileSpec file_spec;
649 file_spec.SetFile(m_name.c_str(), false);
Jason Molenda306bd0a2013-02-19 05:42:46 +0000650
Kate Stoneb9c1b512016-09-06 20:57:50 +0000651 ModuleSP memory_module_sp =
652 process->ReadModuleFromMemory(file_spec, m_load_address);
Jason Molenda306bd0a2013-02-19 05:42:46 +0000653
Kate Stoneb9c1b512016-09-06 20:57:50 +0000654 if (memory_module_sp.get() == NULL)
655 return false;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000656
Kate Stoneb9c1b512016-09-06 20:57:50 +0000657 bool is_kernel = false;
658 if (memory_module_sp->GetObjectFile()) {
659 if (memory_module_sp->GetObjectFile()->GetType() ==
660 ObjectFile::eTypeExecutable &&
661 memory_module_sp->GetObjectFile()->GetStrata() ==
662 ObjectFile::eStrataKernel) {
663 is_kernel = true;
664 } else if (memory_module_sp->GetObjectFile()->GetType() ==
665 ObjectFile::eTypeSharedLibrary) {
666 is_kernel = false;
Jason Molenda87a04b22012-10-19 03:40:45 +0000667 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000668 }
Jason Molenda87a04b22012-10-19 03:40:45 +0000669
Kate Stoneb9c1b512016-09-06 20:57:50 +0000670 // If this is a kext, and the kernel specified what UUID we should find at
671 // this
672 // load address, require that the memory module have a matching UUID or
673 // something
674 // has gone wrong and we should discard it.
675 if (m_uuid.IsValid()) {
676 if (m_uuid != memory_module_sp->GetUUID()) {
677 if (log) {
678 log->Printf("KextImageInfo::ReadMemoryModule the kernel said to find "
679 "uuid %s at 0x%" PRIx64
680 " but instead we found uuid %s, throwing it away",
681 m_uuid.GetAsString().c_str(), m_load_address,
682 memory_module_sp->GetUUID().GetAsString().c_str());
683 }
684 return false;
685 }
686 }
Jason Molenda306bd0a2013-02-19 05:42:46 +0000687
Kate Stoneb9c1b512016-09-06 20:57:50 +0000688 // If the in-memory Module has a UUID, let's use that.
689 if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid()) {
690 m_uuid = memory_module_sp->GetUUID();
691 }
692
693 m_memory_module_sp = memory_module_sp;
694 m_kernel_image = is_kernel;
695 if (is_kernel) {
696 if (log) {
697 // This is unusual and probably not intended
698 log->Printf("KextImageInfo::ReadMemoryModule read the kernel binary out "
699 "of memory");
700 }
701 if (memory_module_sp->GetArchitecture().IsValid()) {
702 process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture());
703 }
704 if (m_uuid.IsValid()) {
705 ModuleSP exe_module_sp = process->GetTarget().GetExecutableModule();
706 if (exe_module_sp.get() && exe_module_sp->GetUUID().IsValid()) {
707 if (m_uuid != exe_module_sp->GetUUID()) {
708 // The user specified a kernel binary that has a different UUID than
709 // the kernel actually running in memory. This never ends well;
710 // clear the user specified kernel binary from the Target.
711
712 m_module_sp.reset();
713
714 ModuleList user_specified_kernel_list;
715 user_specified_kernel_list.Append(exe_module_sp);
716 process->GetTarget().GetImages().Remove(user_specified_kernel_list);
717 }
718 }
719 }
720 }
721
722 return true;
723}
724
725bool DynamicLoaderDarwinKernel::KextImageInfo::IsKernel() const {
726 return m_kernel_image == true;
727}
728
729void DynamicLoaderDarwinKernel::KextImageInfo::SetIsKernel(bool is_kernel) {
730 m_kernel_image = is_kernel;
731}
732
733bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
734 Process *process) {
735 if (IsLoaded())
736 return true;
737
738 Target &target = process->GetTarget();
739
740 // If we don't have / can't create a memory module for this kext, don't try to
741 // load it - we won't
742 // have the correct segment load addresses.
743 if (!ReadMemoryModule(process)) {
744 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
745 if (log)
746 log->Printf("Unable to read '%s' from memory at address 0x%" PRIx64
747 " to get the segment load addresses.",
748 m_name.c_str(), m_load_address);
749 return false;
750 }
751
752 bool uuid_is_valid = m_uuid.IsValid();
753
754 if (IsKernel() && uuid_is_valid && m_memory_module_sp.get()) {
755 Stream *s = target.GetDebugger().GetOutputFile().get();
756 if (s) {
757 s->Printf("Kernel UUID: %s\n",
758 m_memory_module_sp->GetUUID().GetAsString().c_str());
759 s->Printf("Load Address: 0x%" PRIx64 "\n", m_load_address);
760 }
761 }
762
763 if (!m_module_sp) {
764 // See if the kext has already been loaded into the target, probably by the
765 // user doing target modules add.
766 const ModuleList &target_images = target.GetImages();
767 m_module_sp = target_images.FindModule(m_uuid);
768
769 // Search for the kext on the local filesystem via the UUID
770 if (!m_module_sp && uuid_is_valid) {
771 ModuleSpec module_spec;
772 module_spec.GetUUID() = m_uuid;
773 module_spec.GetArchitecture() = target.GetArchitecture();
774
775 // For the kernel, we really do need an on-disk file copy of the binary to
776 // do anything useful.
777 // This will force a clal to
778 if (IsKernel()) {
779 if (Symbols::DownloadObjectAndSymbolFile(module_spec, true)) {
780 if (module_spec.GetFileSpec().Exists()) {
781 m_module_sp.reset(new Module(module_spec.GetFileSpec(),
782 target.GetArchitecture()));
783 if (m_module_sp.get() &&
784 m_module_sp->MatchesModuleSpec(module_spec)) {
785 ModuleList loaded_module_list;
786 loaded_module_list.Append(m_module_sp);
787 target.ModulesDidLoad(loaded_module_list);
788 }
789 }
790 }
791 }
792
793 // If the current platform is PlatformDarwinKernel, create a ModuleSpec
794 // with the filename set
795 // to be the bundle ID for this kext, e.g.
796 // "com.apple.filesystems.msdosfs", and ask the platform
797 // to find it.
798 PlatformSP platform_sp(target.GetPlatform());
799 if (!m_module_sp && platform_sp) {
800 ConstString platform_name(platform_sp->GetPluginName());
801 static ConstString g_platform_name(
802 PlatformDarwinKernel::GetPluginNameStatic());
803 if (platform_name == g_platform_name) {
804 ModuleSpec kext_bundle_module_spec(module_spec);
805 FileSpec kext_filespec(m_name.c_str(), false);
806 kext_bundle_module_spec.GetFileSpec() = kext_filespec;
807 platform_sp->GetSharedModule(
808 kext_bundle_module_spec, process, m_module_sp,
809 &target.GetExecutableSearchPaths(), NULL, NULL);
810 }
811 }
812
813 // Ask the Target to find this file on the local system, if possible.
814 // This will search in the list of currently-loaded files, look in the
815 // standard search paths on the system, and on a Mac it will try calling
816 // the DebugSymbols framework with the UUID to find the binary via its
817 // search methods.
818 if (!m_module_sp) {
819 m_module_sp = target.GetSharedModule(module_spec);
820 }
821
822 if (IsKernel() && !m_module_sp) {
Greg Clayton44d93782014-01-27 23:43:24 +0000823 Stream *s = target.GetDebugger().GetOutputFile().get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000824 if (s) {
825 s->Printf("WARNING: Unable to locate kernel binary on the debugger "
826 "system.\n");
Jason Molendae575e7b2013-02-19 06:11:13 +0000827 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000828 }
Jason Molendae575e7b2013-02-19 06:11:13 +0000829 }
830
Kate Stoneb9c1b512016-09-06 20:57:50 +0000831 // If we managed to find a module, append it to the target's list of images.
832 // If we also have a memory module, require that they have matching UUIDs
833 if (m_module_sp) {
834 bool uuid_match_ok = true;
835 if (m_memory_module_sp) {
836 if (m_module_sp->GetUUID() != m_memory_module_sp->GetUUID()) {
837 uuid_match_ok = false;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000838 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000839 }
840 if (uuid_match_ok) {
841 target.GetImages().AppendIfNeeded(m_module_sp);
842 if (IsKernel() &&
843 target.GetExecutableModulePointer() != m_module_sp.get()) {
844 target.SetExecutableModule(m_module_sp, false);
Greg Claytonc859e2d2012-02-13 23:10:39 +0000845 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000846 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000847 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000848 }
849
850 if (!m_module_sp && !IsKernel() && m_uuid.IsValid() && !m_name.empty()) {
851 Stream *s = target.GetDebugger().GetOutputFile().get();
852 if (s) {
853 s->Printf("warning: Can't find binary/dSYM for %s (%s)\n", m_name.c_str(),
854 m_uuid.GetAsString().c_str());
Jason Molenda56c23282013-02-19 06:39:56 +0000855 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000856 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000857
Kate Stoneb9c1b512016-09-06 20:57:50 +0000858 static ConstString g_section_name_LINKEDIT("__LINKEDIT");
Greg Clayton67408532012-12-11 01:20:51 +0000859
Kate Stoneb9c1b512016-09-06 20:57:50 +0000860 if (m_memory_module_sp && m_module_sp) {
861 if (m_module_sp->GetUUID() == m_memory_module_sp->GetUUID()) {
862 ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();
863 ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile();
Jason Molendabb860bd2012-10-09 01:17:11 +0000864
Kate Stoneb9c1b512016-09-06 20:57:50 +0000865 if (memory_object_file && ondisk_object_file) {
866 // The memory_module for kexts may have an invalid __LINKEDIT seg; skip
867 // it.
868 const bool ignore_linkedit = !IsKernel();
Greg Clayton67408532012-12-11 01:20:51 +0000869
Kate Stoneb9c1b512016-09-06 20:57:50 +0000870 SectionList *ondisk_section_list = ondisk_object_file->GetSectionList();
871 SectionList *memory_section_list = memory_object_file->GetSectionList();
872 if (memory_section_list && ondisk_section_list) {
873 const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
874 // There may be CTF sections in the memory image so we can't
875 // always just compare the number of sections (which are actually
876 // segments in mach-o parlance)
877 uint32_t sect_idx = 0;
878
879 // Use the memory_module's addresses for each section to set the
880 // file module's load address as appropriate. We don't want to use
881 // a single slide value for the entire kext - different segments may
882 // be slid different amounts by the kext loader.
883
884 uint32_t num_sections_loaded = 0;
885 for (sect_idx = 0; sect_idx < num_ondisk_sections; ++sect_idx) {
886 SectionSP ondisk_section_sp(
887 ondisk_section_list->GetSectionAtIndex(sect_idx));
888 if (ondisk_section_sp) {
889 // Don't ever load __LINKEDIT as it may or may not be actually
890 // mapped into memory and there is no current way to tell.
891 // I filed rdar://problem/12851706 to track being able to tell
892 // if the __LINKEDIT is actually mapped, but until then, we need
893 // to not load the __LINKEDIT
894 if (ignore_linkedit &&
895 ondisk_section_sp->GetName() == g_section_name_LINKEDIT)
896 continue;
897
898 const Section *memory_section =
899 memory_section_list
900 ->FindSectionByName(ondisk_section_sp->GetName())
901 .get();
902 if (memory_section) {
903 target.SetSectionLoadAddress(ondisk_section_sp,
904 memory_section->GetFileAddress());
905 ++num_sections_loaded;
906 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000907 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000908 }
909 if (num_sections_loaded > 0)
910 m_load_process_stop_id = process->GetStopID();
911 else
912 m_module_sp.reset(); // No sections were loaded
913 } else
914 m_module_sp.reset(); // One or both section lists
915 } else
916 m_module_sp.reset(); // One or both object files missing
917 } else
918 m_module_sp.reset(); // UUID mismatch
919 }
920
921 bool is_loaded = IsLoaded();
922
923 if (is_loaded && m_module_sp && IsKernel()) {
924 Stream *s = target.GetDebugger().GetOutputFile().get();
925 if (s) {
926 ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
927 if (kernel_object_file) {
928 addr_t file_address =
929 kernel_object_file->GetHeaderAddress().GetFileAddress();
930 if (m_load_address != LLDB_INVALID_ADDRESS &&
931 file_address != LLDB_INVALID_ADDRESS) {
932 s->Printf("Kernel slid 0x%" PRIx64 " in memory.\n",
933 m_load_address - file_address);
Greg Claytonc859e2d2012-02-13 23:10:39 +0000934 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000935 }
936 {
937 s->Printf("Loaded kernel file %s\n",
938 m_module_sp->GetFileSpec().GetPath().c_str());
939 }
940 s->Flush();
Greg Claytonc859e2d2012-02-13 23:10:39 +0000941 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000942 }
943 return is_loaded;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000944}
945
Kate Stoneb9c1b512016-09-06 20:57:50 +0000946uint32_t DynamicLoaderDarwinKernel::KextImageInfo::GetAddressByteSize() {
947 if (m_memory_module_sp)
948 return m_memory_module_sp->GetArchitecture().GetAddressByteSize();
949 if (m_module_sp)
950 return m_module_sp->GetArchitecture().GetAddressByteSize();
951 return 0;
Greg Clayton1f746072012-08-29 21:13:06 +0000952}
953
Kate Stoneb9c1b512016-09-06 20:57:50 +0000954lldb::ByteOrder DynamicLoaderDarwinKernel::KextImageInfo::GetByteOrder() {
955 if (m_memory_module_sp)
956 return m_memory_module_sp->GetArchitecture().GetByteOrder();
957 if (m_module_sp)
958 return m_module_sp->GetArchitecture().GetByteOrder();
959 return endian::InlHostByteOrder();
Greg Clayton1f746072012-08-29 21:13:06 +0000960}
961
962lldb_private::ArchSpec
Kate Stoneb9c1b512016-09-06 20:57:50 +0000963DynamicLoaderDarwinKernel::KextImageInfo::GetArchitecture() const {
964 if (m_memory_module_sp)
965 return m_memory_module_sp->GetArchitecture();
966 if (m_module_sp)
967 return m_module_sp->GetArchitecture();
968 return lldb_private::ArchSpec();
Greg Clayton1f746072012-08-29 21:13:06 +0000969}
970
Greg Clayton7b242382011-07-08 00:48:09 +0000971//----------------------------------------------------------------------
972// Load the kernel module and initialize the "m_kernel" member. Return
973// true _only_ if the kernel is loaded the first time through (subsequent
974// calls to this function should return false after the kernel has been
975// already loaded).
976//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000977void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
978 if (!m_kext_summary_header_ptr_addr.IsValid()) {
979 m_kernel.Clear();
980 m_kernel.SetModule(m_process->GetTarget().GetExecutableModule());
981 m_kernel.SetIsKernel(true);
Jason Molenda4bd4e7e2012-09-29 04:02:01 +0000982
Kate Stoneb9c1b512016-09-06 20:57:50 +0000983 ConstString kernel_name("mach_kernel");
984 if (m_kernel.GetModule().get() && m_kernel.GetModule()->GetObjectFile() &&
985 !m_kernel.GetModule()
986 ->GetObjectFile()
987 ->GetFileSpec()
988 .GetFilename()
989 .IsEmpty()) {
990 kernel_name =
991 m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename();
Greg Clayton7b242382011-07-08 00:48:09 +0000992 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000993 m_kernel.SetName(kernel_name.AsCString());
994
995 if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS) {
996 m_kernel.SetLoadAddress(m_kernel_load_address);
997 if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS &&
998 m_kernel.GetModule()) {
999 // We didn't get a hint from the process, so we will
1000 // try the kernel at the address that it exists at in
1001 // the file if we have one
1002 ObjectFile *kernel_object_file = m_kernel.GetModule()->GetObjectFile();
1003 if (kernel_object_file) {
1004 addr_t load_address =
1005 kernel_object_file->GetHeaderAddress().GetLoadAddress(
1006 &m_process->GetTarget());
1007 addr_t file_address =
1008 kernel_object_file->GetHeaderAddress().GetFileAddress();
1009 if (load_address != LLDB_INVALID_ADDRESS && load_address != 0) {
1010 m_kernel.SetLoadAddress(load_address);
1011 if (load_address != file_address) {
1012 // Don't accidentally relocate the kernel to the File address --
1013 // the Load address has already been set to its actual in-memory
1014 // address.
1015 // Mark it as IsLoaded.
1016 m_kernel.SetProcessStopId(m_process->GetStopID());
1017 }
1018 } else {
1019 m_kernel.SetLoadAddress(file_address);
1020 }
1021 }
1022 }
1023 }
1024
1025 if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS) {
1026 if (!m_kernel.LoadImageUsingMemoryModule(m_process)) {
1027 m_kernel.LoadImageAtFileAddress(m_process);
1028 }
1029 }
Jim Ingham519b0812017-02-28 18:57:54 +00001030
1031 // The operating system plugin gets loaded and initialized in
1032 // LoadImageUsingMemoryModule when we discover the kernel dSYM. For a
1033 // core file in particular, that's the wrong place to do this, since
1034 // we haven't fixed up the section addresses yet. So let's redo it here.
1035 LoadOperatingSystemPlugin(false);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001036
1037 if (m_kernel.IsLoaded() && m_kernel.GetModule()) {
1038 static ConstString kext_summary_symbol("gLoadedKextSummaries");
1039 const Symbol *symbol =
1040 m_kernel.GetModule()->FindFirstSymbolWithNameAndType(
1041 kext_summary_symbol, eSymbolTypeData);
1042 if (symbol) {
1043 m_kext_summary_header_ptr_addr = symbol->GetAddress();
1044 // Update all image infos
1045 ReadAllKextSummaries();
1046 }
1047 } else {
1048 m_kernel.Clear();
1049 }
1050 }
Greg Clayton7b242382011-07-08 00:48:09 +00001051}
1052
Greg Clayton7b242382011-07-08 00:48:09 +00001053//----------------------------------------------------------------------
1054// Static callback function that gets called when our DYLD notification
1055// breakpoint gets hit. We update all of our image infos and then
1056// let our super class DynamicLoader class decide if we should stop
1057// or not (based on global preference).
1058//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001059bool DynamicLoaderDarwinKernel::BreakpointHitCallback(
1060 void *baton, StoppointCallbackContext *context, user_id_t break_id,
1061 user_id_t break_loc_id) {
1062 return static_cast<DynamicLoaderDarwinKernel *>(baton)->BreakpointHit(
1063 context, break_id, break_loc_id);
Greg Clayton7b242382011-07-08 00:48:09 +00001064}
1065
Kate Stoneb9c1b512016-09-06 20:57:50 +00001066bool DynamicLoaderDarwinKernel::BreakpointHit(StoppointCallbackContext *context,
1067 user_id_t break_id,
1068 user_id_t break_loc_id) {
1069 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
1070 if (log)
1071 log->Printf("DynamicLoaderDarwinKernel::BreakpointHit (...)\n");
Greg Claytond16e1e52011-07-12 17:06:17 +00001072
Kate Stoneb9c1b512016-09-06 20:57:50 +00001073 ReadAllKextSummaries();
Greg Claytond16e1e52011-07-12 17:06:17 +00001074
Kate Stoneb9c1b512016-09-06 20:57:50 +00001075 if (log)
1076 PutToLog(log);
1077
1078 return GetStopWhenImagesChange();
Greg Clayton374972e2011-07-09 17:15:55 +00001079}
1080
Kate Stoneb9c1b512016-09-06 20:57:50 +00001081bool DynamicLoaderDarwinKernel::ReadKextSummaryHeader() {
1082 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Clayton374972e2011-07-09 17:15:55 +00001083
Kate Stoneb9c1b512016-09-06 20:57:50 +00001084 // the all image infos is already valid for this process stop ID
Greg Clayton7b242382011-07-08 00:48:09 +00001085
Kate Stoneb9c1b512016-09-06 20:57:50 +00001086 if (m_kext_summary_header_ptr_addr.IsValid()) {
1087 const uint32_t addr_size = m_kernel.GetAddressByteSize();
1088 const ByteOrder byte_order = m_kernel.GetByteOrder();
1089 Error error;
1090 // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure
1091 // which is currently 4 uint32_t and a pointer.
1092 uint8_t buf[24];
1093 DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
1094 const size_t count = 4 * sizeof(uint32_t) + addr_size;
1095 const bool prefer_file_cache = false;
1096 if (m_process->GetTarget().ReadPointerFromMemory(
1097 m_kext_summary_header_ptr_addr, prefer_file_cache, error,
1098 m_kext_summary_header_addr)) {
1099 // We got a valid address for our kext summary header and make sure it
1100 // isn't NULL
1101 if (m_kext_summary_header_addr.IsValid() &&
1102 m_kext_summary_header_addr.GetFileAddress() != 0) {
1103 const size_t bytes_read = m_process->GetTarget().ReadMemory(
1104 m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
1105 if (bytes_read == count) {
1106 lldb::offset_t offset = 0;
1107 m_kext_summary_header.version = data.GetU32(&offset);
1108 if (m_kext_summary_header.version > 128) {
1109 Stream *s =
1110 m_process->GetTarget().GetDebugger().GetOutputFile().get();
1111 s->Printf("WARNING: Unable to read kext summary header, got "
1112 "improbable version number %u\n",
1113 m_kext_summary_header.version);
1114 // If we get an improbably large version number, we're probably
1115 // getting bad memory.
1116 m_kext_summary_header_addr.Clear();
1117 return false;
1118 }
1119 if (m_kext_summary_header.version >= 2) {
1120 m_kext_summary_header.entry_size = data.GetU32(&offset);
1121 if (m_kext_summary_header.entry_size > 4096) {
1122 // If we get an improbably large entry_size, we're probably
1123 // getting bad memory.
1124 Stream *s =
1125 m_process->GetTarget().GetDebugger().GetOutputFile().get();
1126 s->Printf("WARNING: Unable to read kext summary header, got "
1127 "improbable entry_size %u\n",
1128 m_kext_summary_header.entry_size);
1129 m_kext_summary_header_addr.Clear();
1130 return false;
Greg Claytond16e1e52011-07-12 17:06:17 +00001131 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001132 } else {
1133 // Versions less than 2 didn't have an entry size, it was hard coded
1134 m_kext_summary_header.entry_size =
1135 KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
1136 }
1137 m_kext_summary_header.entry_count = data.GetU32(&offset);
1138 if (m_kext_summary_header.entry_count > 10000) {
1139 // If we get an improbably large number of kexts, we're probably
1140 // getting bad memory.
1141 Stream *s =
1142 m_process->GetTarget().GetDebugger().GetOutputFile().get();
1143 s->Printf("WARNING: Unable to read kext summary header, got "
1144 "improbable number of kexts %u\n",
1145 m_kext_summary_header.entry_count);
1146 m_kext_summary_header_addr.Clear();
1147 return false;
1148 }
1149 return true;
Greg Clayton7b242382011-07-08 00:48:09 +00001150 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001151 }
Greg Clayton7b242382011-07-08 00:48:09 +00001152 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001153 }
1154 m_kext_summary_header_addr.Clear();
1155 return false;
Greg Clayton7b242382011-07-08 00:48:09 +00001156}
1157
Kate Stoneb9c1b512016-09-06 20:57:50 +00001158// We've either (a) just attached to a new kernel, or (b) the kexts-changed
1159// breakpoint was hit
Jason Molenda306bd0a2013-02-19 05:42:46 +00001160// and we need to figure out what kexts have been added or removed.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001161// Read the kext summaries from the inferior kernel memory, compare them against
1162// the
1163// m_known_kexts vector and update the m_known_kexts vector as needed to keep in
1164// sync with the
Jason Molenda306bd0a2013-02-19 05:42:46 +00001165// inferior.
Greg Clayton7b242382011-07-08 00:48:09 +00001166
Kate Stoneb9c1b512016-09-06 20:57:50 +00001167bool DynamicLoaderDarwinKernel::ParseKextSummaries(
1168 const Address &kext_summary_addr, uint32_t count) {
1169 KextImageInfo::collection kext_summaries;
1170 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
1171 if (log)
1172 log->Printf("Kexts-changed breakpoint hit, there are %d kexts currently.\n",
1173 count);
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +00001174
Kate Stoneb9c1b512016-09-06 20:57:50 +00001175 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Clayton7b242382011-07-08 00:48:09 +00001176
Kate Stoneb9c1b512016-09-06 20:57:50 +00001177 if (!ReadKextSummaries(kext_summary_addr, count, kext_summaries))
Greg Clayton7b242382011-07-08 00:48:09 +00001178 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001179
1180 // read the plugin.dynamic-loader.darwin-kernel.load-kexts setting -- if the
1181 // user requested no
1182 // kext loading, don't print any messages about kexts & don't try to read
1183 // them.
1184 const bool load_kexts = GetGlobalProperties()->GetLoadKexts();
1185
1186 // By default, all kexts we've loaded in the past are marked as "remove" and
1187 // all of the kexts
1188 // we just found out about from ReadKextSummaries are marked as "add".
1189 std::vector<bool> to_be_removed(m_known_kexts.size(), true);
1190 std::vector<bool> to_be_added(count, true);
1191
1192 int number_of_new_kexts_being_added = 0;
1193 int number_of_old_kexts_being_removed = m_known_kexts.size();
1194
1195 const uint32_t new_kexts_size = kext_summaries.size();
1196 const uint32_t old_kexts_size = m_known_kexts.size();
1197
1198 // The m_known_kexts vector may have entries that have been Cleared,
1199 // or are a kernel.
1200 for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++) {
1201 bool ignore = false;
1202 KextImageInfo &image_info = m_known_kexts[old_kext];
1203 if (image_info.IsKernel()) {
1204 ignore = true;
1205 } else if (image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS &&
1206 !image_info.GetModule()) {
1207 ignore = true;
1208 }
1209
1210 if (ignore) {
1211 number_of_old_kexts_being_removed--;
1212 to_be_removed[old_kext] = false;
1213 }
1214 }
1215
1216 // Scan over the list of kexts we just read from the kernel, note those that
1217 // need to be added and those already loaded.
1218 for (uint32_t new_kext = 0; new_kext < new_kexts_size; new_kext++) {
1219 bool add_this_one = true;
1220 for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++) {
1221 if (m_known_kexts[old_kext] == kext_summaries[new_kext]) {
1222 // We already have this kext, don't re-load it.
1223 to_be_added[new_kext] = false;
1224 // This kext is still present, do not remove it.
1225 to_be_removed[old_kext] = false;
1226
1227 number_of_old_kexts_being_removed--;
1228 add_this_one = false;
1229 break;
1230 }
1231 }
1232 if (add_this_one) {
1233 number_of_new_kexts_being_added++;
1234 }
1235 }
1236
1237 if (number_of_new_kexts_being_added == 0 &&
1238 number_of_old_kexts_being_removed == 0)
1239 return true;
1240
1241 Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
1242 if (s && load_kexts) {
1243 if (number_of_new_kexts_being_added > 0 &&
1244 number_of_old_kexts_being_removed > 0) {
1245 s->Printf("Loading %d kext modules and unloading %d kext modules ",
1246 number_of_new_kexts_being_added,
1247 number_of_old_kexts_being_removed);
1248 } else if (number_of_new_kexts_being_added > 0) {
1249 s->Printf("Loading %d kext modules ", number_of_new_kexts_being_added);
1250 } else if (number_of_old_kexts_being_removed > 0) {
1251 s->Printf("Unloading %d kext modules ",
1252 number_of_old_kexts_being_removed);
1253 }
1254 }
1255
1256 if (log) {
1257 if (load_kexts) {
1258 log->Printf("DynamicLoaderDarwinKernel::ParseKextSummaries: %d kexts "
1259 "added, %d kexts removed",
1260 number_of_new_kexts_being_added,
1261 number_of_old_kexts_being_removed);
1262 } else {
1263 log->Printf(
1264 "DynamicLoaderDarwinKernel::ParseKextSummaries kext loading is "
1265 "disabled, else would have %d kexts added, %d kexts removed",
1266 number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
1267 }
1268 }
1269
1270 if (number_of_new_kexts_being_added > 0) {
1271 ModuleList loaded_module_list;
1272
1273 const uint32_t num_of_new_kexts = kext_summaries.size();
1274 for (uint32_t new_kext = 0; new_kext < num_of_new_kexts; new_kext++) {
1275 if (to_be_added[new_kext] == true) {
1276 KextImageInfo &image_info = kext_summaries[new_kext];
1277 if (load_kexts) {
1278 if (!image_info.LoadImageUsingMemoryModule(m_process)) {
1279 image_info.LoadImageAtFileAddress(m_process);
1280 }
1281 }
1282
1283 m_known_kexts.push_back(image_info);
1284
1285 if (image_info.GetModule() &&
1286 m_process->GetStopID() == image_info.GetProcessStopId())
1287 loaded_module_list.AppendIfNeeded(image_info.GetModule());
1288
1289 if (s && load_kexts)
1290 s->Printf(".");
1291
1292 if (log)
1293 kext_summaries[new_kext].PutToLog(log);
1294 }
1295 }
1296 m_process->GetTarget().ModulesDidLoad(loaded_module_list);
1297 }
1298
1299 if (number_of_old_kexts_being_removed > 0) {
1300 ModuleList loaded_module_list;
1301 const uint32_t num_of_old_kexts = m_known_kexts.size();
1302 for (uint32_t old_kext = 0; old_kext < num_of_old_kexts; old_kext++) {
1303 ModuleList unloaded_module_list;
1304 if (to_be_removed[old_kext]) {
1305 KextImageInfo &image_info = m_known_kexts[old_kext];
1306 // You can't unload the kernel.
1307 if (!image_info.IsKernel()) {
1308 if (image_info.GetModule()) {
1309 unloaded_module_list.AppendIfNeeded(image_info.GetModule());
1310 }
1311 if (s)
1312 s->Printf(".");
1313 image_info.Clear();
1314 // should pull it out of the KextImageInfos vector but that would
1315 // mutate the list and invalidate
1316 // the to_be_removed bool vector; leaving it in place once Cleared()
1317 // is relatively harmless.
1318 }
1319 }
1320 m_process->GetTarget().ModulesDidUnload(unloaded_module_list, false);
1321 }
1322 }
1323
1324 if (s && load_kexts) {
1325 s->Printf(" done.\n");
1326 s->Flush();
1327 }
1328
1329 return true;
1330}
1331
1332uint32_t DynamicLoaderDarwinKernel::ReadKextSummaries(
1333 const Address &kext_summary_addr, uint32_t image_infos_count,
1334 KextImageInfo::collection &image_infos) {
1335 const ByteOrder endian = m_kernel.GetByteOrder();
1336 const uint32_t addr_size = m_kernel.GetAddressByteSize();
1337
1338 image_infos.resize(image_infos_count);
1339 const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
1340 DataBufferHeap data(count, 0);
1341 Error error;
1342
1343 const bool prefer_file_cache = false;
1344 const size_t bytes_read = m_process->GetTarget().ReadMemory(
1345 kext_summary_addr, prefer_file_cache, data.GetBytes(), data.GetByteSize(),
1346 error);
1347 if (bytes_read == count) {
1348
1349 DataExtractor extractor(data.GetBytes(), data.GetByteSize(), endian,
1350 addr_size);
1351 uint32_t i = 0;
1352 for (uint32_t kext_summary_offset = 0;
1353 i < image_infos.size() &&
1354 extractor.ValidOffsetForDataOfSize(kext_summary_offset,
1355 m_kext_summary_header.entry_size);
1356 ++i, kext_summary_offset += m_kext_summary_header.entry_size) {
1357 lldb::offset_t offset = kext_summary_offset;
1358 const void *name_data =
1359 extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
1360 if (name_data == NULL)
1361 break;
1362 image_infos[i].SetName((const char *)name_data);
1363 UUID uuid(extractor.GetData(&offset, 16), 16);
1364 image_infos[i].SetUUID(uuid);
1365 image_infos[i].SetLoadAddress(extractor.GetU64(&offset));
1366 image_infos[i].SetSize(extractor.GetU64(&offset));
1367 }
1368 if (i < image_infos.size())
1369 image_infos.resize(i);
1370 } else {
1371 image_infos.clear();
1372 }
1373 return image_infos.size();
1374}
1375
1376bool DynamicLoaderDarwinKernel::ReadAllKextSummaries() {
1377 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1378
1379 if (ReadKextSummaryHeader()) {
1380 if (m_kext_summary_header.entry_count > 0 &&
1381 m_kext_summary_header_addr.IsValid()) {
1382 Address summary_addr(m_kext_summary_header_addr);
1383 summary_addr.Slide(m_kext_summary_header.GetSize());
1384 if (!ParseKextSummaries(summary_addr,
1385 m_kext_summary_header.entry_count)) {
1386 m_known_kexts.clear();
1387 }
1388 return true;
1389 }
1390 }
1391 return false;
Greg Clayton7b242382011-07-08 00:48:09 +00001392}
1393
1394//----------------------------------------------------------------------
Greg Clayton7b242382011-07-08 00:48:09 +00001395// Dump an image info structure to the file handle provided.
1396//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001397void DynamicLoaderDarwinKernel::KextImageInfo::PutToLog(Log *log) const {
1398 if (log == NULL)
1399 return;
1400 const uint8_t *u = (uint8_t *)m_uuid.GetBytes();
Greg Clayton7b242382011-07-08 00:48:09 +00001401
Kate Stoneb9c1b512016-09-06 20:57:50 +00001402 if (m_load_address == LLDB_INVALID_ADDRESS) {
1403 if (u) {
1404 log->Printf("\tuuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2."
1405 "2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\" (UNLOADED)",
1406 u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7], u[8], u[9],
1407 u[10], u[11], u[12], u[13], u[14], u[15], m_name.c_str());
1408 } else
1409 log->Printf("\tname=\"%s\" (UNLOADED)", m_name.c_str());
1410 } else {
1411 if (u) {
1412 log->Printf("\taddr=0x%16.16" PRIx64 " size=0x%16.16" PRIx64
1413 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-"
1414 "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\"",
1415 m_load_address, m_size, u[0], u[1], u[2], u[3], u[4], u[5],
1416 u[6], u[7], u[8], u[9], u[10], u[11], u[12], u[13], u[14],
1417 u[15], m_name.c_str());
1418 } else {
1419 log->Printf("\t[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") name=\"%s\"",
1420 m_load_address, m_load_address + m_size, m_name.c_str());
Greg Clayton7b242382011-07-08 00:48:09 +00001421 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001422 }
Greg Clayton7b242382011-07-08 00:48:09 +00001423}
1424
1425//----------------------------------------------------------------------
1426// Dump the _dyld_all_image_infos members and all current image infos
1427// that we have parsed to the file handle provided.
1428//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001429void DynamicLoaderDarwinKernel::PutToLog(Log *log) const {
1430 if (log == NULL)
1431 return;
Greg Clayton7b242382011-07-08 00:48:09 +00001432
Kate Stoneb9c1b512016-09-06 20:57:50 +00001433 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1434 log->Printf("gLoadedKextSummaries = 0x%16.16" PRIx64
1435 " { version=%u, entry_size=%u, entry_count=%u }",
1436 m_kext_summary_header_addr.GetFileAddress(),
1437 m_kext_summary_header.version, m_kext_summary_header.entry_size,
1438 m_kext_summary_header.entry_count);
Greg Clayton7b242382011-07-08 00:48:09 +00001439
Kate Stoneb9c1b512016-09-06 20:57:50 +00001440 size_t i;
1441 const size_t count = m_known_kexts.size();
1442 if (count > 0) {
1443 log->PutCString("Loaded:");
1444 for (i = 0; i < count; i++)
1445 m_known_kexts[i].PutToLog(log);
1446 }
Greg Clayton7b242382011-07-08 00:48:09 +00001447}
1448
Kate Stoneb9c1b512016-09-06 20:57:50 +00001449void DynamicLoaderDarwinKernel::PrivateInitialize(Process *process) {
1450 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n",
1451 __FUNCTION__, StateAsCString(m_process->GetState()));
1452 Clear(true);
1453 m_process = process;
Greg Clayton7b242382011-07-08 00:48:09 +00001454}
1455
Kate Stoneb9c1b512016-09-06 20:57:50 +00001456void DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded() {
1457 if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.GetModule()) {
1458 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n",
1459 __FUNCTION__, StateAsCString(m_process->GetState()));
Greg Clayton374972e2011-07-09 17:15:55 +00001460
Kate Stoneb9c1b512016-09-06 20:57:50 +00001461 const bool internal_bp = true;
1462 const bool hardware = false;
1463 const LazyBool skip_prologue = eLazyBoolNo;
1464 FileSpecList module_spec_list;
1465 module_spec_list.Append(m_kernel.GetModule()->GetFileSpec());
1466 Breakpoint *bp =
1467 m_process->GetTarget()
1468 .CreateBreakpoint(&module_spec_list, NULL,
1469 "OSKextLoadedKextSummariesUpdated",
1470 eFunctionNameTypeFull, eLanguageTypeUnknown, 0,
1471 skip_prologue, internal_bp, hardware)
1472 .get();
Greg Clayton374972e2011-07-09 17:15:55 +00001473
Kate Stoneb9c1b512016-09-06 20:57:50 +00001474 bp->SetCallback(DynamicLoaderDarwinKernel::BreakpointHitCallback, this,
1475 true);
1476 m_break_id = bp->GetID();
1477 }
Greg Clayton7b242382011-07-08 00:48:09 +00001478}
1479
1480//----------------------------------------------------------------------
1481// Member function that gets called when the process state changes.
1482//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001483void DynamicLoaderDarwinKernel::PrivateProcessStateChanged(Process *process,
1484 StateType state) {
1485 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__,
1486 StateAsCString(state));
1487 switch (state) {
1488 case eStateConnected:
1489 case eStateAttaching:
1490 case eStateLaunching:
1491 case eStateInvalid:
1492 case eStateUnloaded:
1493 case eStateExited:
1494 case eStateDetached:
1495 Clear(false);
1496 break;
Greg Clayton7b242382011-07-08 00:48:09 +00001497
Kate Stoneb9c1b512016-09-06 20:57:50 +00001498 case eStateStopped:
1499 UpdateIfNeeded();
1500 break;
Greg Clayton7b242382011-07-08 00:48:09 +00001501
Kate Stoneb9c1b512016-09-06 20:57:50 +00001502 case eStateRunning:
1503 case eStateStepping:
1504 case eStateCrashed:
1505 case eStateSuspended:
1506 break;
1507 }
Greg Clayton7b242382011-07-08 00:48:09 +00001508}
1509
1510ThreadPlanSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00001511DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan(Thread &thread,
1512 bool stop_others) {
1513 ThreadPlanSP thread_plan_sp;
1514 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
1515 if (log)
1516 log->Printf("Could not find symbol for step through.");
1517 return thread_plan_sp;
Greg Clayton7b242382011-07-08 00:48:09 +00001518}
1519
Kate Stoneb9c1b512016-09-06 20:57:50 +00001520Error DynamicLoaderDarwinKernel::CanLoadImage() {
1521 Error error;
1522 error.SetErrorString(
1523 "always unsafe to load or unload shared libraries in the darwin kernel");
1524 return error;
Greg Clayton7b242382011-07-08 00:48:09 +00001525}
1526
Kate Stoneb9c1b512016-09-06 20:57:50 +00001527void DynamicLoaderDarwinKernel::Initialize() {
1528 PluginManager::RegisterPlugin(GetPluginNameStatic(),
1529 GetPluginDescriptionStatic(), CreateInstance,
1530 DebuggerInitialize);
Greg Clayton7b242382011-07-08 00:48:09 +00001531}
1532
Kate Stoneb9c1b512016-09-06 20:57:50 +00001533void DynamicLoaderDarwinKernel::Terminate() {
1534 PluginManager::UnregisterPlugin(CreateInstance);
Greg Clayton7b242382011-07-08 00:48:09 +00001535}
1536
Kate Stoneb9c1b512016-09-06 20:57:50 +00001537void DynamicLoaderDarwinKernel::DebuggerInitialize(
1538 lldb_private::Debugger &debugger) {
1539 if (!PluginManager::GetSettingForDynamicLoaderPlugin(
1540 debugger, DynamicLoaderDarwinKernelProperties::GetSettingName())) {
1541 const bool is_global_setting = true;
1542 PluginManager::CreateSettingForDynamicLoaderPlugin(
1543 debugger, GetGlobalProperties()->GetValueProperties(),
1544 ConstString("Properties for the DynamicLoaderDarwinKernel plug-in."),
1545 is_global_setting);
1546 }
Greg Claytone8cd0c92012-10-19 18:02:49 +00001547}
Greg Clayton7b242382011-07-08 00:48:09 +00001548
Kate Stoneb9c1b512016-09-06 20:57:50 +00001549lldb_private::ConstString DynamicLoaderDarwinKernel::GetPluginNameStatic() {
1550 static ConstString g_name("darwin-kernel");
1551 return g_name;
Greg Clayton7b242382011-07-08 00:48:09 +00001552}
1553
Kate Stoneb9c1b512016-09-06 20:57:50 +00001554const char *DynamicLoaderDarwinKernel::GetPluginDescriptionStatic() {
1555 return "Dynamic loader plug-in that watches for shared library loads/unloads "
1556 "in the MacOSX kernel.";
Greg Clayton7b242382011-07-08 00:48:09 +00001557}
1558
Greg Clayton7b242382011-07-08 00:48:09 +00001559//------------------------------------------------------------------
1560// PluginInterface protocol
1561//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001562lldb_private::ConstString DynamicLoaderDarwinKernel::GetPluginName() {
1563 return GetPluginNameStatic();
Greg Clayton7b242382011-07-08 00:48:09 +00001564}
1565
Kate Stoneb9c1b512016-09-06 20:57:50 +00001566uint32_t DynamicLoaderDarwinKernel::GetPluginVersion() { return 1; }
Greg Clayton7b242382011-07-08 00:48:09 +00001567
Greg Clayton1f746072012-08-29 21:13:06 +00001568lldb::ByteOrder
Kate Stoneb9c1b512016-09-06 20:57:50 +00001569DynamicLoaderDarwinKernel::GetByteOrderFromMagic(uint32_t magic) {
1570 switch (magic) {
1571 case llvm::MachO::MH_MAGIC:
1572 case llvm::MachO::MH_MAGIC_64:
1573 return endian::InlHostByteOrder();
Greg Clayton1f746072012-08-29 21:13:06 +00001574
Kate Stoneb9c1b512016-09-06 20:57:50 +00001575 case llvm::MachO::MH_CIGAM:
1576 case llvm::MachO::MH_CIGAM_64:
1577 if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
1578 return lldb::eByteOrderLittle;
1579 else
1580 return lldb::eByteOrderBig;
1581
1582 default:
1583 break;
1584 }
1585 return lldb::eByteOrderInvalid;
1586}