[Lldb-commits] [lldb] 3475b3f - Enable LLDB to load large dSYM files. (#164471)
via lldb-commits
lldb-commits at lists.llvm.org
Thu Oct 30 14:08:48 PDT 2025
Author: Greg Clayton
Date: 2025-10-30T14:08:44-07:00
New Revision: 3475b3f97b3060880c31c8b8a440f47f9d654e49
URL: https://github.com/llvm/llvm-project/commit/3475b3f97b3060880c31c8b8a440f47f9d654e49
DIFF: https://github.com/llvm/llvm-project/commit/3475b3f97b3060880c31c8b8a440f47f9d654e49.diff
LOG: Enable LLDB to load large dSYM files. (#164471)
llvm-dsymutil can produce mach-o files where some sections in __DWARF
exceed the 4GB barrier and subsequent sections in the dSYM will be
inaccessible because the mach-o section_64 structure only has a 32 bit
file offset. This patch enables LLDB to load a large dSYM file by
figuring out when this happens and properly adjusting the file offset of
the LLDB sections.
I was unable to add a test as obj2yaml and yaml2obj are broken for
mach-o files and they can't convert a yaml file back into a valid mach-o
object file. Any suggestions for adding a test would be appreciated.
Added:
lldb/test/Shell/ObjectFile/MachO/Inputs/section-overflow-binary
lldb/test/Shell/ObjectFile/MachO/section-overflow-binary.test
Modified:
lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
Removed:
################################################################################
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 9cdb8467bfc60..c8e520d687f67 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -1674,6 +1674,10 @@ void ObjectFileMachO::ProcessSegmentCommand(
uint32_t segment_sect_idx;
const lldb::user_id_t first_segment_sectID = context.NextSectionIdx + 1;
+ // 64 bit mach-o files have sections with 32 bit file offsets. If any section
+ // data end will exceed UINT32_MAX, then we need to do some bookkeeping to
+ // ensure we can access this data correctly.
+ uint64_t section_offset_adjust = 0;
const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8;
for (segment_sect_idx = 0; segment_sect_idx < load_cmd.nsects;
++segment_sect_idx) {
@@ -1697,6 +1701,16 @@ void ObjectFileMachO::ProcessSegmentCommand(
// isn't stored in the abstracted Sections.
m_mach_sections.push_back(sect64);
+ // Make sure we can load sections in mach-o files where some sections cross
+ // a 4GB boundary. llvm::MachO::section_64 have only 32 bit file offsets
+ // for the file offset of the section contents, so we need to track and
+ // sections that overflow and adjust the offsets accordingly.
+ const uint64_t section_file_offset =
+ (uint64_t)sect64.offset + section_offset_adjust;
+ const uint64_t end_section_offset = (uint64_t)sect64.offset + sect64.size;
+ if (end_section_offset >= UINT32_MAX)
+ section_offset_adjust += end_section_offset & 0xFFFFFFFF00000000ull;
+
if (add_section) {
ConstString section_name(
sect64.sectname, strnlen(sect64.sectname, sizeof(sect64.sectname)));
@@ -1736,13 +1750,13 @@ void ObjectFileMachO::ProcessSegmentCommand(
}
// Grow the section size as needed.
- if (sect64.offset) {
+ if (section_file_offset) {
const lldb::addr_t segment_min_file_offset =
segment->GetFileOffset();
const lldb::addr_t segment_max_file_offset =
segment_min_file_offset + segment->GetFileSize();
- const lldb::addr_t section_min_file_offset = sect64.offset;
+ const lldb::addr_t section_min_file_offset = section_file_offset;
const lldb::addr_t section_max_file_offset =
section_min_file_offset + sect64.size;
const lldb::addr_t new_file_offset =
@@ -1769,10 +1783,10 @@ void ObjectFileMachO::ProcessSegmentCommand(
// other sections.
sect64.addr, // File VM address == addresses as they are
// found in the object file
- sect64.size, // VM size in bytes of this section
- sect64.offset, // Offset to the data for this section in
+ sect64.size, // VM size in bytes of this section
+ section_file_offset, // Offset to the data for this section in
// the file
- sect64.offset ? sect64.size : 0, // Size in bytes of
+ section_file_offset ? sect64.size : 0, // Size in bytes of
// this section as
// found in the file
sect64.align,
@@ -1792,14 +1806,14 @@ void ObjectFileMachO::ProcessSegmentCommand(
SectionSP section_sp(new Section(
segment_sp, module_sp, this, ++context.NextSectionIdx, section_name,
sect_type, sect64.addr - segment_sp->GetFileAddress(), sect64.size,
- sect64.offset, sect64.offset == 0 ? 0 : sect64.size, sect64.align,
- sect64.flags));
+ section_file_offset, section_file_offset == 0 ? 0 : sect64.size,
+ sect64.align, sect64.flags));
// Set the section to be encrypted to match the segment
bool section_is_encrypted = false;
if (!segment_is_encrypted && load_cmd.filesize != 0)
section_is_encrypted = context.EncryptedRanges.FindEntryThatContains(
- sect64.offset) != nullptr;
+ section_file_offset) != nullptr;
section_sp->SetIsEncrypted(segment_is_encrypted || section_is_encrypted);
section_sp->SetPermissions(segment_permissions);
diff --git a/lldb/test/Shell/ObjectFile/MachO/Inputs/section-overflow-binary b/lldb/test/Shell/ObjectFile/MachO/Inputs/section-overflow-binary
new file mode 100644
index 0000000000000..19dc2f4ac9ffe
Binary files /dev/null and b/lldb/test/Shell/ObjectFile/MachO/Inputs/section-overflow-binary
diff er
diff --git a/lldb/test/Shell/ObjectFile/MachO/section-overflow-binary.test b/lldb/test/Shell/ObjectFile/MachO/section-overflow-binary.test
new file mode 100644
index 0000000000000..76c335f65a76a
--- /dev/null
+++ b/lldb/test/Shell/ObjectFile/MachO/section-overflow-binary.test
@@ -0,0 +1,13 @@
+RUN: %lldb -b %p/Inputs/section-overflow-binary \
+RUN: -o 'script dwarf = lldb.target.module[0].sections[0]' \
+RUN: -o 'script section = dwarf.GetSubSectionAtIndex(0)' \
+RUN: -o "script print(f'{section.GetName()} file_offset=0x{section.GetFileOffset():016x}')" \
+RUN: -o 'script section = dwarf.GetSubSectionAtIndex(1)' \
+RUN: -o "script print(f'{section.GetName()} file_offset=0x{section.GetFileOffset():016x}')" \
+RUN: -o 'script section = dwarf.GetSubSectionAtIndex(2)' \
+RUN: -o "script print(f'{section.GetName()} file_offset=0x{section.GetFileOffset():016x}')" \
+RUN: | FileCheck %s
+
+CHECK: __debug_abbrev file_offset=0x00000000fffffff0
+CHECK: __debug_info file_offset=0x0000000100000010
+CHECK: __debug_line file_offset=0x0000000300000010
More information about the lldb-commits
mailing list