authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-19 17:09:07+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:34:41+01:00
log1bdcb23b137b65696d7cad4adcc85697d359995a
tree229e19af5080c69ed2184c0bcf0dc187833178a7
parent0143dd8fdcf39f308a1a68098bb54f78068ac1e6

macho: allocate sections and segments that need it


2 files changed, 56 insertions(+), 30 deletions(-)

src/link/MachO.zig+53-30
...@@ -40,6 +40,7 @@ codesig_cmd: macho.linkedit_data_command = .{ .cmd = .CODE_SIGNATURE },...@@ -40,6 +40,7 @@ codesig_cmd: macho.linkedit_data_command = .{ .cmd = .CODE_SIGNATURE },
40pagezero_seg_index: ?u8 = null,40pagezero_seg_index: ?u8 = null,
41text_seg_index: ?u8 = null,41text_seg_index: ?u8 = null,
42linkedit_seg_index: ?u8 = null,42linkedit_seg_index: ?u8 = null,
43text_sect_index: ?u8 = null,
43data_sect_index: ?u8 = null,44data_sect_index: ?u8 = null,
44got_sect_index: ?u8 = null,45got_sect_index: ?u8 = null,
45stubs_sect_index: ?u8 = null,46stubs_sect_index: ?u8 = null,
...@@ -1757,6 +1758,17 @@ fn initOutputSections(self: *MachO) !void {...@@ -1757,6 +1758,17 @@ fn initOutputSections(self: *MachO) !void {
1757 atom.out_n_sect = try Atom.initOutputSection(atom.getInputSection(self), self);1758 atom.out_n_sect = try Atom.initOutputSection(atom.getInputSection(self), self);
1758 }1759 }
1759 }1760 }
1761 if (self.text_sect_index == null) {
1762 self.text_sect_index = try self.addSection("__TEXT", "__text", .{
1763 .alignment = switch (self.getTarget().cpu.arch) {
1764 .x86_64 => 0,
1765 .aarch64 => 2,
1766 else => unreachable,
1767 },
1768 .flags = macho.S_SYMBOL_STUBS |
1769 macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
1770 });
1771 }
1760 if (self.data_sect_index == null) {1772 if (self.data_sect_index == null) {
1761 self.data_sect_index = try self.addSection("__DATA", "__data", .{});1773 self.data_sect_index = try self.addSection("__DATA", "__data", .{});
1762 }1774 }
...@@ -2227,21 +2239,25 @@ fn allocateSections(self: *MachO) !void {...@@ -2227,21 +2239,25 @@ fn allocateSections(self: *MachO) !void {
22272239
2228 var next_seg_id: u8 = if (self.pagezero_seg_index) |index| index + 1 else 0;2240 var next_seg_id: u8 = if (self.pagezero_seg_index) |index| index + 1 else 0;
2229 for (slice.items(.header), slice.items(.segment_id)) |*header, seg_id| {2241 for (slice.items(.header), slice.items(.segment_id)) |*header, seg_id| {
2230 if (seg_id != next_seg_id) {2242 if (mem.indexOf(u8, header.segName(), "ZIG")) |_| {
2231 vmaddr = mem.alignForward(u64, vmaddr, page_size);2243 vmaddr = header.addr + header.size;
2232 fileoff = mem.alignForward(u32, fileoff, page_size);2244 } else {
2233 }2245 if (seg_id != next_seg_id) {
2246 vmaddr = mem.alignForward(u64, vmaddr, page_size);
2247 fileoff = mem.alignForward(u32, fileoff, page_size);
2248 }
22342249
2235 const alignment = try math.powi(u32, 2, header.@"align");2250 const alignment = try math.powi(u32, 2, header.@"align");
22362251
2237 vmaddr = mem.alignForward(u64, vmaddr, alignment);2252 vmaddr = mem.alignForward(u64, vmaddr, alignment);
2238 header.addr = vmaddr;2253 header.addr = vmaddr;
2239 vmaddr += header.size;2254 vmaddr += header.size;
22402255
2241 if (!header.isZerofill()) {2256 if (!header.isZerofill()) {
2242 fileoff = mem.alignForward(u32, fileoff, alignment);2257 fileoff = mem.alignForward(u32, fileoff, alignment);
2243 header.offset = fileoff;2258 header.offset = fileoff;
2244 fileoff += @intCast(header.size);2259 fileoff += @intCast(header.size);
2260 }
2245 }2261 }
22462262
2247 next_seg_id = seg_id;2263 next_seg_id = seg_id;
...@@ -2260,28 +2276,35 @@ fn allocateSegments(self: *MachO) void {...@@ -2260,28 +2276,35 @@ fn allocateSegments(self: *MachO) void {
2260 const slice = self.sections.slice();2276 const slice = self.sections.slice();
2261 var next_sect_id: u8 = 0;2277 var next_sect_id: u8 = 0;
2262 for (self.segments.items[index..], index..) |*seg, seg_id| {2278 for (self.segments.items[index..], index..) |*seg, seg_id| {
2263 seg.vmaddr = vmaddr;2279 if (mem.indexOf(u8, seg.segName(), "ZIG")) |_| {
2264 seg.fileoff = fileoff;2280 vmaddr = mem.alignForward(u64, seg.vmaddr + seg.vmsize, page_size);
22652281 if (mem.eql(u8, seg.segName(), "__BSS_ZIG")) {
2266 for (2282 fileoff = mem.alignForward(u64, seg.fileoff + seg.filesize, page_size);
2267 slice.items(.header)[next_sect_id..],
2268 slice.items(.segment_id)[next_sect_id..],
2269 ) |header, sid| {
2270 if (seg_id != sid) break;
2271
2272 vmaddr = header.addr + header.size;
2273 if (!header.isZerofill()) {
2274 fileoff = header.offset + header.size;
2275 }2283 }
2284 } else {
2285 seg.vmaddr = vmaddr;
2286 seg.fileoff = fileoff;
2287
2288 for (
2289 slice.items(.header)[next_sect_id..],
2290 slice.items(.segment_id)[next_sect_id..],
2291 ) |header, sid| {
2292 if (seg_id != sid) break;
2293
2294 vmaddr = header.addr + header.size;
2295 if (!header.isZerofill()) {
2296 fileoff = header.offset + header.size;
2297 }
22762298
2277 next_sect_id += 1;2299 next_sect_id += 1;
2278 }2300 }
22792301
2280 vmaddr = mem.alignForward(u64, vmaddr, page_size);2302 vmaddr = mem.alignForward(u64, vmaddr, page_size);
2281 fileoff = mem.alignForward(u64, fileoff, page_size);2303 fileoff = mem.alignForward(u64, fileoff, page_size);
22822304
2283 seg.vmsize = vmaddr - seg.vmaddr;2305 seg.vmsize = vmaddr - seg.vmaddr;
2284 seg.filesize = fileoff - seg.fileoff;2306 seg.filesize = fileoff - seg.fileoff;
2307 }
2285 }2308 }
2286}2309}
22872310
src/link/MachO/Atom.zig+3
...@@ -170,6 +170,9 @@ pub fn initOutputSection(sect: macho.section_64, macho_file: *MachO) !u8 {...@@ -170,6 +170,9 @@ pub fn initOutputSection(sect: macho.section_64, macho_file: *MachO) !u8 {
170 sectname,170 sectname,
171 .{ .flags = flags },171 .{ .flags = flags },
172 );172 );
173 if (mem.eql(u8, segname, "__TEXT") and mem.eql(u8, sectname, "__text")) {
174 macho_file.text_sect_index = osec;
175 }
173 if (mem.eql(u8, segname, "__DATA") and mem.eql(u8, sectname, "__data")) {176 if (mem.eql(u8, segname, "__DATA") and mem.eql(u8, sectname, "__data")) {
174 macho_file.data_sect_index = osec;177 macho_file.data_sect_index = osec;
175 }178 }