blob: 862e48950220326ffd71080eb2d5dc29ad11dd28 [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
Kate Stoneb9c1b512016-09-06 20:57:50 +000011#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h"
Greg Clayton7b242382011-07-08 00:48:09 +000012#include "lldb/Breakpoint/StoppointCallbackContext.h"
Greg Clayton07e66e32011-07-20 03:41:06 +000013#include "lldb/Core/Debugger.h"
Greg Clayton7b242382011-07-08 00:48:09 +000014#include "lldb/Core/Module.h"
Greg Clayton1f746072012-08-29 21:13:06 +000015#include "lldb/Core/ModuleSpec.h"
Greg Clayton7b242382011-07-08 00:48:09 +000016#include "lldb/Core/PluginManager.h"
Greg Clayton1f746072012-08-29 21:13:06 +000017#include "lldb/Core/Section.h"
Greg Clayton44d93782014-01-27 23:43:24 +000018#include "lldb/Core/StreamFile.h"
Jason Molenda68b36072012-10-02 03:49:41 +000019#include "lldb/Host/Symbols.h"
Ilia K41204d02015-03-04 12:05:24 +000020#include "lldb/Interpreter/OptionValueProperties.h"
Greg Clayton7b242382011-07-08 00:48:09 +000021#include "lldb/Symbol/ObjectFile.h"
Jim Ingham519b0812017-02-28 18:57:54 +000022#include "lldb/Target/OperatingSystem.h"
Greg Clayton7b242382011-07-08 00:48:09 +000023#include "lldb/Target/RegisterContext.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000024#include "lldb/Target/StackFrame.h"
Greg Clayton7b242382011-07-08 00:48:09 +000025#include "lldb/Target/Target.h"
26#include "lldb/Target/Thread.h"
27#include "lldb/Target/ThreadPlanRunToAddress.h"
Zachary Turner666cc0b2017-03-04 01:30:05 +000028#include "lldb/Utility/DataBuffer.h"
29#include "lldb/Utility/DataBufferHeap.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000030#include "lldb/Utility/Log.h"
Pavel Labathd821c992018-08-07 11:07:21 +000031#include "lldb/Utility/State.h"
Greg Clayton7b242382011-07-08 00:48:09 +000032
Greg Clayton944b8282011-08-22 22:30:57 +000033#include "DynamicLoaderDarwinKernel.h"
Greg Clayton7b242382011-07-08 00:48:09 +000034
35//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
36#ifdef ENABLE_DEBUG_PRINTF
37#include <stdio.h>
Kate Stoneb9c1b512016-09-06 20:57:50 +000038#define DEBUG_PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__)
Greg Clayton7b242382011-07-08 00:48:09 +000039#else
40#define DEBUG_PRINTF(fmt, ...)
41#endif
42
43using namespace lldb;
44using namespace lldb_private;
45
Adrian Prantl05097242018-04-30 16:49:04 +000046// Progressively greater amounts of scanning we will allow For some targets
47// very early in startup, we can't do any random reads of memory or we can
48// crash the device so a setting is needed that can completely disable the
49// KASLR scans.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000050
Kate Stoneb9c1b512016-09-06 20:57:50 +000051enum KASLRScanType {
52 eKASLRScanNone = 0, // No reading into the inferior at all
53 eKASLRScanLowgloAddresses, // Check one word of memory for a possible kernel
54 // addr, then see if a kernel is there
55 eKASLRScanNearPC, // Scan backwards from the current $pc looking for kernel;
56 // checking at 96 locations total
57 eKASLRScanExhaustiveScan // Scan through the entire possible kernel address
58 // range looking for a kernel
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000059};
60
Tatyana Krasnukha8fe53c492018-09-26 18:50:19 +000061static constexpr OptionEnumValueElement g_kaslr_kernel_scan_enum_values[] = {
Kate Stoneb9c1b512016-09-06 20:57:50 +000062 {eKASLRScanNone, "none",
63 "Do not read memory looking for a Darwin kernel when attaching."},
64 {eKASLRScanLowgloAddresses, "basic", "Check for the Darwin kernel's load "
65 "addr in the lowglo page "
66 "(boot-args=debug) only."},
67 {eKASLRScanNearPC, "fast-scan", "Scan near the pc value on attach to find "
68 "the Darwin kernel's load address."},
69 {eKASLRScanExhaustiveScan, "exhaustive-scan",
70 "Scan through the entire potential address range of Darwin kernel (only "
Tatyana Krasnukha8fe53c492018-09-26 18:50:19 +000071 "on 32-bit targets)."}};
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000072
Tatyana Krasnukha8fe53c492018-09-26 18:50:19 +000073static constexpr PropertyDefinition g_properties[] = {
74 {"load-kexts", OptionValue::eTypeBoolean, true, true, NULL, {},
Kate Stoneb9c1b512016-09-06 20:57:50 +000075 "Automatically loads kext images when attaching to a kernel."},
76 {"scan-type", OptionValue::eTypeEnum, true, eKASLRScanNearPC, NULL,
Tatyana Krasnukha8fe53c492018-09-26 18:50:19 +000077 OptionEnumValues(g_kaslr_kernel_scan_enum_values),
78 "Control how many reads lldb will make while searching for a Darwin "
Tatyana Krasnukhae40db052018-09-27 07:11:58 +000079 "kernel on attach."}};
Greg Claytone8cd0c92012-10-19 18:02:49 +000080
Kate Stoneb9c1b512016-09-06 20:57:50 +000081enum { ePropertyLoadKexts, ePropertyScanType };
Greg Claytone8cd0c92012-10-19 18:02:49 +000082
Kate Stoneb9c1b512016-09-06 20:57:50 +000083class DynamicLoaderDarwinKernelProperties : public Properties {
Greg Claytone8cd0c92012-10-19 18:02:49 +000084public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000085 static ConstString &GetSettingName() {
86 static ConstString g_setting_name("darwin-kernel");
87 return g_setting_name;
88 }
Greg Claytone8cd0c92012-10-19 18:02:49 +000089
Kate Stoneb9c1b512016-09-06 20:57:50 +000090 DynamicLoaderDarwinKernelProperties() : Properties() {
91 m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
92 m_collection_sp->Initialize(g_properties);
93 }
Greg Claytone8cd0c92012-10-19 18:02:49 +000094
Kate Stoneb9c1b512016-09-06 20:57:50 +000095 virtual ~DynamicLoaderDarwinKernelProperties() {}
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000096
Kate Stoneb9c1b512016-09-06 20:57:50 +000097 bool GetLoadKexts() const {
98 const uint32_t idx = ePropertyLoadKexts;
99 return m_collection_sp->GetPropertyAtIndexAsBoolean(
100 NULL, idx, g_properties[idx].default_uint_value != 0);
101 }
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000102
Kate Stoneb9c1b512016-09-06 20:57:50 +0000103 KASLRScanType GetScanType() const {
104 const uint32_t idx = ePropertyScanType;
105 return (KASLRScanType)m_collection_sp->GetPropertyAtIndexAsEnumeration(
106 NULL, idx, g_properties[idx].default_uint_value);
107 }
Greg Claytone8cd0c92012-10-19 18:02:49 +0000108};
109
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110typedef std::shared_ptr<DynamicLoaderDarwinKernelProperties>
111 DynamicLoaderDarwinKernelPropertiesSP;
Greg Claytone8cd0c92012-10-19 18:02:49 +0000112
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113static const DynamicLoaderDarwinKernelPropertiesSP &GetGlobalProperties() {
114 static DynamicLoaderDarwinKernelPropertiesSP g_settings_sp;
115 if (!g_settings_sp)
116 g_settings_sp.reset(new DynamicLoaderDarwinKernelProperties());
117 return g_settings_sp;
Greg Claytone8cd0c92012-10-19 18:02:49 +0000118}
119
Greg Clayton7b242382011-07-08 00:48:09 +0000120//----------------------------------------------------------------------
Adrian Prantl05097242018-04-30 16:49:04 +0000121// Create an instance of this class. This function is filled into the plugin
122// info class that gets handed out by the plugin factory and allows the lldb to
123// instantiate an instance of this class.
Greg Clayton7b242382011-07-08 00:48:09 +0000124//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000125DynamicLoader *DynamicLoaderDarwinKernel::CreateInstance(Process *process,
126 bool force) {
127 if (!force) {
Adrian Prantl05097242018-04-30 16:49:04 +0000128 // If the user provided an executable binary and it is not a kernel, this
129 // plugin should not create an instance.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000130 Module *exe_module = process->GetTarget().GetExecutableModulePointer();
131 if (exe_module) {
132 ObjectFile *object_file = exe_module->GetObjectFile();
133 if (object_file) {
134 if (object_file->GetStrata() != ObjectFile::eStrataKernel) {
135 return NULL;
Greg Claytondf0b7d52011-07-08 04:11:42 +0000136 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137 }
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000138 }
139
Kate Stoneb9c1b512016-09-06 20:57:50 +0000140 // If the target's architecture does not look like an Apple environment,
141 // this plugin should not create an instance.
142 const llvm::Triple &triple_ref =
143 process->GetTarget().GetArchitecture().GetTriple();
144 switch (triple_ref.getOS()) {
145 case llvm::Triple::Darwin:
146 case llvm::Triple::MacOSX:
147 case llvm::Triple::IOS:
148 case llvm::Triple::TvOS:
149 case llvm::Triple::WatchOS:
Jason Molenda32762fd2018-10-11 00:28:35 +0000150 // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000151 if (triple_ref.getVendor() != llvm::Triple::Apple) {
152 return NULL;
153 }
154 break;
Adrian Prantl05097242018-04-30 16:49:04 +0000155 // If we have triple like armv7-unknown-unknown, we should try looking for
156 // a Darwin kernel.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000157 case llvm::Triple::UnknownOS:
158 break;
159 default:
160 return NULL;
161 break;
Jason Molenda503d0182013-03-02 07:19:32 +0000162 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163 }
164
165 // At this point if there is an ExecutableModule, it is a kernel and the
Adrian Prantl05097242018-04-30 16:49:04 +0000166 // Target is some variant of an Apple system. If the Process hasn't provided
167 // the kernel load address, we need to look around in memory to find it.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168
169 const addr_t kernel_load_address = SearchForDarwinKernel(process);
170 if (CheckForKernelImageAtAddress(kernel_load_address, process).IsValid()) {
171 process->SetCanRunCode(false);
172 return new DynamicLoaderDarwinKernel(process, kernel_load_address);
173 }
174 return NULL;
Jason Molenda503d0182013-03-02 07:19:32 +0000175}
176
177lldb::addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000178DynamicLoaderDarwinKernel::SearchForDarwinKernel(Process *process) {
179 addr_t kernel_load_address = process->GetImageInfoAddress();
180 if (kernel_load_address == LLDB_INVALID_ADDRESS) {
181 kernel_load_address = SearchForKernelAtSameLoadAddr(process);
182 if (kernel_load_address == LLDB_INVALID_ADDRESS) {
183 kernel_load_address = SearchForKernelWithDebugHints(process);
184 if (kernel_load_address == LLDB_INVALID_ADDRESS) {
185 kernel_load_address = SearchForKernelNearPC(process);
186 if (kernel_load_address == LLDB_INVALID_ADDRESS) {
187 kernel_load_address = SearchForKernelViaExhaustiveSearch(process);
Greg Claytondf0b7d52011-07-08 04:11:42 +0000188 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000189 }
Greg Clayton7b242382011-07-08 00:48:09 +0000190 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000191 }
192 return kernel_load_address;
Greg Clayton7b242382011-07-08 00:48:09 +0000193}
194
195//----------------------------------------------------------------------
Adrian Prantl05097242018-04-30 16:49:04 +0000196// Check if the kernel binary is loaded in memory without a slide. First verify
197// that the ExecutableModule is a kernel before we proceed. Returns the address
198// of the kernel if one was found, else LLDB_INVALID_ADDRESS.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000199//----------------------------------------------------------------------
200lldb::addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000201DynamicLoaderDarwinKernel::SearchForKernelAtSameLoadAddr(Process *process) {
202 Module *exe_module = process->GetTarget().GetExecutableModulePointer();
203 if (exe_module == NULL)
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000204 return LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000205
206 ObjectFile *exe_objfile = exe_module->GetObjectFile();
207 if (exe_objfile == NULL)
208 return LLDB_INVALID_ADDRESS;
209
210 if (exe_objfile->GetType() != ObjectFile::eTypeExecutable ||
211 exe_objfile->GetStrata() != ObjectFile::eStrataKernel)
212 return LLDB_INVALID_ADDRESS;
213
214 if (!exe_objfile->GetHeaderAddress().IsValid())
215 return LLDB_INVALID_ADDRESS;
216
217 if (CheckForKernelImageAtAddress(
218 exe_objfile->GetHeaderAddress().GetFileAddress(), process) ==
219 exe_module->GetUUID())
220 return exe_objfile->GetHeaderAddress().GetFileAddress();
221
222 return LLDB_INVALID_ADDRESS;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000223}
224
225//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000226// If the debug flag is included in the boot-args nvram setting, the kernel's
Adrian Prantl05097242018-04-30 16:49:04 +0000227// load address will be noted in the lowglo page at a fixed address Returns the
228// address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000229//----------------------------------------------------------------------
230lldb::addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000231DynamicLoaderDarwinKernel::SearchForKernelWithDebugHints(Process *process) {
232 if (GetGlobalProperties()->GetScanType() == eKASLRScanNone)
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000233 return LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000234
Zachary Turner97206d52017-05-12 04:51:55 +0000235 Status read_err;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000236 addr_t kernel_addresses_64[] = {
237 0xfffffff000004010ULL, // newest arm64 devices
238 0xffffff8000004010ULL, // 2014-2015-ish arm64 devices
239 0xffffff8000002010ULL, // oldest arm64 devices
240 LLDB_INVALID_ADDRESS};
Jason Molenda61a8e532016-11-30 23:00:52 +0000241 addr_t kernel_addresses_32[] = {0xffff0110, // 2016 and earlier armv7 devices
242 0xffff1010,
243 LLDB_INVALID_ADDRESS};
Jason Molenda2b0a7be2016-11-15 01:41:27 +0000244
245 uint8_t uval[8];
246 if (process->GetAddressByteSize() == 8) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000247 for (size_t i = 0; kernel_addresses_64[i] != LLDB_INVALID_ADDRESS; i++) {
Jason Molenda2b0a7be2016-11-15 01:41:27 +0000248 if (process->ReadMemoryFromInferior (kernel_addresses_64[i], uval, 8, read_err) == 8)
249 {
250 DataExtractor data (&uval, 8, process->GetByteOrder(), process->GetAddressByteSize());
251 offset_t offset = 0;
252 uint64_t addr = data.GetU64 (&offset);
253 if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
254 return addr;
255 }
256 }
257 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258 }
259
Jason Molenda2b0a7be2016-11-15 01:41:27 +0000260 if (process->GetAddressByteSize() == 4) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000261 for (size_t i = 0; kernel_addresses_32[i] != LLDB_INVALID_ADDRESS; i++) {
Jason Molenda2b0a7be2016-11-15 01:41:27 +0000262 if (process->ReadMemoryFromInferior (kernel_addresses_32[i], uval, 4, read_err) == 4)
263 {
264 DataExtractor data (&uval, 4, process->GetByteOrder(), process->GetAddressByteSize());
265 offset_t offset = 0;
266 uint32_t addr = data.GetU32 (&offset);
267 if (CheckForKernelImageAtAddress(addr, process).IsValid()) {
268 return addr;
269 }
270 }
271 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000272 }
273
274 return LLDB_INVALID_ADDRESS;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000275}
276
277//----------------------------------------------------------------------
Adrian Prantl05097242018-04-30 16:49:04 +0000278// If the kernel is currently executing when lldb attaches, and we don't have a
279// better way of finding the kernel's load address, try searching backwards
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000280// from the current pc value looking for the kernel's Mach header in memory.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000281// Returns the address of the kernel if one was found, else
282// LLDB_INVALID_ADDRESS.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000283//----------------------------------------------------------------------
284lldb::addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000285DynamicLoaderDarwinKernel::SearchForKernelNearPC(Process *process) {
286 if (GetGlobalProperties()->GetScanType() == eKASLRScanNone ||
287 GetGlobalProperties()->GetScanType() == eKASLRScanLowgloAddresses) {
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000288 return LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000289 }
290
291 ThreadSP thread = process->GetThreadList().GetSelectedThread();
292 if (thread.get() == NULL)
293 return LLDB_INVALID_ADDRESS;
294 addr_t pc = thread->GetRegisterContext()->GetPC(LLDB_INVALID_ADDRESS);
295
296 if (pc == LLDB_INVALID_ADDRESS)
297 return LLDB_INVALID_ADDRESS;
298
299 // The kernel will load at at one megabyte boundary (0x100000), or at that
Adrian Prantl05097242018-04-30 16:49:04 +0000300 // boundary plus an offset of one page (0x1000) or two, or four (0x4000),
301 // depending on the device.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000302
303 // Round the current pc down to the nearest one megabyte boundary - the place
304 // where we will start searching.
305 addr_t addr = pc & ~0xfffff;
306
307 // Search backwards 32 megabytes, looking for the start of the kernel at each
308 // one-megabyte boundary.
309 for (int i = 0; i < 32; i++, addr -= 0x100000) {
310 if (CheckForKernelImageAtAddress(addr, process).IsValid())
311 return addr;
312 if (CheckForKernelImageAtAddress(addr + 0x1000, process).IsValid())
313 return addr + 0x1000;
314 if (CheckForKernelImageAtAddress(addr + 0x2000, process).IsValid())
315 return addr + 0x2000;
316 if (CheckForKernelImageAtAddress(addr + 0x4000, process).IsValid())
317 return addr + 0x4000;
318 }
319
320 return LLDB_INVALID_ADDRESS;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000321}
322
323//----------------------------------------------------------------------
Adrian Prantl05097242018-04-30 16:49:04 +0000324// Scan through the valid address range for a kernel binary. This is uselessly
325// slow in 64-bit environments so we don't even try it. This scan is not
326// enabled by default even for 32-bit targets. Returns the address of the
327// kernel if one was found, else LLDB_INVALID_ADDRESS.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000328//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000329lldb::addr_t DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch(
330 Process *process) {
331 if (GetGlobalProperties()->GetScanType() != eKASLRScanExhaustiveScan) {
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000332 return LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000333 }
334
335 addr_t kernel_range_low, kernel_range_high;
336 if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8) {
337 kernel_range_low = 1ULL << 63;
338 kernel_range_high = UINT64_MAX;
339 } else {
340 kernel_range_low = 1ULL << 31;
341 kernel_range_high = UINT32_MAX;
342 }
343
344 // Stepping through memory at one-megabyte resolution looking for a kernel
345 // rarely works (fast enough) with a 64-bit address space -- for now, let's
346 // not even bother. We may be attaching to something which *isn't* a kernel
347 // and we don't want to spin for minutes on-end looking for a kernel.
348 if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
349 return LLDB_INVALID_ADDRESS;
350
351 addr_t addr = kernel_range_low;
352
353 while (addr >= kernel_range_low && addr < kernel_range_high) {
354 if (CheckForKernelImageAtAddress(addr, process).IsValid())
355 return addr;
356 if (CheckForKernelImageAtAddress(addr + 0x1000, process).IsValid())
357 return addr + 0x1000;
358 if (CheckForKernelImageAtAddress(addr + 0x2000, process).IsValid())
359 return addr + 0x2000;
360 if (CheckForKernelImageAtAddress(addr + 0x4000, process).IsValid())
361 return addr + 0x4000;
362 addr += 0x100000;
363 }
364 return LLDB_INVALID_ADDRESS;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000365}
366
367//----------------------------------------------------------------------
Jason Molenda87f0f952018-06-18 23:30:03 +0000368// Read the mach_header struct out of memory and return it.
369// Returns true if the mach_header was successfully read,
370// Returns false if there was a problem reading the header, or it was not
371// a Mach-O header.
372//----------------------------------------------------------------------
373
374bool
375DynamicLoaderDarwinKernel::ReadMachHeader(addr_t addr, Process *process, llvm::MachO::mach_header &header) {
376 Status read_error;
377
378 // Read the mach header and see whether it looks like a kernel
379 if (process->DoReadMemory (addr, &header, sizeof(header), read_error) !=
380 sizeof(header))
381 return false;
382
383 const uint32_t magicks[] = { llvm::MachO::MH_MAGIC_64, llvm::MachO::MH_MAGIC, llvm::MachO::MH_CIGAM, llvm::MachO::MH_CIGAM_64};
384
385 bool found_matching_pattern = false;
386 for (size_t i = 0; i < llvm::array_lengthof (magicks); i++)
387 if (::memcmp (&header.magic, &magicks[i], sizeof (uint32_t)) == 0)
388 found_matching_pattern = true;
389
390 if (found_matching_pattern == false)
391 return false;
392
393 if (header.magic == llvm::MachO::MH_CIGAM ||
394 header.magic == llvm::MachO::MH_CIGAM_64) {
395 header.magic = llvm::ByteSwap_32(header.magic);
396 header.cputype = llvm::ByteSwap_32(header.cputype);
397 header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
398 header.filetype = llvm::ByteSwap_32(header.filetype);
399 header.ncmds = llvm::ByteSwap_32(header.ncmds);
400 header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
401 header.flags = llvm::ByteSwap_32(header.flags);
402 }
403
404 return true;
405}
406
407//----------------------------------------------------------------------
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000408// Given an address in memory, look to see if there is a kernel image at that
Jason Molenda87f0f952018-06-18 23:30:03 +0000409// address.
410// Returns a UUID; if a kernel was not found at that address, UUID.IsValid()
411// will be false.
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000412//----------------------------------------------------------------------
413lldb_private::UUID
Kate Stoneb9c1b512016-09-06 20:57:50 +0000414DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress(lldb::addr_t addr,
415 Process *process) {
416 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
417 if (addr == LLDB_INVALID_ADDRESS)
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000418 return UUID();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000419
420 if (log)
421 log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
422 "looking for kernel binary at 0x%" PRIx64,
423 addr);
424
Kate Stoneb9c1b512016-09-06 20:57:50 +0000425 llvm::MachO::mach_header header;
Jason Molenda87f0f952018-06-18 23:30:03 +0000426
427 if (ReadMachHeader (addr, process, header) == false)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000428 return UUID();
429
Jason Molenda87f0f952018-06-18 23:30:03 +0000430 // First try a quick test -- read the first 4 bytes and see if there is a
431 // valid Mach-O magic field there
432 // (the first field of the mach_header/mach_header_64 struct).
Kate Stoneb9c1b512016-09-06 20:57:50 +0000433 // A kernel is an executable which does not have the dynamic link object flag
434 // set.
435 if (header.filetype == llvm::MachO::MH_EXECUTE &&
436 (header.flags & llvm::MachO::MH_DYLDLINK) == 0) {
437 // Create a full module to get the UUID
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000438 ModuleSP memory_module_sp =
439 process->ReadModuleFromMemory(FileSpec("temp_mach_kernel"), addr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000440 if (!memory_module_sp.get())
441 return UUID();
442
443 ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
Jason Molendabc22c8d2016-10-21 23:45:07 +0000444 if (exe_objfile == NULL) {
445 if (log)
446 log->Printf("DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress "
447 "found a binary at 0x%" PRIx64
448 " but could not create an object file from memory",
449 addr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000450 return UUID();
Jason Molendabc22c8d2016-10-21 23:45:07 +0000451 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000452
453 if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
454 exe_objfile->GetStrata() == ObjectFile::eStrataKernel) {
455 ArchSpec kernel_arch(eArchTypeMachO, header.cputype, header.cpusubtype);
456 if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(
457 kernel_arch)) {
458 process->GetTarget().SetArchitecture(kernel_arch);
459 }
Jason Molendabc22c8d2016-10-21 23:45:07 +0000460 if (log) {
461 std::string uuid_str;
462 if (memory_module_sp->GetUUID().IsValid()) {
463 uuid_str = "with UUID ";
464 uuid_str += memory_module_sp->GetUUID().GetAsString();
465 } else {
466 uuid_str = "and no LC_UUID found in load commands ";
467 }
468 log->Printf(
469 "DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress: "
470 "kernel binary image found at 0x%" PRIx64 " with arch '%s' %s",
471 addr, kernel_arch.GetTriple().str().c_str(), uuid_str.c_str());
472 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000473 return memory_module_sp->GetUUID();
474 }
475 }
476
477 return UUID();
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000478}
479
480//----------------------------------------------------------------------
Greg Clayton7b242382011-07-08 00:48:09 +0000481// Constructor
482//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000483DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel(Process *process,
484 lldb::addr_t kernel_addr)
485 : DynamicLoader(process), m_kernel_load_address(kernel_addr), m_kernel(),
486 m_kext_summary_header_ptr_addr(), m_kext_summary_header_addr(),
487 m_kext_summary_header(), m_known_kexts(), m_mutex(),
488 m_break_id(LLDB_INVALID_BREAK_ID) {
Zachary Turner97206d52017-05-12 04:51:55 +0000489 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000490 PlatformSP platform_sp(
491 Platform::Create(PlatformDarwinKernel::GetPluginNameStatic(), error));
492 // Only select the darwin-kernel Platform if we've been asked to load kexts.
493 // It can take some time to scan over all of the kext info.plists and that
494 // shouldn't be done if kext loading is explicitly disabled.
495 if (platform_sp.get() && GetGlobalProperties()->GetLoadKexts()) {
496 process->GetTarget().SetPlatform(platform_sp);
497 }
Greg Clayton7b242382011-07-08 00:48:09 +0000498}
499
500//----------------------------------------------------------------------
501// Destructor
502//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000503DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel() { Clear(true); }
Greg Clayton7b242382011-07-08 00:48:09 +0000504
Kate Stoneb9c1b512016-09-06 20:57:50 +0000505void DynamicLoaderDarwinKernel::UpdateIfNeeded() {
506 LoadKernelModuleIfNeeded();
507 SetNotificationBreakpointIfNeeded();
Greg Clayton374972e2011-07-09 17:15:55 +0000508}
Greg Clayton7b242382011-07-08 00:48:09 +0000509//------------------------------------------------------------------
510/// Called after attaching a process.
511///
512/// Allow DynamicLoader plug-ins to execute some code after
513/// attaching to a process.
514//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000515void DynamicLoaderDarwinKernel::DidAttach() {
516 PrivateInitialize(m_process);
517 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000518}
519
520//------------------------------------------------------------------
521/// Called after attaching a process.
522///
523/// Allow DynamicLoader plug-ins to execute some code after
524/// attaching to a process.
525//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000526void DynamicLoaderDarwinKernel::DidLaunch() {
527 PrivateInitialize(m_process);
528 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000529}
530
Greg Clayton7b242382011-07-08 00:48:09 +0000531//----------------------------------------------------------------------
532// Clear out the state of this class.
533//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000534void DynamicLoaderDarwinKernel::Clear(bool clear_process) {
535 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Clayton7b242382011-07-08 00:48:09 +0000536
Kate Stoneb9c1b512016-09-06 20:57:50 +0000537 if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
538 m_process->ClearBreakpointSiteByID(m_break_id);
Greg Clayton7b242382011-07-08 00:48:09 +0000539
Kate Stoneb9c1b512016-09-06 20:57:50 +0000540 if (clear_process)
541 m_process = NULL;
542 m_kernel.Clear();
543 m_known_kexts.clear();
544 m_kext_summary_header_ptr_addr.Clear();
545 m_kext_summary_header_addr.Clear();
546 m_break_id = LLDB_INVALID_BREAK_ID;
Greg Clayton7b242382011-07-08 00:48:09 +0000547}
548
Kate Stoneb9c1b512016-09-06 20:57:50 +0000549bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageAtFileAddress(
550 Process *process) {
551 if (IsLoaded())
552 return true;
Greg Clayton7b242382011-07-08 00:48:09 +0000553
Kate Stoneb9c1b512016-09-06 20:57:50 +0000554 if (m_module_sp) {
555 bool changed = false;
556 if (m_module_sp->SetLoadAddress(process->GetTarget(), 0, true, changed))
557 m_load_process_stop_id = process->GetStopID();
558 }
559 return false;
560}
Greg Clayton2af282a2012-03-21 04:25:00 +0000561
Kate Stoneb9c1b512016-09-06 20:57:50 +0000562void DynamicLoaderDarwinKernel::KextImageInfo::SetModule(ModuleSP module_sp) {
563 m_module_sp = module_sp;
564 if (module_sp.get() && module_sp->GetObjectFile()) {
565 if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable &&
566 module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel) {
567 m_kernel_image = true;
568 } else {
569 m_kernel_image = false;
570 }
571 }
572}
573
574ModuleSP DynamicLoaderDarwinKernel::KextImageInfo::GetModule() {
575 return m_module_sp;
576}
577
578void DynamicLoaderDarwinKernel::KextImageInfo::SetLoadAddress(
579 addr_t load_addr) {
580 m_load_address = load_addr;
581}
582
583addr_t DynamicLoaderDarwinKernel::KextImageInfo::GetLoadAddress() const {
584 return m_load_address;
585}
586
587uint64_t DynamicLoaderDarwinKernel::KextImageInfo::GetSize() const {
588 return m_size;
589}
590
591void DynamicLoaderDarwinKernel::KextImageInfo::SetSize(uint64_t size) {
592 m_size = size;
593}
594
595uint32_t DynamicLoaderDarwinKernel::KextImageInfo::GetProcessStopId() const {
596 return m_load_process_stop_id;
597}
598
599void DynamicLoaderDarwinKernel::KextImageInfo::SetProcessStopId(
600 uint32_t stop_id) {
601 m_load_process_stop_id = stop_id;
602}
603
604bool DynamicLoaderDarwinKernel::KextImageInfo::
605operator==(const KextImageInfo &rhs) {
606 if (m_uuid.IsValid() || rhs.GetUUID().IsValid()) {
607 if (m_uuid == rhs.GetUUID()) {
608 return true;
Greg Clayton2af282a2012-03-21 04:25:00 +0000609 }
610 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000611 }
612
613 if (m_name == rhs.GetName() && m_load_address == rhs.GetLoadAddress())
614 return true;
615
616 return false;
Greg Clayton2af282a2012-03-21 04:25:00 +0000617}
618
Kate Stoneb9c1b512016-09-06 20:57:50 +0000619void DynamicLoaderDarwinKernel::KextImageInfo::SetName(const char *name) {
620 m_name = name;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000621}
622
Kate Stoneb9c1b512016-09-06 20:57:50 +0000623std::string DynamicLoaderDarwinKernel::KextImageInfo::GetName() const {
624 return m_name;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000625}
626
Kate Stoneb9c1b512016-09-06 20:57:50 +0000627void DynamicLoaderDarwinKernel::KextImageInfo::SetUUID(const UUID &uuid) {
628 m_uuid = uuid;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000629}
630
Kate Stoneb9c1b512016-09-06 20:57:50 +0000631UUID DynamicLoaderDarwinKernel::KextImageInfo::GetUUID() const {
632 return m_uuid;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000633}
634
Kate Stoneb9c1b512016-09-06 20:57:50 +0000635// Given the m_load_address from the kext summaries, and a UUID, try to create
Adrian Prantl05097242018-04-30 16:49:04 +0000636// an in-memory Module at that address. Require that the MemoryModule have a
637// matching UUID and detect if this MemoryModule is a kernel or a kext.
Jason Molenda306bd0a2013-02-19 05:42:46 +0000638//
Kate Stoneb9c1b512016-09-06 20:57:50 +0000639// Returns true if m_memory_module_sp is now set to a valid Module.
Jason Molenda306bd0a2013-02-19 05:42:46 +0000640
Kate Stoneb9c1b512016-09-06 20:57:50 +0000641bool DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule(
642 Process *process) {
643 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
644 if (m_memory_module_sp.get() != NULL)
Jason Molenda306bd0a2013-02-19 05:42:46 +0000645 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000646 if (m_load_address == LLDB_INVALID_ADDRESS)
647 return false;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000648
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000649 FileSpec file_spec(m_name.c_str());
Jason Molenda306bd0a2013-02-19 05:42:46 +0000650
Jason Molenda87f0f952018-06-18 23:30:03 +0000651 llvm::MachO::mach_header mh;
652 size_t size_to_read = 512;
David Bolvansky52cadf02018-09-03 22:09:08 +0000653 if (ReadMachHeader(m_load_address, process, mh)) {
654 if (mh.magic == llvm::MachO::MH_CIGAM || mh.magic == llvm::MachO::MH_MAGIC)
655 size_to_read = sizeof(llvm::MachO::mach_header) + mh.sizeofcmds;
656 if (mh.magic == llvm::MachO::MH_CIGAM_64 ||
657 mh.magic == llvm::MachO::MH_MAGIC_64)
658 size_to_read = sizeof(llvm::MachO::mach_header_64) + mh.sizeofcmds;
Jason Molenda87f0f952018-06-18 23:30:03 +0000659 }
660
Kate Stoneb9c1b512016-09-06 20:57:50 +0000661 ModuleSP memory_module_sp =
Jason Molenda87f0f952018-06-18 23:30:03 +0000662 process->ReadModuleFromMemory(file_spec, m_load_address, size_to_read);
Jason Molenda306bd0a2013-02-19 05:42:46 +0000663
Kate Stoneb9c1b512016-09-06 20:57:50 +0000664 if (memory_module_sp.get() == NULL)
665 return false;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000666
Kate Stoneb9c1b512016-09-06 20:57:50 +0000667 bool is_kernel = false;
668 if (memory_module_sp->GetObjectFile()) {
669 if (memory_module_sp->GetObjectFile()->GetType() ==
670 ObjectFile::eTypeExecutable &&
671 memory_module_sp->GetObjectFile()->GetStrata() ==
672 ObjectFile::eStrataKernel) {
673 is_kernel = true;
674 } else if (memory_module_sp->GetObjectFile()->GetType() ==
675 ObjectFile::eTypeSharedLibrary) {
676 is_kernel = false;
Jason Molenda87a04b22012-10-19 03:40:45 +0000677 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000678 }
Jason Molenda87a04b22012-10-19 03:40:45 +0000679
Kate Stoneb9c1b512016-09-06 20:57:50 +0000680 // If this is a kext, and the kernel specified what UUID we should find at
Adrian Prantl05097242018-04-30 16:49:04 +0000681 // this load address, require that the memory module have a matching UUID or
682 // something has gone wrong and we should discard it.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000683 if (m_uuid.IsValid()) {
684 if (m_uuid != memory_module_sp->GetUUID()) {
685 if (log) {
686 log->Printf("KextImageInfo::ReadMemoryModule the kernel said to find "
687 "uuid %s at 0x%" PRIx64
688 " but instead we found uuid %s, throwing it away",
689 m_uuid.GetAsString().c_str(), m_load_address,
690 memory_module_sp->GetUUID().GetAsString().c_str());
691 }
692 return false;
693 }
694 }
Jason Molenda306bd0a2013-02-19 05:42:46 +0000695
Kate Stoneb9c1b512016-09-06 20:57:50 +0000696 // If the in-memory Module has a UUID, let's use that.
697 if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid()) {
698 m_uuid = memory_module_sp->GetUUID();
699 }
700
701 m_memory_module_sp = memory_module_sp;
702 m_kernel_image = is_kernel;
703 if (is_kernel) {
704 if (log) {
705 // This is unusual and probably not intended
706 log->Printf("KextImageInfo::ReadMemoryModule read the kernel binary out "
707 "of memory");
708 }
709 if (memory_module_sp->GetArchitecture().IsValid()) {
710 process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture());
711 }
712 if (m_uuid.IsValid()) {
713 ModuleSP exe_module_sp = process->GetTarget().GetExecutableModule();
714 if (exe_module_sp.get() && exe_module_sp->GetUUID().IsValid()) {
715 if (m_uuid != exe_module_sp->GetUUID()) {
716 // The user specified a kernel binary that has a different UUID than
717 // the kernel actually running in memory. This never ends well;
718 // clear the user specified kernel binary from the Target.
719
720 m_module_sp.reset();
721
722 ModuleList user_specified_kernel_list;
723 user_specified_kernel_list.Append(exe_module_sp);
724 process->GetTarget().GetImages().Remove(user_specified_kernel_list);
725 }
726 }
727 }
728 }
729
730 return true;
731}
732
733bool DynamicLoaderDarwinKernel::KextImageInfo::IsKernel() const {
734 return m_kernel_image == true;
735}
736
737void DynamicLoaderDarwinKernel::KextImageInfo::SetIsKernel(bool is_kernel) {
738 m_kernel_image = is_kernel;
739}
740
741bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
742 Process *process) {
743 if (IsLoaded())
744 return true;
745
746 Target &target = process->GetTarget();
747
Adrian Prantl05097242018-04-30 16:49:04 +0000748 // If we don't have / can't create a memory module for this kext, don't try
749 // to load it - we won't have the correct segment load addresses.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000750 if (!ReadMemoryModule(process)) {
751 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
752 if (log)
753 log->Printf("Unable to read '%s' from memory at address 0x%" PRIx64
754 " to get the segment load addresses.",
755 m_name.c_str(), m_load_address);
756 return false;
757 }
758
759 bool uuid_is_valid = m_uuid.IsValid();
760
761 if (IsKernel() && uuid_is_valid && m_memory_module_sp.get()) {
762 Stream *s = target.GetDebugger().GetOutputFile().get();
763 if (s) {
764 s->Printf("Kernel UUID: %s\n",
765 m_memory_module_sp->GetUUID().GetAsString().c_str());
766 s->Printf("Load Address: 0x%" PRIx64 "\n", m_load_address);
767 }
768 }
769
770 if (!m_module_sp) {
771 // See if the kext has already been loaded into the target, probably by the
772 // user doing target modules add.
773 const ModuleList &target_images = target.GetImages();
774 m_module_sp = target_images.FindModule(m_uuid);
775
776 // Search for the kext on the local filesystem via the UUID
777 if (!m_module_sp && uuid_is_valid) {
778 ModuleSpec module_spec;
779 module_spec.GetUUID() = m_uuid;
780 module_spec.GetArchitecture() = target.GetArchitecture();
781
Adrian Prantl05097242018-04-30 16:49:04 +0000782 // For the kernel, we really do need an on-disk file copy of the binary
783 // to do anything useful. This will force a clal to
Kate Stoneb9c1b512016-09-06 20:57:50 +0000784 if (IsKernel()) {
785 if (Symbols::DownloadObjectAndSymbolFile(module_spec, true)) {
Jonas Devliegheredbd7fab2018-11-01 17:09:25 +0000786 if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000787 m_module_sp.reset(new Module(module_spec.GetFileSpec(),
788 target.GetArchitecture()));
789 if (m_module_sp.get() &&
790 m_module_sp->MatchesModuleSpec(module_spec)) {
791 ModuleList loaded_module_list;
792 loaded_module_list.Append(m_module_sp);
793 target.ModulesDidLoad(loaded_module_list);
794 }
795 }
796 }
797 }
798
799 // If the current platform is PlatformDarwinKernel, create a ModuleSpec
Adrian Prantl05097242018-04-30 16:49:04 +0000800 // with the filename set to be the bundle ID for this kext, e.g.
801 // "com.apple.filesystems.msdosfs", and ask the platform to find it.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000802 PlatformSP platform_sp(target.GetPlatform());
803 if (!m_module_sp && platform_sp) {
804 ConstString platform_name(platform_sp->GetPluginName());
805 static ConstString g_platform_name(
806 PlatformDarwinKernel::GetPluginNameStatic());
807 if (platform_name == g_platform_name) {
808 ModuleSpec kext_bundle_module_spec(module_spec);
Jonas Devlieghere8f3be7a2018-11-01 21:05:36 +0000809 FileSpec kext_filespec(m_name.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000810 kext_bundle_module_spec.GetFileSpec() = kext_filespec;
811 platform_sp->GetSharedModule(
812 kext_bundle_module_spec, process, m_module_sp,
813 &target.GetExecutableSearchPaths(), NULL, NULL);
814 }
815 }
816
817 // Ask the Target to find this file on the local system, if possible.
818 // This will search in the list of currently-loaded files, look in the
819 // standard search paths on the system, and on a Mac it will try calling
820 // the DebugSymbols framework with the UUID to find the binary via its
821 // search methods.
822 if (!m_module_sp) {
823 m_module_sp = target.GetSharedModule(module_spec);
824 }
825
826 if (IsKernel() && !m_module_sp) {
Greg Clayton44d93782014-01-27 23:43:24 +0000827 Stream *s = target.GetDebugger().GetOutputFile().get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000828 if (s) {
829 s->Printf("WARNING: Unable to locate kernel binary on the debugger "
830 "system.\n");
Jason Molendae575e7b2013-02-19 06:11:13 +0000831 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000832 }
Jason Molendae575e7b2013-02-19 06:11:13 +0000833 }
834
Adrian Prantl05097242018-04-30 16:49:04 +0000835 // If we managed to find a module, append it to the target's list of
836 // images. If we also have a memory module, require that they have matching
837 // UUIDs
Kate Stoneb9c1b512016-09-06 20:57:50 +0000838 if (m_module_sp) {
839 bool uuid_match_ok = true;
840 if (m_memory_module_sp) {
841 if (m_module_sp->GetUUID() != m_memory_module_sp->GetUUID()) {
842 uuid_match_ok = false;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000843 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000844 }
845 if (uuid_match_ok) {
846 target.GetImages().AppendIfNeeded(m_module_sp);
847 if (IsKernel() &&
848 target.GetExecutableModulePointer() != m_module_sp.get()) {
Jonas Devliegheref9a07e92018-09-20 09:09:05 +0000849 target.SetExecutableModule(m_module_sp, eLoadDependentsNo);
Greg Claytonc859e2d2012-02-13 23:10:39 +0000850 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000851 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000852 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000853 }
854
855 if (!m_module_sp && !IsKernel() && m_uuid.IsValid() && !m_name.empty()) {
856 Stream *s = target.GetDebugger().GetOutputFile().get();
857 if (s) {
858 s->Printf("warning: Can't find binary/dSYM for %s (%s)\n", m_name.c_str(),
859 m_uuid.GetAsString().c_str());
Jason Molenda56c23282013-02-19 06:39:56 +0000860 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000861 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000862
Kate Stoneb9c1b512016-09-06 20:57:50 +0000863 static ConstString g_section_name_LINKEDIT("__LINKEDIT");
Greg Clayton67408532012-12-11 01:20:51 +0000864
Kate Stoneb9c1b512016-09-06 20:57:50 +0000865 if (m_memory_module_sp && m_module_sp) {
866 if (m_module_sp->GetUUID() == m_memory_module_sp->GetUUID()) {
867 ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();
868 ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile();
Jason Molendabb860bd2012-10-09 01:17:11 +0000869
Kate Stoneb9c1b512016-09-06 20:57:50 +0000870 if (memory_object_file && ondisk_object_file) {
871 // The memory_module for kexts may have an invalid __LINKEDIT seg; skip
872 // it.
873 const bool ignore_linkedit = !IsKernel();
Greg Clayton67408532012-12-11 01:20:51 +0000874
Kate Stoneb9c1b512016-09-06 20:57:50 +0000875 SectionList *ondisk_section_list = ondisk_object_file->GetSectionList();
876 SectionList *memory_section_list = memory_object_file->GetSectionList();
877 if (memory_section_list && ondisk_section_list) {
878 const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
Adrian Prantl05097242018-04-30 16:49:04 +0000879 // There may be CTF sections in the memory image so we can't always
880 // just compare the number of sections (which are actually segments
881 // in mach-o parlance)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000882 uint32_t sect_idx = 0;
883
Adrian Prantl05097242018-04-30 16:49:04 +0000884 // Use the memory_module's addresses for each section to set the file
885 // module's load address as appropriate. We don't want to use a
886 // single slide value for the entire kext - different segments may be
887 // slid different amounts by the kext loader.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000888
889 uint32_t num_sections_loaded = 0;
890 for (sect_idx = 0; sect_idx < num_ondisk_sections; ++sect_idx) {
891 SectionSP ondisk_section_sp(
892 ondisk_section_list->GetSectionAtIndex(sect_idx));
893 if (ondisk_section_sp) {
894 // Don't ever load __LINKEDIT as it may or may not be actually
895 // mapped into memory and there is no current way to tell.
896 // I filed rdar://problem/12851706 to track being able to tell
897 // if the __LINKEDIT is actually mapped, but until then, we need
898 // to not load the __LINKEDIT
899 if (ignore_linkedit &&
900 ondisk_section_sp->GetName() == g_section_name_LINKEDIT)
901 continue;
902
903 const Section *memory_section =
904 memory_section_list
905 ->FindSectionByName(ondisk_section_sp->GetName())
906 .get();
907 if (memory_section) {
908 target.SetSectionLoadAddress(ondisk_section_sp,
909 memory_section->GetFileAddress());
910 ++num_sections_loaded;
911 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000912 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000913 }
914 if (num_sections_loaded > 0)
915 m_load_process_stop_id = process->GetStopID();
916 else
917 m_module_sp.reset(); // No sections were loaded
918 } else
919 m_module_sp.reset(); // One or both section lists
920 } else
921 m_module_sp.reset(); // One or both object files missing
922 } else
923 m_module_sp.reset(); // UUID mismatch
924 }
925
926 bool is_loaded = IsLoaded();
927
928 if (is_loaded && m_module_sp && IsKernel()) {
929 Stream *s = target.GetDebugger().GetOutputFile().get();
930 if (s) {
931 ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
932 if (kernel_object_file) {
933 addr_t file_address =
934 kernel_object_file->GetHeaderAddress().GetFileAddress();
935 if (m_load_address != LLDB_INVALID_ADDRESS &&
936 file_address != LLDB_INVALID_ADDRESS) {
937 s->Printf("Kernel slid 0x%" PRIx64 " in memory.\n",
938 m_load_address - file_address);
Greg Claytonc859e2d2012-02-13 23:10:39 +0000939 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000940 }
941 {
942 s->Printf("Loaded kernel file %s\n",
943 m_module_sp->GetFileSpec().GetPath().c_str());
944 }
945 s->Flush();
Greg Claytonc859e2d2012-02-13 23:10:39 +0000946 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000947 }
948 return is_loaded;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000949}
950
Kate Stoneb9c1b512016-09-06 20:57:50 +0000951uint32_t DynamicLoaderDarwinKernel::KextImageInfo::GetAddressByteSize() {
952 if (m_memory_module_sp)
953 return m_memory_module_sp->GetArchitecture().GetAddressByteSize();
954 if (m_module_sp)
955 return m_module_sp->GetArchitecture().GetAddressByteSize();
956 return 0;
Greg Clayton1f746072012-08-29 21:13:06 +0000957}
958
Kate Stoneb9c1b512016-09-06 20:57:50 +0000959lldb::ByteOrder DynamicLoaderDarwinKernel::KextImageInfo::GetByteOrder() {
960 if (m_memory_module_sp)
961 return m_memory_module_sp->GetArchitecture().GetByteOrder();
962 if (m_module_sp)
963 return m_module_sp->GetArchitecture().GetByteOrder();
964 return endian::InlHostByteOrder();
Greg Clayton1f746072012-08-29 21:13:06 +0000965}
966
967lldb_private::ArchSpec
Kate Stoneb9c1b512016-09-06 20:57:50 +0000968DynamicLoaderDarwinKernel::KextImageInfo::GetArchitecture() const {
969 if (m_memory_module_sp)
970 return m_memory_module_sp->GetArchitecture();
971 if (m_module_sp)
972 return m_module_sp->GetArchitecture();
973 return lldb_private::ArchSpec();
Greg Clayton1f746072012-08-29 21:13:06 +0000974}
975
Greg Clayton7b242382011-07-08 00:48:09 +0000976//----------------------------------------------------------------------
Adrian Prantl05097242018-04-30 16:49:04 +0000977// Load the kernel module and initialize the "m_kernel" member. Return true
978// _only_ if the kernel is loaded the first time through (subsequent calls to
979// this function should return false after the kernel has been already loaded).
Greg Clayton7b242382011-07-08 00:48:09 +0000980//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000981void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
982 if (!m_kext_summary_header_ptr_addr.IsValid()) {
983 m_kernel.Clear();
984 m_kernel.SetModule(m_process->GetTarget().GetExecutableModule());
985 m_kernel.SetIsKernel(true);
Jason Molenda4bd4e7e2012-09-29 04:02:01 +0000986
Kate Stoneb9c1b512016-09-06 20:57:50 +0000987 ConstString kernel_name("mach_kernel");
988 if (m_kernel.GetModule().get() && m_kernel.GetModule()->GetObjectFile() &&
989 !m_kernel.GetModule()
990 ->GetObjectFile()
991 ->GetFileSpec()
992 .GetFilename()
993 .IsEmpty()) {
994 kernel_name =
995 m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename();
Greg Clayton7b242382011-07-08 00:48:09 +0000996 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000997 m_kernel.SetName(kernel_name.AsCString());
998
999 if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS) {
1000 m_kernel.SetLoadAddress(m_kernel_load_address);
1001 if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS &&
1002 m_kernel.GetModule()) {
Adrian Prantl05097242018-04-30 16:49:04 +00001003 // We didn't get a hint from the process, so we will try the kernel at
1004 // the address that it exists at in the file if we have one
Kate Stoneb9c1b512016-09-06 20:57:50 +00001005 ObjectFile *kernel_object_file = m_kernel.GetModule()->GetObjectFile();
1006 if (kernel_object_file) {
1007 addr_t load_address =
1008 kernel_object_file->GetHeaderAddress().GetLoadAddress(
1009 &m_process->GetTarget());
1010 addr_t file_address =
1011 kernel_object_file->GetHeaderAddress().GetFileAddress();
1012 if (load_address != LLDB_INVALID_ADDRESS && load_address != 0) {
1013 m_kernel.SetLoadAddress(load_address);
1014 if (load_address != file_address) {
1015 // Don't accidentally relocate the kernel to the File address --
1016 // the Load address has already been set to its actual in-memory
Adrian Prantl05097242018-04-30 16:49:04 +00001017 // address. Mark it as IsLoaded.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001018 m_kernel.SetProcessStopId(m_process->GetStopID());
1019 }
1020 } else {
1021 m_kernel.SetLoadAddress(file_address);
1022 }
1023 }
1024 }
1025 }
1026
1027 if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS) {
1028 if (!m_kernel.LoadImageUsingMemoryModule(m_process)) {
1029 m_kernel.LoadImageAtFileAddress(m_process);
1030 }
1031 }
Jim Ingham519b0812017-02-28 18:57:54 +00001032
Adrian Prantl05097242018-04-30 16:49:04 +00001033 // The operating system plugin gets loaded and initialized in
1034 // LoadImageUsingMemoryModule when we discover the kernel dSYM. For a core
1035 // file in particular, that's the wrong place to do this, since we haven't
1036 // fixed up the section addresses yet. So let's redo it here.
Jim Ingham519b0812017-02-28 18:57:54 +00001037 LoadOperatingSystemPlugin(false);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001038
1039 if (m_kernel.IsLoaded() && m_kernel.GetModule()) {
1040 static ConstString kext_summary_symbol("gLoadedKextSummaries");
1041 const Symbol *symbol =
1042 m_kernel.GetModule()->FindFirstSymbolWithNameAndType(
1043 kext_summary_symbol, eSymbolTypeData);
1044 if (symbol) {
1045 m_kext_summary_header_ptr_addr = symbol->GetAddress();
1046 // Update all image infos
1047 ReadAllKextSummaries();
1048 }
1049 } else {
1050 m_kernel.Clear();
1051 }
1052 }
Greg Clayton7b242382011-07-08 00:48:09 +00001053}
1054
Greg Clayton7b242382011-07-08 00:48:09 +00001055//----------------------------------------------------------------------
1056// Static callback function that gets called when our DYLD notification
Adrian Prantl05097242018-04-30 16:49:04 +00001057// breakpoint gets hit. We update all of our image infos and then let our super
1058// class DynamicLoader class decide if we should stop or not (based on global
1059// preference).
Greg Clayton7b242382011-07-08 00:48:09 +00001060//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001061bool DynamicLoaderDarwinKernel::BreakpointHitCallback(
1062 void *baton, StoppointCallbackContext *context, user_id_t break_id,
1063 user_id_t break_loc_id) {
1064 return static_cast<DynamicLoaderDarwinKernel *>(baton)->BreakpointHit(
1065 context, break_id, break_loc_id);
Greg Clayton7b242382011-07-08 00:48:09 +00001066}
1067
Kate Stoneb9c1b512016-09-06 20:57:50 +00001068bool DynamicLoaderDarwinKernel::BreakpointHit(StoppointCallbackContext *context,
1069 user_id_t break_id,
1070 user_id_t break_loc_id) {
1071 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
1072 if (log)
1073 log->Printf("DynamicLoaderDarwinKernel::BreakpointHit (...)\n");
Greg Claytond16e1e52011-07-12 17:06:17 +00001074
Kate Stoneb9c1b512016-09-06 20:57:50 +00001075 ReadAllKextSummaries();
Greg Claytond16e1e52011-07-12 17:06:17 +00001076
Kate Stoneb9c1b512016-09-06 20:57:50 +00001077 if (log)
1078 PutToLog(log);
1079
1080 return GetStopWhenImagesChange();
Greg Clayton374972e2011-07-09 17:15:55 +00001081}
1082
Kate Stoneb9c1b512016-09-06 20:57:50 +00001083bool DynamicLoaderDarwinKernel::ReadKextSummaryHeader() {
1084 std::lock_guard<std::recursive_mutex> guard(m_mutex);
Greg Clayton374972e2011-07-09 17:15:55 +00001085
Kate Stoneb9c1b512016-09-06 20:57:50 +00001086 // the all image infos is already valid for this process stop ID
Greg Clayton7b242382011-07-08 00:48:09 +00001087
Kate Stoneb9c1b512016-09-06 20:57:50 +00001088 if (m_kext_summary_header_ptr_addr.IsValid()) {
1089 const uint32_t addr_size = m_kernel.GetAddressByteSize();
1090 const ByteOrder byte_order = m_kernel.GetByteOrder();
Zachary Turner97206d52017-05-12 04:51:55 +00001091 Status error;
Adrian Prantl05097242018-04-30 16:49:04 +00001092 // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure which
1093 // is currently 4 uint32_t and a pointer.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001094 uint8_t buf[24];
1095 DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
1096 const size_t count = 4 * sizeof(uint32_t) + addr_size;
1097 const bool prefer_file_cache = false;
1098 if (m_process->GetTarget().ReadPointerFromMemory(
1099 m_kext_summary_header_ptr_addr, prefer_file_cache, error,
1100 m_kext_summary_header_addr)) {
1101 // We got a valid address for our kext summary header and make sure it
1102 // isn't NULL
1103 if (m_kext_summary_header_addr.IsValid() &&
1104 m_kext_summary_header_addr.GetFileAddress() != 0) {
1105 const size_t bytes_read = m_process->GetTarget().ReadMemory(
1106 m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
1107 if (bytes_read == count) {
1108 lldb::offset_t offset = 0;
1109 m_kext_summary_header.version = data.GetU32(&offset);
1110 if (m_kext_summary_header.version > 128) {
1111 Stream *s =
1112 m_process->GetTarget().GetDebugger().GetOutputFile().get();
1113 s->Printf("WARNING: Unable to read kext summary header, got "
1114 "improbable version number %u\n",
1115 m_kext_summary_header.version);
1116 // If we get an improbably large version number, we're probably
1117 // getting bad memory.
1118 m_kext_summary_header_addr.Clear();
1119 return false;
1120 }
1121 if (m_kext_summary_header.version >= 2) {
1122 m_kext_summary_header.entry_size = data.GetU32(&offset);
1123 if (m_kext_summary_header.entry_size > 4096) {
1124 // If we get an improbably large entry_size, we're probably
1125 // getting bad memory.
1126 Stream *s =
1127 m_process->GetTarget().GetDebugger().GetOutputFile().get();
1128 s->Printf("WARNING: Unable to read kext summary header, got "
1129 "improbable entry_size %u\n",
1130 m_kext_summary_header.entry_size);
1131 m_kext_summary_header_addr.Clear();
1132 return false;
Greg Claytond16e1e52011-07-12 17:06:17 +00001133 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001134 } else {
Adrian Prantl05097242018-04-30 16:49:04 +00001135 // Versions less than 2 didn't have an entry size, it was hard
1136 // coded
Kate Stoneb9c1b512016-09-06 20:57:50 +00001137 m_kext_summary_header.entry_size =
1138 KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
1139 }
1140 m_kext_summary_header.entry_count = data.GetU32(&offset);
1141 if (m_kext_summary_header.entry_count > 10000) {
1142 // If we get an improbably large number of kexts, we're probably
1143 // getting bad memory.
1144 Stream *s =
1145 m_process->GetTarget().GetDebugger().GetOutputFile().get();
1146 s->Printf("WARNING: Unable to read kext summary header, got "
1147 "improbable number of kexts %u\n",
1148 m_kext_summary_header.entry_count);
1149 m_kext_summary_header_addr.Clear();
1150 return false;
1151 }
1152 return true;
Greg Clayton7b242382011-07-08 00:48:09 +00001153 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001154 }
Greg Clayton7b242382011-07-08 00:48:09 +00001155 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001156 }
1157 m_kext_summary_header_addr.Clear();
1158 return false;
Greg Clayton7b242382011-07-08 00:48:09 +00001159}
1160
Kate Stoneb9c1b512016-09-06 20:57:50 +00001161// We've either (a) just attached to a new kernel, or (b) the kexts-changed
Adrian Prantl05097242018-04-30 16:49:04 +00001162// breakpoint was hit and we need to figure out what kexts have been added or
1163// removed. Read the kext summaries from the inferior kernel memory, compare
1164// them against the m_known_kexts vector and update the m_known_kexts vector as
1165// needed to keep in sync with the 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
Adrian Prantl05097242018-04-30 16:49:04 +00001181 // user requested no kext loading, don't print any messages about kexts &
1182 // don't try to read them.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001183 const bool load_kexts = GetGlobalProperties()->GetLoadKexts();
1184
1185 // By default, all kexts we've loaded in the past are marked as "remove" and
Adrian Prantl05097242018-04-30 16:49:04 +00001186 // all of the kexts we just found out about from ReadKextSummaries are marked
1187 // as "add".
Kate Stoneb9c1b512016-09-06 20:57:50 +00001188 std::vector<bool> to_be_removed(m_known_kexts.size(), true);
1189 std::vector<bool> to_be_added(count, true);
1190
1191 int number_of_new_kexts_being_added = 0;
1192 int number_of_old_kexts_being_removed = m_known_kexts.size();
1193
1194 const uint32_t new_kexts_size = kext_summaries.size();
1195 const uint32_t old_kexts_size = m_known_kexts.size();
1196
Adrian Prantl05097242018-04-30 16:49:04 +00001197 // The m_known_kexts vector may have entries that have been Cleared, or are a
1198 // kernel.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001199 for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++) {
1200 bool ignore = false;
1201 KextImageInfo &image_info = m_known_kexts[old_kext];
1202 if (image_info.IsKernel()) {
1203 ignore = true;
1204 } else if (image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS &&
1205 !image_info.GetModule()) {
1206 ignore = true;
1207 }
1208
1209 if (ignore) {
1210 number_of_old_kexts_being_removed--;
1211 to_be_removed[old_kext] = false;
1212 }
1213 }
1214
1215 // Scan over the list of kexts we just read from the kernel, note those that
1216 // need to be added and those already loaded.
1217 for (uint32_t new_kext = 0; new_kext < new_kexts_size; new_kext++) {
1218 bool add_this_one = true;
1219 for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++) {
1220 if (m_known_kexts[old_kext] == kext_summaries[new_kext]) {
1221 // We already have this kext, don't re-load it.
1222 to_be_added[new_kext] = false;
1223 // This kext is still present, do not remove it.
1224 to_be_removed[old_kext] = false;
1225
1226 number_of_old_kexts_being_removed--;
1227 add_this_one = false;
1228 break;
1229 }
1230 }
Adrian Prantl05097242018-04-30 16:49:04 +00001231 // If this "kext" entry is actually an alias for the kernel -- the kext was
1232 // compiled into the kernel or something -- then we don't want to load the
1233 // kernel's text section at a different address. Ignore this kext entry.
Jason Molendac1871472017-11-30 23:31:18 +00001234 if (kext_summaries[new_kext].GetUUID().IsValid()
1235 && m_kernel.GetUUID().IsValid()
1236 && kext_summaries[new_kext].GetUUID() == m_kernel.GetUUID()) {
1237 to_be_added[new_kext] = false;
1238 break;
1239 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001240 if (add_this_one) {
1241 number_of_new_kexts_being_added++;
1242 }
1243 }
1244
1245 if (number_of_new_kexts_being_added == 0 &&
1246 number_of_old_kexts_being_removed == 0)
1247 return true;
1248
1249 Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
1250 if (s && load_kexts) {
1251 if (number_of_new_kexts_being_added > 0 &&
1252 number_of_old_kexts_being_removed > 0) {
1253 s->Printf("Loading %d kext modules and unloading %d kext modules ",
1254 number_of_new_kexts_being_added,
1255 number_of_old_kexts_being_removed);
1256 } else if (number_of_new_kexts_being_added > 0) {
1257 s->Printf("Loading %d kext modules ", number_of_new_kexts_being_added);
1258 } else if (number_of_old_kexts_being_removed > 0) {
1259 s->Printf("Unloading %d kext modules ",
1260 number_of_old_kexts_being_removed);
1261 }
1262 }
1263
1264 if (log) {
1265 if (load_kexts) {
1266 log->Printf("DynamicLoaderDarwinKernel::ParseKextSummaries: %d kexts "
1267 "added, %d kexts removed",
1268 number_of_new_kexts_being_added,
1269 number_of_old_kexts_being_removed);
1270 } else {
1271 log->Printf(
1272 "DynamicLoaderDarwinKernel::ParseKextSummaries kext loading is "
1273 "disabled, else would have %d kexts added, %d kexts removed",
1274 number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
1275 }
1276 }
1277
1278 if (number_of_new_kexts_being_added > 0) {
1279 ModuleList loaded_module_list;
1280
1281 const uint32_t num_of_new_kexts = kext_summaries.size();
1282 for (uint32_t new_kext = 0; new_kext < num_of_new_kexts; new_kext++) {
1283 if (to_be_added[new_kext] == true) {
1284 KextImageInfo &image_info = kext_summaries[new_kext];
1285 if (load_kexts) {
1286 if (!image_info.LoadImageUsingMemoryModule(m_process)) {
1287 image_info.LoadImageAtFileAddress(m_process);
1288 }
1289 }
1290
1291 m_known_kexts.push_back(image_info);
1292
1293 if (image_info.GetModule() &&
1294 m_process->GetStopID() == image_info.GetProcessStopId())
1295 loaded_module_list.AppendIfNeeded(image_info.GetModule());
1296
1297 if (s && load_kexts)
1298 s->Printf(".");
1299
1300 if (log)
1301 kext_summaries[new_kext].PutToLog(log);
1302 }
1303 }
1304 m_process->GetTarget().ModulesDidLoad(loaded_module_list);
1305 }
1306
1307 if (number_of_old_kexts_being_removed > 0) {
1308 ModuleList loaded_module_list;
1309 const uint32_t num_of_old_kexts = m_known_kexts.size();
1310 for (uint32_t old_kext = 0; old_kext < num_of_old_kexts; old_kext++) {
1311 ModuleList unloaded_module_list;
1312 if (to_be_removed[old_kext]) {
1313 KextImageInfo &image_info = m_known_kexts[old_kext];
1314 // You can't unload the kernel.
1315 if (!image_info.IsKernel()) {
1316 if (image_info.GetModule()) {
1317 unloaded_module_list.AppendIfNeeded(image_info.GetModule());
1318 }
1319 if (s)
1320 s->Printf(".");
1321 image_info.Clear();
1322 // should pull it out of the KextImageInfos vector but that would
Adrian Prantl05097242018-04-30 16:49:04 +00001323 // mutate the list and invalidate the to_be_removed bool vector;
1324 // leaving it in place once Cleared() is relatively harmless.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001325 }
1326 }
1327 m_process->GetTarget().ModulesDidUnload(unloaded_module_list, false);
1328 }
1329 }
1330
1331 if (s && load_kexts) {
1332 s->Printf(" done.\n");
1333 s->Flush();
1334 }
1335
1336 return true;
1337}
1338
1339uint32_t DynamicLoaderDarwinKernel::ReadKextSummaries(
1340 const Address &kext_summary_addr, uint32_t image_infos_count,
1341 KextImageInfo::collection &image_infos) {
1342 const ByteOrder endian = m_kernel.GetByteOrder();
1343 const uint32_t addr_size = m_kernel.GetAddressByteSize();
1344
1345 image_infos.resize(image_infos_count);
1346 const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
1347 DataBufferHeap data(count, 0);
Zachary Turner97206d52017-05-12 04:51:55 +00001348 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001349
1350 const bool prefer_file_cache = false;
1351 const size_t bytes_read = m_process->GetTarget().ReadMemory(
1352 kext_summary_addr, prefer_file_cache, data.GetBytes(), data.GetByteSize(),
1353 error);
1354 if (bytes_read == count) {
1355
1356 DataExtractor extractor(data.GetBytes(), data.GetByteSize(), endian,
1357 addr_size);
1358 uint32_t i = 0;
1359 for (uint32_t kext_summary_offset = 0;
1360 i < image_infos.size() &&
1361 extractor.ValidOffsetForDataOfSize(kext_summary_offset,
1362 m_kext_summary_header.entry_size);
1363 ++i, kext_summary_offset += m_kext_summary_header.entry_size) {
1364 lldb::offset_t offset = kext_summary_offset;
1365 const void *name_data =
1366 extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
1367 if (name_data == NULL)
1368 break;
1369 image_infos[i].SetName((const char *)name_data);
Pavel Labath2f93fd12018-06-26 15:12:20 +00001370 UUID uuid = UUID::fromOptionalData(extractor.GetData(&offset, 16), 16);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001371 image_infos[i].SetUUID(uuid);
1372 image_infos[i].SetLoadAddress(extractor.GetU64(&offset));
1373 image_infos[i].SetSize(extractor.GetU64(&offset));
1374 }
1375 if (i < image_infos.size())
1376 image_infos.resize(i);
1377 } else {
1378 image_infos.clear();
1379 }
1380 return image_infos.size();
1381}
1382
1383bool DynamicLoaderDarwinKernel::ReadAllKextSummaries() {
1384 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1385
1386 if (ReadKextSummaryHeader()) {
1387 if (m_kext_summary_header.entry_count > 0 &&
1388 m_kext_summary_header_addr.IsValid()) {
1389 Address summary_addr(m_kext_summary_header_addr);
1390 summary_addr.Slide(m_kext_summary_header.GetSize());
1391 if (!ParseKextSummaries(summary_addr,
1392 m_kext_summary_header.entry_count)) {
1393 m_known_kexts.clear();
1394 }
1395 return true;
1396 }
1397 }
1398 return false;
Greg Clayton7b242382011-07-08 00:48:09 +00001399}
1400
1401//----------------------------------------------------------------------
Greg Clayton7b242382011-07-08 00:48:09 +00001402// Dump an image info structure to the file handle provided.
1403//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001404void DynamicLoaderDarwinKernel::KextImageInfo::PutToLog(Log *log) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001405 if (m_load_address == LLDB_INVALID_ADDRESS) {
Pavel Labathfbb14282018-06-20 20:13:04 +00001406 LLDB_LOG(log, "uuid={0} name=\"{1}\" (UNLOADED)", m_uuid.GetAsString(),
1407 m_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001408 } else {
Pavel Labathfbb14282018-06-20 20:13:04 +00001409 LLDB_LOG(log, "addr={0:x+16} size={1:x+16} uuid={2} name=\"{3}\"",
1410 m_load_address, m_size, m_uuid.GetAsString(), m_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001411 }
Greg Clayton7b242382011-07-08 00:48:09 +00001412}
1413
1414//----------------------------------------------------------------------
Adrian Prantl05097242018-04-30 16:49:04 +00001415// Dump the _dyld_all_image_infos members and all current image infos that we
1416// have parsed to the file handle provided.
Greg Clayton7b242382011-07-08 00:48:09 +00001417//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001418void DynamicLoaderDarwinKernel::PutToLog(Log *log) const {
1419 if (log == NULL)
1420 return;
Greg Clayton7b242382011-07-08 00:48:09 +00001421
Kate Stoneb9c1b512016-09-06 20:57:50 +00001422 std::lock_guard<std::recursive_mutex> guard(m_mutex);
1423 log->Printf("gLoadedKextSummaries = 0x%16.16" PRIx64
1424 " { version=%u, entry_size=%u, entry_count=%u }",
1425 m_kext_summary_header_addr.GetFileAddress(),
1426 m_kext_summary_header.version, m_kext_summary_header.entry_size,
1427 m_kext_summary_header.entry_count);
Greg Clayton7b242382011-07-08 00:48:09 +00001428
Kate Stoneb9c1b512016-09-06 20:57:50 +00001429 size_t i;
1430 const size_t count = m_known_kexts.size();
1431 if (count > 0) {
1432 log->PutCString("Loaded:");
1433 for (i = 0; i < count; i++)
1434 m_known_kexts[i].PutToLog(log);
1435 }
Greg Clayton7b242382011-07-08 00:48:09 +00001436}
1437
Kate Stoneb9c1b512016-09-06 20:57:50 +00001438void DynamicLoaderDarwinKernel::PrivateInitialize(Process *process) {
1439 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n",
1440 __FUNCTION__, StateAsCString(m_process->GetState()));
1441 Clear(true);
1442 m_process = process;
Greg Clayton7b242382011-07-08 00:48:09 +00001443}
1444
Kate Stoneb9c1b512016-09-06 20:57:50 +00001445void DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded() {
1446 if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.GetModule()) {
1447 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n",
1448 __FUNCTION__, StateAsCString(m_process->GetState()));
Greg Clayton374972e2011-07-09 17:15:55 +00001449
Kate Stoneb9c1b512016-09-06 20:57:50 +00001450 const bool internal_bp = true;
1451 const bool hardware = false;
1452 const LazyBool skip_prologue = eLazyBoolNo;
1453 FileSpecList module_spec_list;
1454 module_spec_list.Append(m_kernel.GetModule()->GetFileSpec());
1455 Breakpoint *bp =
1456 m_process->GetTarget()
1457 .CreateBreakpoint(&module_spec_list, NULL,
1458 "OSKextLoadedKextSummariesUpdated",
1459 eFunctionNameTypeFull, eLanguageTypeUnknown, 0,
1460 skip_prologue, internal_bp, hardware)
1461 .get();
Greg Clayton374972e2011-07-09 17:15:55 +00001462
Kate Stoneb9c1b512016-09-06 20:57:50 +00001463 bp->SetCallback(DynamicLoaderDarwinKernel::BreakpointHitCallback, this,
1464 true);
1465 m_break_id = bp->GetID();
1466 }
Greg Clayton7b242382011-07-08 00:48:09 +00001467}
1468
1469//----------------------------------------------------------------------
1470// Member function that gets called when the process state changes.
1471//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001472void DynamicLoaderDarwinKernel::PrivateProcessStateChanged(Process *process,
1473 StateType state) {
1474 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__,
1475 StateAsCString(state));
1476 switch (state) {
1477 case eStateConnected:
1478 case eStateAttaching:
1479 case eStateLaunching:
1480 case eStateInvalid:
1481 case eStateUnloaded:
1482 case eStateExited:
1483 case eStateDetached:
1484 Clear(false);
1485 break;
Greg Clayton7b242382011-07-08 00:48:09 +00001486
Kate Stoneb9c1b512016-09-06 20:57:50 +00001487 case eStateStopped:
1488 UpdateIfNeeded();
1489 break;
Greg Clayton7b242382011-07-08 00:48:09 +00001490
Kate Stoneb9c1b512016-09-06 20:57:50 +00001491 case eStateRunning:
1492 case eStateStepping:
1493 case eStateCrashed:
1494 case eStateSuspended:
1495 break;
1496 }
Greg Clayton7b242382011-07-08 00:48:09 +00001497}
1498
1499ThreadPlanSP
Kate Stoneb9c1b512016-09-06 20:57:50 +00001500DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan(Thread &thread,
1501 bool stop_others) {
1502 ThreadPlanSP thread_plan_sp;
1503 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
1504 if (log)
1505 log->Printf("Could not find symbol for step through.");
1506 return thread_plan_sp;
Greg Clayton7b242382011-07-08 00:48:09 +00001507}
1508
Zachary Turner97206d52017-05-12 04:51:55 +00001509Status DynamicLoaderDarwinKernel::CanLoadImage() {
1510 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001511 error.SetErrorString(
1512 "always unsafe to load or unload shared libraries in the darwin kernel");
1513 return error;
Greg Clayton7b242382011-07-08 00:48:09 +00001514}
1515
Kate Stoneb9c1b512016-09-06 20:57:50 +00001516void DynamicLoaderDarwinKernel::Initialize() {
1517 PluginManager::RegisterPlugin(GetPluginNameStatic(),
1518 GetPluginDescriptionStatic(), CreateInstance,
1519 DebuggerInitialize);
Greg Clayton7b242382011-07-08 00:48:09 +00001520}
1521
Kate Stoneb9c1b512016-09-06 20:57:50 +00001522void DynamicLoaderDarwinKernel::Terminate() {
1523 PluginManager::UnregisterPlugin(CreateInstance);
Greg Clayton7b242382011-07-08 00:48:09 +00001524}
1525
Kate Stoneb9c1b512016-09-06 20:57:50 +00001526void DynamicLoaderDarwinKernel::DebuggerInitialize(
1527 lldb_private::Debugger &debugger) {
1528 if (!PluginManager::GetSettingForDynamicLoaderPlugin(
1529 debugger, DynamicLoaderDarwinKernelProperties::GetSettingName())) {
1530 const bool is_global_setting = true;
1531 PluginManager::CreateSettingForDynamicLoaderPlugin(
1532 debugger, GetGlobalProperties()->GetValueProperties(),
1533 ConstString("Properties for the DynamicLoaderDarwinKernel plug-in."),
1534 is_global_setting);
1535 }
Greg Claytone8cd0c92012-10-19 18:02:49 +00001536}
Greg Clayton7b242382011-07-08 00:48:09 +00001537
Kate Stoneb9c1b512016-09-06 20:57:50 +00001538lldb_private::ConstString DynamicLoaderDarwinKernel::GetPluginNameStatic() {
1539 static ConstString g_name("darwin-kernel");
1540 return g_name;
Greg Clayton7b242382011-07-08 00:48:09 +00001541}
1542
Kate Stoneb9c1b512016-09-06 20:57:50 +00001543const char *DynamicLoaderDarwinKernel::GetPluginDescriptionStatic() {
1544 return "Dynamic loader plug-in that watches for shared library loads/unloads "
1545 "in the MacOSX kernel.";
Greg Clayton7b242382011-07-08 00:48:09 +00001546}
1547
Greg Clayton7b242382011-07-08 00:48:09 +00001548//------------------------------------------------------------------
1549// PluginInterface protocol
1550//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001551lldb_private::ConstString DynamicLoaderDarwinKernel::GetPluginName() {
1552 return GetPluginNameStatic();
Greg Clayton7b242382011-07-08 00:48:09 +00001553}
1554
Kate Stoneb9c1b512016-09-06 20:57:50 +00001555uint32_t DynamicLoaderDarwinKernel::GetPluginVersion() { return 1; }
Greg Clayton7b242382011-07-08 00:48:09 +00001556
Greg Clayton1f746072012-08-29 21:13:06 +00001557lldb::ByteOrder
Kate Stoneb9c1b512016-09-06 20:57:50 +00001558DynamicLoaderDarwinKernel::GetByteOrderFromMagic(uint32_t magic) {
1559 switch (magic) {
1560 case llvm::MachO::MH_MAGIC:
1561 case llvm::MachO::MH_MAGIC_64:
1562 return endian::InlHostByteOrder();
Greg Clayton1f746072012-08-29 21:13:06 +00001563
Kate Stoneb9c1b512016-09-06 20:57:50 +00001564 case llvm::MachO::MH_CIGAM:
1565 case llvm::MachO::MH_CIGAM_64:
1566 if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
1567 return lldb::eByteOrderLittle;
1568 else
1569 return lldb::eByteOrderBig;
1570
1571 default:
1572 break;
1573 }
1574 return lldb::eByteOrderInvalid;
1575}