blob: 8be3c15f32d2f190339631765abed7e32d3f1e18 [file] [log] [blame]
Greg Clayton944b8282011-08-22 22:30:57 +00001//===-- DynamicLoaderDarwinKernel.cpp -----------------------------*- C++ -*-===//
Greg Clayton7b242382011-07-08 00:48:09 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Jim Ingham46d005d2014-04-02 22:53:21 +000010#include "lldb/Utility/SafeMachO.h"
Greg Claytoneadcca92014-04-02 20:36:22 +000011
Greg Clayton7b242382011-07-08 00:48:09 +000012#include "lldb/Breakpoint/StoppointCallbackContext.h"
13#include "lldb/Core/DataBuffer.h"
14#include "lldb/Core/DataBufferHeap.h"
Greg Clayton07e66e32011-07-20 03:41:06 +000015#include "lldb/Core/Debugger.h"
Greg Clayton7b242382011-07-08 00:48:09 +000016#include "lldb/Core/Log.h"
17#include "lldb/Core/Module.h"
Greg Clayton1f746072012-08-29 21:13:06 +000018#include "lldb/Core/ModuleSpec.h"
Greg Clayton7b242382011-07-08 00:48:09 +000019#include "lldb/Core/PluginManager.h"
Greg Clayton1f746072012-08-29 21:13:06 +000020#include "lldb/Core/Section.h"
Greg Clayton7b242382011-07-08 00:48:09 +000021#include "lldb/Core/State.h"
Greg Clayton44d93782014-01-27 23:43:24 +000022#include "lldb/Core/StreamFile.h"
Jason Molenda68b36072012-10-02 03:49:41 +000023#include "lldb/Host/Symbols.h"
Ilia K41204d02015-03-04 12:05:24 +000024#include "lldb/Interpreter/OptionValueProperties.h"
Greg Clayton7b242382011-07-08 00:48:09 +000025#include "lldb/Symbol/ObjectFile.h"
Greg Clayton7b242382011-07-08 00:48:09 +000026#include "lldb/Target/RegisterContext.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000027#include "lldb/Target/StackFrame.h"
Greg Clayton7b242382011-07-08 00:48:09 +000028#include "lldb/Target/Target.h"
29#include "lldb/Target/Thread.h"
30#include "lldb/Target/ThreadPlanRunToAddress.h"
Greg Clayton57abc5d2013-05-10 21:47:16 +000031#include "Plugins/Platform/MacOSX/PlatformDarwinKernel.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>
38#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
39#else
40#define DEBUG_PRINTF(fmt, ...)
41#endif
42
43using namespace lldb;
44using namespace lldb_private;
45
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000046// Progressively greater amounts of scanning we will allow
47// For some targets very early in startup, we can't do any random reads of memory or we can crash the device
48// so a setting is needed that can completely disable the KASLR scans.
49
50enum KASLRScanType
51{
52 eKASLRScanNone = 0, // No reading into the inferior at all
53 eKASLRScanLowgloAddresses, // Check one word of memory for a possible kernel addr, then see if a kernel is there
Jason Molenda63969222013-01-30 04:48:16 +000054 eKASLRScanNearPC, // Scan backwards from the current $pc looking for kernel; checking at 96 locations total
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000055 eKASLRScanExhaustiveScan // Scan through the entire possible kernel address range looking for a kernel
56};
57
58OptionEnumValueElement
59g_kaslr_kernel_scan_enum_values[] =
60{
61 { eKASLRScanNone, "none", "Do not read memory looking for a Darwin kernel when attaching." },
62 { eKASLRScanLowgloAddresses, "basic", "Check for the Darwin kernel's load addr in the lowglo page (boot-args=debug) only." },
63 { eKASLRScanNearPC, "fast-scan", "Scan near the pc value on attach to find the Darwin kernel's load address."},
64 { eKASLRScanExhaustiveScan, "exhaustive-scan", "Scan through the entire potential address range of Darwin kernel (only on 32-bit targets)."},
65 { 0, NULL, NULL }
66};
67
Greg Claytone8cd0c92012-10-19 18:02:49 +000068static PropertyDefinition
69g_properties[] =
70{
Greg Clayton66763ee2012-10-19 20:53:18 +000071 { "load-kexts" , OptionValue::eTypeBoolean, true, true, NULL, NULL, "Automatically loads kext images when attaching to a kernel." },
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000072 { "scan-type", OptionValue::eTypeEnum, true, eKASLRScanNearPC, NULL, g_kaslr_kernel_scan_enum_values, "Control how many reads lldb will make while searching for a Darwin kernel on attach." },
Greg Clayton66763ee2012-10-19 20:53:18 +000073 { NULL , OptionValue::eTypeInvalid, false, 0 , NULL, NULL, NULL }
Greg Claytone8cd0c92012-10-19 18:02:49 +000074};
75
76enum {
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000077 ePropertyLoadKexts,
78 ePropertyScanType
Greg Claytone8cd0c92012-10-19 18:02:49 +000079};
80
81class DynamicLoaderDarwinKernelProperties : public Properties
82{
83public:
84
85 static ConstString &
86 GetSettingName ()
87 {
Greg Clayton468ea4e2012-10-19 18:14:47 +000088 static ConstString g_setting_name("darwin-kernel");
Greg Claytone8cd0c92012-10-19 18:02:49 +000089 return g_setting_name;
90 }
91
92 DynamicLoaderDarwinKernelProperties() :
93 Properties ()
94 {
95 m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
96 m_collection_sp->Initialize(g_properties);
97 }
98
99 virtual
100 ~DynamicLoaderDarwinKernelProperties()
101 {
102 }
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000103
Greg Claytone8cd0c92012-10-19 18:02:49 +0000104 bool
Greg Clayton66763ee2012-10-19 20:53:18 +0000105 GetLoadKexts() const
Greg Claytone8cd0c92012-10-19 18:02:49 +0000106 {
Greg Clayton66763ee2012-10-19 20:53:18 +0000107 const uint32_t idx = ePropertyLoadKexts;
Greg Claytone8cd0c92012-10-19 18:02:49 +0000108 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
109 }
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000110
111 KASLRScanType
112 GetScanType() const
113 {
114 const uint32_t idx = ePropertyScanType;
Jason Molenda63969222013-01-30 04:48:16 +0000115 return (KASLRScanType) m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000116 }
117
118
Greg Claytone8cd0c92012-10-19 18:02:49 +0000119};
120
Greg Clayton7b0992d2013-04-18 22:45:39 +0000121typedef std::shared_ptr<DynamicLoaderDarwinKernelProperties> DynamicLoaderDarwinKernelPropertiesSP;
Greg Claytone8cd0c92012-10-19 18:02:49 +0000122
123static const DynamicLoaderDarwinKernelPropertiesSP &
124GetGlobalProperties()
125{
126 static DynamicLoaderDarwinKernelPropertiesSP g_settings_sp;
127 if (!g_settings_sp)
128 g_settings_sp.reset (new DynamicLoaderDarwinKernelProperties ());
129 return g_settings_sp;
130}
131
Greg Clayton7b242382011-07-08 00:48:09 +0000132//----------------------------------------------------------------------
133// Create an instance of this class. This function is filled into
134// the plugin info class that gets handed out by the plugin factory and
135// allows the lldb to instantiate an instance of this class.
136//----------------------------------------------------------------------
137DynamicLoader *
Greg Clayton944b8282011-08-22 22:30:57 +0000138DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force)
Greg Clayton7b242382011-07-08 00:48:09 +0000139{
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000140 if (!force)
Greg Clayton7b242382011-07-08 00:48:09 +0000141 {
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000142 // If the user provided an executable binary and it is not a kernel,
143 // this plugin should not create an instance.
Greg Claytonaa149cb2011-08-11 02:48:45 +0000144 Module* exe_module = process->GetTarget().GetExecutableModulePointer();
Greg Claytondf0b7d52011-07-08 04:11:42 +0000145 if (exe_module)
146 {
147 ObjectFile *object_file = exe_module->GetObjectFile();
148 if (object_file)
149 {
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000150 if (object_file->GetStrata() != ObjectFile::eStrataKernel)
151 {
152 return NULL;
153 }
Greg Claytondf0b7d52011-07-08 04:11:42 +0000154 }
155 }
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000156
157 // If the target's architecture does not look like an Apple environment,
158 // this plugin should not create an instance.
159 const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
160 switch (triple_ref.getOS())
Greg Claytondf0b7d52011-07-08 04:11:42 +0000161 {
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000162 case llvm::Triple::Darwin:
163 case llvm::Triple::MacOSX:
164 case llvm::Triple::IOS:
165 if (triple_ref.getVendor() != llvm::Triple::Apple)
166 {
167 return NULL;
168 }
169 break;
170 // If we have triple like armv7-unknown-unknown, we should try looking for a Darwin kernel.
171 case llvm::Triple::UnknownOS:
172 break;
173 default:
174 return NULL;
175 break;
176 }
177 }
178
179 // At this point if there is an ExecutableModule, it is a kernel and the Target is some variant of an Apple system.
180 // If the Process hasn't provided the kernel load address, we need to look around in memory to find it.
181
Jason Molenda503d0182013-03-02 07:19:32 +0000182 addr_t kernel_load_address = SearchForDarwinKernel (process);
183 if (kernel_load_address != LLDB_INVALID_ADDRESS)
184 {
185 process->SetCanJIT(false);
186 return new DynamicLoaderDarwinKernel (process, kernel_load_address);
187 }
188 return NULL;
189}
190
191lldb::addr_t
192DynamicLoaderDarwinKernel::SearchForDarwinKernel (Process *process)
193{
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000194 addr_t kernel_load_address = process->GetImageInfoAddress();
195 if (kernel_load_address == LLDB_INVALID_ADDRESS)
196 {
197 kernel_load_address = SearchForKernelAtSameLoadAddr (process);
198 if (kernel_load_address == LLDB_INVALID_ADDRESS)
199 {
200 kernel_load_address = SearchForKernelWithDebugHints (process);
201 if (kernel_load_address == LLDB_INVALID_ADDRESS)
Greg Clayton70512312012-05-08 01:45:38 +0000202 {
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000203 kernel_load_address = SearchForKernelNearPC (process);
204 if (kernel_load_address == LLDB_INVALID_ADDRESS)
205 {
206 kernel_load_address = SearchForKernelViaExhaustiveSearch (process);
207 }
Greg Clayton70512312012-05-08 01:45:38 +0000208 }
Greg Claytondf0b7d52011-07-08 04:11:42 +0000209 }
Greg Clayton7b242382011-07-08 00:48:09 +0000210 }
Jason Molenda503d0182013-03-02 07:19:32 +0000211 return kernel_load_address;
Greg Clayton7b242382011-07-08 00:48:09 +0000212}
213
214//----------------------------------------------------------------------
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000215// Check if the kernel binary is loaded in memory without a slide.
216// First verify that the ExecutableModule is a kernel before we proceed.
217// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
218//----------------------------------------------------------------------
219lldb::addr_t
220DynamicLoaderDarwinKernel::SearchForKernelAtSameLoadAddr (Process *process)
221{
222 Module *exe_module = process->GetTarget().GetExecutableModulePointer();
223 if (exe_module == NULL)
224 return LLDB_INVALID_ADDRESS;
225
226 ObjectFile *exe_objfile = exe_module->GetObjectFile();
227 if (exe_objfile == NULL)
228 return LLDB_INVALID_ADDRESS;
229
230 if (exe_objfile->GetType() != ObjectFile::eTypeExecutable || exe_objfile->GetStrata() != ObjectFile::eStrataKernel)
231 return LLDB_INVALID_ADDRESS;
232
233 if (!exe_objfile->GetHeaderAddress().IsValid())
234 return LLDB_INVALID_ADDRESS;
235
236 if (CheckForKernelImageAtAddress (exe_objfile->GetHeaderAddress().GetFileAddress(), process) == exe_module->GetUUID())
237 return exe_objfile->GetHeaderAddress().GetFileAddress();
238
239 return LLDB_INVALID_ADDRESS;
240}
241
242//----------------------------------------------------------------------
243// If the debug flag is included in the boot-args nvram setting, the kernel's load address
244// will be noted in the lowglo page at a fixed address
245// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
246//----------------------------------------------------------------------
247lldb::addr_t
248DynamicLoaderDarwinKernel::SearchForKernelWithDebugHints (Process *process)
249{
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000250 if (GetGlobalProperties()->GetScanType() == eKASLRScanNone)
251 return LLDB_INVALID_ADDRESS;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000252
253 Error read_err;
254 addr_t addr = LLDB_INVALID_ADDRESS;
255 if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
256 {
257 addr = process->ReadUnsignedIntegerFromMemory (0xffffff8000002010ULL, 8, LLDB_INVALID_ADDRESS, read_err);
Jason Molenda7dd29392014-10-06 22:23:30 +0000258 if (CheckForKernelImageAtAddress (addr, process).IsValid())
259 {
260 return addr;
261 }
262 addr = process->ReadUnsignedIntegerFromMemory (0xffffff8000004010ULL, 8, LLDB_INVALID_ADDRESS, read_err);
263 if (CheckForKernelImageAtAddress (addr, process).IsValid())
264 {
265 return addr;
266 }
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000267 }
268 else
269 {
270 addr = process->ReadUnsignedIntegerFromMemory (0xffff0110, 4, LLDB_INVALID_ADDRESS, read_err);
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000271 if (CheckForKernelImageAtAddress (addr, process).IsValid())
Jason Molenda7dd29392014-10-06 22:23:30 +0000272 {
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000273 return addr;
Jason Molenda7dd29392014-10-06 22:23:30 +0000274 }
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000275 }
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000276 return LLDB_INVALID_ADDRESS;
277}
278
279//----------------------------------------------------------------------
280// If the kernel is currently executing when lldb attaches, and we don't have
281// a better way of finding the kernel's load address, try searching backwards
282// from the current pc value looking for the kernel's Mach header in memory.
283// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
284//----------------------------------------------------------------------
285lldb::addr_t
286DynamicLoaderDarwinKernel::SearchForKernelNearPC (Process *process)
287{
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000288 if (GetGlobalProperties()->GetScanType() == eKASLRScanNone
289 || GetGlobalProperties()->GetScanType() == eKASLRScanLowgloAddresses)
290 {
291 return LLDB_INVALID_ADDRESS;
292 }
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000293
294 ThreadSP thread = process->GetThreadList().GetSelectedThread ();
295 if (thread.get() == NULL)
296 return LLDB_INVALID_ADDRESS;
297 addr_t pc = thread->GetRegisterContext ()->GetPC(LLDB_INVALID_ADDRESS);
298
299 if (pc == LLDB_INVALID_ADDRESS)
300 return LLDB_INVALID_ADDRESS;
301
Jason Molenda44edbf12013-04-19 00:50:28 +0000302 addr_t kernel_range_low;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000303 if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
304 {
305 kernel_range_low = 1ULL << 63;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000306 }
307 else
308 {
309 kernel_range_low = 1ULL << 31;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000310 }
311
312 // Outside the normal kernel address range, this is probably userland code running right now
313 if (pc < kernel_range_low)
Jason Molenda44edbf12013-04-19 00:50:28 +0000314 return LLDB_INVALID_ADDRESS;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000315
316 // The kernel will load at at one megabyte boundary (0x100000), or at that boundary plus
317 // an offset of one page (0x1000) or two, depending on the device.
318
319 // Round the current pc down to the nearest one megabyte boundary - the place where we will start searching.
320 addr_t addr = pc & ~0xfffff;
321
322 int i = 0;
323 while (i < 32 && pc >= kernel_range_low)
324 {
325 if (CheckForKernelImageAtAddress (addr, process).IsValid())
326 return addr;
327 if (CheckForKernelImageAtAddress (addr + 0x1000, process).IsValid())
328 return addr + 0x1000;
329 if (CheckForKernelImageAtAddress (addr + 0x2000, process).IsValid())
330 return addr + 0x2000;
Jason Molendaa02869d2014-07-31 06:07:04 +0000331 if (CheckForKernelImageAtAddress (addr + 0x4000, process).IsValid())
332 return addr + 0x4000;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000333 i++;
334 addr -= 0x100000;
335 }
336
337 return LLDB_INVALID_ADDRESS;
338}
339
340//----------------------------------------------------------------------
341// Scan through the valid address range for a kernel binary.
342// This is uselessly slow in 64-bit environments so we don't even try it.
343// This scan is not enabled by default even for 32-bit targets.
344// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
345//----------------------------------------------------------------------
346lldb::addr_t
347DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch (Process *process)
348{
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000349 if (GetGlobalProperties()->GetScanType() != eKASLRScanExhaustiveScan)
350 {
351 return LLDB_INVALID_ADDRESS;
352 }
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000353
354 addr_t kernel_range_low, kernel_range_high;
355 if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
356 {
357 kernel_range_low = 1ULL << 63;
358 kernel_range_high = UINT64_MAX;
359 }
360 else
361 {
362 kernel_range_low = 1ULL << 31;
363 kernel_range_high = UINT32_MAX;
364 }
365
366 // Stepping through memory at one-megabyte resolution looking for a kernel
367 // rarely works (fast enough) with a 64-bit address space -- for now, let's
368 // not even bother. We may be attaching to something which *isn't* a kernel
369 // and we don't want to spin for minutes on-end looking for a kernel.
370 if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
371 return LLDB_INVALID_ADDRESS;
372
373 addr_t addr = kernel_range_low;
374
375 while (addr >= kernel_range_low && addr < kernel_range_high)
376 {
377 if (CheckForKernelImageAtAddress (addr, process).IsValid())
378 return addr;
379 if (CheckForKernelImageAtAddress (addr + 0x1000, process).IsValid())
380 return addr + 0x1000;
381 if (CheckForKernelImageAtAddress (addr + 0x2000, process).IsValid())
382 return addr + 0x2000;
Jason Molendaa02869d2014-07-31 06:07:04 +0000383 if (CheckForKernelImageAtAddress (addr + 0x4000, process).IsValid())
384 return addr + 0x4000;
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000385 addr += 0x100000;
386 }
387 return LLDB_INVALID_ADDRESS;
388}
389
390//----------------------------------------------------------------------
391// Given an address in memory, look to see if there is a kernel image at that
392// address.
393// Returns a UUID; if a kernel was not found at that address, UUID.IsValid() will be false.
394//----------------------------------------------------------------------
395lldb_private::UUID
396DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress (lldb::addr_t addr, Process *process)
397{
398 if (addr == LLDB_INVALID_ADDRESS)
399 return UUID();
400
401 // First try a quick test -- read the first 4 bytes and see if there is a valid Mach-O magic field there
402 // (the first field of the mach_header/mach_header_64 struct).
403
404 Error read_error;
405 uint64_t result = process->ReadUnsignedIntegerFromMemory (addr, 4, LLDB_INVALID_ADDRESS, read_error);
Charles Davis510938e2013-08-27 05:04:57 +0000406 if (result != llvm::MachO::MH_MAGIC_64
407 && result != llvm::MachO::MH_MAGIC
408 && result != llvm::MachO::MH_CIGAM
409 && result != llvm::MachO::MH_CIGAM_64)
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000410 {
411 return UUID();
412 }
413
414 // Read the mach header and see whether it looks like a kernel
415 llvm::MachO::mach_header header;
416 if (process->DoReadMemory (addr, &header, sizeof(header), read_error) != sizeof(header))
417 return UUID();
418
Charles Davis510938e2013-08-27 05:04:57 +0000419 if (header.magic == llvm::MachO::MH_CIGAM ||
420 header.magic == llvm::MachO::MH_CIGAM_64)
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000421 {
422 header.magic = llvm::ByteSwap_32(header.magic);
423 header.cputype = llvm::ByteSwap_32(header.cputype);
424 header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
425 header.filetype = llvm::ByteSwap_32(header.filetype);
426 header.ncmds = llvm::ByteSwap_32(header.ncmds);
427 header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
428 header.flags = llvm::ByteSwap_32(header.flags);
429 }
430
431 // A kernel is an executable which does not have the dynamic link object flag set.
Charles Davis510938e2013-08-27 05:04:57 +0000432 if (header.filetype == llvm::MachO::MH_EXECUTE
433 && (header.flags & llvm::MachO::MH_DYLDLINK) == 0)
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000434 {
435 // Create a full module to get the UUID
Greg Clayton39f7ee82013-02-01 21:38:35 +0000436 ModuleSP memory_module_sp = process->ReadModuleFromMemory (FileSpec ("temp_mach_kernel", false), addr);
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000437 if (!memory_module_sp.get())
438 return UUID();
439
440 ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
441 if (exe_objfile == NULL)
442 return UUID();
443
444 if (exe_objfile->GetType() == ObjectFile::eTypeExecutable && exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
445 {
Jason Molendaa4ce2532013-05-02 22:02:57 +0000446 ArchSpec kernel_arch (eArchTypeMachO, header.cputype, header.cpusubtype);
447 if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(kernel_arch))
448 {
449 process->GetTarget().SetArchitecture (kernel_arch);
450 }
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000451 return memory_module_sp->GetUUID();
452 }
453 }
454
455 return UUID();
456}
457
458//----------------------------------------------------------------------
Greg Clayton7b242382011-07-08 00:48:09 +0000459// Constructor
460//----------------------------------------------------------------------
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000461DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process, lldb::addr_t kernel_addr) :
Greg Clayton7b242382011-07-08 00:48:09 +0000462 DynamicLoader(process),
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000463 m_kernel_load_address (kernel_addr),
Greg Clayton7b242382011-07-08 00:48:09 +0000464 m_kernel(),
Greg Claytond16e1e52011-07-12 17:06:17 +0000465 m_kext_summary_header_ptr_addr (),
Greg Clayton0d9fc762011-07-08 03:21:57 +0000466 m_kext_summary_header_addr (),
Greg Clayton7b242382011-07-08 00:48:09 +0000467 m_kext_summary_header (),
Jason Molenda306bd0a2013-02-19 05:42:46 +0000468 m_known_kexts (),
Daniel Dunbara08823f2011-10-31 22:50:49 +0000469 m_mutex(Mutex::eMutexTypeRecursive),
470 m_break_id (LLDB_INVALID_BREAK_ID)
Greg Clayton7b242382011-07-08 00:48:09 +0000471{
Greg Clayton615eb7e2014-09-19 20:11:50 +0000472 Error error;
473 PlatformSP platform_sp(Platform::Create(PlatformDarwinKernel::GetPluginNameStatic(), error));
Jason Molenda1c627542013-04-05 01:03:25 +0000474 // Only select the darwin-kernel Platform if we've been asked to load kexts.
475 // It can take some time to scan over all of the kext info.plists and that
476 // shouldn't be done if kext loading is explicitly disabled.
477 if (platform_sp.get() && GetGlobalProperties()->GetLoadKexts())
478 {
479 process->GetTarget().SetPlatform (platform_sp);
Jason Molenda1c627542013-04-05 01:03:25 +0000480 }
Greg Clayton7b242382011-07-08 00:48:09 +0000481}
482
483//----------------------------------------------------------------------
484// Destructor
485//----------------------------------------------------------------------
Greg Clayton944b8282011-08-22 22:30:57 +0000486DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel()
Greg Clayton7b242382011-07-08 00:48:09 +0000487{
488 Clear(true);
489}
490
Greg Clayton374972e2011-07-09 17:15:55 +0000491void
Greg Clayton944b8282011-08-22 22:30:57 +0000492DynamicLoaderDarwinKernel::UpdateIfNeeded()
Greg Clayton374972e2011-07-09 17:15:55 +0000493{
494 LoadKernelModuleIfNeeded();
495 SetNotificationBreakpointIfNeeded ();
496}
Greg Clayton7b242382011-07-08 00:48:09 +0000497//------------------------------------------------------------------
498/// Called after attaching a process.
499///
500/// Allow DynamicLoader plug-ins to execute some code after
501/// attaching to a process.
502//------------------------------------------------------------------
503void
Greg Clayton944b8282011-08-22 22:30:57 +0000504DynamicLoaderDarwinKernel::DidAttach ()
Greg Clayton7b242382011-07-08 00:48:09 +0000505{
506 PrivateInitialize(m_process);
Greg Clayton374972e2011-07-09 17:15:55 +0000507 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000508}
509
510//------------------------------------------------------------------
511/// Called after attaching a process.
512///
513/// Allow DynamicLoader plug-ins to execute some code after
514/// attaching to a process.
515//------------------------------------------------------------------
516void
Greg Clayton944b8282011-08-22 22:30:57 +0000517DynamicLoaderDarwinKernel::DidLaunch ()
Greg Clayton7b242382011-07-08 00:48:09 +0000518{
519 PrivateInitialize(m_process);
Greg Clayton374972e2011-07-09 17:15:55 +0000520 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000521}
522
523
524//----------------------------------------------------------------------
525// Clear out the state of this class.
526//----------------------------------------------------------------------
527void
Greg Clayton944b8282011-08-22 22:30:57 +0000528DynamicLoaderDarwinKernel::Clear (bool clear_process)
Greg Clayton7b242382011-07-08 00:48:09 +0000529{
530 Mutex::Locker locker(m_mutex);
531
532 if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
533 m_process->ClearBreakpointSiteByID(m_break_id);
534
535 if (clear_process)
536 m_process = NULL;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000537 m_kernel.Clear();
538 m_known_kexts.clear();
Greg Claytond16e1e52011-07-12 17:06:17 +0000539 m_kext_summary_header_ptr_addr.Clear();
Greg Clayton0d9fc762011-07-08 03:21:57 +0000540 m_kext_summary_header_addr.Clear();
Greg Clayton7b242382011-07-08 00:48:09 +0000541 m_break_id = LLDB_INVALID_BREAK_ID;
542}
543
Greg Clayton7b242382011-07-08 00:48:09 +0000544
Greg Claytonc859e2d2012-02-13 23:10:39 +0000545bool
Jason Molenda306bd0a2013-02-19 05:42:46 +0000546DynamicLoaderDarwinKernel::KextImageInfo::LoadImageAtFileAddress (Process *process)
Greg Clayton2af282a2012-03-21 04:25:00 +0000547{
548 if (IsLoaded())
549 return true;
550
Jason Molenda306bd0a2013-02-19 05:42:46 +0000551 if (m_module_sp)
Greg Clayton2af282a2012-03-21 04:25:00 +0000552 {
553 bool changed = false;
Greg Clayton751caf62014-02-07 22:54:47 +0000554 if (m_module_sp->SetLoadAddress (process->GetTarget(), 0, true, changed))
Jason Molenda306bd0a2013-02-19 05:42:46 +0000555 m_load_process_stop_id = process->GetStopID();
Greg Clayton2af282a2012-03-21 04:25:00 +0000556 }
557 return false;
558}
559
Jason Molenda306bd0a2013-02-19 05:42:46 +0000560void
561DynamicLoaderDarwinKernel::KextImageInfo::SetModule (ModuleSP module_sp)
562{
563 m_module_sp = module_sp;
564 if (module_sp.get() && module_sp->GetObjectFile())
565 {
566 if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
567 && module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
568 {
569 m_kernel_image = true;
570 }
571 else
572 {
573 m_kernel_image = false;
574 }
575 }
576}
577
578ModuleSP
579DynamicLoaderDarwinKernel::KextImageInfo::GetModule ()
580{
581 return m_module_sp;
582}
583
584void
585DynamicLoaderDarwinKernel::KextImageInfo::SetLoadAddress (addr_t load_addr)
586{
587 m_load_address = load_addr;
588}
589
590addr_t
591DynamicLoaderDarwinKernel::KextImageInfo::GetLoadAddress () const
592{
593 return m_load_address;
594}
595
596uint64_t
597DynamicLoaderDarwinKernel::KextImageInfo::GetSize () const
598{
599 return m_size;
600}
601
602void
603DynamicLoaderDarwinKernel::KextImageInfo::SetSize (uint64_t size)
604{
605 m_size = size;
606}
607
608uint32_t
609DynamicLoaderDarwinKernel::KextImageInfo::GetProcessStopId () const
610{
611 return m_load_process_stop_id;
612}
613
614void
615DynamicLoaderDarwinKernel::KextImageInfo::SetProcessStopId (uint32_t stop_id)
616{
617 m_load_process_stop_id = stop_id;
618}
619
Greg Clayton2af282a2012-03-21 04:25:00 +0000620bool
Jason Molenda306bd0a2013-02-19 05:42:46 +0000621DynamicLoaderDarwinKernel::KextImageInfo::operator== (const KextImageInfo &rhs)
622{
623 if (m_uuid.IsValid() || rhs.GetUUID().IsValid())
624 {
625 if (m_uuid == rhs.GetUUID())
626 {
627 return true;
628 }
629 return false;
630 }
631
632 if (m_name == rhs.GetName() && m_load_address == rhs.GetLoadAddress())
633 return true;
634
635 return false;
636}
637
638void
639DynamicLoaderDarwinKernel::KextImageInfo::SetName (const char *name)
640{
641 m_name = name;
642}
643
644std::string
645DynamicLoaderDarwinKernel::KextImageInfo::GetName () const
646{
647 return m_name;
648}
649
650void
651DynamicLoaderDarwinKernel::KextImageInfo::SetUUID (const UUID &uuid)
652{
653 m_uuid = uuid;
654}
655
656UUID
657DynamicLoaderDarwinKernel::KextImageInfo::GetUUID () const
658{
659 return m_uuid;
660}
661
662// Given the m_load_address from the kext summaries, and a UUID, try to create an in-memory
663// Module at that address. Require that the MemoryModule have a matching UUID and detect
664// if this MemoryModule is a kernel or a kext.
665//
666// Returns true if m_memory_module_sp is now set to a valid Module.
667
668bool
669DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule (Process *process)
670{
671 if (m_memory_module_sp.get() != NULL)
672 return true;
673 if (m_load_address == LLDB_INVALID_ADDRESS)
674 return false;
675
676 FileSpec file_spec;
677 file_spec.SetFile (m_name.c_str(), false);
678
679 ModuleSP memory_module_sp = process->ReadModuleFromMemory (file_spec, m_load_address);
680
681 if (memory_module_sp.get() == NULL)
682 return false;
683
684 bool is_kernel = false;
685 if (memory_module_sp->GetObjectFile())
686 {
687 if (memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
688 && memory_module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
689 {
690 is_kernel = true;
691 }
692 else if (memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeSharedLibrary)
693 {
694 is_kernel = false;
695 }
696 }
697
Jason Molenda38e70d12013-02-27 03:07:49 +0000698 // If this is a kext, and the kernel specified what UUID we should find at this
699 // load address, require that the memory module have a matching UUID or something
700 // has gone wrong and we should discard it.
Jason Molenda306bd0a2013-02-19 05:42:46 +0000701 if (m_uuid.IsValid())
702 {
703 if (m_uuid != memory_module_sp->GetUUID())
704 {
705 return false;
706 }
707 }
708
709 // If the in-memory Module has a UUID, let's use that.
710 if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid())
711 {
712 m_uuid = memory_module_sp->GetUUID();
713 }
714
715 m_memory_module_sp = memory_module_sp;
716 m_kernel_image = is_kernel;
717 if (is_kernel)
718 {
Jason Molenda38e70d12013-02-27 03:07:49 +0000719 if (memory_module_sp->GetArchitecture().IsValid())
Jason Molenda306bd0a2013-02-19 05:42:46 +0000720 {
721 process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture());
722 }
Jason Molenda38e70d12013-02-27 03:07:49 +0000723 if (m_uuid.IsValid())
724 {
Jason Molenda48975832015-03-10 23:34:52 +0000725 ModuleSP exe_module_sp = process->GetTarget().GetExecutableModule();
726 if (exe_module_sp.get() && exe_module_sp->GetUUID().IsValid())
Jason Molenda38e70d12013-02-27 03:07:49 +0000727 {
Jason Molenda48975832015-03-10 23:34:52 +0000728 if (m_uuid != exe_module_sp->GetUUID())
Jason Molenda38e70d12013-02-27 03:07:49 +0000729 {
Jason Molenda48975832015-03-10 23:34:52 +0000730 // The user specified a kernel binary that has a different UUID than
731 // the kernel actually running in memory. This never ends well;
732 // clear the user specified kernel binary from the Target.
733
734 m_module_sp.reset();
735
736 ModuleList user_specified_kernel_list;
737 user_specified_kernel_list.Append (exe_module_sp);
738 process->GetTarget().GetImages().Remove (user_specified_kernel_list);
Jason Molenda38e70d12013-02-27 03:07:49 +0000739 }
740 }
741 }
Jason Molenda306bd0a2013-02-19 05:42:46 +0000742 }
743
744 return true;
745}
746
747bool
748DynamicLoaderDarwinKernel::KextImageInfo::IsKernel () const
749{
750 return m_kernel_image == true;
751}
752
753void
754DynamicLoaderDarwinKernel::KextImageInfo::SetIsKernel (bool is_kernel)
755{
756 m_kernel_image = is_kernel;
757}
758
759bool
760DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule (Process *process)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000761{
762 if (IsLoaded())
763 return true;
764
Greg Claytonc859e2d2012-02-13 23:10:39 +0000765
766 Target &target = process->GetTarget();
Jason Molenda87a04b22012-10-19 03:40:45 +0000767
Jason Molenda306bd0a2013-02-19 05:42:46 +0000768 // If we don't have / can't create a memory module for this kext, don't try to load it - we won't
769 // have the correct segment load addresses.
770 if (!ReadMemoryModule (process))
Jason Molenda87a04b22012-10-19 03:40:45 +0000771 {
772 return false;
773 }
774
Jason Molenda306bd0a2013-02-19 05:42:46 +0000775 bool uuid_is_valid = m_uuid.IsValid();
776
Jason Molendae575e7b2013-02-19 06:11:13 +0000777 if (IsKernel() && uuid_is_valid && m_memory_module_sp.get())
778 {
Greg Clayton44d93782014-01-27 23:43:24 +0000779 Stream *s = target.GetDebugger().GetOutputFile().get();
Jason Molendae575e7b2013-02-19 06:11:13 +0000780 if (s)
781 {
Jason Molendac16b4af2013-05-03 23:56:12 +0000782 s->Printf ("Kernel UUID: %s\n", m_memory_module_sp->GetUUID().GetAsString().c_str());
Jason Molendae575e7b2013-02-19 06:11:13 +0000783 s->Printf ("Load Address: 0x%" PRIx64 "\n", m_load_address);
784 }
785 }
786
Jason Molenda306bd0a2013-02-19 05:42:46 +0000787 if (!m_module_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000788 {
Jason Molenda306bd0a2013-02-19 05:42:46 +0000789 // See if the kext has already been loaded into the target, probably by the user doing target modules add.
790 const ModuleList &target_images = target.GetImages();
791 m_module_sp = target_images.FindModule(m_uuid);
792
793 // Search for the kext on the local filesystem via the UUID
794 if (!m_module_sp && uuid_is_valid)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000795 {
Jason Molenda306bd0a2013-02-19 05:42:46 +0000796 ModuleSpec module_spec;
797 module_spec.GetUUID() = m_uuid;
798 module_spec.GetArchitecture() = target.GetArchitecture();
Jason Molenda53667f52012-10-06 02:02:26 +0000799
Jason Molendad76fb6e2013-02-19 07:16:22 +0000800 // For the kernel, we really do need an on-disk file copy of the binary to do anything useful.
801 // This will force a clal to
Jason Molenda306bd0a2013-02-19 05:42:46 +0000802 if (IsKernel())
Greg Claytonb9a01b32012-02-26 05:51:37 +0000803 {
Jason Molendad76fb6e2013-02-19 07:16:22 +0000804 if (Symbols::DownloadObjectAndSymbolFile (module_spec, true))
Jason Molendabb860bd2012-10-09 01:17:11 +0000805 {
Jason Molendad76fb6e2013-02-19 07:16:22 +0000806 if (module_spec.GetFileSpec().Exists())
Jason Molendabb860bd2012-10-09 01:17:11 +0000807 {
Jason Molendad76fb6e2013-02-19 07:16:22 +0000808 m_module_sp.reset(new Module (module_spec.GetFileSpec(), target.GetArchitecture()));
809 if (m_module_sp.get() && m_module_sp->MatchesModuleSpec (module_spec))
810 {
811 ModuleList loaded_module_list;
812 loaded_module_list.Append (m_module_sp);
813 target.ModulesDidLoad (loaded_module_list);
814 }
Jason Molendabb860bd2012-10-09 01:17:11 +0000815 }
816 }
Jason Molenda306bd0a2013-02-19 05:42:46 +0000817 }
Jason Molendad76fb6e2013-02-19 07:16:22 +0000818
Jason Molenda1c627542013-04-05 01:03:25 +0000819 // If the current platform is PlatformDarwinKernel, create a ModuleSpec with the filename set
820 // to be the bundle ID for this kext, e.g. "com.apple.filesystems.msdosfs", and ask the platform
821 // to find it.
822 PlatformSP platform_sp (target.GetPlatform());
Jason Molenda0ddfe7f2014-03-05 03:33:01 +0000823 if (!m_module_sp && platform_sp)
Jason Molenda1c627542013-04-05 01:03:25 +0000824 {
Greg Clayton57abc5d2013-05-10 21:47:16 +0000825 ConstString platform_name (platform_sp->GetPluginName());
826 static ConstString g_platform_name (PlatformDarwinKernel::GetPluginNameStatic());
827 if (platform_name == g_platform_name)
Jason Molenda1c627542013-04-05 01:03:25 +0000828 {
829 ModuleSpec kext_bundle_module_spec(module_spec);
830 FileSpec kext_filespec(m_name.c_str(), false);
831 kext_bundle_module_spec.GetFileSpec() = kext_filespec;
Ilia K667ef222015-03-24 14:30:28 +0000832 platform_sp->GetSharedModule (kext_bundle_module_spec, process, m_module_sp, &target.GetExecutableSearchPaths(), NULL, NULL);
Jason Molenda1c627542013-04-05 01:03:25 +0000833 }
834 }
835
Jason Molendad76fb6e2013-02-19 07:16:22 +0000836 // Ask the Target to find this file on the local system, if possible.
Jason Molenda306bd0a2013-02-19 05:42:46 +0000837 // This will search in the list of currently-loaded files, look in the
838 // standard search paths on the system, and on a Mac it will try calling
839 // the DebugSymbols framework with the UUID to find the binary via its
840 // search methods.
841 if (!m_module_sp)
842 {
843 m_module_sp = target.GetSharedModule (module_spec);
844 }
Jason Molendae575e7b2013-02-19 06:11:13 +0000845
Jason Molendad76fb6e2013-02-19 07:16:22 +0000846 if (IsKernel() && !m_module_sp)
Jason Molendae575e7b2013-02-19 06:11:13 +0000847 {
Greg Clayton44d93782014-01-27 23:43:24 +0000848 Stream *s = target.GetDebugger().GetOutputFile().get();
Jason Molendae575e7b2013-02-19 06:11:13 +0000849 if (s)
850 {
Jason Molendacc6dc782013-04-30 22:38:28 +0000851 s->Printf ("WARNING: Unable to locate kernel binary on the debugger system.\n");
Jason Molendae575e7b2013-02-19 06:11:13 +0000852 }
853 }
Jason Molenda306bd0a2013-02-19 05:42:46 +0000854 }
Jason Molenda65d57a32012-12-01 06:13:29 +0000855
Jason Molenda306bd0a2013-02-19 05:42:46 +0000856 // If we managed to find a module, append it to the target's list of images.
857 // If we also have a memory module, require that they have matching UUIDs
858 if (m_module_sp)
859 {
860 bool uuid_match_ok = true;
861 if (m_memory_module_sp)
862 {
863 if (m_module_sp->GetUUID() != m_memory_module_sp->GetUUID())
Jason Molenda65d57a32012-12-01 06:13:29 +0000864 {
Jason Molenda306bd0a2013-02-19 05:42:46 +0000865 uuid_match_ok = false;
866 }
867 }
868 if (uuid_match_ok)
869 {
Jason Molendaa4d3e1d2013-02-19 07:41:13 +0000870 target.GetImages().AppendIfNeeded(m_module_sp);
Jason Molenda306bd0a2013-02-19 05:42:46 +0000871 if (IsKernel() && target.GetExecutableModulePointer() != m_module_sp.get())
872 {
873 target.SetExecutableModule (m_module_sp, false);
Jason Molenda65d57a32012-12-01 06:13:29 +0000874 }
Greg Claytonb9a01b32012-02-26 05:51:37 +0000875 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000876 }
877 }
878
Jason Molenda56c23282013-02-19 06:39:56 +0000879 if (!m_module_sp && !IsKernel() && m_uuid.IsValid() && !m_name.empty())
880 {
Greg Clayton44d93782014-01-27 23:43:24 +0000881 Stream *s = target.GetDebugger().GetOutputFile().get();
Jason Molenda56c23282013-02-19 06:39:56 +0000882 if (s)
883 {
Jason Molenda56c23282013-02-19 06:39:56 +0000884 s->Printf ("warning: Can't find binary/dSYM for %s (%s)\n",
Jason Molendac16b4af2013-05-03 23:56:12 +0000885 m_name.c_str(), m_uuid.GetAsString().c_str());
Jason Molenda56c23282013-02-19 06:39:56 +0000886 }
887 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000888
Greg Clayton67408532012-12-11 01:20:51 +0000889 static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
890
Jason Molenda306bd0a2013-02-19 05:42:46 +0000891 if (m_memory_module_sp && m_module_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000892 {
Jason Molenda306bd0a2013-02-19 05:42:46 +0000893 if (m_module_sp->GetUUID() == m_memory_module_sp->GetUUID())
Greg Claytonc859e2d2012-02-13 23:10:39 +0000894 {
Jason Molenda306bd0a2013-02-19 05:42:46 +0000895 ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();
896 ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile();
Greg Clayton67408532012-12-11 01:20:51 +0000897
Jason Molendabb860bd2012-10-09 01:17:11 +0000898 if (memory_object_file && ondisk_object_file)
899 {
Jason Molenda306bd0a2013-02-19 05:42:46 +0000900 // The memory_module for kexts may have an invalid __LINKEDIT seg; skip it.
901 const bool ignore_linkedit = !IsKernel ();
Greg Clayton67408532012-12-11 01:20:51 +0000902
Jason Molendabb860bd2012-10-09 01:17:11 +0000903 SectionList *ondisk_section_list = ondisk_object_file->GetSectionList ();
904 SectionList *memory_section_list = memory_object_file->GetSectionList ();
905 if (memory_section_list && ondisk_section_list)
906 {
907 const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
908 // There may be CTF sections in the memory image so we can't
909 // always just compare the number of sections (which are actually
910 // segments in mach-o parlance)
911 uint32_t sect_idx = 0;
912
913 // Use the memory_module's addresses for each section to set the
914 // file module's load address as appropriate. We don't want to use
915 // a single slide value for the entire kext - different segments may
916 // be slid different amounts by the kext loader.
917
918 uint32_t num_sections_loaded = 0;
919 for (sect_idx=0; sect_idx<num_ondisk_sections; ++sect_idx)
920 {
921 SectionSP ondisk_section_sp(ondisk_section_list->GetSectionAtIndex(sect_idx));
922 if (ondisk_section_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000923 {
Greg Clayton67408532012-12-11 01:20:51 +0000924 // Don't ever load __LINKEDIT as it may or may not be actually
925 // mapped into memory and there is no current way to tell.
926 // I filed rdar://problem/12851706 to track being able to tell
927 // if the __LINKEDIT is actually mapped, but until then, we need
928 // to not load the __LINKEDIT
929 if (ignore_linkedit && ondisk_section_sp->GetName() == g_section_name_LINKEDIT)
930 continue;
931
Jason Molendabb860bd2012-10-09 01:17:11 +0000932 const Section *memory_section = memory_section_list->FindSectionByName(ondisk_section_sp->GetName()).get();
933 if (memory_section)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000934 {
Greg Claytond5944cd2013-12-06 01:12:00 +0000935 target.SetSectionLoadAddress (ondisk_section_sp, memory_section->GetFileAddress());
Jason Molendabb860bd2012-10-09 01:17:11 +0000936 ++num_sections_loaded;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000937 }
938 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000939 }
Jason Molendabb860bd2012-10-09 01:17:11 +0000940 if (num_sections_loaded > 0)
Jason Molenda306bd0a2013-02-19 05:42:46 +0000941 m_load_process_stop_id = process->GetStopID();
Greg Claytonc859e2d2012-02-13 23:10:39 +0000942 else
Jason Molenda306bd0a2013-02-19 05:42:46 +0000943 m_module_sp.reset(); // No sections were loaded
Greg Claytonc859e2d2012-02-13 23:10:39 +0000944 }
945 else
Jason Molenda306bd0a2013-02-19 05:42:46 +0000946 m_module_sp.reset(); // One or both section lists
Greg Claytonc859e2d2012-02-13 23:10:39 +0000947 }
948 else
Jason Molenda306bd0a2013-02-19 05:42:46 +0000949 m_module_sp.reset(); // One or both object files missing
Greg Claytonc859e2d2012-02-13 23:10:39 +0000950 }
Jason Molendabb860bd2012-10-09 01:17:11 +0000951 else
Jason Molenda306bd0a2013-02-19 05:42:46 +0000952 m_module_sp.reset(); // UUID mismatch
Greg Claytonc859e2d2012-02-13 23:10:39 +0000953 }
Jason Molendabb860bd2012-10-09 01:17:11 +0000954
Greg Claytonc859e2d2012-02-13 23:10:39 +0000955 bool is_loaded = IsLoaded();
956
Jason Molenda306bd0a2013-02-19 05:42:46 +0000957 if (is_loaded && m_module_sp && IsKernel())
Jason Molenda68b36072012-10-02 03:49:41 +0000958 {
Greg Clayton44d93782014-01-27 23:43:24 +0000959 Stream *s = target.GetDebugger().GetOutputFile().get();
Jason Molenda68b36072012-10-02 03:49:41 +0000960 if (s)
961 {
Jason Molenda732238c2013-03-01 00:06:37 +0000962 ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
963 if (kernel_object_file)
964 {
965 addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress();
966 if (m_load_address != LLDB_INVALID_ADDRESS && file_address != LLDB_INVALID_ADDRESS)
967 {
Matt Kopec787d1622013-03-12 17:45:38 +0000968 s->Printf ("Kernel slid 0x%" PRIx64 " in memory.\n", m_load_address - file_address);
Jason Molenda732238c2013-03-01 00:06:37 +0000969 }
970 }
Jason Molenda743e43962012-10-02 22:23:42 +0000971 {
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000972 s->Printf ("Loaded kernel file %s\n",
973 m_module_sp->GetFileSpec().GetPath().c_str());
Jason Molenda743e43962012-10-02 22:23:42 +0000974 }
Jason Molenda68b36072012-10-02 03:49:41 +0000975 s->Flush ();
976 }
977 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000978 return is_loaded;
979}
980
Greg Clayton1f746072012-08-29 21:13:06 +0000981uint32_t
Jason Molenda306bd0a2013-02-19 05:42:46 +0000982DynamicLoaderDarwinKernel::KextImageInfo::GetAddressByteSize ()
Greg Clayton1f746072012-08-29 21:13:06 +0000983{
Jason Molenda306bd0a2013-02-19 05:42:46 +0000984 if (m_memory_module_sp)
985 return m_memory_module_sp->GetArchitecture().GetAddressByteSize();
986 if (m_module_sp)
987 return m_module_sp->GetArchitecture().GetAddressByteSize();
Greg Clayton1f746072012-08-29 21:13:06 +0000988 return 0;
989}
990
991lldb::ByteOrder
Jason Molenda306bd0a2013-02-19 05:42:46 +0000992DynamicLoaderDarwinKernel::KextImageInfo::GetByteOrder()
Greg Clayton1f746072012-08-29 21:13:06 +0000993{
Jason Molenda306bd0a2013-02-19 05:42:46 +0000994 if (m_memory_module_sp)
995 return m_memory_module_sp->GetArchitecture().GetByteOrder();
996 if (m_module_sp)
997 return m_module_sp->GetArchitecture().GetByteOrder();
Greg Clayton1f746072012-08-29 21:13:06 +0000998 return lldb::endian::InlHostByteOrder();
999}
1000
1001lldb_private::ArchSpec
Jason Molenda306bd0a2013-02-19 05:42:46 +00001002DynamicLoaderDarwinKernel::KextImageInfo::GetArchitecture () const
Greg Clayton1f746072012-08-29 21:13:06 +00001003{
Jason Molenda306bd0a2013-02-19 05:42:46 +00001004 if (m_memory_module_sp)
1005 return m_memory_module_sp->GetArchitecture();
1006 if (m_module_sp)
1007 return m_module_sp->GetArchitecture();
Greg Clayton1f746072012-08-29 21:13:06 +00001008 return lldb_private::ArchSpec ();
1009}
1010
1011
Greg Clayton7b242382011-07-08 00:48:09 +00001012//----------------------------------------------------------------------
1013// Load the kernel module and initialize the "m_kernel" member. Return
1014// true _only_ if the kernel is loaded the first time through (subsequent
1015// calls to this function should return false after the kernel has been
1016// already loaded).
1017//----------------------------------------------------------------------
Greg Clayton374972e2011-07-09 17:15:55 +00001018void
Greg Clayton944b8282011-08-22 22:30:57 +00001019DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded()
Greg Clayton7b242382011-07-08 00:48:09 +00001020{
Greg Claytond16e1e52011-07-12 17:06:17 +00001021 if (!m_kext_summary_header_ptr_addr.IsValid())
Greg Clayton7b242382011-07-08 00:48:09 +00001022 {
Jason Molenda306bd0a2013-02-19 05:42:46 +00001023 m_kernel.Clear();
1024 m_kernel.SetModule (m_process->GetTarget().GetExecutableModule());
1025 m_kernel.SetIsKernel(true);
Jason Molenda4bd4e7e2012-09-29 04:02:01 +00001026
1027 ConstString kernel_name("mach_kernel");
Jason Molenda306bd0a2013-02-19 05:42:46 +00001028 if (m_kernel.GetModule().get()
1029 && m_kernel.GetModule()->GetObjectFile()
1030 && !m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty())
Jason Molenda4bd4e7e2012-09-29 04:02:01 +00001031 {
Jason Molenda306bd0a2013-02-19 05:42:46 +00001032 kernel_name = m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename();
Jason Molenda4bd4e7e2012-09-29 04:02:01 +00001033 }
Jason Molenda306bd0a2013-02-19 05:42:46 +00001034 m_kernel.SetName (kernel_name.AsCString());
Jason Molenda4bd4e7e2012-09-29 04:02:01 +00001035
Jason Molenda306bd0a2013-02-19 05:42:46 +00001036 if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS)
Greg Clayton7b242382011-07-08 00:48:09 +00001037 {
Jason Molenda306bd0a2013-02-19 05:42:46 +00001038 m_kernel.SetLoadAddress(m_kernel_load_address);
1039 if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS && m_kernel.GetModule())
Greg Clayton7b242382011-07-08 00:48:09 +00001040 {
Greg Claytonc859e2d2012-02-13 23:10:39 +00001041 // We didn't get a hint from the process, so we will
1042 // try the kernel at the address that it exists at in
1043 // the file if we have one
Jason Molenda306bd0a2013-02-19 05:42:46 +00001044 ObjectFile *kernel_object_file = m_kernel.GetModule()->GetObjectFile();
Greg Claytonc859e2d2012-02-13 23:10:39 +00001045 if (kernel_object_file)
Jason Molenda4bd4e7e2012-09-29 04:02:01 +00001046 {
1047 addr_t load_address = kernel_object_file->GetHeaderAddress().GetLoadAddress(&m_process->GetTarget());
1048 addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress();
1049 if (load_address != LLDB_INVALID_ADDRESS && load_address != 0)
1050 {
Jason Molenda306bd0a2013-02-19 05:42:46 +00001051 m_kernel.SetLoadAddress (load_address);
Jason Molenda4bd4e7e2012-09-29 04:02:01 +00001052 if (load_address != file_address)
1053 {
1054 // Don't accidentally relocate the kernel to the File address --
1055 // the Load address has already been set to its actual in-memory address.
1056 // Mark it as IsLoaded.
Jason Molenda306bd0a2013-02-19 05:42:46 +00001057 m_kernel.SetProcessStopId (m_process->GetStopID());
Jason Molenda4bd4e7e2012-09-29 04:02:01 +00001058 }
1059 }
1060 else
1061 {
Jason Molenda306bd0a2013-02-19 05:42:46 +00001062 m_kernel.SetLoadAddress(file_address);
Jason Molenda4bd4e7e2012-09-29 04:02:01 +00001063 }
1064 }
Greg Clayton7b242382011-07-08 00:48:09 +00001065 }
1066 }
Greg Claytonc859e2d2012-02-13 23:10:39 +00001067
Jason Molenda306bd0a2013-02-19 05:42:46 +00001068 if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS)
Greg Clayton2af282a2012-03-21 04:25:00 +00001069 {
1070 if (!m_kernel.LoadImageUsingMemoryModule (m_process))
1071 {
1072 m_kernel.LoadImageAtFileAddress (m_process);
1073 }
1074 }
Greg Clayton7b242382011-07-08 00:48:09 +00001075
Jason Molenda306bd0a2013-02-19 05:42:46 +00001076 if (m_kernel.IsLoaded() && m_kernel.GetModule())
Greg Clayton7b242382011-07-08 00:48:09 +00001077 {
Greg Claytonc859e2d2012-02-13 23:10:39 +00001078 static ConstString kext_summary_symbol ("gLoadedKextSummaries");
Jason Molenda306bd0a2013-02-19 05:42:46 +00001079 const Symbol *symbol = m_kernel.GetModule()->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
Greg Claytonc859e2d2012-02-13 23:10:39 +00001080 if (symbol)
1081 {
Greg Claytone7612132012-03-07 21:03:09 +00001082 m_kext_summary_header_ptr_addr = symbol->GetAddress();
Greg Claytonc859e2d2012-02-13 23:10:39 +00001083 // Update all image infos
1084 ReadAllKextSummaries ();
1085 }
Greg Clayton7b242382011-07-08 00:48:09 +00001086 }
1087 else
Greg Clayton7b242382011-07-08 00:48:09 +00001088 {
Jason Molenda306bd0a2013-02-19 05:42:46 +00001089 m_kernel.Clear();
Greg Clayton7b242382011-07-08 00:48:09 +00001090 }
1091 }
Greg Clayton7b242382011-07-08 00:48:09 +00001092}
1093
Greg Clayton7b242382011-07-08 00:48:09 +00001094//----------------------------------------------------------------------
1095// Static callback function that gets called when our DYLD notification
1096// breakpoint gets hit. We update all of our image infos and then
1097// let our super class DynamicLoader class decide if we should stop
1098// or not (based on global preference).
1099//----------------------------------------------------------------------
1100bool
Greg Clayton944b8282011-08-22 22:30:57 +00001101DynamicLoaderDarwinKernel::BreakpointHitCallback (void *baton,
Greg Clayton374972e2011-07-09 17:15:55 +00001102 StoppointCallbackContext *context,
1103 user_id_t break_id,
1104 user_id_t break_loc_id)
Greg Clayton0d9fc762011-07-08 03:21:57 +00001105{
Greg Clayton944b8282011-08-22 22:30:57 +00001106 return static_cast<DynamicLoaderDarwinKernel*>(baton)->BreakpointHit (context, break_id, break_loc_id);
Greg Clayton7b242382011-07-08 00:48:09 +00001107}
1108
1109bool
Greg Clayton944b8282011-08-22 22:30:57 +00001110DynamicLoaderDarwinKernel::BreakpointHit (StoppointCallbackContext *context,
Greg Clayton374972e2011-07-09 17:15:55 +00001111 user_id_t break_id,
1112 user_id_t break_loc_id)
1113{
Greg Clayton5160ce52013-03-27 23:08:40 +00001114 Log *log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
Greg Claytond16e1e52011-07-12 17:06:17 +00001115 if (log)
Greg Clayton944b8282011-08-22 22:30:57 +00001116 log->Printf ("DynamicLoaderDarwinKernel::BreakpointHit (...)\n");
Greg Claytond16e1e52011-07-12 17:06:17 +00001117
Greg Clayton374972e2011-07-09 17:15:55 +00001118 ReadAllKextSummaries ();
Greg Claytond16e1e52011-07-12 17:06:17 +00001119
1120 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00001121 PutToLog(log);
Greg Claytond16e1e52011-07-12 17:06:17 +00001122
Greg Clayton374972e2011-07-09 17:15:55 +00001123 return GetStopWhenImagesChange();
1124}
1125
1126
1127bool
Greg Clayton944b8282011-08-22 22:30:57 +00001128DynamicLoaderDarwinKernel::ReadKextSummaryHeader ()
Greg Clayton7b242382011-07-08 00:48:09 +00001129{
1130 Mutex::Locker locker(m_mutex);
1131
1132 // the all image infos is already valid for this process stop ID
Greg Clayton7b242382011-07-08 00:48:09 +00001133
Greg Claytond16e1e52011-07-12 17:06:17 +00001134 if (m_kext_summary_header_ptr_addr.IsValid())
Greg Clayton7b242382011-07-08 00:48:09 +00001135 {
1136 const uint32_t addr_size = m_kernel.GetAddressByteSize ();
1137 const ByteOrder byte_order = m_kernel.GetByteOrder();
1138 Error error;
1139 // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure
Bruce Mitcheneraaa0ba32014-07-08 18:05:41 +00001140 // which is currently 4 uint32_t and a pointer.
Greg Clayton7b242382011-07-08 00:48:09 +00001141 uint8_t buf[24];
1142 DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
1143 const size_t count = 4 * sizeof(uint32_t) + addr_size;
Greg Clayton0d9fc762011-07-08 03:21:57 +00001144 const bool prefer_file_cache = false;
Greg Claytond16e1e52011-07-12 17:06:17 +00001145 if (m_process->GetTarget().ReadPointerFromMemory (m_kext_summary_header_ptr_addr,
1146 prefer_file_cache,
1147 error,
1148 m_kext_summary_header_addr))
Greg Clayton7b242382011-07-08 00:48:09 +00001149 {
Greg Claytond16e1e52011-07-12 17:06:17 +00001150 // We got a valid address for our kext summary header and make sure it isn't NULL
1151 if (m_kext_summary_header_addr.IsValid() &&
1152 m_kext_summary_header_addr.GetFileAddress() != 0)
1153 {
1154 const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
1155 if (bytes_read == count)
1156 {
Greg Claytonc7bece562013-01-25 18:06:21 +00001157 lldb::offset_t offset = 0;
Greg Claytona63d08c2011-07-19 03:57:15 +00001158 m_kext_summary_header.version = data.GetU32(&offset);
Jason Molendac6fa5db2014-04-15 01:04:00 +00001159 if (m_kext_summary_header.version > 128)
1160 {
1161 Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
1162 s->Printf ("WARNING: Unable to read kext summary header, got improbable version number %u\n", m_kext_summary_header.version);
Bruce Mitcheneraaa0ba32014-07-08 18:05:41 +00001163 // If we get an improbably large version number, we're probably getting bad memory.
Jason Molendac6fa5db2014-04-15 01:04:00 +00001164 m_kext_summary_header_addr.Clear();
1165 return false;
1166 }
Greg Claytona63d08c2011-07-19 03:57:15 +00001167 if (m_kext_summary_header.version >= 2)
1168 {
1169 m_kext_summary_header.entry_size = data.GetU32(&offset);
Jason Molendac6fa5db2014-04-15 01:04:00 +00001170 if (m_kext_summary_header.entry_size > 4096)
1171 {
1172 // If we get an improbably large entry_size, we're probably getting bad memory.
1173 Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
1174 s->Printf ("WARNING: Unable to read kext summary header, got improbable entry_size %u\n", m_kext_summary_header.entry_size);
1175 m_kext_summary_header_addr.Clear();
1176 return false;
1177 }
Greg Claytona63d08c2011-07-19 03:57:15 +00001178 }
1179 else
1180 {
1181 // Versions less than 2 didn't have an entry size, it was hard coded
1182 m_kext_summary_header.entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
1183 }
1184 m_kext_summary_header.entry_count = data.GetU32(&offset);
Jason Molendac6fa5db2014-04-15 01:04:00 +00001185 if (m_kext_summary_header.entry_count > 10000)
1186 {
1187 // If we get an improbably large number of kexts, we're probably getting bad memory.
1188 Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
1189 s->Printf ("WARNING: Unable to read kext summary header, got improbable number of kexts %u\n", m_kext_summary_header.entry_count);
1190 m_kext_summary_header_addr.Clear();
1191 return false;
1192 }
Greg Claytond16e1e52011-07-12 17:06:17 +00001193 return true;
1194 }
1195 }
Greg Clayton7b242382011-07-08 00:48:09 +00001196 }
1197 }
Greg Claytond16e1e52011-07-12 17:06:17 +00001198 m_kext_summary_header_addr.Clear();
Greg Clayton7b242382011-07-08 00:48:09 +00001199 return false;
1200}
1201
Jason Molenda306bd0a2013-02-19 05:42:46 +00001202// We've either (a) just attached to a new kernel, or (b) the kexts-changed breakpoint was hit
1203// and we need to figure out what kexts have been added or removed.
1204// Read the kext summaries from the inferior kernel memory, compare them against the
1205// m_known_kexts vector and update the m_known_kexts vector as needed to keep in sync with the
1206// inferior.
Greg Clayton7b242382011-07-08 00:48:09 +00001207
1208bool
Jason Molenda306bd0a2013-02-19 05:42:46 +00001209DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr, uint32_t count)
Greg Clayton7b242382011-07-08 00:48:09 +00001210{
Jason Molenda306bd0a2013-02-19 05:42:46 +00001211 KextImageInfo::collection kext_summaries;
Greg Clayton5160ce52013-03-27 23:08:40 +00001212 Log *log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
Greg Clayton7b242382011-07-08 00:48:09 +00001213 if (log)
Jason Molenda306bd0a2013-02-19 05:42:46 +00001214 log->Printf ("Kexts-changed breakpoint hit, there are %d kexts currently.\n", count);
Greg Clayton7b242382011-07-08 00:48:09 +00001215
1216 Mutex::Locker locker(m_mutex);
Greg Clayton7b242382011-07-08 00:48:09 +00001217
1218 if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries))
1219 return false;
1220
Jason Molenda4da2e322013-02-26 00:26:47 +00001221 // read the plugin.dynamic-loader.darwin-kernel.load-kexts setting -- if the user requested no
1222 // kext loading, don't print any messages about kexts & don't try to read them.
1223 const bool load_kexts = GetGlobalProperties()->GetLoadKexts();
1224
Jason Molenda306bd0a2013-02-19 05:42:46 +00001225 // By default, all kexts we've loaded in the past are marked as "remove" and all of the kexts
1226 // we just found out about from ReadKextSummaries are marked as "add".
1227 std::vector<bool> to_be_removed(m_known_kexts.size(), true);
1228 std::vector<bool> to_be_added(count, true);
1229
1230 int number_of_new_kexts_being_added = 0;
1231 int number_of_old_kexts_being_removed = m_known_kexts.size();
1232
1233 const uint32_t new_kexts_size = kext_summaries.size();
1234 const uint32_t old_kexts_size = m_known_kexts.size();
1235
1236 // The m_known_kexts vector may have entries that have been Cleared,
1237 // or are a kernel.
1238 for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++)
1239 {
1240 bool ignore = false;
1241 KextImageInfo &image_info = m_known_kexts[old_kext];
1242 if (image_info.IsKernel())
1243 {
1244 ignore = true;
1245 }
1246 else if (image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS && !image_info.GetModule())
1247 {
1248 ignore = true;
1249 }
1250
1251 if (ignore)
1252 {
1253 number_of_old_kexts_being_removed--;
1254 to_be_removed[old_kext] = false;
1255 }
1256 }
1257
1258 // Scan over the list of kexts we just read from the kernel, note those that
1259 // need to be added and those already loaded.
1260 for (uint32_t new_kext = 0; new_kext < new_kexts_size; new_kext++)
1261 {
1262 bool add_this_one = true;
1263 for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++)
1264 {
1265 if (m_known_kexts[old_kext] == kext_summaries[new_kext])
1266 {
1267 // We already have this kext, don't re-load it.
1268 to_be_added[new_kext] = false;
1269 // This kext is still present, do not remove it.
1270 to_be_removed[old_kext] = false;
1271
1272 number_of_old_kexts_being_removed--;
1273 add_this_one = false;
1274 break;
1275 }
1276 }
1277 if (add_this_one)
1278 {
1279 number_of_new_kexts_being_added++;
1280 }
1281 }
1282
1283 if (number_of_new_kexts_being_added == 0 && number_of_old_kexts_being_removed == 0)
1284 return true;
1285
Greg Clayton44d93782014-01-27 23:43:24 +00001286 Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get();
Jason Molenda4da2e322013-02-26 00:26:47 +00001287 if (s && load_kexts)
Greg Clayton7b242382011-07-08 00:48:09 +00001288 {
Jason Molenda306bd0a2013-02-19 05:42:46 +00001289 if (number_of_new_kexts_being_added > 0 && number_of_old_kexts_being_removed > 0)
1290 {
1291 s->Printf ("Loading %d kext modules and unloading %d kext modules ", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
1292 }
1293 else if (number_of_new_kexts_being_added > 0)
1294 {
1295 s->Printf ("Loading %d kext modules ", number_of_new_kexts_being_added);
1296 }
1297 else if (number_of_old_kexts_being_removed > 0)
1298 {
1299 s->Printf ("Unloading %d kext modules ", number_of_old_kexts_being_removed);
1300 }
Greg Clayton7b242382011-07-08 00:48:09 +00001301 }
Jason Molenda306bd0a2013-02-19 05:42:46 +00001302
1303 if (log)
Jason Molenda4da2e322013-02-26 00:26:47 +00001304 {
1305 if (load_kexts)
1306 {
1307 log->Printf ("DynamicLoaderDarwinKernel::ParseKextSummaries: %d kexts added, %d kexts removed", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
1308 }
1309 else
1310 {
1311 log->Printf ("DynamicLoaderDarwinKernel::ParseKextSummaries kext loading is disabled, else would have %d kexts added, %d kexts removed", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
1312 }
1313 }
1314
Jason Molenda306bd0a2013-02-19 05:42:46 +00001315
1316 if (number_of_new_kexts_being_added > 0)
1317 {
1318 ModuleList loaded_module_list;
1319
1320 const uint32_t num_of_new_kexts = kext_summaries.size();
1321 for (uint32_t new_kext = 0; new_kext < num_of_new_kexts; new_kext++)
1322 {
1323 if (to_be_added[new_kext] == true)
1324 {
1325 KextImageInfo &image_info = kext_summaries[new_kext];
Jason Molenda4da2e322013-02-26 00:26:47 +00001326 if (load_kexts)
1327 {
1328 if (!image_info.LoadImageUsingMemoryModule (m_process))
1329 {
1330 image_info.LoadImageAtFileAddress (m_process);
1331 }
1332 }
Jason Molenda306bd0a2013-02-19 05:42:46 +00001333
1334 m_known_kexts.push_back(image_info);
1335
1336 if (image_info.GetModule() && m_process->GetStopID() == image_info.GetProcessStopId())
1337 loaded_module_list.AppendIfNeeded (image_info.GetModule());
1338
Jason Molenda4da2e322013-02-26 00:26:47 +00001339 if (s && load_kexts)
Jason Molenda306bd0a2013-02-19 05:42:46 +00001340 s->Printf (".");
1341
1342 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +00001343 kext_summaries[new_kext].PutToLog (log);
Jason Molenda306bd0a2013-02-19 05:42:46 +00001344 }
1345 }
1346 m_process->GetTarget().ModulesDidLoad (loaded_module_list);
1347 }
1348
1349 if (number_of_old_kexts_being_removed > 0)
1350 {
1351 ModuleList loaded_module_list;
1352 const uint32_t num_of_old_kexts = m_known_kexts.size();
1353 for (uint32_t old_kext = 0; old_kext < num_of_old_kexts; old_kext++)
1354 {
1355 ModuleList unloaded_module_list;
1356 if (to_be_removed[old_kext])
1357 {
1358 KextImageInfo &image_info = m_known_kexts[old_kext];
1359 // You can't unload the kernel.
1360 if (!image_info.IsKernel())
1361 {
1362 if (image_info.GetModule())
1363 {
1364 unloaded_module_list.AppendIfNeeded (image_info.GetModule());
1365 }
1366 if (s)
1367 s->Printf (".");
1368 image_info.Clear();
1369 // should pull it out of the KextImageInfos vector but that would mutate the list and invalidate
1370 // the to_be_removed bool vector; leaving it in place once Cleared() is relatively harmless.
1371 }
1372 }
Greg Clayton095eeaa2013-11-05 23:28:00 +00001373 m_process->GetTarget().ModulesDidUnload (unloaded_module_list, false);
Jason Molenda306bd0a2013-02-19 05:42:46 +00001374 }
1375 }
1376
Jason Molenda4da2e322013-02-26 00:26:47 +00001377 if (s && load_kexts)
Jason Molenda68b36072012-10-02 03:49:41 +00001378 {
1379 s->Printf (" done.\n");
1380 s->Flush ();
1381 }
1382
Jason Molenda306bd0a2013-02-19 05:42:46 +00001383 return true;
Greg Clayton7b242382011-07-08 00:48:09 +00001384}
1385
Greg Clayton7b242382011-07-08 00:48:09 +00001386uint32_t
Greg Clayton944b8282011-08-22 22:30:57 +00001387DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr,
Greg Clayton7b242382011-07-08 00:48:09 +00001388 uint32_t image_infos_count,
Jason Molenda306bd0a2013-02-19 05:42:46 +00001389 KextImageInfo::collection &image_infos)
Greg Clayton7b242382011-07-08 00:48:09 +00001390{
1391 const ByteOrder endian = m_kernel.GetByteOrder();
1392 const uint32_t addr_size = m_kernel.GetAddressByteSize();
1393
1394 image_infos.resize(image_infos_count);
1395 const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
1396 DataBufferHeap data(count, 0);
1397 Error error;
Greg Clayton5b882162011-07-21 01:12:01 +00001398
Greg Clayton0d9fc762011-07-08 03:21:57 +00001399 const bool prefer_file_cache = false;
1400 const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr,
1401 prefer_file_cache,
1402 data.GetBytes(),
1403 data.GetByteSize(),
1404 error);
Greg Clayton7b242382011-07-08 00:48:09 +00001405 if (bytes_read == count)
1406 {
Greg Claytona63d08c2011-07-19 03:57:15 +00001407
Greg Clayton7b242382011-07-08 00:48:09 +00001408 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size);
1409 uint32_t i=0;
Greg Claytona63d08c2011-07-19 03:57:15 +00001410 for (uint32_t kext_summary_offset = 0;
1411 i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size);
1412 ++i, kext_summary_offset += m_kext_summary_header.entry_size)
Greg Clayton7b242382011-07-08 00:48:09 +00001413 {
Greg Claytonc7bece562013-01-25 18:06:21 +00001414 lldb::offset_t offset = kext_summary_offset;
Greg Clayton7b242382011-07-08 00:48:09 +00001415 const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
1416 if (name_data == NULL)
1417 break;
Jason Molenda306bd0a2013-02-19 05:42:46 +00001418 image_infos[i].SetName ((const char *) name_data);
1419 UUID uuid (extractor.GetData (&offset, 16), 16);
1420 image_infos[i].SetUUID (uuid);
1421 image_infos[i].SetLoadAddress (extractor.GetU64(&offset));
1422 image_infos[i].SetSize (extractor.GetU64(&offset));
Greg Clayton7b242382011-07-08 00:48:09 +00001423 }
1424 if (i < image_infos.size())
1425 image_infos.resize(i);
1426 }
1427 else
1428 {
1429 image_infos.clear();
1430 }
1431 return image_infos.size();
1432}
1433
1434bool
Greg Clayton944b8282011-08-22 22:30:57 +00001435DynamicLoaderDarwinKernel::ReadAllKextSummaries ()
Greg Clayton7b242382011-07-08 00:48:09 +00001436{
Greg Clayton7b242382011-07-08 00:48:09 +00001437 Mutex::Locker locker(m_mutex);
Greg Clayton374972e2011-07-09 17:15:55 +00001438
Greg Clayton7b242382011-07-08 00:48:09 +00001439 if (ReadKextSummaryHeader ())
1440 {
Greg Clayton374972e2011-07-09 17:15:55 +00001441 if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid())
Greg Clayton7b242382011-07-08 00:48:09 +00001442 {
Greg Clayton0d9fc762011-07-08 03:21:57 +00001443 Address summary_addr (m_kext_summary_header_addr);
Greg Claytona63d08c2011-07-19 03:57:15 +00001444 summary_addr.Slide(m_kext_summary_header.GetSize());
Greg Clayton0d9fc762011-07-08 03:21:57 +00001445 if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count))
Greg Clayton7b242382011-07-08 00:48:09 +00001446 {
Jason Molenda306bd0a2013-02-19 05:42:46 +00001447 m_known_kexts.clear();
Greg Clayton7b242382011-07-08 00:48:09 +00001448 }
1449 return true;
1450 }
1451 }
1452 return false;
1453}
1454
1455//----------------------------------------------------------------------
Greg Clayton7b242382011-07-08 00:48:09 +00001456// Dump an image info structure to the file handle provided.
1457//----------------------------------------------------------------------
1458void
Jason Molenda306bd0a2013-02-19 05:42:46 +00001459DynamicLoaderDarwinKernel::KextImageInfo::PutToLog (Log *log) const
Greg Clayton7b242382011-07-08 00:48:09 +00001460{
1461 if (log == NULL)
1462 return;
Jason Molenda306bd0a2013-02-19 05:42:46 +00001463 const uint8_t *u = (uint8_t *) m_uuid.GetBytes();
Greg Clayton7b242382011-07-08 00:48:09 +00001464
Jason Molenda306bd0a2013-02-19 05:42:46 +00001465 if (m_load_address == LLDB_INVALID_ADDRESS)
Greg Clayton7b242382011-07-08 00:48:09 +00001466 {
1467 if (u)
1468 {
Greg Claytona63d08c2011-07-19 03:57:15 +00001469 log->Printf("\tuuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\" (UNLOADED)",
Greg Clayton7b242382011-07-08 00:48:09 +00001470 u[ 0], u[ 1], u[ 2], u[ 3],
1471 u[ 4], u[ 5], u[ 6], u[ 7],
1472 u[ 8], u[ 9], u[10], u[11],
1473 u[12], u[13], u[14], u[15],
Jason Molenda306bd0a2013-02-19 05:42:46 +00001474 m_name.c_str());
Greg Clayton7b242382011-07-08 00:48:09 +00001475 }
1476 else
Jason Molenda306bd0a2013-02-19 05:42:46 +00001477 log->Printf("\tname=\"%s\" (UNLOADED)", m_name.c_str());
Greg Clayton7b242382011-07-08 00:48:09 +00001478 }
1479 else
1480 {
1481 if (u)
1482 {
Jason Molenda306bd0a2013-02-19 05:42:46 +00001483 log->Printf("\taddr=0x%16.16" PRIx64 " size=0x%16.16" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\"",
1484 m_load_address, m_size,
Greg Claytona63d08c2011-07-19 03:57:15 +00001485 u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
1486 u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
Jason Molenda306bd0a2013-02-19 05:42:46 +00001487 m_name.c_str());
Greg Clayton7b242382011-07-08 00:48:09 +00001488 }
1489 else
1490 {
Jason Molenda306bd0a2013-02-19 05:42:46 +00001491 log->Printf("\t[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") name=\"%s\"",
1492 m_load_address, m_load_address+m_size, m_name.c_str());
Greg Clayton7b242382011-07-08 00:48:09 +00001493 }
Greg Clayton7b242382011-07-08 00:48:09 +00001494 }
1495}
1496
1497//----------------------------------------------------------------------
1498// Dump the _dyld_all_image_infos members and all current image infos
1499// that we have parsed to the file handle provided.
1500//----------------------------------------------------------------------
1501void
Greg Clayton944b8282011-08-22 22:30:57 +00001502DynamicLoaderDarwinKernel::PutToLog(Log *log) const
Greg Clayton7b242382011-07-08 00:48:09 +00001503{
1504 if (log == NULL)
1505 return;
1506
1507 Mutex::Locker locker(m_mutex);
Daniel Malead01b2952012-11-29 21:49:15 +00001508 log->Printf("gLoadedKextSummaries = 0x%16.16" PRIx64 " { version=%u, entry_size=%u, entry_count=%u }",
Greg Clayton0d9fc762011-07-08 03:21:57 +00001509 m_kext_summary_header_addr.GetFileAddress(),
Greg Clayton7b242382011-07-08 00:48:09 +00001510 m_kext_summary_header.version,
1511 m_kext_summary_header.entry_size,
Greg Claytona63d08c2011-07-19 03:57:15 +00001512 m_kext_summary_header.entry_count);
Greg Clayton7b242382011-07-08 00:48:09 +00001513
1514 size_t i;
Jason Molenda306bd0a2013-02-19 05:42:46 +00001515 const size_t count = m_known_kexts.size();
Greg Clayton7b242382011-07-08 00:48:09 +00001516 if (count > 0)
1517 {
1518 log->PutCString("Loaded:");
1519 for (i = 0; i<count; i++)
Jason Molenda306bd0a2013-02-19 05:42:46 +00001520 m_known_kexts[i].PutToLog(log);
Greg Clayton7b242382011-07-08 00:48:09 +00001521 }
1522}
1523
1524void
Greg Clayton944b8282011-08-22 22:30:57 +00001525DynamicLoaderDarwinKernel::PrivateInitialize(Process *process)
Greg Clayton7b242382011-07-08 00:48:09 +00001526{
Greg Clayton944b8282011-08-22 22:30:57 +00001527 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
Greg Clayton7b242382011-07-08 00:48:09 +00001528 Clear(true);
1529 m_process = process;
Greg Clayton7b242382011-07-08 00:48:09 +00001530}
1531
Greg Clayton374972e2011-07-09 17:15:55 +00001532void
Greg Clayton944b8282011-08-22 22:30:57 +00001533DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded ()
Greg Clayton7b242382011-07-08 00:48:09 +00001534{
Jason Molenda306bd0a2013-02-19 05:42:46 +00001535 if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.GetModule())
Greg Clayton374972e2011-07-09 17:15:55 +00001536 {
Greg Clayton944b8282011-08-22 22:30:57 +00001537 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
Greg Clayton374972e2011-07-09 17:15:55 +00001538
Greg Claytond16e1e52011-07-12 17:06:17 +00001539
Jim Inghama8558b62012-05-22 00:12:20 +00001540 const bool internal_bp = true;
Greg Claytoneb023e72013-10-11 19:48:25 +00001541 const bool hardware = false;
Greg Claytond16e1e52011-07-12 17:06:17 +00001542 const LazyBool skip_prologue = eLazyBoolNo;
Jim Ingham969795f2011-09-21 01:17:13 +00001543 FileSpecList module_spec_list;
Jason Molenda306bd0a2013-02-19 05:42:46 +00001544 module_spec_list.Append (m_kernel.GetModule()->GetFileSpec());
Jim Ingham969795f2011-09-21 01:17:13 +00001545 Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list,
Jim Ingham87df91b2011-09-23 00:54:11 +00001546 NULL,
Greg Clayton374972e2011-07-09 17:15:55 +00001547 "OSKextLoadedKextSummariesUpdated",
1548 eFunctionNameTypeFull,
Jim Inghama8558b62012-05-22 00:12:20 +00001549 skip_prologue,
Greg Claytoneb023e72013-10-11 19:48:25 +00001550 internal_bp,
1551 hardware).get();
Greg Clayton374972e2011-07-09 17:15:55 +00001552
Greg Clayton944b8282011-08-22 22:30:57 +00001553 bp->SetCallback (DynamicLoaderDarwinKernel::BreakpointHitCallback, this, true);
Greg Clayton374972e2011-07-09 17:15:55 +00001554 m_break_id = bp->GetID();
1555 }
Greg Clayton7b242382011-07-08 00:48:09 +00001556}
1557
1558//----------------------------------------------------------------------
1559// Member function that gets called when the process state changes.
1560//----------------------------------------------------------------------
1561void
Greg Clayton944b8282011-08-22 22:30:57 +00001562DynamicLoaderDarwinKernel::PrivateProcessStateChanged (Process *process, StateType state)
Greg Clayton7b242382011-07-08 00:48:09 +00001563{
Greg Clayton944b8282011-08-22 22:30:57 +00001564 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state));
Greg Clayton7b242382011-07-08 00:48:09 +00001565 switch (state)
1566 {
1567 case eStateConnected:
1568 case eStateAttaching:
1569 case eStateLaunching:
1570 case eStateInvalid:
1571 case eStateUnloaded:
1572 case eStateExited:
1573 case eStateDetached:
1574 Clear(false);
1575 break;
1576
1577 case eStateStopped:
Greg Clayton374972e2011-07-09 17:15:55 +00001578 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +00001579 break;
1580
1581 case eStateRunning:
1582 case eStateStepping:
1583 case eStateCrashed:
1584 case eStateSuspended:
1585 break;
Greg Clayton7b242382011-07-08 00:48:09 +00001586 }
1587}
1588
1589ThreadPlanSP
Greg Clayton944b8282011-08-22 22:30:57 +00001590DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
Greg Clayton7b242382011-07-08 00:48:09 +00001591{
1592 ThreadPlanSP thread_plan_sp;
Greg Clayton5160ce52013-03-27 23:08:40 +00001593 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Greg Clayton374972e2011-07-09 17:15:55 +00001594 if (log)
1595 log->Printf ("Could not find symbol for step through.");
Greg Clayton7b242382011-07-08 00:48:09 +00001596 return thread_plan_sp;
1597}
1598
1599Error
Greg Clayton944b8282011-08-22 22:30:57 +00001600DynamicLoaderDarwinKernel::CanLoadImage ()
Greg Clayton7b242382011-07-08 00:48:09 +00001601{
1602 Error error;
1603 error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel");
1604 return error;
1605}
1606
1607void
Greg Clayton944b8282011-08-22 22:30:57 +00001608DynamicLoaderDarwinKernel::Initialize()
Greg Clayton7b242382011-07-08 00:48:09 +00001609{
1610 PluginManager::RegisterPlugin (GetPluginNameStatic(),
1611 GetPluginDescriptionStatic(),
Greg Claytone8cd0c92012-10-19 18:02:49 +00001612 CreateInstance,
1613 DebuggerInitialize);
Greg Clayton7b242382011-07-08 00:48:09 +00001614}
1615
1616void
Greg Clayton944b8282011-08-22 22:30:57 +00001617DynamicLoaderDarwinKernel::Terminate()
Greg Clayton7b242382011-07-08 00:48:09 +00001618{
1619 PluginManager::UnregisterPlugin (CreateInstance);
1620}
1621
Greg Claytone8cd0c92012-10-19 18:02:49 +00001622void
1623DynamicLoaderDarwinKernel::DebuggerInitialize (lldb_private::Debugger &debugger)
1624{
1625 if (!PluginManager::GetSettingForDynamicLoaderPlugin (debugger, DynamicLoaderDarwinKernelProperties::GetSettingName()))
1626 {
1627 const bool is_global_setting = true;
1628 PluginManager::CreateSettingForDynamicLoaderPlugin (debugger,
1629 GetGlobalProperties()->GetValueProperties(),
1630 ConstString ("Properties for the DynamicLoaderDarwinKernel plug-in."),
1631 is_global_setting);
1632 }
1633}
Greg Clayton7b242382011-07-08 00:48:09 +00001634
Greg Clayton57abc5d2013-05-10 21:47:16 +00001635lldb_private::ConstString
Greg Clayton944b8282011-08-22 22:30:57 +00001636DynamicLoaderDarwinKernel::GetPluginNameStatic()
Greg Clayton7b242382011-07-08 00:48:09 +00001637{
Greg Clayton57abc5d2013-05-10 21:47:16 +00001638 static ConstString g_name("darwin-kernel");
1639 return g_name;
Greg Clayton7b242382011-07-08 00:48:09 +00001640}
1641
1642const char *
Greg Clayton944b8282011-08-22 22:30:57 +00001643DynamicLoaderDarwinKernel::GetPluginDescriptionStatic()
Greg Clayton7b242382011-07-08 00:48:09 +00001644{
1645 return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel.";
1646}
1647
1648
1649//------------------------------------------------------------------
1650// PluginInterface protocol
1651//------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +00001652lldb_private::ConstString
Greg Clayton944b8282011-08-22 22:30:57 +00001653DynamicLoaderDarwinKernel::GetPluginName()
Greg Clayton7b242382011-07-08 00:48:09 +00001654{
Greg Clayton7b242382011-07-08 00:48:09 +00001655 return GetPluginNameStatic();
1656}
1657
1658uint32_t
Greg Clayton944b8282011-08-22 22:30:57 +00001659DynamicLoaderDarwinKernel::GetPluginVersion()
Greg Clayton7b242382011-07-08 00:48:09 +00001660{
1661 return 1;
1662}
1663
Greg Clayton1f746072012-08-29 21:13:06 +00001664lldb::ByteOrder
1665DynamicLoaderDarwinKernel::GetByteOrderFromMagic (uint32_t magic)
1666{
1667 switch (magic)
1668 {
Charles Davis510938e2013-08-27 05:04:57 +00001669 case llvm::MachO::MH_MAGIC:
1670 case llvm::MachO::MH_MAGIC_64:
Greg Clayton1f746072012-08-29 21:13:06 +00001671 return lldb::endian::InlHostByteOrder();
1672
Charles Davis510938e2013-08-27 05:04:57 +00001673 case llvm::MachO::MH_CIGAM:
1674 case llvm::MachO::MH_CIGAM_64:
Greg Clayton1f746072012-08-29 21:13:06 +00001675 if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig)
1676 return lldb::eByteOrderLittle;
1677 else
1678 return lldb::eByteOrderBig;
1679
1680 default:
1681 break;
1682 }
1683 return lldb::eByteOrderInvalid;
1684}
1685