1 //===-- ProcessMachCore.cpp -----------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include <cerrno>
10 #include <cstdlib>
11
12 #include "llvm/Support/MathExtras.h"
13 #include "llvm/Support/Threading.h"
14
15 #include "lldb/Core/Debugger.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/ModuleSpec.h"
18 #include "lldb/Core/PluginManager.h"
19 #include "lldb/Core/Section.h"
20 #include "lldb/Host/Host.h"
21 #include "lldb/Symbol/LocateSymbolFile.h"
22 #include "lldb/Symbol/ObjectFile.h"
23 #include "lldb/Target/MemoryRegionInfo.h"
24 #include "lldb/Target/SectionLoadList.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Target/Thread.h"
27 #include "lldb/Utility/DataBuffer.h"
28 #include "lldb/Utility/LLDBLog.h"
29 #include "lldb/Utility/Log.h"
30 #include "lldb/Utility/State.h"
31
32 #include "ProcessMachCore.h"
33 #include "Plugins/Process/Utility/StopInfoMachException.h"
34 #include "ThreadMachCore.h"
35
36 // Needed for the plug-in names for the dynamic loaders.
37 #include "lldb/Host/SafeMachO.h"
38
39 #include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
40 #include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
41 #include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
42 #include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
43
44 #include <memory>
45 #include <mutex>
46
47 using namespace lldb;
48 using namespace lldb_private;
49
LLDB_PLUGIN_DEFINE(ProcessMachCore)50 LLDB_PLUGIN_DEFINE(ProcessMachCore)
51
52 llvm::StringRef ProcessMachCore::GetPluginDescriptionStatic() {
53 return "Mach-O core file debugging plug-in.";
54 }
55
Terminate()56 void ProcessMachCore::Terminate() {
57 PluginManager::UnregisterPlugin(ProcessMachCore::CreateInstance);
58 }
59
CreateInstance(lldb::TargetSP target_sp,ListenerSP listener_sp,const FileSpec * crash_file,bool can_connect)60 lldb::ProcessSP ProcessMachCore::CreateInstance(lldb::TargetSP target_sp,
61 ListenerSP listener_sp,
62 const FileSpec *crash_file,
63 bool can_connect) {
64 lldb::ProcessSP process_sp;
65 if (crash_file && !can_connect) {
66 const size_t header_size = sizeof(llvm::MachO::mach_header);
67 auto data_sp = FileSystem::Instance().CreateDataBuffer(
68 crash_file->GetPath(), header_size, 0);
69 if (data_sp && data_sp->GetByteSize() == header_size) {
70 DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
71
72 lldb::offset_t data_offset = 0;
73 llvm::MachO::mach_header mach_header;
74 if (ObjectFileMachO::ParseHeader(data, &data_offset, mach_header)) {
75 if (mach_header.filetype == llvm::MachO::MH_CORE)
76 process_sp = std::make_shared<ProcessMachCore>(target_sp, listener_sp,
77 *crash_file);
78 }
79 }
80 }
81 return process_sp;
82 }
83
CanDebug(lldb::TargetSP target_sp,bool plugin_specified_by_name)84 bool ProcessMachCore::CanDebug(lldb::TargetSP target_sp,
85 bool plugin_specified_by_name) {
86 if (plugin_specified_by_name)
87 return true;
88
89 // For now we are just making sure the file exists for a given module
90 if (!m_core_module_sp && FileSystem::Instance().Exists(m_core_file)) {
91 // Don't add the Target's architecture to the ModuleSpec - we may be
92 // working with a core file that doesn't have the correct cpusubtype in the
93 // header but we should still try to use it -
94 // ModuleSpecList::FindMatchingModuleSpec enforces a strict arch mach.
95 ModuleSpec core_module_spec(m_core_file);
96 Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp,
97 nullptr, nullptr, nullptr));
98
99 if (m_core_module_sp) {
100 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
101 if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
102 return true;
103 }
104 }
105 return false;
106 }
107
108 // ProcessMachCore constructor
ProcessMachCore(lldb::TargetSP target_sp,ListenerSP listener_sp,const FileSpec & core_file)109 ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp,
110 ListenerSP listener_sp,
111 const FileSpec &core_file)
112 : PostMortemProcess(target_sp, listener_sp), m_core_aranges(),
113 m_core_range_infos(), m_core_module_sp(), m_core_file(core_file),
114 m_dyld_addr(LLDB_INVALID_ADDRESS),
115 m_mach_kernel_addr(LLDB_INVALID_ADDRESS) {}
116
117 // Destructor
~ProcessMachCore()118 ProcessMachCore::~ProcessMachCore() {
119 Clear();
120 // We need to call finalize on the process before destroying ourselves to
121 // make sure all of the broadcaster cleanup goes as planned. If we destruct
122 // this class, then Process::~Process() might have problems trying to fully
123 // destroy the broadcaster.
124 Finalize();
125 }
126
GetDynamicLoaderAddress(lldb::addr_t addr)127 bool ProcessMachCore::GetDynamicLoaderAddress(lldb::addr_t addr) {
128 Log *log(GetLog(LLDBLog::DynamicLoader | LLDBLog::Process));
129 llvm::MachO::mach_header header;
130 Status error;
131 if (DoReadMemory(addr, &header, sizeof(header), error) != sizeof(header))
132 return false;
133 if (header.magic == llvm::MachO::MH_CIGAM ||
134 header.magic == llvm::MachO::MH_CIGAM_64) {
135 header.magic = llvm::ByteSwap_32(header.magic);
136 header.cputype = llvm::ByteSwap_32(header.cputype);
137 header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
138 header.filetype = llvm::ByteSwap_32(header.filetype);
139 header.ncmds = llvm::ByteSwap_32(header.ncmds);
140 header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
141 header.flags = llvm::ByteSwap_32(header.flags);
142 }
143
144 // TODO: swap header if needed...
145 // printf("0x%16.16" PRIx64 ": magic = 0x%8.8x, file_type= %u\n", vaddr,
146 // header.magic, header.filetype);
147 if (header.magic == llvm::MachO::MH_MAGIC ||
148 header.magic == llvm::MachO::MH_MAGIC_64) {
149 // Check MH_EXECUTABLE to see if we can find the mach image that contains
150 // the shared library list. The dynamic loader (dyld) is what contains the
151 // list for user applications, and the mach kernel contains a global that
152 // has the list of kexts to load
153 switch (header.filetype) {
154 case llvm::MachO::MH_DYLINKER:
155 // printf("0x%16.16" PRIx64 ": file_type = MH_DYLINKER\n", vaddr);
156 // Address of dyld "struct mach_header" in the core file
157 LLDB_LOGF(log,
158 "ProcessMachCore::GetDynamicLoaderAddress found a user "
159 "process dyld binary image at 0x%" PRIx64,
160 addr);
161 m_dyld_addr = addr;
162 return true;
163
164 case llvm::MachO::MH_EXECUTE:
165 // printf("0x%16.16" PRIx64 ": file_type = MH_EXECUTE\n", vaddr);
166 // Check MH_EXECUTABLE file types to see if the dynamic link object flag
167 // is NOT set. If it isn't, then we have a mach_kernel.
168 if ((header.flags & llvm::MachO::MH_DYLDLINK) == 0) {
169 LLDB_LOGF(log,
170 "ProcessMachCore::GetDynamicLoaderAddress found a mach "
171 "kernel binary image at 0x%" PRIx64,
172 addr);
173 // Address of the mach kernel "struct mach_header" in the core file.
174 m_mach_kernel_addr = addr;
175 return true;
176 }
177 break;
178 }
179 }
180 return false;
181 }
182
183 // We have a hint about a binary -- a UUID, possibly a load address.
184 // Try to load a file with that UUID into lldb, and if we have a load
185 // address, set it correctly. Else assume that the binary was loaded
186 // with no slide.
load_standalone_binary(UUID uuid,addr_t value,bool value_is_offset,Target & target)187 static bool load_standalone_binary(UUID uuid, addr_t value,
188 bool value_is_offset, Target &target) {
189 if (uuid.IsValid()) {
190 ModuleSpec module_spec;
191 module_spec.GetUUID() = uuid;
192
193 // Look up UUID in global module cache before attempting
194 // dsymForUUID-like action.
195 ModuleSP module_sp;
196 Status error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr,
197 nullptr, nullptr);
198
199 if (!module_sp.get()) {
200 // Force a a dsymForUUID lookup, if that tool is available.
201 if (!module_spec.GetSymbolFileSpec()) {
202 Status error;
203 Symbols::DownloadObjectAndSymbolFile(module_spec, error, true);
204 }
205
206 if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
207 module_sp = std::make_shared<Module>(module_spec);
208 }
209 }
210
211 // If we couldn't find the binary anywhere else, as a last resort,
212 // read it out of memory in the corefile.
213 if (!module_sp.get() && value != LLDB_INVALID_ADDRESS && !value_is_offset) {
214 char namebuf[80];
215 snprintf(namebuf, sizeof(namebuf), "mem-image-0x%" PRIx64, value);
216 module_sp =
217 target.GetProcessSP()->ReadModuleFromMemory(FileSpec(namebuf), value);
218 }
219
220 if (module_sp.get()) {
221 target.SetArchitecture(module_sp->GetObjectFile()->GetArchitecture());
222 target.GetImages().AppendIfNeeded(module_sp, false);
223
224 // TODO: Instead of using the load address as a value, if we create a
225 // memory module from that address, we could get the correct segment
226 // offset values from the in-memory load commands and set them correctly.
227 // In case the load address we were given is not correct for all segments,
228 // e.g. something in the shared cache. DynamicLoaderDarwinKernel does
229 // something similar for kexts. In the context of a corefile, this would
230 // be an inexpensive operation. Not all binaries in a corefile will have
231 // a Mach-O header/load commands in memory, so this will not work in all
232 // cases.
233
234 bool changed = false;
235 if (module_sp->GetObjectFile()) {
236 if (value != LLDB_INVALID_ADDRESS) {
237 module_sp->SetLoadAddress(target, value, value_is_offset, changed);
238 } else {
239 // No address/offset/slide, load the binary at file address,
240 // offset 0.
241 const bool value_is_slide = true;
242 module_sp->SetLoadAddress(target, 0, value_is_slide, changed);
243 }
244 } else {
245 // In-memory image, load at its true address, offset 0.
246 const bool value_is_slide = true;
247 module_sp->SetLoadAddress(target, 0, value_is_slide, changed);
248 }
249
250 ModuleList added_module;
251 added_module.Append(module_sp, false);
252 target.ModulesDidLoad(added_module);
253
254 // Flush info in the process (stack frames, etc).
255 ProcessSP process_sp(target.GetProcessSP());
256 if (process_sp)
257 process_sp->Flush();
258
259 return true;
260 }
261 }
262 return false;
263 }
264
265 // Process Control
DoLoadCore()266 Status ProcessMachCore::DoLoadCore() {
267 Log *log(GetLog(LLDBLog::DynamicLoader | LLDBLog::Process));
268 Status error;
269 if (!m_core_module_sp) {
270 error.SetErrorString("invalid core module");
271 return error;
272 }
273
274 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
275 if (core_objfile == nullptr) {
276 error.SetErrorString("invalid core object file");
277 return error;
278 }
279
280 if (core_objfile->GetNumThreadContexts() == 0) {
281 error.SetErrorString("core file doesn't contain any LC_THREAD load "
282 "commands, or the LC_THREAD architecture is not "
283 "supported in this lldb");
284 return error;
285 }
286
287 SectionList *section_list = core_objfile->GetSectionList();
288 if (section_list == nullptr) {
289 error.SetErrorString("core file has no sections");
290 return error;
291 }
292
293 const uint32_t num_sections = section_list->GetNumSections(0);
294 if (num_sections == 0) {
295 error.SetErrorString("core file has no sections");
296 return error;
297 }
298
299 SetCanJIT(false);
300
301 llvm::MachO::mach_header header;
302 DataExtractor data(&header, sizeof(header),
303 m_core_module_sp->GetArchitecture().GetByteOrder(),
304 m_core_module_sp->GetArchitecture().GetAddressByteSize());
305
306 bool ranges_are_sorted = true;
307 addr_t vm_addr = 0;
308 for (uint32_t i = 0; i < num_sections; ++i) {
309 Section *section = section_list->GetSectionAtIndex(i).get();
310 if (section && section->GetFileSize() > 0) {
311 lldb::addr_t section_vm_addr = section->GetFileAddress();
312 FileRange file_range(section->GetFileOffset(), section->GetFileSize());
313 VMRangeToFileOffset::Entry range_entry(
314 section_vm_addr, section->GetByteSize(), file_range);
315
316 if (vm_addr > section_vm_addr)
317 ranges_are_sorted = false;
318 vm_addr = section->GetFileAddress();
319 VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
320
321 if (last_entry &&
322 last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
323 last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase()) {
324 last_entry->SetRangeEnd(range_entry.GetRangeEnd());
325 last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd());
326 } else {
327 m_core_aranges.Append(range_entry);
328 }
329 // Some core files don't fill in the permissions correctly. If that is
330 // the case assume read + execute so clients don't think the memory is
331 // not readable, or executable. The memory isn't writable since this
332 // plug-in doesn't implement DoWriteMemory.
333 uint32_t permissions = section->GetPermissions();
334 if (permissions == 0)
335 permissions = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
336 m_core_range_infos.Append(VMRangeToPermissions::Entry(
337 section_vm_addr, section->GetByteSize(), permissions));
338 }
339 }
340 if (!ranges_are_sorted) {
341 m_core_aranges.Sort();
342 m_core_range_infos.Sort();
343 }
344
345 bool found_main_binary_definitively = false;
346
347 addr_t objfile_binary_value;
348 bool objfile_binary_value_is_offset;
349 UUID objfile_binary_uuid;
350 ObjectFile::BinaryType type;
351 if (core_objfile->GetCorefileMainBinaryInfo(objfile_binary_value,
352 objfile_binary_value_is_offset,
353 objfile_binary_uuid, type)) {
354 if (log) {
355 log->Printf(
356 "ProcessMachCore::DoLoadCore: using binary hint from 'main bin spec' "
357 "LC_NOTE with UUID %s value 0x%" PRIx64
358 " value is offset %d and type %d",
359 objfile_binary_uuid.GetAsString().c_str(), objfile_binary_value,
360 objfile_binary_value_is_offset, type);
361 }
362 if (objfile_binary_value != LLDB_INVALID_ADDRESS &&
363 !objfile_binary_value_is_offset) {
364 if (type == ObjectFile::eBinaryTypeUser) {
365 load_standalone_binary(objfile_binary_uuid, objfile_binary_value,
366 objfile_binary_value_is_offset, GetTarget());
367 m_dyld_addr = objfile_binary_value;
368 m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
369 found_main_binary_definitively = true;
370 }
371 if (type == ObjectFile::eBinaryTypeKernel) {
372 m_mach_kernel_addr = objfile_binary_value;
373 m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
374 found_main_binary_definitively = true;
375 }
376 }
377 if (!found_main_binary_definitively) {
378 // ObjectFile::eBinaryTypeStandalone, undeclared types
379 if (load_standalone_binary(objfile_binary_uuid, objfile_binary_value,
380 objfile_binary_value_is_offset, GetTarget())) {
381 found_main_binary_definitively = true;
382 m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic();
383 }
384 }
385 }
386
387 // This checks for the presence of an LC_IDENT string in a core file;
388 // LC_IDENT is very obsolete and should not be used in new code, but if the
389 // load command is present, let's use the contents.
390 UUID ident_uuid;
391 addr_t ident_binary_addr = LLDB_INVALID_ADDRESS;
392 if (!found_main_binary_definitively) {
393 std::string corefile_identifier = core_objfile->GetIdentifierString();
394
395 // Search for UUID= and stext= strings in the identifier str.
396 if (corefile_identifier.find("UUID=") != std::string::npos) {
397 size_t p = corefile_identifier.find("UUID=") + strlen("UUID=");
398 std::string uuid_str = corefile_identifier.substr(p, 36);
399 ident_uuid.SetFromStringRef(uuid_str);
400 if (log)
401 log->Printf("Got a UUID from LC_IDENT/kern ver str LC_NOTE: %s",
402 ident_uuid.GetAsString().c_str());
403 }
404 if (corefile_identifier.find("stext=") != std::string::npos) {
405 size_t p = corefile_identifier.find("stext=") + strlen("stext=");
406 if (corefile_identifier[p] == '0' && corefile_identifier[p + 1] == 'x') {
407 ident_binary_addr =
408 ::strtoul(corefile_identifier.c_str() + p, nullptr, 16);
409 if (log)
410 log->Printf("Got a load address from LC_IDENT/kern ver str "
411 "LC_NOTE: 0x%" PRIx64,
412 ident_binary_addr);
413 }
414 }
415
416 // Search for a "Darwin Kernel" str indicating kernel; else treat as
417 // standalone
418 if (corefile_identifier.find("Darwin Kernel") != std::string::npos &&
419 ident_uuid.IsValid() && ident_binary_addr != LLDB_INVALID_ADDRESS) {
420 if (log)
421 log->Printf("ProcessMachCore::DoLoadCore: Found kernel binary via "
422 "LC_IDENT/kern ver str LC_NOTE");
423 m_mach_kernel_addr = ident_binary_addr;
424 found_main_binary_definitively = true;
425 } else if (ident_uuid.IsValid()) {
426 // We have no address specified, only a UUID. Load it at the file
427 // address.
428 const bool value_is_offset = false;
429 if (load_standalone_binary(ident_uuid, ident_binary_addr, value_is_offset,
430 GetTarget())) {
431 found_main_binary_definitively = true;
432 m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic();
433 }
434 }
435 }
436
437 bool did_load_extra_binaries = core_objfile->LoadCoreFileImages(*this);
438 // If we have a "all image infos" LC_NOTE, try to load all of the
439 // binaries listed, and set their Section load addresses in the Target.
440 if (found_main_binary_definitively == false && did_load_extra_binaries) {
441 m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
442 found_main_binary_definitively = true;
443 }
444
445 if (!found_main_binary_definitively &&
446 (m_dyld_addr == LLDB_INVALID_ADDRESS ||
447 m_mach_kernel_addr == LLDB_INVALID_ADDRESS)) {
448 // We need to locate the main executable in the memory ranges we have in
449 // the core file. We need to search for both a user-process dyld binary
450 // and a kernel binary in memory; we must look at all the pages in the
451 // binary so we don't miss one or the other. Step through all memory
452 // segments searching for a kernel binary and for a user process dyld --
453 // we'll decide which to prefer later if both are present.
454
455 const size_t num_core_aranges = m_core_aranges.GetSize();
456 for (size_t i = 0; i < num_core_aranges; ++i) {
457 const VMRangeToFileOffset::Entry *entry =
458 m_core_aranges.GetEntryAtIndex(i);
459 lldb::addr_t section_vm_addr_start = entry->GetRangeBase();
460 lldb::addr_t section_vm_addr_end = entry->GetRangeEnd();
461 for (lldb::addr_t section_vm_addr = section_vm_addr_start;
462 section_vm_addr < section_vm_addr_end; section_vm_addr += 0x1000) {
463 GetDynamicLoaderAddress(section_vm_addr);
464 }
465 }
466 }
467
468 if (!found_main_binary_definitively &&
469 m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
470 // In the case of multiple kernel images found in the core file via
471 // exhaustive search, we may not pick the correct one. See if the
472 // DynamicLoaderDarwinKernel's search heuristics might identify the correct
473 // one. Most of the time, I expect the address from SearchForDarwinKernel()
474 // will be the same as the address we found via exhaustive search.
475
476 if (!GetTarget().GetArchitecture().IsValid() && m_core_module_sp.get()) {
477 GetTarget().SetArchitecture(m_core_module_sp->GetArchitecture());
478 }
479
480 // SearchForDarwinKernel will end up calling back into this this class in
481 // the GetImageInfoAddress method which will give it the
482 // m_mach_kernel_addr/m_dyld_addr it already has. Save that aside and set
483 // m_mach_kernel_addr/m_dyld_addr to an invalid address temporarily so
484 // DynamicLoaderDarwinKernel does a real search for the kernel using its
485 // own heuristics.
486
487 addr_t saved_mach_kernel_addr = m_mach_kernel_addr;
488 addr_t saved_user_dyld_addr = m_dyld_addr;
489 m_mach_kernel_addr = LLDB_INVALID_ADDRESS;
490 m_dyld_addr = LLDB_INVALID_ADDRESS;
491
492 addr_t better_kernel_address =
493 DynamicLoaderDarwinKernel::SearchForDarwinKernel(this);
494
495 m_mach_kernel_addr = saved_mach_kernel_addr;
496 m_dyld_addr = saved_user_dyld_addr;
497
498 if (better_kernel_address != LLDB_INVALID_ADDRESS) {
499 LLDB_LOGF(log, "ProcessMachCore::DoLoadCore: Using the kernel address "
500 "from DynamicLoaderDarwinKernel");
501 m_mach_kernel_addr = better_kernel_address;
502 }
503 }
504
505 if (m_dyld_plugin_name.empty()) {
506 // If we found both a user-process dyld and a kernel binary, we need to
507 // decide which to prefer.
508 if (GetCorefilePreference() == eKernelCorefile) {
509 if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
510 LLDB_LOGF(log,
511 "ProcessMachCore::DoLoadCore: Using kernel corefile image "
512 "at 0x%" PRIx64,
513 m_mach_kernel_addr);
514 m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
515 } else if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
516 LLDB_LOGF(log,
517 "ProcessMachCore::DoLoadCore: Using user process dyld "
518 "image at 0x%" PRIx64,
519 m_dyld_addr);
520 m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
521 }
522 } else {
523 if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
524 LLDB_LOGF(log,
525 "ProcessMachCore::DoLoadCore: Using user process dyld "
526 "image at 0x%" PRIx64,
527 m_dyld_addr);
528 m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
529 } else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
530 LLDB_LOGF(log,
531 "ProcessMachCore::DoLoadCore: Using kernel corefile image "
532 "at 0x%" PRIx64,
533 m_mach_kernel_addr);
534 m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
535 }
536 }
537 }
538
539 if (m_dyld_plugin_name != DynamicLoaderMacOSXDYLD::GetPluginNameStatic()) {
540 // For non-user process core files, the permissions on the core file
541 // segments are usually meaningless, they may be just "read", because we're
542 // dealing with kernel coredumps or early startup coredumps and the dumper
543 // is grabbing pages of memory without knowing what they are. If they
544 // aren't marked as "executable", that can break the unwinder which will
545 // check a pc value to see if it is in an executable segment and stop the
546 // backtrace early if it is not ("executable" and "unknown" would both be
547 // fine, but "not executable" will break the unwinder).
548 size_t core_range_infos_size = m_core_range_infos.GetSize();
549 for (size_t i = 0; i < core_range_infos_size; i++) {
550 VMRangeToPermissions::Entry *ent =
551 m_core_range_infos.GetMutableEntryAtIndex(i);
552 ent->data = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
553 }
554 }
555
556 // Even if the architecture is set in the target, we need to override it to
557 // match the core file which is always single arch.
558 ArchSpec arch(m_core_module_sp->GetArchitecture());
559 if (arch.GetCore() == ArchSpec::eCore_x86_32_i486) {
560 arch = Platform::GetAugmentedArchSpec(GetTarget().GetPlatform().get(), "i386");
561 }
562 if (arch.IsValid())
563 GetTarget().SetArchitecture(arch);
564
565 addr_t address_mask = core_objfile->GetAddressMask();
566 if (address_mask != 0) {
567 SetCodeAddressMask(address_mask);
568 SetDataAddressMask(address_mask);
569 }
570 return error;
571 }
572
GetDynamicLoader()573 lldb_private::DynamicLoader *ProcessMachCore::GetDynamicLoader() {
574 if (m_dyld_up.get() == nullptr)
575 m_dyld_up.reset(DynamicLoader::FindPlugin(this, m_dyld_plugin_name));
576 return m_dyld_up.get();
577 }
578
DoUpdateThreadList(ThreadList & old_thread_list,ThreadList & new_thread_list)579 bool ProcessMachCore::DoUpdateThreadList(ThreadList &old_thread_list,
580 ThreadList &new_thread_list) {
581 if (old_thread_list.GetSize(false) == 0) {
582 // Make up the thread the first time this is called so we can setup our one
583 // and only core thread state.
584 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
585
586 if (core_objfile) {
587 const uint32_t num_threads = core_objfile->GetNumThreadContexts();
588 for (lldb::tid_t tid = 0; tid < num_threads; ++tid) {
589 ThreadSP thread_sp(new ThreadMachCore(*this, tid));
590 new_thread_list.AddThread(thread_sp);
591 }
592 }
593 } else {
594 const uint32_t num_threads = old_thread_list.GetSize(false);
595 for (uint32_t i = 0; i < num_threads; ++i)
596 new_thread_list.AddThread(old_thread_list.GetThreadAtIndex(i, false));
597 }
598 return new_thread_list.GetSize(false) > 0;
599 }
600
RefreshStateAfterStop()601 void ProcessMachCore::RefreshStateAfterStop() {
602 // Let all threads recover from stopping and do any clean up based on the
603 // previous thread state (if any).
604 m_thread_list.RefreshStateAfterStop();
605 // SetThreadStopInfo (m_last_stop_packet);
606 }
607
DoDestroy()608 Status ProcessMachCore::DoDestroy() { return Status(); }
609
610 // Process Queries
611
IsAlive()612 bool ProcessMachCore::IsAlive() { return true; }
613
WarnBeforeDetach() const614 bool ProcessMachCore::WarnBeforeDetach() const { return false; }
615
616 // Process Memory
ReadMemory(addr_t addr,void * buf,size_t size,Status & error)617 size_t ProcessMachCore::ReadMemory(addr_t addr, void *buf, size_t size,
618 Status &error) {
619 // Don't allow the caching that lldb_private::Process::ReadMemory does since
620 // in core files we have it all cached our our core file anyway.
621 return DoReadMemory(addr, buf, size, error);
622 }
623
DoReadMemory(addr_t addr,void * buf,size_t size,Status & error)624 size_t ProcessMachCore::DoReadMemory(addr_t addr, void *buf, size_t size,
625 Status &error) {
626 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
627 size_t bytes_read = 0;
628
629 if (core_objfile) {
630 // Segments are not always contiguous in mach-o core files. We have core
631 // files that have segments like:
632 // Address Size File off File size
633 // ---------- ---------- ---------- ----------
634 // LC_SEGMENT 0x000f6000 0x00001000 0x1d509ee8 0x00001000 --- --- 0
635 // 0x00000000 __TEXT LC_SEGMENT 0x0f600000 0x00100000 0x1d50aee8 0x00100000
636 // --- --- 0 0x00000000 __TEXT LC_SEGMENT 0x000f7000 0x00001000
637 // 0x1d60aee8 0x00001000 --- --- 0 0x00000000 __TEXT
638 //
639 // Any if the user executes the following command:
640 //
641 // (lldb) mem read 0xf6ff0
642 //
643 // We would attempt to read 32 bytes from 0xf6ff0 but would only get 16
644 // unless we loop through consecutive memory ranges that are contiguous in
645 // the address space, but not in the file data.
646 while (bytes_read < size) {
647 const addr_t curr_addr = addr + bytes_read;
648 const VMRangeToFileOffset::Entry *core_memory_entry =
649 m_core_aranges.FindEntryThatContains(curr_addr);
650
651 if (core_memory_entry) {
652 const addr_t offset = curr_addr - core_memory_entry->GetRangeBase();
653 const addr_t bytes_left = core_memory_entry->GetRangeEnd() - curr_addr;
654 const size_t bytes_to_read =
655 std::min(size - bytes_read, (size_t)bytes_left);
656 const size_t curr_bytes_read = core_objfile->CopyData(
657 core_memory_entry->data.GetRangeBase() + offset, bytes_to_read,
658 (char *)buf + bytes_read);
659 if (curr_bytes_read == 0)
660 break;
661 bytes_read += curr_bytes_read;
662 } else {
663 // Only set the error if we didn't read any bytes
664 if (bytes_read == 0)
665 error.SetErrorStringWithFormat(
666 "core file does not contain 0x%" PRIx64, curr_addr);
667 break;
668 }
669 }
670 }
671
672 return bytes_read;
673 }
674
DoGetMemoryRegionInfo(addr_t load_addr,MemoryRegionInfo & region_info)675 Status ProcessMachCore::DoGetMemoryRegionInfo(addr_t load_addr,
676 MemoryRegionInfo ®ion_info) {
677 region_info.Clear();
678 const VMRangeToPermissions::Entry *permission_entry =
679 m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
680 if (permission_entry) {
681 if (permission_entry->Contains(load_addr)) {
682 region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
683 region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
684 const Flags permissions(permission_entry->data);
685 region_info.SetReadable(permissions.Test(ePermissionsReadable)
686 ? MemoryRegionInfo::eYes
687 : MemoryRegionInfo::eNo);
688 region_info.SetWritable(permissions.Test(ePermissionsWritable)
689 ? MemoryRegionInfo::eYes
690 : MemoryRegionInfo::eNo);
691 region_info.SetExecutable(permissions.Test(ePermissionsExecutable)
692 ? MemoryRegionInfo::eYes
693 : MemoryRegionInfo::eNo);
694 region_info.SetMapped(MemoryRegionInfo::eYes);
695 } else if (load_addr < permission_entry->GetRangeBase()) {
696 region_info.GetRange().SetRangeBase(load_addr);
697 region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
698 region_info.SetReadable(MemoryRegionInfo::eNo);
699 region_info.SetWritable(MemoryRegionInfo::eNo);
700 region_info.SetExecutable(MemoryRegionInfo::eNo);
701 region_info.SetMapped(MemoryRegionInfo::eNo);
702 }
703 return Status();
704 }
705
706 region_info.GetRange().SetRangeBase(load_addr);
707 region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
708 region_info.SetReadable(MemoryRegionInfo::eNo);
709 region_info.SetWritable(MemoryRegionInfo::eNo);
710 region_info.SetExecutable(MemoryRegionInfo::eNo);
711 region_info.SetMapped(MemoryRegionInfo::eNo);
712 return Status();
713 }
714
Clear()715 void ProcessMachCore::Clear() { m_thread_list.Clear(); }
716
Initialize()717 void ProcessMachCore::Initialize() {
718 static llvm::once_flag g_once_flag;
719
720 llvm::call_once(g_once_flag, []() {
721 PluginManager::RegisterPlugin(GetPluginNameStatic(),
722 GetPluginDescriptionStatic(), CreateInstance);
723 });
724 }
725
GetImageInfoAddress()726 addr_t ProcessMachCore::GetImageInfoAddress() {
727 // If we found both a user-process dyld and a kernel binary, we need to
728 // decide which to prefer.
729 if (GetCorefilePreference() == eKernelCorefile) {
730 if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
731 return m_mach_kernel_addr;
732 }
733 return m_dyld_addr;
734 } else {
735 if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
736 return m_dyld_addr;
737 }
738 return m_mach_kernel_addr;
739 }
740 }
741
GetCoreObjectFile()742 lldb_private::ObjectFile *ProcessMachCore::GetCoreObjectFile() {
743 return m_core_module_sp->GetObjectFile();
744 }
745