LLDB  mainline
ProcessMachCore.cpp
Go to the documentation of this file.
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 <errno.h>
10 #include <stdlib.h>
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"
19 #include "lldb/Core/Section.h"
20 #include "lldb/Host/Host.h"
22 #include "lldb/Symbol/ObjectFile.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/Thread.h"
27 #include "lldb/Utility/Log.h"
28 #include "lldb/Utility/State.h"
29 
30 #include "ProcessMachCore.h"
32 #include "ThreadMachCore.h"
33 
34 // Needed for the plug-in names for the dynamic loaders.
35 #include "lldb/Host/SafeMachO.h"
36 
40 
41 #include <memory>
42 #include <mutex>
43 
44 using namespace lldb;
45 using namespace lldb_private;
46 
48 
49 ConstString ProcessMachCore::GetPluginNameStatic() {
50  static ConstString g_name("mach-o-core");
51  return g_name;
52 }
53 
55  return "Mach-O core file debugging plug-in.";
56 }
57 
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  lldb::ProcessSP process_sp;
66  if (crash_file) {
67  const size_t header_size = sizeof(llvm::MachO::mach_header);
68  auto data_sp = FileSystem::Instance().CreateDataBuffer(
69  crash_file->GetPath(), header_size, 0);
70  if (data_sp && data_sp->GetByteSize() == header_size) {
71  DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
72 
73  lldb::offset_t data_offset = 0;
74  llvm::MachO::mach_header mach_header;
75  if (ObjectFileMachO::ParseHeader(data, &data_offset, mach_header)) {
76  if (mach_header.filetype == llvm::MachO::MH_CORE)
77  process_sp = std::make_shared<ProcessMachCore>(target_sp, listener_sp,
78  *crash_file);
79  }
80  }
81  }
82  return process_sp;
83 }
84 
85 bool ProcessMachCore::CanDebug(lldb::TargetSP target_sp,
86  bool plugin_specified_by_name) {
87  if (plugin_specified_by_name)
88  return true;
89 
90  // For now we are just making sure the file exists for a given module
91  if (!m_core_module_sp && FileSystem::Instance().Exists(m_core_file)) {
92  // Don't add the Target's architecture to the ModuleSpec - we may be
93  // working with a core file that doesn't have the correct cpusubtype in the
94  // header but we should still try to use it -
95  // ModuleSpecList::FindMatchingModuleSpec enforces a strict arch mach.
96  ModuleSpec core_module_spec(m_core_file);
97  Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp,
98  nullptr, nullptr, nullptr));
99 
100  if (m_core_module_sp) {
101  ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
102  if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
103  return true;
104  }
105  }
106  return false;
107 }
108 
109 // ProcessMachCore constructor
110 ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp,
111  ListenerSP listener_sp,
112  const FileSpec &core_file)
113  : Process(target_sp, listener_sp), m_core_aranges(), m_core_range_infos(),
114  m_core_module_sp(), m_core_file(core_file),
115  m_dyld_addr(LLDB_INVALID_ADDRESS),
116  m_mach_kernel_addr(LLDB_INVALID_ADDRESS), m_dyld_plugin_name() {}
117 
118 // Destructor
120  Clear();
121  // We need to call finalize on the process before destroying ourselves to
122  // make sure all of the broadcaster cleanup goes as planned. If we destruct
123  // this class, then Process::~Process() might have problems trying to fully
124  // destroy the broadcaster.
125  Finalize();
126 }
127 
128 // PluginInterface
129 ConstString ProcessMachCore::GetPluginName() { return GetPluginNameStatic(); }
130 
132 
136  llvm::MachO::mach_header header;
137  Status error;
138  if (DoReadMemory(addr, &header, sizeof(header), error) != sizeof(header))
139  return false;
140  if (header.magic == llvm::MachO::MH_CIGAM ||
141  header.magic == llvm::MachO::MH_CIGAM_64) {
142  header.magic = llvm::ByteSwap_32(header.magic);
143  header.cputype = llvm::ByteSwap_32(header.cputype);
144  header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
145  header.filetype = llvm::ByteSwap_32(header.filetype);
146  header.ncmds = llvm::ByteSwap_32(header.ncmds);
147  header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
148  header.flags = llvm::ByteSwap_32(header.flags);
149  }
150 
151  // TODO: swap header if needed...
152  // printf("0x%16.16" PRIx64 ": magic = 0x%8.8x, file_type= %u\n", vaddr,
153  // header.magic, header.filetype);
154  if (header.magic == llvm::MachO::MH_MAGIC ||
155  header.magic == llvm::MachO::MH_MAGIC_64) {
156  // Check MH_EXECUTABLE to see if we can find the mach image that contains
157  // the shared library list. The dynamic loader (dyld) is what contains the
158  // list for user applications, and the mach kernel contains a global that
159  // has the list of kexts to load
160  switch (header.filetype) {
161  case llvm::MachO::MH_DYLINKER:
162  // printf("0x%16.16" PRIx64 ": file_type = MH_DYLINKER\n", vaddr);
163  // Address of dyld "struct mach_header" in the core file
164  LLDB_LOGF(log,
165  "ProcessMachCore::GetDynamicLoaderAddress found a user "
166  "process dyld binary image at 0x%" PRIx64,
167  addr);
168  m_dyld_addr = addr;
169  return true;
170 
171  case llvm::MachO::MH_EXECUTE:
172  // printf("0x%16.16" PRIx64 ": file_type = MH_EXECUTE\n", vaddr);
173  // Check MH_EXECUTABLE file types to see if the dynamic link object flag
174  // is NOT set. If it isn't, then we have a mach_kernel.
175  if ((header.flags & llvm::MachO::MH_DYLDLINK) == 0) {
176  LLDB_LOGF(log,
177  "ProcessMachCore::GetDynamicLoaderAddress found a mach "
178  "kernel binary image at 0x%" PRIx64,
179  addr);
180  // Address of the mach kernel "struct mach_header" in the core file.
181  m_mach_kernel_addr = addr;
182  return true;
183  }
184  break;
185  }
186  }
187  return false;
188 }
189 
190 // Process Control
194  Status error;
195  if (!m_core_module_sp) {
196  error.SetErrorString("invalid core module");
197  return error;
198  }
199 
200  ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
201  if (core_objfile == nullptr) {
202  error.SetErrorString("invalid core object file");
203  return error;
204  }
205 
206  if (core_objfile->GetNumThreadContexts() == 0) {
207  error.SetErrorString("core file doesn't contain any LC_THREAD load "
208  "commands, or the LC_THREAD architecture is not "
209  "supported in this lldb");
210  return error;
211  }
212 
213  SectionList *section_list = core_objfile->GetSectionList();
214  if (section_list == nullptr) {
215  error.SetErrorString("core file has no sections");
216  return error;
217  }
218 
219  const uint32_t num_sections = section_list->GetNumSections(0);
220  if (num_sections == 0) {
221  error.SetErrorString("core file has no sections");
222  return error;
223  }
224 
225  SetCanJIT(false);
226 
227  llvm::MachO::mach_header header;
228  DataExtractor data(&header, sizeof(header),
229  m_core_module_sp->GetArchitecture().GetByteOrder(),
230  m_core_module_sp->GetArchitecture().GetAddressByteSize());
231 
232  bool ranges_are_sorted = true;
233  addr_t vm_addr = 0;
234  for (uint32_t i = 0; i < num_sections; ++i) {
235  Section *section = section_list->GetSectionAtIndex(i).get();
236  if (section) {
237  lldb::addr_t section_vm_addr = section->GetFileAddress();
238  FileRange file_range(section->GetFileOffset(), section->GetFileSize());
239  VMRangeToFileOffset::Entry range_entry(
240  section_vm_addr, section->GetByteSize(), file_range);
241 
242  if (vm_addr > section_vm_addr)
243  ranges_are_sorted = false;
244  vm_addr = section->GetFileAddress();
245  VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
246  // printf ("LC_SEGMENT[%u] arange=[0x%16.16" PRIx64 " -
247  // 0x%16.16" PRIx64 "), frange=[0x%8.8x - 0x%8.8x)\n",
248  // i,
249  // range_entry.GetRangeBase(),
250  // range_entry.GetRangeEnd(),
251  // range_entry.data.GetRangeBase(),
252  // range_entry.data.GetRangeEnd());
253 
254  if (last_entry &&
255  last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
256  last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase()) {
257  last_entry->SetRangeEnd(range_entry.GetRangeEnd());
258  last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd());
259  // puts("combine");
260  } else {
261  m_core_aranges.Append(range_entry);
262  }
263  // Some core files don't fill in the permissions correctly. If that is
264  // the case assume read + execute so clients don't think the memory is
265  // not readable, or executable. The memory isn't writable since this
266  // plug-in doesn't implement DoWriteMemory.
267  uint32_t permissions = section->GetPermissions();
268  if (permissions == 0)
269  permissions = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
270  m_core_range_infos.Append(VMRangeToPermissions::Entry(
271  section_vm_addr, section->GetByteSize(), permissions));
272  }
273  }
274  if (!ranges_are_sorted) {
275  m_core_aranges.Sort();
276  m_core_range_infos.Sort();
277  }
278 
279 
280  bool found_main_binary_definitively = false;
281 
282  addr_t objfile_binary_addr;
283  UUID objfile_binary_uuid;
284  if (core_objfile->GetCorefileMainBinaryInfo (objfile_binary_addr, objfile_binary_uuid))
285  {
286  if (objfile_binary_addr != LLDB_INVALID_ADDRESS)
287  {
288  m_mach_kernel_addr = objfile_binary_addr;
289  found_main_binary_definitively = true;
290  LLDB_LOGF(log,
291  "ProcessMachCore::DoLoadCore: using kernel address 0x%" PRIx64
292  " from LC_NOTE 'main bin spec' load command.",
293  m_mach_kernel_addr);
294  }
295  }
296 
297  // This checks for the presence of an LC_IDENT string in a core file;
298  // LC_IDENT is very obsolete and should not be used in new code, but if the
299  // load command is present, let's use the contents.
300  std::string corefile_identifier = core_objfile->GetIdentifierString();
301  if (!found_main_binary_definitively &&
302  corefile_identifier.find("Darwin Kernel") != std::string::npos) {
303  UUID uuid;
305  if (corefile_identifier.find("UUID=") != std::string::npos) {
306  size_t p = corefile_identifier.find("UUID=") + strlen("UUID=");
307  std::string uuid_str = corefile_identifier.substr(p, 36);
308  uuid.SetFromStringRef(uuid_str);
309  }
310  if (corefile_identifier.find("stext=") != std::string::npos) {
311  size_t p = corefile_identifier.find("stext=") + strlen("stext=");
312  if (corefile_identifier[p] == '0' && corefile_identifier[p + 1] == 'x') {
313  errno = 0;
314  addr = ::strtoul(corefile_identifier.c_str() + p, nullptr, 16);
315  if (errno != 0 || addr == 0)
316  addr = LLDB_INVALID_ADDRESS;
317  }
318  }
319  if (uuid.IsValid() && addr != LLDB_INVALID_ADDRESS) {
320  m_mach_kernel_addr = addr;
321  found_main_binary_definitively = true;
322  LLDB_LOGF(
323  log,
324  "ProcessMachCore::DoLoadCore: Using the kernel address 0x%" PRIx64
325  " from LC_IDENT/LC_NOTE 'kern ver str' string: '%s'",
326  addr, corefile_identifier.c_str());
327  }
328  }
329  if (found_main_binary_definitively == false
330  && corefile_identifier.find("EFI ") != std::string::npos) {
331  UUID uuid;
332  if (corefile_identifier.find("UUID=") != std::string::npos) {
333  size_t p = corefile_identifier.find("UUID=") + strlen("UUID=");
334  std::string uuid_str = corefile_identifier.substr(p, 36);
335  uuid.SetFromStringRef(uuid_str);
336  }
337  if (uuid.IsValid()) {
338  LLDB_LOGF(log,
339  "ProcessMachCore::DoLoadCore: Using the EFI "
340  "from LC_IDENT/LC_NOTE 'kern ver str' string: '%s'",
341  corefile_identifier.c_str());
342 
343  // We're only given a UUID here, not a load address.
344  // But there are python scripts in the EFI binary's dSYM which
345  // know how to relocate the binary to the correct load address.
346  // lldb only needs to locate & load the binary + dSYM.
347  ModuleSpec module_spec;
348  module_spec.GetUUID() = uuid;
349  module_spec.GetArchitecture() = GetTarget().GetArchitecture();
350 
351  // Lookup UUID locally, before attempting dsymForUUID like action
352  FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
353  module_spec.GetSymbolFileSpec() =
354  Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
355  if (module_spec.GetSymbolFileSpec()) {
356  ModuleSpec executable_module_spec =
357  Symbols::LocateExecutableObjectFile(module_spec);
358  if (FileSystem::Instance().Exists(
359  executable_module_spec.GetFileSpec())) {
360  module_spec.GetFileSpec() = executable_module_spec.GetFileSpec();
361  }
362  }
363 
364  // Force a a dsymForUUID lookup, if that tool is available.
365  if (!module_spec.GetSymbolFileSpec())
366  Symbols::DownloadObjectAndSymbolFile(module_spec, true);
367 
368  if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
369  ModuleSP module_sp(new Module(module_spec));
370  if (module_sp.get() && module_sp->GetObjectFile()) {
371  // Get the current target executable
372  ModuleSP exe_module_sp(GetTarget().GetExecutableModule());
373 
374  // Make sure you don't already have the right module loaded
375  // and they will be uniqued
376  if (exe_module_sp.get() != module_sp.get())
377  GetTarget().SetExecutableModule(module_sp, eLoadDependentsNo);
378  }
379  }
380  }
381  }
382 
383  if (!found_main_binary_definitively &&
384  (m_dyld_addr == LLDB_INVALID_ADDRESS ||
385  m_mach_kernel_addr == LLDB_INVALID_ADDRESS)) {
386  // We need to locate the main executable in the memory ranges we have in
387  // the core file. We need to search for both a user-process dyld binary
388  // and a kernel binary in memory; we must look at all the pages in the
389  // binary so we don't miss one or the other. Step through all memory
390  // segments searching for a kernel binary and for a user process dyld --
391  // we'll decide which to prefer later if both are present.
392 
393  const size_t num_core_aranges = m_core_aranges.GetSize();
394  for (size_t i = 0; i < num_core_aranges; ++i) {
395  const VMRangeToFileOffset::Entry *entry =
396  m_core_aranges.GetEntryAtIndex(i);
397  lldb::addr_t section_vm_addr_start = entry->GetRangeBase();
398  lldb::addr_t section_vm_addr_end = entry->GetRangeEnd();
399  for (lldb::addr_t section_vm_addr = section_vm_addr_start;
400  section_vm_addr < section_vm_addr_end; section_vm_addr += 0x1000) {
401  GetDynamicLoaderAddress(section_vm_addr);
402  }
403  }
404  }
405 
406  if (!found_main_binary_definitively &&
407  m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
408  // In the case of multiple kernel images found in the core file via
409  // exhaustive search, we may not pick the correct one. See if the
410  // DynamicLoaderDarwinKernel's search heuristics might identify the correct
411  // one. Most of the time, I expect the address from SearchForDarwinKernel()
412  // will be the same as the address we found via exhaustive search.
413 
414  if (!GetTarget().GetArchitecture().IsValid() && m_core_module_sp.get()) {
415  GetTarget().SetArchitecture(m_core_module_sp->GetArchitecture());
416  }
417 
418  // SearchForDarwinKernel will end up calling back into this this class in
419  // the GetImageInfoAddress method which will give it the
420  // m_mach_kernel_addr/m_dyld_addr it already has. Save that aside and set
421  // m_mach_kernel_addr/m_dyld_addr to an invalid address temporarily so
422  // DynamicLoaderDarwinKernel does a real search for the kernel using its
423  // own heuristics.
424 
425  addr_t saved_mach_kernel_addr = m_mach_kernel_addr;
426  addr_t saved_user_dyld_addr = m_dyld_addr;
427  m_mach_kernel_addr = LLDB_INVALID_ADDRESS;
428  m_dyld_addr = LLDB_INVALID_ADDRESS;
429 
430  addr_t better_kernel_address =
432 
433  m_mach_kernel_addr = saved_mach_kernel_addr;
434  m_dyld_addr = saved_user_dyld_addr;
435 
436  if (better_kernel_address != LLDB_INVALID_ADDRESS) {
437  LLDB_LOGF(log, "ProcessMachCore::DoLoadCore: Using the kernel address "
438  "from DynamicLoaderDarwinKernel");
439  m_mach_kernel_addr = better_kernel_address;
440  }
441  }
442 
443  // If we found both a user-process dyld and a kernel binary, we need to
444  // decide which to prefer.
445  if (GetCorefilePreference() == eKernelCorefile) {
446  if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
447  LLDB_LOGF(log,
448  "ProcessMachCore::DoLoadCore: Using kernel corefile image "
449  "at 0x%" PRIx64,
450  m_mach_kernel_addr);
451  m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
452  } else if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
453  LLDB_LOGF(log,
454  "ProcessMachCore::DoLoadCore: Using user process dyld "
455  "image at 0x%" PRIx64,
456  m_dyld_addr);
457  m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
458  }
459  } else {
460  if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
461  LLDB_LOGF(log,
462  "ProcessMachCore::DoLoadCore: Using user process dyld "
463  "image at 0x%" PRIx64,
464  m_dyld_addr);
465  m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
466  } else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
467  LLDB_LOGF(log,
468  "ProcessMachCore::DoLoadCore: Using kernel corefile image "
469  "at 0x%" PRIx64,
470  m_mach_kernel_addr);
471  m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
472  }
473  }
474 
475  if (m_dyld_plugin_name != DynamicLoaderMacOSXDYLD::GetPluginNameStatic()) {
476  // For non-user process core files, the permissions on the core file
477  // segments are usually meaningless, they may be just "read", because we're
478  // dealing with kernel coredumps or early startup coredumps and the dumper
479  // is grabbing pages of memory without knowing what they are. If they
480  // aren't marked as "executable", that can break the unwinder which will
481  // check a pc value to see if it is in an executable segment and stop the
482  // backtrace early if it is not ("executable" and "unknown" would both be
483  // fine, but "not executable" will break the unwinder).
484  size_t core_range_infos_size = m_core_range_infos.GetSize();
485  for (size_t i = 0; i < core_range_infos_size; i++) {
487  m_core_range_infos.GetMutableEntryAtIndex(i);
488  ent->data = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
489  }
490  }
491 
492  // Even if the architecture is set in the target, we need to override it to
493  // match the core file which is always single arch.
494  ArchSpec arch(m_core_module_sp->GetArchitecture());
495  if (arch.GetCore() == ArchSpec::eCore_x86_32_i486) {
496  arch = Platform::GetAugmentedArchSpec(GetTarget().GetPlatform().get(), "i386");
497  }
498  if (arch.IsValid())
499  GetTarget().SetArchitecture(arch);
500 
501  return error;
502 }
503 
505  if (m_dyld_up.get() == nullptr)
506  m_dyld_up.reset(DynamicLoader::FindPlugin(
507  this, m_dyld_plugin_name.IsEmpty() ? nullptr
508  : m_dyld_plugin_name.GetCString()));
509  return m_dyld_up.get();
510 }
511 
513  ThreadList &new_thread_list) {
514  if (old_thread_list.GetSize(false) == 0) {
515  // Make up the thread the first time this is called so we can setup our one
516  // and only core thread state.
517  ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
518 
519  if (core_objfile) {
520  const uint32_t num_threads = core_objfile->GetNumThreadContexts();
521  for (lldb::tid_t tid = 0; tid < num_threads; ++tid) {
522  ThreadSP thread_sp(new ThreadMachCore(*this, tid));
523  new_thread_list.AddThread(thread_sp);
524  }
525  }
526  } else {
527  const uint32_t num_threads = old_thread_list.GetSize(false);
528  for (uint32_t i = 0; i < num_threads; ++i)
529  new_thread_list.AddThread(old_thread_list.GetThreadAtIndex(i, false));
530  }
531  return new_thread_list.GetSize(false) > 0;
532 }
533 
535  // Let all threads recover from stopping and do any clean up based on the
536  // previous thread state (if any).
537  m_thread_list.RefreshStateAfterStop();
538  // SetThreadStopInfo (m_last_stop_packet);
539 }
540 
542 
543 // Process Queries
544 
545 bool ProcessMachCore::IsAlive() { return true; }
546 
547 bool ProcessMachCore::WarnBeforeDetach() const { return false; }
548 
549 // Process Memory
550 size_t ProcessMachCore::ReadMemory(addr_t addr, void *buf, size_t size,
551  Status &error) {
552  // Don't allow the caching that lldb_private::Process::ReadMemory does since
553  // in core files we have it all cached our our core file anyway.
554  return DoReadMemory(addr, buf, size, error);
555 }
556 
557 size_t ProcessMachCore::DoReadMemory(addr_t addr, void *buf, size_t size,
558  Status &error) {
559  ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
560  size_t bytes_read = 0;
561 
562  if (core_objfile) {
563  // Segments are not always contiguous in mach-o core files. We have core
564  // files that have segments like:
565  // Address Size File off File size
566  // ---------- ---------- ---------- ----------
567  // LC_SEGMENT 0x000f6000 0x00001000 0x1d509ee8 0x00001000 --- --- 0
568  // 0x00000000 __TEXT LC_SEGMENT 0x0f600000 0x00100000 0x1d50aee8 0x00100000
569  // --- --- 0 0x00000000 __TEXT LC_SEGMENT 0x000f7000 0x00001000
570  // 0x1d60aee8 0x00001000 --- --- 0 0x00000000 __TEXT
571  //
572  // Any if the user executes the following command:
573  //
574  // (lldb) mem read 0xf6ff0
575  //
576  // We would attempt to read 32 bytes from 0xf6ff0 but would only get 16
577  // unless we loop through consecutive memory ranges that are contiguous in
578  // the address space, but not in the file data.
579  while (bytes_read < size) {
580  const addr_t curr_addr = addr + bytes_read;
581  const VMRangeToFileOffset::Entry *core_memory_entry =
582  m_core_aranges.FindEntryThatContains(curr_addr);
583 
584  if (core_memory_entry) {
585  const addr_t offset = curr_addr - core_memory_entry->GetRangeBase();
586  const addr_t bytes_left = core_memory_entry->GetRangeEnd() - curr_addr;
587  const size_t bytes_to_read =
588  std::min(size - bytes_read, (size_t)bytes_left);
589  const size_t curr_bytes_read = core_objfile->CopyData(
590  core_memory_entry->data.GetRangeBase() + offset, bytes_to_read,
591  (char *)buf + bytes_read);
592  if (curr_bytes_read == 0)
593  break;
594  bytes_read += curr_bytes_read;
595  } else {
596  // Only set the error if we didn't read any bytes
597  if (bytes_read == 0)
599  "core file does not contain 0x%" PRIx64, curr_addr);
600  break;
601  }
602  }
603  }
604 
605  return bytes_read;
606 }
607 
609  MemoryRegionInfo &region_info) {
610  region_info.Clear();
611  const VMRangeToPermissions::Entry *permission_entry =
612  m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
613  if (permission_entry) {
614  if (permission_entry->Contains(load_addr)) {
615  region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
616  region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
617  const Flags permissions(permission_entry->data);
618  region_info.SetReadable(permissions.Test(ePermissionsReadable)
619  ? MemoryRegionInfo::eYes
620  : MemoryRegionInfo::eNo);
621  region_info.SetWritable(permissions.Test(ePermissionsWritable)
622  ? MemoryRegionInfo::eYes
623  : MemoryRegionInfo::eNo);
624  region_info.SetExecutable(permissions.Test(ePermissionsExecutable)
625  ? MemoryRegionInfo::eYes
626  : MemoryRegionInfo::eNo);
627  region_info.SetMapped(MemoryRegionInfo::eYes);
628  } else if (load_addr < permission_entry->GetRangeBase()) {
629  region_info.GetRange().SetRangeBase(load_addr);
630  region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
631  region_info.SetReadable(MemoryRegionInfo::eNo);
632  region_info.SetWritable(MemoryRegionInfo::eNo);
633  region_info.SetExecutable(MemoryRegionInfo::eNo);
634  region_info.SetMapped(MemoryRegionInfo::eNo);
635  }
636  return Status();
637  }
638 
639  region_info.GetRange().SetRangeBase(load_addr);
641  region_info.SetReadable(MemoryRegionInfo::eNo);
642  region_info.SetWritable(MemoryRegionInfo::eNo);
643  region_info.SetExecutable(MemoryRegionInfo::eNo);
644  region_info.SetMapped(MemoryRegionInfo::eNo);
645  return Status();
646 }
647 
648 void ProcessMachCore::Clear() { m_thread_list.Clear(); }
649 
651  static llvm::once_flag g_once_flag;
652 
653  llvm::call_once(g_once_flag, []() {
654  PluginManager::RegisterPlugin(GetPluginNameStatic(),
655  GetPluginDescriptionStatic(), CreateInstance);
656  });
657 }
658 
660  // If we found both a user-process dyld and a kernel binary, we need to
661  // decide which to prefer.
662  if (GetCorefilePreference() == eKernelCorefile) {
663  if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
664  return m_mach_kernel_addr;
665  }
666  return m_dyld_addr;
667  } else {
668  if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
669  return m_dyld_addr;
670  }
671  return m_mach_kernel_addr;
672  }
673 }
674 
676  return m_core_module_sp->GetObjectFile();
677 }
bool GetDynamicLoaderAddress(lldb::addr_t addr)
bool WarnBeforeDetach() const override
Before lldb detaches from a process, it warns the user that they are about to lose their debug sessio...
An data extractor class.
Definition: DataExtractor.h:46
static const char * GetPluginDescriptionStatic()
#define LIBLLDB_LOG_PROCESS
Definition: Logging.h:15
A class that represents a running process on the host machine.
void SetExecutable(OptionalBool val)
virtual uint32_t GetNumThreadContexts()
Definition: ObjectFile.h:474
bool Contains(BaseType r) const
Definition: RangeMap.h:77
bool IsValid() const
Definition: UUID.h:62
static lldb_private::ConstString GetPluginNameStatic()
lldb::offset_t GetFileOffset() const
Definition: Section.h:140
A file utility class.
Definition: FileSpec.h:56
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener, const lldb_private::FileSpec *crash_file_path)
An architecture specification class.
Definition: ArchSpec.h:33
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:58
void SetMapped(OptionalBool val)
bool IsAlive() override
Check if a process is still alive.
void SetRangeEnd(BaseType end)
Definition: RangeMap.h:64
virtual std::string GetIdentifierString()
Some object files may have an identifier string embedded in them, e.g.
Definition: ObjectFile.h:483
lldb::offset_t GetFileSize() const
Definition: Section.h:146
size_t CopyData(lldb::offset_t offset, size_t length, void *dst) const
Definition: ObjectFile.cpp:486
lldb_private::ObjectFile * GetCoreObjectFile()
size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb_private::Status &error) override
Read of memory from a process.
lldb::addr_t GetFileAddress() const
Definition: Section.cpp:203
void RefreshStateAfterStop() override
Currently called as part of ShouldStop.
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
Definition: ThreadList.cpp:90
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
#define LLDB_PLUGIN_DEFINE(PluginName)
Definition: PluginManager.h:31
bool Test(ValueType bit) const
Test a single flag bit.
Definition: Flags.h:96
uint64_t offset_t
Definition: lldb-types.h:87
static llvm::raw_ostream & error(Stream &strm)
A class that describes an executable image and its associated object and symbol files.
Definition: Module.h:75
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb_private::Status &error) override
Actually do the reading of memory from a process.
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
Definition: ObjectFile.cpp:607
uint64_t tid_t
Definition: lldb-types.h:86
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:242
lldb::addr_t GetByteSize() const
Definition: Section.h:156
A plug-in interface definition class for debugging a process.
Definition: Process.h:362
lldb::SectionSP GetSectionAtIndex(size_t idx) const
Definition: Section.cpp:476
static lldb_private::ConstString GetPluginNameStatic()
lldb_private::Status GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &region_info) override
Locate the memory region that contains load_addr.
FileSpec & GetFileSpec()
Definition: ModuleSpec.h:75
static size_t DoReadMemory(lldb::pid_t pid, lldb::addr_t vm_addr, void *buf, size_t size, Status &error)
uint32_t GetPermissions() const
Get the permissions as OR&#39;ed bits from lldb::Permissions.
Definition: Section.cpp:368
lldb_private::DynamicLoader * GetDynamicLoader() override
Get the dynamic loader plug-in for this process.
A plug-in interface definition class for dynamic loaders.
Definition: DynamicLoader.h:52
static void Terminate()
#define LIBLLDB_LOG_DYNAMIC_LOADER
Definition: Logging.h:17
#define LLDB_LOGF(log,...)
Definition: Log.h:249
A class to manage flags.
Definition: Flags.h:22
~ProcessMachCore() override
uint64_t addr_t
Definition: lldb-types.h:83
void SetReadable(OptionalBool val)
size_t GetNumSections(uint32_t depth) const
Definition: Section.cpp:465
lldb_private::Status DoDestroy() override
A uniqued constant string class.
Definition: ConstString.h:40
bool ParseHeader() override
Attempts to parse the object header.
Log * GetLogIfAnyCategoriesSet(uint32_t mask)
Definition: Logging.cpp:62
Definition: SBAddress.h:15
lldb_private::Status DoLoadCore() override
void SetRangeBase(BaseType b)
Definition: RangeMap.h:48
void SetWritable(OptionalBool val)
bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override
Check if a plug-in instance can debug the file in module.
static lldb::addr_t SearchForDarwinKernel(lldb_private::Process *process)
BaseType GetRangeEnd() const
Definition: RangeMap.h:62
void AddThread(const lldb::ThreadSP &thread_sp)
uint32_t GetSize(bool can_update=true)
Definition: ThreadList.cpp:82
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:256
lldb_private::ConstString GetPluginName() override
bool UpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list) override
lldb::addr_t GetImageInfoAddress() override
Get the image information address for the current process.
bool SetFromStringRef(llvm::StringRef str)
Definition: UUID.cpp:86
ProcessMachCore(lldb::TargetSP target_sp, lldb::ListenerSP listener, const lldb_private::FileSpec &core_file)
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:348
virtual bool GetCorefileMainBinaryInfo(lldb::addr_t &address, UUID &uuid)
When the ObjectFile is a core file, lldb needs to locate the "binary" in the core file...
Definition: ObjectFile.h:505
uint32_t GetPluginVersion() override
static void Initialize()
An error handling class.
Definition: Status.h:44
BaseType GetRangeBase() const
Definition: RangeMap.h:46