@@ -1674,6 +1674,10 @@ void ObjectFileMachO::ProcessSegmentCommand(
16741674 uint32_t segment_sect_idx;
16751675 const lldb::user_id_t first_segment_sectID = context.NextSectionIdx + 1 ;
16761676
1677+ // dSYM files can create sections whose data exceeds the 4GB barrier, but
1678+ // mach-o sections only have 32 bit offsets. So keep track of when we
1679+ // overflow and fix the sections offsets as we iterate.
1680+ uint64_t section_offset_adjust = 0 ;
16771681 const uint32_t num_u32s = load_cmd.cmd == LC_SEGMENT ? 7 : 8 ;
16781682 for (segment_sect_idx = 0 ; segment_sect_idx < load_cmd.nsects ;
16791683 ++segment_sect_idx) {
@@ -1697,6 +1701,14 @@ void ObjectFileMachO::ProcessSegmentCommand(
16971701 // isn't stored in the abstracted Sections.
16981702 m_mach_sections.push_back (sect64);
16991703
1704+ // Make sure we can load dSYM files whose __DWARF sections exceed the 4GB
1705+ // barrier. llvm::MachO::section_64 have only 32 bit file offsets for the
1706+ // section contents.
1707+ const uint64_t section_file_offset = sect64.offset + section_offset_adjust;
1708+ // If this section overflows a 4GB barrier, then we need to adjust any
1709+ // subsequent the section offsets.
1710+ if (is_dsym && ((uint64_t )sect64.offset + sect64.size ) >= UINT32_MAX)
1711+ section_offset_adjust += 0x100000000ull ;
17001712 if (add_section) {
17011713 ConstString section_name (
17021714 sect64.sectname , strnlen (sect64.sectname , sizeof (sect64.sectname )));
@@ -1736,13 +1748,13 @@ void ObjectFileMachO::ProcessSegmentCommand(
17361748 }
17371749
17381750 // Grow the section size as needed.
1739- if (sect64. offset ) {
1751+ if (section_file_offset ) {
17401752 const lldb::addr_t segment_min_file_offset =
17411753 segment->GetFileOffset ();
17421754 const lldb::addr_t segment_max_file_offset =
17431755 segment_min_file_offset + segment->GetFileSize ();
17441756
1745- const lldb::addr_t section_min_file_offset = sect64. offset ;
1757+ const lldb::addr_t section_min_file_offset = section_file_offset ;
17461758 const lldb::addr_t section_max_file_offset =
17471759 section_min_file_offset + sect64.size ;
17481760 const lldb::addr_t new_file_offset =
@@ -1770,9 +1782,9 @@ void ObjectFileMachO::ProcessSegmentCommand(
17701782 sect64.addr , // File VM address == addresses as they are
17711783 // found in the object file
17721784 sect64.size , // VM size in bytes of this section
1773- sect64. offset , // Offset to the data for this section in
1785+ section_file_offset , // Offset to the data for this section in
17741786 // the file
1775- sect64. offset ? sect64.size : 0 , // Size in bytes of
1787+ section_file_offset ? sect64.size : 0 , // Size in bytes of
17761788 // this section as
17771789 // found in the file
17781790 sect64.align ,
@@ -1792,14 +1804,14 @@ void ObjectFileMachO::ProcessSegmentCommand(
17921804 SectionSP section_sp (new Section (
17931805 segment_sp, module_sp, this , ++context.NextSectionIdx , section_name,
17941806 sect_type, sect64.addr - segment_sp->GetFileAddress (), sect64.size ,
1795- sect64. offset , sect64. offset == 0 ? 0 : sect64.size , sect64. align ,
1796- sect64.flags ));
1807+ section_file_offset, section_file_offset == 0 ? 0 : sect64.size ,
1808+ sect64.align , sect64. flags ));
17971809 // Set the section to be encrypted to match the segment
17981810
17991811 bool section_is_encrypted = false ;
18001812 if (!segment_is_encrypted && load_cmd.filesize != 0 )
18011813 section_is_encrypted = context.EncryptedRanges .FindEntryThatContains (
1802- sect64. offset ) != nullptr ;
1814+ section_file_offset ) != nullptr ;
18031815
18041816 section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
18051817 section_sp->SetPermissions (segment_permissions);
0 commit comments