12 #include "llvm/Support/MathExtras.h"
13 #include "llvm/Support/Threading.h"
53 return "Mach-O core file debugging plug-in.";
61 ListenerSP listener_sp,
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) {
73 llvm::MachO::mach_header mach_header;
75 if (mach_header.filetype == llvm::MachO::MH_CORE)
76 process_sp = std::make_shared<ProcessMachCore>(target_sp, listener_sp,
85 bool plugin_specified_by_name) {
86 if (plugin_specified_by_name)
90 if (!m_core_module_sp && FileSystem::Instance().Exists(m_core_file)) {
96 Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp,
97 nullptr,
nullptr,
nullptr));
99 if (m_core_module_sp) {
100 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
101 if (core_objfile && core_objfile->
GetType() == ObjectFile::eTypeCoreFile)
110 ListenerSP listener_sp,
113 m_core_range_infos(), m_core_module_sp(), m_core_file(core_file),
128 Log *log(
GetLog(LLDBLog::DynamicLoader | LLDBLog::Process));
129 llvm::MachO::mach_header header;
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);
147 if (header.magic == llvm::MachO::MH_MAGIC ||
148 header.magic == llvm::MachO::MH_MAGIC_64) {
153 switch (header.filetype) {
154 case llvm::MachO::MH_DYLINKER:
158 "ProcessMachCore::GetDynamicLoaderAddress found a user "
159 "process dyld binary image at 0x%" PRIx64,
164 case llvm::MachO::MH_EXECUTE:
168 if ((header.flags & llvm::MachO::MH_DYLDLINK) == 0) {
170 "ProcessMachCore::GetDynamicLoaderAddress found a mach "
171 "kernel binary image at 0x%" PRIx64,
188 bool value_is_offset,
Target &target) {
196 Status error = ModuleList::GetSharedModule(module_spec, module_sp,
nullptr,
199 if (!module_sp.get()) {
203 Symbols::DownloadObjectAndSymbolFile(module_spec,
error,
true);
206 if (FileSystem::Instance().Exists(module_spec.
GetFileSpec())) {
207 module_sp = std::make_shared<Module>(module_spec);
215 snprintf(namebuf,
sizeof(namebuf),
"mem-image-0x%" PRIx64, value);
220 if (module_sp.get()) {
234 bool changed =
false;
235 if (module_sp->GetObjectFile()) {
237 module_sp->SetLoadAddress(target, value, value_is_offset, changed);
241 const bool value_is_slide =
true;
242 module_sp->SetLoadAddress(target, 0, value_is_slide, changed);
246 const bool value_is_slide =
true;
247 module_sp->SetLoadAddress(target, 0, value_is_slide, changed);
251 added_module.
Append(module_sp,
false);
267 Log *log(
GetLog(LLDBLog::DynamicLoader | LLDBLog::Process));
270 error.SetErrorString(
"invalid core module");
275 if (core_objfile ==
nullptr) {
276 error.SetErrorString(
"invalid core object file");
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");
288 if (section_list ==
nullptr) {
289 error.SetErrorString(
"core file has no sections");
294 if (num_sections == 0) {
295 error.SetErrorString(
"core file has no sections");
301 llvm::MachO::mach_header header;
306 bool ranges_are_sorted =
true;
308 for (
uint32_t i = 0; i < num_sections; ++i) {
314 section_vm_addr, section->
GetByteSize(), file_range);
316 if (vm_addr > section_vm_addr)
317 ranges_are_sorted =
false;
323 last_entry->
data.GetRangeEnd() == range_entry.
data.GetRangeBase()) {
325 last_entry->
data.SetRangeEnd(range_entry.
data.GetRangeEnd());
334 if (permissions == 0)
335 permissions = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
337 section_vm_addr, section->
GetByteSize(), permissions));
340 if (!ranges_are_sorted) {
345 bool found_main_binary_definitively =
false;
347 addr_t objfile_binary_value;
348 bool objfile_binary_value_is_offset;
349 UUID objfile_binary_uuid;
352 objfile_binary_value_is_offset,
353 objfile_binary_uuid, type)) {
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);
363 !objfile_binary_value_is_offset) {
364 if (type == ObjectFile::eBinaryTypeUser) {
366 objfile_binary_value_is_offset,
GetTarget());
369 found_main_binary_definitively =
true;
371 if (type == ObjectFile::eBinaryTypeKernel) {
374 found_main_binary_definitively =
true;
377 if (!found_main_binary_definitively) {
380 objfile_binary_value_is_offset,
GetTarget())) {
381 found_main_binary_definitively =
true;
392 if (!found_main_binary_definitively) {
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);
401 log->
Printf(
"Got a UUID from LC_IDENT/kern ver str LC_NOTE: %s",
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') {
408 ::strtoul(corefile_identifier.c_str() + p,
nullptr, 16);
410 log->
Printf(
"Got a load address from LC_IDENT/kern ver str "
411 "LC_NOTE: 0x%" PRIx64,
418 if (corefile_identifier.find(
"Darwin Kernel") != std::string::npos &&
421 log->
Printf(
"ProcessMachCore::DoLoadCore: Found kernel binary via "
422 "LC_IDENT/kern ver str LC_NOTE");
424 found_main_binary_definitively =
true;
425 }
else if (ident_uuid.
IsValid()) {
428 const bool value_is_offset =
false;
431 found_main_binary_definitively =
true;
440 if (found_main_binary_definitively ==
false && did_load_extra_binaries) {
442 found_main_binary_definitively =
true;
445 if (!found_main_binary_definitively &&
456 for (
size_t i = 0; i < num_core_aranges; ++i) {
461 for (
lldb::addr_t section_vm_addr = section_vm_addr_start;
462 section_vm_addr < section_vm_addr_end; section_vm_addr += 0x1000) {
468 if (!found_main_binary_definitively &&
492 addr_t better_kernel_address =
499 LLDB_LOGF(log,
"ProcessMachCore::DoLoadCore: Using the kernel address "
500 "from DynamicLoaderDarwinKernel");
511 "ProcessMachCore::DoLoadCore: Using kernel corefile image "
517 "ProcessMachCore::DoLoadCore: Using user process dyld "
518 "image at 0x%" PRIx64,
525 "ProcessMachCore::DoLoadCore: Using user process dyld "
526 "image at 0x%" PRIx64,
531 "ProcessMachCore::DoLoadCore: Using kernel corefile image "
549 for (
size_t i = 0; i < core_range_infos_size; i++) {
552 ent->
data = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
559 if (arch.
GetCore() == ArchSpec::eCore_x86_32_i486) {
560 arch = Platform::GetAugmentedArchSpec(
GetTarget().GetPlatform().get(),
"i386");
566 if (address_mask != 0) {
581 if (old_thread_list.
GetSize(
false) == 0) {
588 for (
lldb::tid_t tid = 0; tid < num_threads; ++tid) {
595 for (
uint32_t i = 0; i < num_threads; ++i)
598 return new_thread_list.
GetSize(
false) > 0;
627 size_t bytes_read = 0;
646 while (bytes_read < size) {
647 const addr_t curr_addr = addr + bytes_read;
651 if (core_memory_entry) {
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)
661 bytes_read += curr_bytes_read;
665 error.SetErrorStringWithFormat(
666 "core file does not contain 0x%" PRIx64, curr_addr);
680 if (permission_entry) {
681 if (permission_entry->
Contains(load_addr)) {
684 const Flags permissions(permission_entry->
data);
686 ? MemoryRegionInfo::eYes
687 : MemoryRegionInfo::eNo);
689 ? MemoryRegionInfo::eYes
690 : MemoryRegionInfo::eNo);
692 ? MemoryRegionInfo::eYes
693 : MemoryRegionInfo::eNo);
694 region_info.
SetMapped(MemoryRegionInfo::eYes);
695 }
else if (load_addr < permission_entry->GetRangeBase()) {
701 region_info.
SetMapped(MemoryRegionInfo::eNo);
711 region_info.
SetMapped(MemoryRegionInfo::eNo);
718 static llvm::once_flag g_once_flag;
720 llvm::call_once(g_once_flag, []() {