| ... | @@ -133,6 +133,9 @@ objc_selrefs_section_index: ?u16 = null, | ... | @@ -133,6 +133,9 @@ 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: ?u64 = null, |
| | 137 | tlv_bss_file_offset: ?u64 = null, |
| | 138 | |
| 136 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | 139 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 137 | globals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | 140 | globals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 138 | undefs: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | 141 | undefs: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| ... | @@ -1714,11 +1717,30 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void { | ... | @@ -1714,11 +1717,30 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void { |
| 1714 | | 1717 | |
| 1715 | // Allocate the sections according to their alignment at the beginning of the segment. | 1718 | // Allocate the sections according to their alignment at the beginning of the segment. |
| 1716 | var start: u64 = offset; | 1719 | var start: u64 = offset; |
| 1717 | for (seg.sections.items) |*sect| { | 1720 | for (seg.sections.items) |*sect, sect_id| { |
| 1718 | const alignment = try math.powi(u32, 2, sect.@"align"); | 1721 | const alignment = try math.powi(u32, 2, sect.@"align"); |
| 1719 | const start_aligned = mem.alignForwardGeneric(u64, start, alignment); | 1722 | const start_aligned = mem.alignForwardGeneric(u64, start, alignment); |
| 1720 | const end_aligned = mem.alignForwardGeneric(u64, start_aligned + sect.size, alignment); | 1723 | const end_aligned = mem.alignForwardGeneric(u64, start_aligned + sect.size, alignment); |
| 1721 | sect.offset = @intCast(u32, seg.inner.fileoff + start_aligned); | 1724 | const file_offset = @intCast(u32, seg.inner.fileoff + start_aligned); |
| | 1725 | |
| | 1726 | blk: { |
| | 1727 | if (index == self.data_segment_cmd_index.?) { |
| | 1728 | if (self.bss_section_index) |idx| { |
| | 1729 | if (sect_id == idx) { |
| | 1730 | self.bss_file_offset = file_offset; |
| | 1731 | break :blk; |
| | 1732 | } |
| | 1733 | } |
| | 1734 | if (self.tlv_bss_section_index) |idx| { |
| | 1735 | if (sect_id == idx) { |
| | 1736 | self.tlv_bss_file_offset = file_offset; |
| | 1737 | break :blk; |
| | 1738 | } |
| | 1739 | } |
| | 1740 | } |
| | 1741 | sect.offset = @intCast(u32, seg.inner.fileoff + start_aligned); |
| | 1742 | } |
| | 1743 | |
| 1722 | sect.addr = seg.inner.vmaddr + start_aligned; | 1744 | sect.addr = seg.inner.vmaddr + start_aligned; |
| 1723 | start = end_aligned; | 1745 | start = end_aligned; |
| 1724 | } | 1746 | } |
| ... | @@ -1821,6 +1843,18 @@ fn writeTextBlocks(self: *MachO) !void { | ... | @@ -1821,6 +1843,18 @@ fn writeTextBlocks(self: *MachO) !void { |
| 1821 | var code = try self.base.allocator.alloc(u8, sect.size); | 1843 | var code = try self.base.allocator.alloc(u8, sect.size); |
| 1822 | defer self.base.allocator.free(code); | 1844 | defer self.base.allocator.free(code); |
| 1823 | | 1845 | |
| | 1846 | const file_offset: u64 = blk: { |
| | 1847 | if (self.data_segment_cmd_index.? == match.seg) { |
| | 1848 | if (self.bss_section_index) |idx| { |
| | 1849 | if (idx == match.sect) break :blk self.bss_file_offset.?; |
| | 1850 | } |
| | 1851 | if (self.tlv_bss_section_index) |idx| { |
| | 1852 | if (idx == match.sect) break :blk self.tlv_bss_file_offset.?; |
| | 1853 | } |
| | 1854 | } |
| | 1855 | break :blk sect.offset; |
| | 1856 | }; |
| | 1857 | |
| 1824 | if (sect_type == macho.S_ZEROFILL or sect_type == macho.S_THREAD_LOCAL_ZEROFILL) { | 1858 | if (sect_type == macho.S_ZEROFILL or sect_type == macho.S_THREAD_LOCAL_ZEROFILL) { |
| 1825 | mem.set(u8, code, 0); | 1859 | mem.set(u8, code, 0); |
| 1826 | } else { | 1860 | } else { |
| ... | @@ -1856,7 +1890,7 @@ fn writeTextBlocks(self: *MachO) !void { | ... | @@ -1856,7 +1890,7 @@ fn writeTextBlocks(self: *MachO) !void { |
| 1856 | mem.set(u8, code[base_off..], 0); | 1890 | mem.set(u8, code[base_off..], 0); |
| 1857 | } | 1891 | } |
| 1858 | | 1892 | |
| 1859 | try self.base.file.?.pwriteAll(code, sect.offset); | 1893 | try self.base.file.?.pwriteAll(code, file_offset); |
| 1860 | } | 1894 | } |
| 1861 | } | 1895 | } |
| 1862 | | 1896 | |
| ... | @@ -1925,7 +1959,18 @@ pub fn writeAtom(self: *MachO, atom: *TextBlock, match: MatchingSection) !void { | ... | @@ -1925,7 +1959,18 @@ pub fn writeAtom(self: *MachO, atom: *TextBlock, match: MatchingSection) !void { |
| 1925 | const seg = self.load_commands.items[match.seg].Segment; | 1959 | const seg = self.load_commands.items[match.seg].Segment; |
| 1926 | const sect = seg.sections.items[match.sect]; | 1960 | const sect = seg.sections.items[match.sect]; |
| 1927 | const sym = self.locals.items[atom.local_sym_index]; | 1961 | const sym = self.locals.items[atom.local_sym_index]; |
| 1928 | const file_offset = sect.offset + sym.n_value - sect.addr; | 1962 | const sect_offset: u64 = blk: { |
| | 1963 | if (self.data_segment_cmd_index.? == match.seg) { |
| | 1964 | if (self.bss_section_index) |idx| { |
| | 1965 | if (idx == match.sect) break :blk self.bss_file_offset.?; |
| | 1966 | } |
| | 1967 | if (self.tlv_bss_section_index) |idx| { |
| | 1968 | if (idx == match.sect) break :blk self.tlv_bss_file_offset.?; |
| | 1969 | } |
| | 1970 | } |
| | 1971 | break :blk sect.offset; |
| | 1972 | }; |
| | 1973 | const file_offset = sect_offset + sym.n_value - sect.addr; |
| 1929 | try atom.resolveRelocs(self); | 1974 | try atom.resolveRelocs(self); |
| 1930 | log.debug("writing atom for symbol {s} at file offset 0x{x}", .{ self.getString(sym.n_strx), file_offset }); | 1975 | log.debug("writing atom for symbol {s} at file offset 0x{x}", .{ self.getString(sym.n_strx), file_offset }); |
| 1931 | try self.base.file.?.pwriteAll(atom.code.items, file_offset); | 1976 | try self.base.file.?.pwriteAll(atom.code.items, file_offset); |
| ... | @@ -2873,19 +2918,6 @@ fn addLoadDylibLCs(self: *MachO) !void { | ... | @@ -2873,19 +2918,6 @@ fn addLoadDylibLCs(self: *MachO) !void { |
| 2873 | | 2918 | |
| 2874 | fn flushZld(self: *MachO) !void { | 2919 | fn flushZld(self: *MachO) !void { |
| 2875 | try self.writeTextBlocks(); | 2920 | try self.writeTextBlocks(); |
| 2876 | | | |
| 2877 | // if (self.bss_section_index) |index| { | | |
| 2878 | // const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | | |
| 2879 | // const sect = &seg.sections.items[index]; | | |
| 2880 | // sect.offset = 0; | | |
| 2881 | // } | | |
| 2882 | | | |
| 2883 | // if (self.tlv_bss_section_index) |index| { | | |
| 2884 | // const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | | |
| 2885 | // const sect = &seg.sections.items[index]; | | |
| 2886 | // sect.offset = 0; | | |
| 2887 | // } | | |
| 2888 | | | |
| 2889 | try self.setEntryPoint(); | 2921 | try self.setEntryPoint(); |
| 2890 | try self.writeRebaseInfoTableZld(); | 2922 | try self.writeRebaseInfoTableZld(); |
| 2891 | try self.writeBindInfoTableZld(); | 2923 | try self.writeBindInfoTableZld(); |
| ... | @@ -4203,10 +4235,12 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4203,10 +4235,12 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4203 | | 4235 | |
| 4204 | log.debug("found __thread_bss section free space 0x{x} to 0x{x}", .{ off, off + needed_size }); | 4236 | log.debug("found __thread_bss section free space 0x{x} to 0x{x}", .{ off, off + needed_size }); |
| 4205 | | 4237 | |
| | 4238 | // We keep offset to the section in a separate variable as the actual section is usually pointing at the |
| | 4239 | // beginning of the file. |
| | 4240 | self.tlv_bss_file_offset = off; |
| 4206 | try data_segment.addSection(self.base.allocator, "__thread_bss", .{ | 4241 | try data_segment.addSection(self.base.allocator, "__thread_bss", .{ |
| 4207 | .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff, | 4242 | .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff, |
| 4208 | .size = needed_size, | 4243 | .size = needed_size, |
| 4209 | .offset = @intCast(u32, off), | | |
| 4210 | .@"align" = 3, // 2^3 = @sizeOf(u64) | 4244 | .@"align" = 3, // 2^3 = @sizeOf(u64) |
| 4211 | .flags = macho.S_THREAD_LOCAL_ZEROFILL, | 4245 | .flags = macho.S_THREAD_LOCAL_ZEROFILL, |
| 4212 | }); | 4246 | }); |
| ... | @@ -4229,10 +4263,12 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4229,10 +4263,12 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4229 | | 4263 | |
| 4230 | log.debug("found __bss section free space 0x{x} to 0x{x}", .{ off, off + needed_size }); | 4264 | log.debug("found __bss section free space 0x{x} to 0x{x}", .{ off, off + needed_size }); |
| 4231 | | 4265 | |
| | 4266 | // We keep offset to the section in a separate variable as the actual section is usually pointing at the |
| | 4267 | // beginning of the file. |
| | 4268 | self.bss_file_offset = off; |
| 4232 | try data_segment.addSection(self.base.allocator, "__bss", .{ | 4269 | try data_segment.addSection(self.base.allocator, "__bss", .{ |
| 4233 | .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff, | 4270 | .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff, |
| 4234 | .size = 0, | 4271 | .size = 0, |
| 4235 | .offset = @intCast(u32, off), | | |
| 4236 | .@"align" = 3, // 2^3 = @sizeOf(u64) | 4272 | .@"align" = 3, // 2^3 = @sizeOf(u64) |
| 4237 | .flags = macho.S_ZEROFILL, | 4273 | .flags = macho.S_ZEROFILL, |
| 4238 | }); | 4274 | }); |