@@ -6476,9 +6476,8 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
6476
6476
return false ;
6477
6477
6478
6478
// Default on macOS is to create a dirty-memory-only corefile.
6479
- if (core_style == SaveCoreStyle::eSaveCoreUnspecified) {
6479
+ if (core_style == SaveCoreStyle::eSaveCoreUnspecified)
6480
6480
core_style = SaveCoreStyle::eSaveCoreDirtyOnly;
6481
- }
6482
6481
6483
6482
Target &target = process_sp->GetTarget ();
6484
6483
const ArchSpec target_arch = target.GetArchitecture ();
@@ -6507,115 +6506,42 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
6507
6506
}
6508
6507
6509
6508
if (make_core) {
6510
- std::vector<llvm::MachO::segment_command_64> segment_load_commands;
6511
- // uint32_t range_info_idx = 0;
6512
- MemoryRegionInfo range_info;
6513
- Status range_error = process_sp->GetMemoryRegionInfo (0 , range_info);
6514
- const uint32_t addr_byte_size = target_arch.GetAddressByteSize ();
6515
- const ByteOrder byte_order = target_arch.GetByteOrder ();
6516
- std::vector<page_object> pages_to_copy;
6517
-
6518
- if (range_error.Success ()) {
6519
- while (range_info.GetRange ().GetRangeBase () != LLDB_INVALID_ADDRESS) {
6520
- // Calculate correct protections
6521
- uint32_t prot = 0 ;
6522
- if (range_info.GetReadable () == MemoryRegionInfo::eYes)
6523
- prot |= VM_PROT_READ;
6524
- if (range_info.GetWritable () == MemoryRegionInfo::eYes)
6525
- prot |= VM_PROT_WRITE;
6526
- if (range_info.GetExecutable () == MemoryRegionInfo::eYes)
6527
- prot |= VM_PROT_EXECUTE;
6528
-
6529
- const addr_t addr = range_info.GetRange ().GetRangeBase ();
6530
- const addr_t size = range_info.GetRange ().GetByteSize ();
6531
-
6532
- if (size == 0 )
6533
- break ;
6534
-
6535
- bool include_this_region = true ;
6536
- bool dirty_pages_only = false ;
6537
- if (core_style == SaveCoreStyle::eSaveCoreStackOnly) {
6538
- dirty_pages_only = true ;
6539
- if (range_info.IsStackMemory () != MemoryRegionInfo::eYes) {
6540
- include_this_region = false ;
6541
- }
6542
- }
6543
- if (core_style == SaveCoreStyle::eSaveCoreDirtyOnly) {
6544
- dirty_pages_only = true ;
6545
- }
6546
-
6547
- if (prot != 0 && include_this_region) {
6548
- addr_t pagesize = range_info.GetPageSize ();
6549
- const std::optional<std::vector<addr_t >> &dirty_page_list =
6550
- range_info.GetDirtyPageList ();
6551
- if (dirty_pages_only && dirty_page_list) {
6552
- for (addr_t dirtypage : *dirty_page_list) {
6553
- page_object obj;
6554
- obj.addr = dirtypage;
6555
- obj.size = pagesize;
6556
- obj.prot = prot;
6557
- pages_to_copy.push_back (obj);
6558
- }
6559
- } else {
6560
- page_object obj;
6561
- obj.addr = addr;
6562
- obj.size = size;
6563
- obj.prot = prot;
6564
- pages_to_copy.push_back (obj);
6565
- }
6566
- }
6567
-
6568
- range_error = process_sp->GetMemoryRegionInfo (
6569
- range_info.GetRange ().GetRangeEnd (), range_info);
6570
- if (range_error.Fail ())
6571
- break ;
6572
- }
6573
-
6574
- // Combine contiguous entries that have the same
6575
- // protections so we don't have an excess of
6576
- // load commands.
6577
- std::vector<page_object> combined_page_objects;
6578
- page_object last_obj;
6579
- last_obj.addr = LLDB_INVALID_ADDRESS;
6580
- last_obj.size = 0 ;
6581
- for (page_object obj : pages_to_copy) {
6582
- if (last_obj.addr == LLDB_INVALID_ADDRESS) {
6583
- last_obj = obj;
6584
- continue ;
6585
- }
6586
- if (last_obj.addr + last_obj.size == obj.addr &&
6587
- last_obj.prot == obj.prot ) {
6588
- last_obj.size += obj.size ;
6589
- continue ;
6590
- }
6591
- combined_page_objects.push_back (last_obj);
6592
- last_obj = obj;
6593
- }
6594
- // Add the last entry we were looking to combine
6595
- // on to the array.
6596
- if (last_obj.addr != LLDB_INVALID_ADDRESS && last_obj.size != 0 )
6597
- combined_page_objects.push_back (last_obj);
6598
-
6599
- for (page_object obj : combined_page_objects) {
6509
+ Process::CoreFileMemoryRanges core_ranges;
6510
+ error = process_sp->CalculateCoreFileSaveRanges (core_style, core_ranges);
6511
+ if (error.Success ()) {
6512
+ const uint32_t addr_byte_size = target_arch.GetAddressByteSize ();
6513
+ const ByteOrder byte_order = target_arch.GetByteOrder ();
6514
+ std::vector<llvm::MachO::segment_command_64> segment_load_commands;
6515
+ for (const auto &core_range : core_ranges) {
6600
6516
uint32_t cmd_type = LC_SEGMENT_64;
6601
6517
uint32_t segment_size = sizeof (llvm::MachO::segment_command_64);
6602
6518
if (addr_byte_size == 4 ) {
6603
6519
cmd_type = LC_SEGMENT;
6604
6520
segment_size = sizeof (llvm::MachO::segment_command);
6605
6521
}
6522
+ // Skip any ranges with no read/write/execute permissions and empty
6523
+ // ranges.
6524
+ if (core_range.lldb_permissions == 0 || core_range.range .size () == 0 )
6525
+ continue ;
6526
+ uint32_t vm_prot = 0 ;
6527
+ if (core_range.lldb_permissions & ePermissionsReadable)
6528
+ vm_prot |= VM_PROT_READ;
6529
+ if (core_range.lldb_permissions & ePermissionsWritable)
6530
+ vm_prot |= VM_PROT_WRITE;
6531
+ if (core_range.lldb_permissions & ePermissionsExecutable)
6532
+ vm_prot |= VM_PROT_EXECUTE;
6533
+ const addr_t vm_addr = core_range.range .start ();
6534
+ const addr_t vm_size = core_range.range .size ();
6606
6535
llvm::MachO::segment_command_64 segment = {
6607
6536
cmd_type, // uint32_t cmd;
6608
6537
segment_size, // uint32_t cmdsize;
6609
6538
{0 }, // char segname[16];
6610
- obj.addr , // uint64_t vmaddr; // uint32_t for 32-bit
6611
- // Mach-O
6612
- obj.size , // uint64_t vmsize; // uint32_t for 32-bit
6613
- // Mach-O
6614
- 0 , // uint64_t fileoff; // uint32_t for 32-bit Mach-O
6615
- obj.size , // uint64_t filesize; // uint32_t for 32-bit
6616
- // Mach-O
6617
- obj.prot , // uint32_t maxprot;
6618
- obj.prot , // uint32_t initprot;
6539
+ vm_addr, // uint64_t vmaddr; // uint32_t for 32-bit Mach-O
6540
+ vm_size, // uint64_t vmsize; // uint32_t for 32-bit Mach-O
6541
+ 0 , // uint64_t fileoff; // uint32_t for 32-bit Mach-O
6542
+ vm_size, // uint64_t filesize; // uint32_t for 32-bit Mach-O
6543
+ vm_prot, // uint32_t maxprot;
6544
+ vm_prot, // uint32_t initprot;
6619
6545
0 , // uint32_t nsects;
6620
6546
0 }; // uint32_t flags;
6621
6547
segment_load_commands.push_back (segment);
@@ -6624,11 +6550,7 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
6624
6550
StreamString buffer (Stream::eBinary, addr_byte_size, byte_order);
6625
6551
6626
6552
llvm::MachO::mach_header_64 mach_header;
6627
- if (addr_byte_size == 8 ) {
6628
- mach_header.magic = MH_MAGIC_64;
6629
- } else {
6630
- mach_header.magic = MH_MAGIC;
6631
- }
6553
+ mach_header.magic = addr_byte_size == 8 ? MH_MAGIC_64 : MH_MAGIC;
6632
6554
mach_header.cputype = target_arch.GetMachOCPUType ();
6633
6555
mach_header.cpusubtype = target_arch.GetMachOCPUSubType ();
6634
6556
mach_header.filetype = MH_CORE;
@@ -6913,9 +6835,6 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
6913
6835
}
6914
6836
}
6915
6837
}
6916
- } else {
6917
- error.SetErrorString (
6918
- " process doesn't support getting memory region info" );
6919
6838
}
6920
6839
}
6921
6840
return true ; // This is the right plug to handle saving core files for
0 commit comments