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