| ... | ... | @@ -133,6 +133,9 @@ objc_selrefs_section_index: ?u16 = null, |
| 133 | 133 | objc_classrefs_section_index: ?u16 = null, |
| 134 | 134 | objc_data_section_index: ?u16 = null, |
| 135 | 135 | |
| 136 | bss_file_offset: ?u64 = null, |
| 137 | tlv_bss_file_offset: ?u64 = null, |
| 138 | |
| 136 | 139 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 137 | 140 | globals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 138 | 141 | undefs: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| ... | ... | @@ -1714,11 +1717,30 @@ fn allocateSegment(self: *MachO, index: u16, offset: u64) !void { |
| 1714 | 1717 | |
| 1715 | 1718 | // Allocate the sections according to their alignment at the beginning of the segment. |
| 1716 | 1719 | var start: u64 = offset; |
| 1717 | | for (seg.sections.items) |*sect| { |
| 1720 | for (seg.sections.items) |*sect, sect_id| { |
| 1718 | 1721 | const alignment = try math.powi(u32, 2, sect.@"align"); |
| 1719 | 1722 | const start_aligned = mem.alignForwardGeneric(u64, start, alignment); |
| 1720 | 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 | 1744 | sect.addr = seg.inner.vmaddr + start_aligned; |
| 1723 | 1745 | start = end_aligned; |
| 1724 | 1746 | } |
| ... | ... | @@ -1821,6 +1843,18 @@ fn writeTextBlocks(self: *MachO) !void { |
| 1821 | 1843 | var code = try self.base.allocator.alloc(u8, sect.size); |
| 1822 | 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 | 1858 | if (sect_type == macho.S_ZEROFILL or sect_type == macho.S_THREAD_LOCAL_ZEROFILL) { |
| 1825 | 1859 | mem.set(u8, code, 0); |
| 1826 | 1860 | } else { |
| ... | ... | @@ -1856,7 +1890,7 @@ fn writeTextBlocks(self: *MachO) !void { |
| 1856 | 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 | 1959 | const seg = self.load_commands.items[match.seg].Segment; |
| 1926 | 1960 | const sect = seg.sections.items[match.sect]; |
| 1927 | 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 | 1974 | try atom.resolveRelocs(self); |
| 1930 | 1975 | log.debug("writing atom for symbol {s} at file offset 0x{x}", .{ self.getString(sym.n_strx), file_offset }); |
| 1931 | 1976 | try self.base.file.?.pwriteAll(atom.code.items, file_offset); |
| ... | ... | @@ -2873,19 +2918,6 @@ fn addLoadDylibLCs(self: *MachO) !void { |
| 2873 | 2918 | |
| 2874 | 2919 | fn flushZld(self: *MachO) !void { |
| 2875 | 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 | 2921 | try self.setEntryPoint(); |
| 2890 | 2922 | try self.writeRebaseInfoTableZld(); |
| 2891 | 2923 | try self.writeBindInfoTableZld(); |
| ... | ... | @@ -4203,10 +4235,12 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4203 | 4235 | |
| 4204 | 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 | 4241 | try data_segment.addSection(self.base.allocator, "__thread_bss", .{ |
| 4207 | 4242 | .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff, |
| 4208 | 4243 | .size = needed_size, |
| 4209 | | .offset = @intCast(u32, off), |
| 4210 | 4244 | .@"align" = 3, // 2^3 = @sizeOf(u64) |
| 4211 | 4245 | .flags = macho.S_THREAD_LOCAL_ZEROFILL, |
| 4212 | 4246 | }); |
| ... | ... | @@ -4229,10 +4263,12 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4229 | 4263 | |
| 4230 | 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 | 4269 | try data_segment.addSection(self.base.allocator, "__bss", .{ |
| 4233 | 4270 | .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff, |
| 4234 | 4271 | .size = 0, |
| 4235 | | .offset = @intCast(u32, off), |
| 4236 | 4272 | .@"align" = 3, // 2^3 = @sizeOf(u64) |
| 4237 | 4273 | .flags = macho.S_ZEROFILL, |
| 4238 | 4274 | }); |