| ... | @@ -133,8 +133,8 @@ objc_selrefs_section_index: ?u16 = null, | ... | @@ -133,8 +133,8 @@ objc_selrefs_section_index: ?u16 = null, |
| 133 | objc_classrefs_section_index: ?u16 = null, | 133 | objc_classrefs_section_index: ?u16 = null, |
| 134 | objc_data_section_index: ?u16 = null, | 134 | objc_data_section_index: ?u16 = null, |
| 135 | | 135 | |
| 136 | bss_file_offset: ?u32 = null, | 136 | bss_file_offset: u32 = 0, |
| 137 | tlv_bss_file_offset: ?u32 = null, | 137 | tlv_bss_file_offset: u32 = 0, |
| 138 | | 138 | |
| 139 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | 139 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 140 | globals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | 140 | globals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| ... | @@ -749,6 +749,17 @@ pub fn flush(self: *MachO, comp: *Compilation) !void { | ... | @@ -749,6 +749,17 @@ pub fn flush(self: *MachO, comp: *Compilation) !void { |
| 749 | try self.parseInputFiles(positionals.items, self.base.options.sysroot); | 749 | try self.parseInputFiles(positionals.items, self.base.options.sysroot); |
| 750 | try self.parseLibs(libs.items, self.base.options.sysroot); | 750 | try self.parseLibs(libs.items, self.base.options.sysroot); |
| 751 | | 751 | |
| | 752 | if (self.bss_section_index) |idx| { |
| | 753 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| | 754 | const sect = &seg.sections.items[idx]; |
| | 755 | sect.offset = self.bss_file_offset; |
| | 756 | } |
| | 757 | if (self.tlv_bss_section_index) |idx| { |
| | 758 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| | 759 | const sect = &seg.sections.items[idx]; |
| | 760 | sect.offset = self.tlv_bss_file_offset; |
| | 761 | } |
| | 762 | |
| 752 | try self.resolveSymbols(); | 763 | try self.resolveSymbols(); |
| 753 | try self.addRpathLCs(rpath_table.keys()); | 764 | try self.addRpathLCs(rpath_table.keys()); |
| 754 | try self.addLoadDylibLCs(); | 765 | try self.addLoadDylibLCs(); |
| ... | @@ -781,6 +792,20 @@ pub fn flush(self: *MachO, comp: *Compilation) !void { | ... | @@ -781,6 +792,20 @@ pub fn flush(self: *MachO, comp: *Compilation) !void { |
| 781 | } | 792 | } |
| 782 | } | 793 | } |
| 783 | try self.writeAtoms(); | 794 | try self.writeAtoms(); |
| | 795 | |
| | 796 | if (self.bss_section_index) |idx| { |
| | 797 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| | 798 | const sect = &seg.sections.items[idx]; |
| | 799 | self.bss_file_offset = sect.offset; |
| | 800 | sect.offset = 0; |
| | 801 | } |
| | 802 | if (self.tlv_bss_section_index) |idx| { |
| | 803 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| | 804 | const sect = &seg.sections.items[idx]; |
| | 805 | self.tlv_bss_file_offset = sect.offset; |
| | 806 | sect.offset = 0; |
| | 807 | } |
| | 808 | |
| 784 | try self.flushModule(comp); | 809 | try self.flushModule(comp); |
| 785 | } | 810 | } |
| 786 | | 811 | |
| ... | @@ -1687,8 +1712,7 @@ pub fn writeAtom(self: *MachO, atom: *TextBlock, match: MatchingSection) !void { | ... | @@ -1687,8 +1712,7 @@ pub fn writeAtom(self: *MachO, atom: *TextBlock, match: MatchingSection) !void { |
| 1687 | const seg = self.load_commands.items[match.seg].Segment; | 1712 | const seg = self.load_commands.items[match.seg].Segment; |
| 1688 | const sect = seg.sections.items[match.sect]; | 1713 | const sect = seg.sections.items[match.sect]; |
| 1689 | const sym = self.locals.items[atom.local_sym_index]; | 1714 | const sym = self.locals.items[atom.local_sym_index]; |
| 1690 | const sect_offset = self.getPtrToSectionOffset(match).*; | 1715 | const file_offset = sect.offset + sym.n_value - sect.addr; |
| 1691 | const file_offset = sect_offset + sym.n_value - sect.addr; | | |
| 1692 | try atom.resolveRelocs(self); | 1716 | try atom.resolveRelocs(self); |
| 1693 | log.debug("writing atom for symbol {s} at file offset 0x{x}", .{ self.getString(sym.n_strx), file_offset }); | 1717 | log.debug("writing atom for symbol {s} at file offset 0x{x}", .{ self.getString(sym.n_strx), file_offset }); |
| 1694 | try self.base.file.?.pwriteAll(atom.code.items, file_offset); | 1718 | try self.base.file.?.pwriteAll(atom.code.items, file_offset); |
| ... | @@ -3469,13 +3493,9 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -3469,13 +3493,9 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 3469 | .flags = macho.S_THREAD_LOCAL_ZEROFILL, | 3493 | .flags = macho.S_THREAD_LOCAL_ZEROFILL, |
| 3470 | }, | 3494 | }, |
| 3471 | ); | 3495 | ); |
| 3472 | | 3496 | const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 3473 | // We keep offset to the section in a separate variable as the actual section is usually pointing at the | 3497 | const sect = seg.sections.items[self.tlv_bss_section_index.?]; |
| 3474 | // beginning of the file. | 3498 | self.tlv_bss_file_offset = sect.offset; |
| 3475 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | | |
| 3476 | const out_sect = &seg.sections.items[self.tlv_bss_section_index.?]; | | |
| 3477 | self.tlv_bss_file_offset = out_sect.offset; | | |
| 3478 | out_sect.offset = 0; | | |
| 3479 | } | 3499 | } |
| 3480 | | 3500 | |
| 3481 | if (self.bss_section_index == null) { | 3501 | if (self.bss_section_index == null) { |
| ... | @@ -3490,13 +3510,9 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -3490,13 +3510,9 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 3490 | .flags = macho.S_ZEROFILL, | 3510 | .flags = macho.S_ZEROFILL, |
| 3491 | }, | 3511 | }, |
| 3492 | ); | 3512 | ); |
| 3493 | | 3513 | const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 3494 | // We keep offset to the section in a separate variable as the actual section is usually pointing at the | 3514 | const sect = seg.sections.items[self.bss_section_index.?]; |
| 3495 | // beginning of the file. | 3515 | self.bss_file_offset = sect.offset; |
| 3496 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | | |
| 3497 | const out_sect = &seg.sections.items[self.bss_section_index.?]; | | |
| 3498 | self.bss_file_offset = out_sect.offset; | | |
| 3499 | out_sect.offset = 0; | | |
| 3500 | } | 3516 | } |
| 3501 | | 3517 | |
| 3502 | if (self.linkedit_segment_cmd_index == null) { | 3518 | if (self.linkedit_segment_cmd_index == null) { |
| ... | @@ -3767,8 +3783,7 @@ fn growSection(self: *MachO, match: MatchingSection, new_size: u32) !void { | ... | @@ -3767,8 +3783,7 @@ fn growSection(self: *MachO, match: MatchingSection, new_size: u32) !void { |
| 3767 | const sect = &seg.sections.items[match.sect]; | 3783 | const sect = &seg.sections.items[match.sect]; |
| 3768 | | 3784 | |
| 3769 | const alignment = try math.powi(u32, 2, sect.@"align"); | 3785 | const alignment = try math.powi(u32, 2, sect.@"align"); |
| 3770 | const sect_offset = self.getPtrToSectionOffset(match); | 3786 | const max_size = self.allocatedSize(match.seg, sect.offset); |
| 3771 | const max_size = self.allocatedSize(match.seg, sect_offset.*); | | |
| 3772 | const ideal_size = padToIdeal(new_size); | 3787 | const ideal_size = padToIdeal(new_size); |
| 3773 | const needed_size = mem.alignForwardGeneric(u32, ideal_size, alignment); | 3788 | const needed_size = mem.alignForwardGeneric(u32, ideal_size, alignment); |
| 3774 | | 3789 | |
| ... | @@ -3830,24 +3845,22 @@ fn growSection(self: *MachO, match: MatchingSection, new_size: u32) !void { | ... | @@ -3830,24 +3845,22 @@ fn growSection(self: *MachO, match: MatchingSection, new_size: u32) !void { |
| 3830 | }); | 3845 | }); |
| 3831 | | 3846 | |
| 3832 | for (next_seg.sections.items) |*moved_sect, moved_sect_id| { | 3847 | for (next_seg.sections.items) |*moved_sect, moved_sect_id| { |
| 3833 | const moved_match = MatchingSection{ | 3848 | moved_sect.offset += @intCast(u32, seg_offset_amt); |
| 3834 | .seg = @intCast(u16, next), | | |
| 3835 | .sect = @intCast(u16, moved_sect_id), | | |
| 3836 | }; | | |
| 3837 | const ptr_sect_offset = self.getPtrToSectionOffset(moved_match); | | |
| 3838 | ptr_sect_offset.* += @intCast(u32, seg_offset_amt); | | |
| 3839 | moved_sect.addr += seg_offset_amt; | 3849 | moved_sect.addr += seg_offset_amt; |
| 3840 | | 3850 | |
| 3841 | log.warn(" (new {s},{s} file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ | 3851 | log.warn(" (new {s},{s} file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ |
| 3842 | commands.segmentName(moved_sect.*), | 3852 | commands.segmentName(moved_sect.*), |
| 3843 | commands.sectionName(moved_sect.*), | 3853 | commands.sectionName(moved_sect.*), |
| 3844 | ptr_sect_offset.*, | 3854 | moved_sect.offset, |
| 3845 | ptr_sect_offset.* + moved_sect.size, | 3855 | moved_sect.offset + moved_sect.size, |
| 3846 | moved_sect.addr, | 3856 | moved_sect.addr, |
| 3847 | moved_sect.addr + moved_sect.size, | 3857 | moved_sect.addr + moved_sect.size, |
| 3848 | }); | 3858 | }); |
| 3849 | | 3859 | |
| 3850 | try self.allocateLocalSymbols(moved_match, @intCast(i64, seg_offset_amt)); | 3860 | try self.allocateLocalSymbols(.{ |
| | 3861 | .seg = @intCast(u16, next), |
| | 3862 | .sect = @intCast(u16, moved_sect_id), |
| | 3863 | }, @intCast(i64, seg_offset_amt)); |
| 3851 | } | 3864 | } |
| 3852 | } | 3865 | } |
| 3853 | } | 3866 | } |
| ... | @@ -3867,25 +3880,23 @@ fn growSection(self: *MachO, match: MatchingSection, new_size: u32) !void { | ... | @@ -3867,25 +3880,23 @@ fn growSection(self: *MachO, match: MatchingSection, new_size: u32) !void { |
| 3867 | | 3880 | |
| 3868 | var next = match.sect + 1; | 3881 | var next = match.sect + 1; |
| 3869 | while (next < seg.sections.items.len) : (next += 1) { | 3882 | while (next < seg.sections.items.len) : (next += 1) { |
| 3870 | const moved_match = MatchingSection{ | | |
| 3871 | .seg = match.seg, | | |
| 3872 | .sect = next, | | |
| 3873 | }; | | |
| 3874 | const moved_sect = &seg.sections.items[next]; | 3883 | const moved_sect = &seg.sections.items[next]; |
| 3875 | const ptr_sect_offset = self.getPtrToSectionOffset(moved_match); | 3884 | moved_sect.offset += @intCast(u32, offset_amt); |
| 3876 | ptr_sect_offset.* += @intCast(u32, offset_amt); | | |
| 3877 | moved_sect.addr += offset_amt; | 3885 | moved_sect.addr += offset_amt; |
| 3878 | | 3886 | |
| 3879 | log.warn(" (new {s},{s} file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ | 3887 | log.warn(" (new {s},{s} file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ |
| 3880 | commands.segmentName(moved_sect.*), | 3888 | commands.segmentName(moved_sect.*), |
| 3881 | commands.sectionName(moved_sect.*), | 3889 | commands.sectionName(moved_sect.*), |
| 3882 | ptr_sect_offset.*, | 3890 | moved_sect.offset, |
| 3883 | ptr_sect_offset.* + moved_sect.size, | 3891 | moved_sect.offset + moved_sect.size, |
| 3884 | moved_sect.addr, | 3892 | moved_sect.addr, |
| 3885 | moved_sect.addr + moved_sect.size, | 3893 | moved_sect.addr + moved_sect.size, |
| 3886 | }); | 3894 | }); |
| 3887 | | 3895 | |
| 3888 | try self.allocateLocalSymbols(moved_match, @intCast(i64, offset_amt)); | 3896 | try self.allocateLocalSymbols(.{ |
| | 3897 | .seg = match.seg, |
| | 3898 | .sect = next, |
| | 3899 | }, @intCast(i64, offset_amt)); |
| 3889 | } | 3900 | } |
| 3890 | } | 3901 | } |
| 3891 | | 3902 | |
| ... | @@ -3916,25 +3927,6 @@ fn getSectionMaxAlignment(self: *MachO, segment_id: u16, start_sect_id: u16) !u3 | ... | @@ -3916,25 +3927,6 @@ fn getSectionMaxAlignment(self: *MachO, segment_id: u16, start_sect_id: u16) !u3 |
| 3916 | return max_alignment; | 3927 | return max_alignment; |
| 3917 | } | 3928 | } |
| 3918 | | 3929 | |
| 3919 | fn getPtrToSectionOffset(self: *MachO, match: MatchingSection) *u32 { | | |
| 3920 | if (self.data_segment_cmd_index.? == match.seg) { | | |
| 3921 | if (self.bss_section_index) |idx| { | | |
| 3922 | if (idx == match.sect) { | | |
| 3923 | return &self.bss_file_offset.?; | | |
| 3924 | } | | |
| 3925 | } | | |
| 3926 | if (self.tlv_bss_section_index) |idx| { | | |
| 3927 | if (idx == match.sect) { | | |
| 3928 | return &self.tlv_bss_file_offset.?; | | |
| 3929 | } | | |
| 3930 | } | | |
| 3931 | } | | |
| 3932 | | | |
| 3933 | const seg = &self.load_commands.items[match.seg].Segment; | | |
| 3934 | const sect = &seg.sections.items[match.sect]; | | |
| 3935 | return &sect.offset; | | |
| 3936 | } | | |
| 3937 | | | |
| 3938 | fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 { | 3930 | fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 { |
| 3939 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 3931 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 3940 | const text_section = &text_segment.sections.items[self.text_section_index.?]; | 3932 | const text_section = &text_segment.sections.items[self.text_section_index.?]; |