[Go to site: main page, start]

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 <cerrno>
10#include <cstdlib>
11
12#include "lldb/Core/Debugger.h"
13#include "lldb/Core/Module.h"
16#include "lldb/Core/Section.h"
17#include "lldb/Host/Host.h"
21#include "lldb/Target/Target.h"
22#include "lldb/Target/Thread.h"
26#include "lldb/Utility/Log.h"
27#include "lldb/Utility/State.h"
28#include "lldb/Utility/UUID.h"
29#include "llvm/Support/MathExtras.h"
30
31#include "ProcessMachCore.h"
33#include "ThreadMachCore.h"
34
35// Needed for the plug-in names for the dynamic loaders.
36#include "lldb/Host/SafeMachO.h"
37
43
44#include <memory>
45
46using namespace lldb;
47using namespace lldb_private;
48
50
52 return "Mach-O core file debugging plug-in.";
53}
54
58
60 ListenerSP listener_sp,
61 const FileSpec *crash_file,
62 bool can_connect) {
63 lldb::ProcessSP process_sp;
64 if (crash_file && !can_connect) {
65 const size_t header_size = sizeof(llvm::MachO::mach_header);
67 crash_file->GetPath(), header_size, 0);
68 if (data_sp && data_sp->GetByteSize() == header_size) {
69 DataExtractorSP extractor_sp =
70 std::make_shared<DataExtractor>(data_sp, lldb::eByteOrderLittle, 4);
71
72 lldb::offset_t data_offset = 0;
73 llvm::MachO::mach_header mach_header;
74 if (ObjectFileMachO::ParseHeader(extractor_sp, &data_offset,
75 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
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
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 core_module_spec.SetTarget(target_sp);
99 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
119
120// Destructor
122 Clear();
123 // We need to call finalize on the process before destroying ourselves to
124 // make sure all of the broadcaster cleanup goes as planned. If we destruct
125 // this class, then Process::~Process() might have problems trying to fully
126 // destroy the broadcaster.
127 Finalize(true /* destructing */);
128}
129
131 addr_t &dyld,
132 addr_t &kernel) {
134 llvm::MachO::mach_header header;
136 dyld = kernel = LLDB_INVALID_ADDRESS;
137 if (DoReadMemory(addr, &header, sizeof(header), error) != sizeof(header))
138 return false;
139 if (header.magic == llvm::MachO::MH_CIGAM ||
140 header.magic == llvm::MachO::MH_CIGAM_64) {
141 header.magic = llvm::byteswap<uint32_t>(header.magic);
142 header.cputype = llvm::byteswap<uint32_t>(header.cputype);
143 header.cpusubtype = llvm::byteswap<uint32_t>(header.cpusubtype);
144 header.filetype = llvm::byteswap<uint32_t>(header.filetype);
145 header.ncmds = llvm::byteswap<uint32_t>(header.ncmds);
146 header.sizeofcmds = llvm::byteswap<uint32_t>(header.sizeofcmds);
147 header.flags = llvm::byteswap<uint32_t>(header.flags);
148 }
149
150 if (header.magic == llvm::MachO::MH_MAGIC ||
151 header.magic == llvm::MachO::MH_MAGIC_64) {
152 // Check MH_EXECUTABLE to see if we can find the mach image that contains
153 // the shared library list. The dynamic loader (dyld) is what contains the
154 // list for user applications, and the mach kernel contains a global that
155 // has the list of kexts to load
156 switch (header.filetype) {
157 case llvm::MachO::MH_DYLINKER:
158 LLDB_LOGF(log,
159 "ProcessMachCore::%s found a user "
160 "process dyld binary image at 0x%" PRIx64,
161 __FUNCTION__, addr);
162 dyld = addr;
163 return true;
164
165 case llvm::MachO::MH_EXECUTE:
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::%s found a mach "
171 "kernel binary image at 0x%" PRIx64,
172 __FUNCTION__, addr);
173 // Address of the mach kernel "struct mach_header" in the core file.
174 kernel = addr;
175 return true;
176 }
177 break;
178 }
179 }
180 return false;
181}
182
184 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
185 SectionList *section_list = core_objfile->GetSectionList();
186 const uint32_t num_sections = section_list->GetNumSections(0);
187
188 bool ranges_are_sorted = true;
189 addr_t vm_addr = 0;
190 for (uint32_t i = 0; i < num_sections; ++i) {
191 Section *section = section_list->GetSectionAtIndex(i).get();
192 if (section && section->GetFileSize() > 0) {
193 lldb::addr_t section_vm_addr = section->GetFileAddress();
194 FileRange file_range(section->GetFileOffset(), section->GetFileSize());
195 VMRangeToFileOffset::Entry range_entry(
196 section_vm_addr, section->GetByteSize(), file_range);
197
198 if (vm_addr > section_vm_addr)
199 ranges_are_sorted = false;
200 vm_addr = section->GetFileAddress();
201 VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
202
203 if (last_entry &&
204 last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
205 last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase()) {
206 last_entry->SetRangeEnd(range_entry.GetRangeEnd());
207 last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd());
208 } else {
209 m_core_aranges.Append(range_entry);
210 }
211 // Some core files don't fill in the permissions correctly. If that is
212 // the case assume read + execute so clients don't think the memory is
213 // not readable, or executable. The memory isn't writable since this
214 // plug-in doesn't implement DoWriteMemory.
215 uint32_t permissions = section->GetPermissions();
216 if (permissions == 0)
217 permissions = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
219 section_vm_addr, section->GetByteSize(), permissions));
220 }
221 }
222 if (!ranges_are_sorted) {
223 m_core_aranges.Sort();
224 m_core_range_infos.Sort();
225 }
226}
227
228// Some corefiles have a UUID stored in a low memory
229// address. We inspect a set list of addresses for
230// the characters 'uuid' and 16 bytes later there will
231// be a uuid_t UUID. If we can find a binary that
232// matches the UUID, it is loaded with no slide in the target.
235 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
236
237 uint64_t lowmem_uuid_addresses[] = {0x2000204, 0x1000204, 0x1000020, 0x4204,
238 0x1204, 0x1020, 0x4020, 0xc00,
239 0xC0, 0};
240
241 for (uint64_t addr : lowmem_uuid_addresses) {
242 const VMRangeToFileOffset::Entry *core_memory_entry =
243 m_core_aranges.FindEntryThatContains(addr);
244 if (core_memory_entry) {
245 const addr_t offset = addr - core_memory_entry->GetRangeBase();
246 const addr_t bytes_left = core_memory_entry->GetRangeEnd() - addr;
247 // (4-bytes 'uuid' + 12 bytes pad for align + 16 bytes uuid_t) == 32 bytes
248 if (bytes_left >= 32) {
249 char strbuf[4];
250 if (core_objfile->CopyData(
251 core_memory_entry->data.GetRangeBase() + offset, 4, &strbuf) &&
252 strncmp("uuid", (char *)&strbuf, 4) == 0) {
253 uuid_t uuid_bytes;
254 if (core_objfile->CopyData(core_memory_entry->data.GetRangeBase() +
255 offset + 16,
256 sizeof(uuid_t), uuid_bytes)) {
257 UUID uuid(uuid_bytes, sizeof(uuid_t));
258 if (uuid.IsValid()) {
259 LLDB_LOGF(log,
260 "ProcessMachCore::LoadBinaryViaLowmemUUID: found "
261 "binary uuid %s at low memory address 0x%" PRIx64,
262 uuid.GetAsString().c_str(), addr);
263 // We have no address specified, only a UUID. Load it at the file
264 // address.
266 bin_spec.uuid = uuid;
267 bin_spec.value = 0;
268 bin_spec.value_is_offset = true;
269 bin_spec.force_symbol_search = true;
270 bin_spec.notify = true;
271 bin_spec.set_address_in_target = true;
272 llvm::Expected<ModuleSP> module =
274 if (module)
276 else
278 << llvm::toString(module.takeError()) << "\n";
279 // We found metadata saying which binary should be loaded; don't
280 // try an exhaustive search.
281 return true;
282 }
283 }
284 }
285 }
286 }
287 }
288 return false;
289}
290
293 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
294
295 addr_t objfile_binary_value;
296 bool objfile_binary_value_is_offset;
297 UUID objfile_binary_uuid;
299
300 // This will be set to true if we had a metadata hint
301 // specifying a UUID or address -- and we should not fall back
302 // to doing an exhaustive search.
303 bool found_binary_spec_in_metadata = false;
304
305 if (core_objfile->GetCorefileMainBinaryInfo(objfile_binary_value,
306 objfile_binary_value_is_offset,
307 objfile_binary_uuid, type)) {
308 if (log) {
309 log->Printf("ProcessMachCore::LoadBinariesViaMetadata: using binary hint "
310 "from 'main bin spec' "
311 "LC_NOTE with UUID %s value 0x%" PRIx64
312 " value is offset %d and type %d",
313 objfile_binary_uuid.GetAsString().c_str(),
314 objfile_binary_value, objfile_binary_value_is_offset, type);
315 }
316 found_binary_spec_in_metadata = true;
317
318 // If this is the xnu kernel, don't load it now. Note the correct
319 // DynamicLoader plugin to use, and the address of the kernel, and
320 // let the DynamicLoader handle the finding & loading of the binary.
321 if (type == ObjectFile::eBinaryTypeKernel) {
322 m_mach_kernel_addr = objfile_binary_value;
324 } else if (type == ObjectFile::eBinaryTypeUser) {
325 m_dyld_addr = objfile_binary_value;
327 } else if (type == ObjectFile::eBinaryTypeUserAllImageInfos) {
328 m_dyld_all_image_infos_addr = objfile_binary_value;
330 } else {
332 bin_spec.uuid = objfile_binary_uuid;
333 bin_spec.value = objfile_binary_value;
334 bin_spec.value_is_offset = objfile_binary_value_is_offset;
335 bin_spec.force_symbol_search = true;
336 bin_spec.notify = true;
337 bin_spec.set_address_in_target = true;
338 llvm::Expected<ModuleSP> module =
340 if (module)
342 else
344 << llvm::toString(module.takeError()) << "\n";
345 }
346 }
347
348 // This checks for the presence of an LC_IDENT string in a core file;
349 // LC_IDENT is very obsolete and should not be used in new code, but if the
350 // load command is present, let's use the contents.
351 UUID ident_uuid;
352 addr_t ident_binary_addr = LLDB_INVALID_ADDRESS;
353 std::string corefile_identifier = core_objfile->GetIdentifierString();
354
355 // Search for UUID= and stext= strings in the identifier str.
356 if (corefile_identifier.find("UUID=") != std::string::npos) {
357 size_t p = corefile_identifier.find("UUID=") + strlen("UUID=");
358 std::string uuid_str = corefile_identifier.substr(p, 36);
359 ident_uuid.SetFromStringRef(uuid_str);
360 if (log)
361 log->Printf("Got a UUID from LC_IDENT/kern ver str LC_NOTE: %s",
362 ident_uuid.GetAsString().c_str());
363 found_binary_spec_in_metadata = true;
364 }
365 if (corefile_identifier.find("stext=") != std::string::npos) {
366 size_t p = corefile_identifier.find("stext=") + strlen("stext=");
367 if (corefile_identifier[p] == '0' && corefile_identifier[p + 1] == 'x') {
368 ident_binary_addr =
369 ::strtoul(corefile_identifier.c_str() + p, nullptr, 16);
370 if (log)
371 log->Printf("Got a load address from LC_IDENT/kern ver str "
372 "LC_NOTE: 0x%" PRIx64,
373 ident_binary_addr);
374 found_binary_spec_in_metadata = true;
375 }
376 }
377
378 // Search for a "Darwin Kernel" str indicating kernel; else treat as
379 // standalone
380 if (corefile_identifier.find("Darwin Kernel") != std::string::npos &&
381 ident_uuid.IsValid() && ident_binary_addr != LLDB_INVALID_ADDRESS) {
382 if (log)
383 log->Printf(
384 "ProcessMachCore::LoadBinariesViaMetadata: Found kernel binary via "
385 "LC_IDENT/kern ver str LC_NOTE");
386 m_mach_kernel_addr = ident_binary_addr;
387 found_binary_spec_in_metadata = true;
388 } else if (ident_uuid.IsValid()) {
389 // We have no address specified, only a UUID. Load it at the file
390 // address.
392 bin_spec.uuid = ident_uuid;
393 bin_spec.value = ident_binary_addr;
394 bin_spec.force_symbol_search = true;
395 bin_spec.notify = true;
396 bin_spec.set_address_in_target = true;
397 llvm::Expected<ModuleSP> module =
399 if (module) {
400 found_binary_spec_in_metadata = true;
402 } else {
404 << llvm::toString(module.takeError()) << "\n";
405 }
406 }
407
408 // Finally, load any binaries noted by "load binary" LC_NOTEs in the
409 // corefile
410 if (core_objfile->LoadCoreFileImages(*this)) {
411 found_binary_spec_in_metadata = true;
413 }
414
415 if (!found_binary_spec_in_metadata && LoadBinaryViaLowmemUUID())
416 found_binary_spec_in_metadata = true;
417
418 // LoadCoreFileImges may have set the dynamic loader, e.g. in
419 // PlatformDarwinKernel::LoadPlatformBinaryAndSetup().
420 // If we now have a dynamic loader, save its name so we don't
421 // un-set it later.
422 if (m_dyld_up)
424
425 return found_binary_spec_in_metadata;
426}
427
430
431 // Search the pages of the corefile for dyld or mach kernel
432 // binaries. There may be multiple things that look like a kernel
433 // in the corefile; disambiguating to the correct one can be difficult.
434
435 std::vector<addr_t> dylds_found;
436 std::vector<addr_t> kernels_found;
437
438 // To do an exhaustive search, we'll need to create data extractors
439 // to get correctly sized/endianness fields. If we had a main binary
440 // already, we would have set the Target to that - so here we'll use
441 // the corefile's cputype/cpusubtype as the best guess.
442 if (!GetTarget().GetArchitecture().IsValid()) {
443 // The corefile's architecture is our best starting point.
444 ArchSpec arch(m_core_module_sp->GetArchitecture());
445 if (arch.IsValid()) {
446 LLDB_LOGF(log,
447 "ProcessMachCore::%s: Setting target ArchSpec based on "
448 "corefile mach-o cputype/cpusubtype",
449 __FUNCTION__);
451 }
452 }
453
454 const size_t num_core_aranges = m_core_aranges.GetSize();
455 for (size_t i = 0; i < num_core_aranges; ++i) {
456 const VMRangeToFileOffset::Entry *entry = m_core_aranges.GetEntryAtIndex(i);
457 lldb::addr_t section_vm_addr_start = entry->GetRangeBase();
458 lldb::addr_t section_vm_addr_end = entry->GetRangeEnd();
459 for (lldb::addr_t section_vm_addr = section_vm_addr_start;
460 section_vm_addr < section_vm_addr_end; section_vm_addr += 0x1000) {
461 addr_t dyld, kernel;
462 if (CheckAddressForDyldOrKernel(section_vm_addr, dyld, kernel)) {
463 if (dyld != LLDB_INVALID_ADDRESS)
464 dylds_found.push_back(dyld);
465 if (kernel != LLDB_INVALID_ADDRESS)
466 kernels_found.push_back(kernel);
467 }
468 }
469 }
470
471 // If we found more than one dyld mach-o header in the corefile,
472 // pick the first one.
473 if (dylds_found.size() > 0)
474 m_dyld_addr = dylds_found[0];
475 if (kernels_found.size() > 0)
476 m_mach_kernel_addr = kernels_found[0];
477
478 // Zero or one kernels found, we're done.
479 if (kernels_found.size() < 2)
480 return;
481
482 // In the case of multiple kernel images found in the core file via
483 // exhaustive search, we may not pick the correct one. See if the
484 // DynamicLoaderDarwinKernel's search heuristics might identify the correct
485 // one.
486
487 // SearchForDarwinKernel will call this class' GetImageInfoAddress method
488 // which will give it the addresses we already have.
489 // Save those aside and set
490 // m_mach_kernel_addr/m_dyld_addr to an invalid address temporarily so
491 // DynamicLoaderDarwinKernel does a real search for the kernel using its
492 // own heuristics.
493
494 addr_t saved_mach_kernel_addr = m_mach_kernel_addr;
495 addr_t saved_user_dyld_addr = m_dyld_addr;
499
500 addr_t better_kernel_address =
502
503 m_mach_kernel_addr = saved_mach_kernel_addr;
504 m_dyld_addr = saved_user_dyld_addr;
505
506 if (better_kernel_address != LLDB_INVALID_ADDRESS) {
507 LLDB_LOGF(log,
508 "ProcessMachCore::%s: Using "
509 "the kernel address "
510 "from DynamicLoaderDarwinKernel",
511 __FUNCTION__);
512 m_mach_kernel_addr = better_kernel_address;
513 }
514}
515
518
519 bool found_binary_spec_in_metadata = LoadBinariesViaMetadata();
520 if (!found_binary_spec_in_metadata)
522
523 if (m_dyld_plugin_name.empty()) {
524 // If we found both a user-process dyld and a kernel binary, we need to
525 // decide which to prefer.
528 LLDB_LOGF(log,
529 "ProcessMachCore::%s: Using kernel "
530 "corefile image "
531 "at 0x%" PRIx64,
532 __FUNCTION__, m_mach_kernel_addr);
534 } else if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
535 LLDB_LOGF(log,
536 "ProcessMachCore::%s: Using user process dyld "
537 "image at 0x%" PRIx64,
538 __FUNCTION__, m_dyld_addr);
541 LLDB_LOGF(log,
542 "ProcessMachCore::%s: Using user process dyld "
543 "dyld_all_image_infos at 0x%" PRIx64,
544 __FUNCTION__, m_dyld_all_image_infos_addr);
546 }
547 } else {
549 LLDB_LOGF(log,
550 "ProcessMachCore::%s: Using user process dyld "
551 "image at 0x%" PRIx64,
552 __FUNCTION__, m_dyld_addr);
555 LLDB_LOGF(log,
556 "ProcessMachCore::%s: Using user process dyld "
557 "dyld_all_image_infos at 0x%" PRIx64,
558 __FUNCTION__, m_dyld_all_image_infos_addr);
560 LLDB_LOGF(log,
561 "ProcessMachCore::%s: Using kernel "
562 "corefile image "
563 "at 0x%" PRIx64,
564 __FUNCTION__, m_mach_kernel_addr);
566 }
567 }
568 }
569}
570
573 // For non-user process core files, the permissions on the core file
574 // segments are usually meaningless, they may be just "read", because we're
575 // dealing with kernel coredumps or early startup coredumps and the dumper
576 // is grabbing pages of memory without knowing what they are. If they
577 // aren't marked as "executable", that can break the unwinder which will
578 // check a pc value to see if it is in an executable segment and stop the
579 // backtrace early if it is not ("executable" and "unknown" would both be
580 // fine, but "not executable" will break the unwinder).
581 size_t core_range_infos_size = m_core_range_infos.GetSize();
582 for (size_t i = 0; i < core_range_infos_size; i++) {
584 m_core_range_infos.GetMutableEntryAtIndex(i);
585 ent->data = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
586 }
587 }
588}
589
590// Process Control
593 if (!m_core_module_sp) {
594 error = Status::FromErrorString("invalid core module");
595 return error;
596 }
598
599 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
600 if (core_objfile == nullptr) {
601 error = Status::FromErrorString("invalid core object file");
602 return error;
603 }
604
605 SetCanJIT(false);
606
607 // If we have an executable binary in the Target already,
608 // use that to set the Target's ArchSpec.
609 //
610 // Don't initialize the ArchSpec based on the corefile's cputype/cpusubtype
611 // here, the corefile creator may not know the correct subtype of the code
612 // that is executing, initialize the Target to that, and if the
613 // main binary has Python code which initializes based on the Target arch,
614 // get the wrong subtype value.
615 ModuleSP exe_module_sp = GetTarget().GetExecutableModule();
616 if (exe_module_sp && exe_module_sp->GetArchitecture().IsValid()) {
617 LLDB_LOGF(log,
618 "ProcessMachCore::%s: Was given binary + corefile, setting "
619 "target ArchSpec to binary to start",
620 __FUNCTION__);
621 GetTarget().SetArchitecture(exe_module_sp->GetArchitecture());
622 }
623
625
627
629
630 exe_module_sp = GetTarget().GetExecutableModule();
631 if (exe_module_sp && exe_module_sp->GetArchitecture().IsValid()) {
632 LLDB_LOGF(log,
633 "ProcessMachCore::%s: have executable binary in the Target "
634 "after metadata/scan. Setting Target's ArchSpec based on "
635 "that.",
636 __FUNCTION__);
637 GetTarget().SetArchitecture(exe_module_sp->GetArchitecture());
638 } else {
639 // The corefile's architecture is our best starting point.
640 ArchSpec arch(m_core_module_sp->GetArchitecture());
641 if (arch.IsValid()) {
642 LLDB_LOGF(log,
643 "ProcessMachCore::%s: Setting target ArchSpec based on "
644 "corefile mach-o cputype/cpusubtype",
645 __FUNCTION__);
647 }
648 }
649
650 AddressableBits addressable_bits = core_objfile->GetAddressableBits();
651 SetAddressableBitMasks(addressable_bits);
652
653 return error;
654}
655
661
663 ThreadList &new_thread_list) {
664 if (old_thread_list.GetSize(false) == 0) {
665 // Make up the thread the first time this is called so we can setup our one
666 // and only core thread state.
667 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
668
669 if (core_objfile) {
670 const uint32_t num_threads = core_objfile->GetNumThreadContexts();
671 std::vector<lldb::tid_t> tids;
672 if (core_objfile->GetCorefileThreadExtraInfos(tids)) {
673 assert(tids.size() == num_threads);
674
675 // Find highest tid value.
676 lldb::tid_t highest_tid = 0;
677 for (uint32_t i = 0; i < num_threads; i++) {
678 if (tids[i] != LLDB_INVALID_THREAD_ID && tids[i] > highest_tid)
679 highest_tid = tids[i];
680 }
681 lldb::tid_t current_unused_tid = highest_tid + 1;
682 for (uint32_t i = 0; i < num_threads; i++) {
683 if (tids[i] == LLDB_INVALID_THREAD_ID) {
684 tids[i] = current_unused_tid++;
685 }
686 }
687 } else {
688 // No metadata, insert numbers sequentially from 0.
689 for (uint32_t i = 0; i < num_threads; i++) {
690 tids.push_back(i);
691 }
692 }
693
694 for (uint32_t i = 0; i < num_threads; i++) {
695 ThreadSP thread_sp =
696 std::make_shared<ThreadMachCore>(*this, tids[i], i);
697 new_thread_list.AddThread(thread_sp);
698 }
699 }
700 } else {
701 const uint32_t num_threads = old_thread_list.GetSize(false);
702 for (uint32_t i = 0; i < num_threads; ++i)
703 new_thread_list.AddThread(old_thread_list.GetThreadAtIndex(i, false));
704 }
705 return new_thread_list.GetSize(false) > 0;
706}
707
709 // Let all threads recover from stopping and do any clean up based on the
710 // previous thread state (if any).
711 m_thread_list.RefreshStateAfterStop();
712 // SetThreadStopInfo (m_last_stop_packet);
713}
714
716
717// Process Queries
718
719bool ProcessMachCore::IsAlive() { return true; }
720
721bool ProcessMachCore::WarnBeforeDetach() const { return false; }
722
723// Process Memory
724size_t ProcessMachCore::ReadMemory(addr_t addr, void *buf, size_t size,
725 Status &error) {
726 // Don't allow the caching that lldb_private::Process::ReadMemory does since
727 // in core files we have it all cached our our core file anyway.
728 return DoReadMemory(FixAnyAddress(addr), buf, size, error);
729}
730
731size_t ProcessMachCore::DoReadMemory(addr_t addr, void *buf, size_t size,
732 Status &error) {
733 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
734 size_t bytes_read = 0;
735
736 if (core_objfile) {
737 // Segments are not always contiguous in mach-o core files. We have core
738 // files that have segments like:
739 // Address Size File off File size
740 // ---------- ---------- ---------- ----------
741 // LC_SEGMENT 0x000f6000 0x00001000 0x1d509ee8 0x00001000 --- --- 0
742 // 0x00000000 __TEXT LC_SEGMENT 0x0f600000 0x00100000 0x1d50aee8 0x00100000
743 // --- --- 0 0x00000000 __TEXT LC_SEGMENT 0x000f7000 0x00001000
744 // 0x1d60aee8 0x00001000 --- --- 0 0x00000000 __TEXT
745 //
746 // Any if the user executes the following command:
747 //
748 // (lldb) mem read 0xf6ff0
749 //
750 // We would attempt to read 32 bytes from 0xf6ff0 but would only get 16
751 // unless we loop through consecutive memory ranges that are contiguous in
752 // the address space, but not in the file data.
753 while (bytes_read < size) {
754 const addr_t curr_addr = addr + bytes_read;
755 const VMRangeToFileOffset::Entry *core_memory_entry =
756 m_core_aranges.FindEntryThatContains(curr_addr);
757
758 if (core_memory_entry) {
759 const addr_t offset = curr_addr - core_memory_entry->GetRangeBase();
760 const addr_t bytes_left = core_memory_entry->GetRangeEnd() - curr_addr;
761 const size_t bytes_to_read =
762 std::min(size - bytes_read, (size_t)bytes_left);
763 const size_t curr_bytes_read = core_objfile->CopyData(
764 core_memory_entry->data.GetRangeBase() + offset, bytes_to_read,
765 (char *)buf + bytes_read);
766 if (curr_bytes_read == 0)
767 break;
768 bytes_read += curr_bytes_read;
769 } else {
770 // Only set the error if we didn't read any bytes
771 if (bytes_read == 0)
773 "core file does not contain 0x%" PRIx64, curr_addr);
774 break;
775 }
776 }
777 }
778
779 return bytes_read;
780}
781
783 MemoryRegionInfo &region_info) {
784 region_info.Clear();
785 const VMRangeToPermissions::Entry *permission_entry =
786 m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
787 if (permission_entry) {
788 if (permission_entry->Contains(load_addr)) {
789 region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
790 region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
791 const Flags permissions(permission_entry->data);
792 region_info.SetReadable(
793 permissions.Test(ePermissionsReadable) ? eLazyBoolYes : eLazyBoolNo);
794 region_info.SetWritable(
795 permissions.Test(ePermissionsWritable) ? eLazyBoolYes : eLazyBoolNo);
796 region_info.SetExecutable(permissions.Test(ePermissionsExecutable)
798 : eLazyBoolNo);
799 region_info.SetMapped(eLazyBoolYes);
800 } else if (load_addr < permission_entry->GetRangeBase()) {
801 region_info.GetRange().SetRangeBase(load_addr);
802 region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
803 region_info.SetReadable(eLazyBoolNo);
804 region_info.SetWritable(eLazyBoolNo);
805 region_info.SetExecutable(eLazyBoolNo);
806 region_info.SetMapped(eLazyBoolNo);
807 }
808 return Status();
809 } else {
810 // The corefile has no LC_SEGMENT at this virtual address,
811 // but see if there is a binary whose Section has been
812 // loaded at that address in the current Target.
813 Address addr;
814 if (GetTarget().ResolveLoadAddress(load_addr, addr)) {
815 SectionSP section_sp(addr.GetSection());
816 if (section_sp) {
817 region_info.GetRange().SetRangeBase(
818 section_sp->GetLoadBaseAddress(&GetTarget()));
819 region_info.GetRange().SetByteSize(section_sp->GetByteSize());
820 if (region_info.GetRange().Contains(load_addr)) {
821 region_info.SetLLDBPermissions(section_sp->GetPermissions());
822 return Status();
823 }
824 }
825 }
826 }
827
828 region_info.GetRange().SetRangeBase(load_addr);
830 region_info.SetReadable(eLazyBoolNo);
831 region_info.SetWritable(eLazyBoolNo);
832 region_info.SetExecutable(eLazyBoolNo);
833 region_info.SetMapped(eLazyBoolNo);
834 return Status();
835}
836
838
843
845 // The DynamicLoader plugin will call back in to this Process
846 // method to find the virtual address of one of these:
847 // 1. The xnu mach kernel binary Mach-O header
848 // 2. The dyld binary Mach-O header
849 // 3. dyld's dyld_all_image_infos object
850 //
851 // DynamicLoaderMacOSX will accept either the dyld Mach-O header
852 // address or the dyld_all_image_infos interchangably, no need
853 // to distinguish between them. It disambiguates by the Mach-O
854 // file magic number at the start.
857 return m_mach_kernel_addr;
859 return m_dyld_addr;
860 } else {
862 return m_dyld_addr;
864 return m_mach_kernel_addr;
865 }
866
867 // m_dyld_addr and m_mach_kernel_addr both
868 // invalid, return m_dyld_all_image_infos_addr
869 // in case it has a useful value.
871}
872
unsigned char uuid_t[16]
static llvm::raw_ostream & error(Stream &strm)
static llvm::Expected< lldb::addr_t > ResolveLoadAddress(EvalContext &eval_ctx, const char *dw_op_type, lldb::addr_t file_addr, Address &so_addr, bool check_sectionoffset=false)
Helper function to move common code used to resolve a file address and turn into a load address.
#define LLDB_LOGF(log,...)
Definition Log.h:389
#define LLDB_PLUGIN_DEFINE(PluginName)
static llvm::StringRef GetPluginNameStatic()
static lldb::addr_t SearchForDarwinKernel(lldb_private::Process *process)
static llvm::StringRef GetPluginNameStatic()
static llvm::StringRef GetPluginNameStatic()
bool ParseHeader() override
Attempts to parse the object header.
lldb::addr_t m_dyld_addr
bool WarnBeforeDetach() const override
Before lldb detaches from a process, it warns the user that they are about to lose their debug sessio...
static llvm::StringRef GetPluginDescriptionStatic()
static void Initialize()
size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb_private::Status &error) override
Read of memory from a process.
VMRangeToFileOffset m_core_aranges
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.
CorefilePreference GetCorefilePreference()
If a core file can be interpreted multiple ways, this establishes which style wins.
bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override
Check if a plug-in instance can debug the file in module.
void CleanupMemoryRegionPermissions()
lldb_private::ObjectFile * GetCoreObjectFile()
ProcessMachCore(lldb::TargetSP target_sp, lldb::ListenerSP listener, const lldb_private::FileSpec &core_file)
llvm::StringRef m_dyld_plugin_name
lldb_private::DynamicLoader * GetDynamicLoader() override
Get the dynamic loader plug-in for this process.
lldb_private::Status DoDestroy() override
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener, const lldb_private::FileSpec *crash_file_path, bool can_connect)
lldb::addr_t m_dyld_all_image_infos_addr
void RefreshStateAfterStop() override
Currently called as part of ShouldStop.
bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list) override
Update the thread list following process plug-in's specific logic.
static llvm::StringRef GetPluginNameStatic()
bool IsAlive() override
Check if a process is still alive.
bool CheckAddressForDyldOrKernel(lldb::addr_t addr, lldb::addr_t &dyld, lldb::addr_t &kernel)
lldb_private::Range< lldb::addr_t, lldb::addr_t > FileRange
VMRangeToPermissions m_core_range_infos
lldb_private::Status DoLoadCore() override
void LoadBinariesViaExhaustiveSearch()
lldb::addr_t m_mach_kernel_addr
lldb::addr_t GetImageInfoAddress() override
Get the image information address for the current process.
~ProcessMachCore() override
lldb::ModuleSP m_core_module_sp
lldb_private::Status DoGetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &region_info) override
DoGetMemoryRegionInfo is called by GetMemoryRegionInfo after it has removed non address bits from loa...
static void Terminate()
A section + offset based address class.
Definition Address.h:62
lldb::SectionSP GetSection() const
Get const accessor for the section.
Definition Address.h:426
A class which holds the metadata from a remote stub/corefile note about how many bits are used for ad...
An architecture specification class.
Definition ArchSpec.h:32
bool IsValid() const
Tests if this ArchSpec is valid.
Definition ArchSpec.h:452
lldb::StreamUP GetAsyncErrorStream()
A plug-in interface definition class for dynamic loaders.
static llvm::Expected< lldb::ModuleSP > LocateAndLoadBinary(Process *process, BinarySpec &bin_spec)
Find a binary and load it into a Target.
static DynamicLoader * FindPlugin(Process *process, llvm::StringRef plugin_name)
Find a dynamic loader plugin for a given process.
A file utility class.
Definition FileSpec.h:56
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:380
static FileSystem & Instance()
std::shared_ptr< DataBuffer > CreateDataBuffer(const llvm::Twine &path, uint64_t size=0, uint64_t offset=0)
Create memory buffer from path.
A class to manage flags.
Definition Flags.h:22
bool Test(ValueType bit) const
Test a single flag bit.
Definition Flags.h:96
void void Printf(const char *format,...) __attribute__((format(printf
Prefer using LLDB_LOGF whenever possible.
Definition Log.cpp:177
void SetLLDBPermissions(uint32_t permissions)
static Status GetSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, llvm::SmallVectorImpl< lldb::ModuleSP > *old_modules, bool *did_create_ptr, bool invoke_locate_callback=true, bool invoke_symbol_locators=true)
void SetTarget(lldb::TargetSP target)
Set the target to be used when resolving a module.
Definition ModuleSpec.h:150
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:46
virtual bool GetCorefileThreadExtraInfos(std::vector< lldb::tid_t > &tids)
Get metadata about thread ids from the corefile.
Definition ObjectFile.h:544
virtual std::string GetIdentifierString()
Some object files may have an identifier string embedded in them, e.g.
Definition ObjectFile.h:475
virtual uint32_t GetNumThreadContexts()
Definition ObjectFile.h:466
virtual bool LoadCoreFileImages(lldb_private::Process &process)
Load binaries listed in a corefile.
Definition ObjectFile.h:733
@ eTypeCoreFile
A core file that has a checkpoint of a program's execution state.
Definition ObjectFile.h:53
virtual lldb_private::AddressableBits GetAddressableBits()
Some object files may have the number of bits used for addressing embedded in them,...
Definition ObjectFile.h:487
size_t CopyData(lldb::offset_t offset, size_t length, void *dst) const
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
virtual bool GetCorefileMainBinaryInfo(lldb::addr_t &value, bool &value_is_offset, UUID &uuid, ObjectFile::BinaryType &type)
When the ObjectFile is a core file, lldb needs to locate the "binary" in the core file.
Definition ObjectFile.h:515
BinaryType
If we have a corefile binary hint, this enum specifies the binary type which we can use to select the...
Definition ObjectFile.h:83
@ eBinaryTypeKernel
kernel binary
Definition ObjectFile.h:87
@ eBinaryTypeUser
user process binary, dyld addr
Definition ObjectFile.h:89
@ eBinaryTypeUserAllImageInfos
user process binary, dyld_all_image_infos addr
Definition ObjectFile.h:91
virtual llvm::StringRef GetPluginName()=0
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
PostMortemProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec &core_file)
void SetAddressableBitMasks(AddressableBits bit_masks)
Definition Process.cpp:7085
void SetCanJIT(bool can_jit)
Sets whether executing JIT-compiled code in this process is possible.
Definition Process.cpp:2755
lldb::DynamicLoaderUP m_dyld_up
Definition Process.h:3535
lldb::addr_t FixAnyAddress(lldb::addr_t pc)
Use this method when you do not know, or do not care what kind of address you are fixing.
Definition Process.cpp:6239
bool IsValid() const
Return whether this object is valid (i.e.
Definition Process.h:578
virtual void Finalize(bool destructing)
This object is about to be destroyed, do any necessary cleanup.
Definition Process.cpp:564
ThreadList m_thread_list
The threads for this process as the user will see them.
Definition Process.h:3508
friend class ThreadList
Definition Process.h:366
Target & GetTarget()
Get the target object pointer for this module.
Definition Process.h:1258
RangeData< lldb::addr_t, lldb::addr_t, FileRange > Entry
Definition RangeMap.h:462
size_t GetNumSections(uint32_t depth) const
Definition Section.cpp:544
lldb::SectionSP GetSectionAtIndex(size_t idx) const
Definition Section.cpp:555
uint32_t GetPermissions() const
Get the permissions as OR'ed bits from lldb::Permissions.
Definition Section.cpp:357
lldb::offset_t GetFileOffset() const
Definition Section.h:181
lldb::addr_t GetFileAddress() const
Definition Section.cpp:194
lldb::addr_t GetByteSize() const
Definition Section.h:197
lldb::offset_t GetFileSize() const
Definition Section.h:187
An error handling class.
Definition Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
Debugger & GetDebugger() const
Definition Target.h:1330
bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform=false, bool merge=true)
Set the architecture for this target.
Definition Target.cpp:1786
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition Target.cpp:1624
void AddThread(const lldb::ThreadSP &thread_sp)
uint32_t GetSize(bool can_update=true)
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
Represents UUID's of various sizes.
Definition UUID.h:27
bool SetFromStringRef(llvm::StringRef str)
Definition UUID.cpp:101
std::string GetAsString(llvm::StringRef separator="-") const
Definition UUID.cpp:54
bool IsValid() const
Definition UUID.h:69
#define LLDB_INVALID_THREAD_ID
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:338
std::shared_ptr< lldb_private::Thread > ThreadSP
uint64_t offset_t
Definition lldb-types.h:86
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Listener > ListenerSP
std::shared_ptr< lldb_private::Section > SectionSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::DataExtractor > DataExtractorSP
uint64_t tid_t
Definition lldb-types.h:85
std::shared_ptr< lldb_private::Module > ModuleSP
A binary to find and load into a Target.
lldb::addr_t value
Address where the binary should be loaded, or read out of memory.
UUID uuid
UUID of the binary to be loaded.
bool force_symbol_search
Allow the search to do a possibly expensive external search for the ObjectFile and/or SymbolFile.
bool set_address_in_target
Whether the address of the binary should be set in the Target if it is added.
bool notify
Whether ModulesDidLoad should be called once the binary has been added to the Target.
bool value_is_offset
A flag indicating that value is an address, or an offset to be applied to the file addresses.
bool Contains(BaseType r) const
Definition RangeMap.h:93
BaseType GetRangeBase() const
Definition RangeMap.h:45
void SetRangeEnd(BaseType end)
Definition RangeMap.h:80
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
Definition RangeMap.h:48
BaseType GetRangeEnd() const
Definition RangeMap.h:78
void SetByteSize(SizeType s)
Definition RangeMap.h:89