| ... | @@ -1923,12 +1923,13 @@ fn getSegmentProt(segname: []const u8) macho.vm_prot_t { | ... | @@ -1923,12 +1923,13 @@ fn getSegmentProt(segname: []const u8) macho.vm_prot_t { |
| 1923 | return macho.PROT.READ | macho.PROT.WRITE; | 1923 | return macho.PROT.READ | macho.PROT.WRITE; |
| 1924 | } | 1924 | } |
| 1925 | | 1925 | |
| 1926 | fn getSegmentRank(segname: []const u8) u4 { | 1926 | fn getSegmentRank(segname: []const u8) u8 { |
| 1927 | if (mem.eql(u8, segname, "__PAGEZERO")) return 0x0; | 1927 | if (mem.eql(u8, segname, "__PAGEZERO")) return 0x0; |
| 1928 | if (mem.eql(u8, segname, "__TEXT")) return 0x1; | 1928 | if (mem.eql(u8, segname, "__TEXT")) return 0x1; |
| 1929 | if (mem.eql(u8, segname, "__DATA_CONST")) return 0x2; | 1929 | if (mem.eql(u8, segname, "__DATA_CONST")) return 0x2; |
| 1930 | if (mem.eql(u8, segname, "__DATA")) return 0x3; | 1930 | if (mem.eql(u8, segname, "__DATA")) return 0x3; |
| 1931 | if (mem.eql(u8, segname, "__LINKEDIT")) return 0x5; | 1931 | if (mem.indexOf(u8, segname, "ZIG")) |_| return 0xe; |
| | 1932 | if (mem.eql(u8, segname, "__LINKEDIT")) return 0xf; |
| 1932 | return 0x4; | 1933 | return 0x4; |
| 1933 | } | 1934 | } |
| 1934 | | 1935 | |
| ... | @@ -2282,28 +2283,55 @@ fn allocateSections(self: *MachO) !void { | ... | @@ -2282,28 +2283,55 @@ fn allocateSections(self: *MachO) !void { |
| 2282 | | 2283 | |
| 2283 | var next_seg_id: u8 = if (self.pagezero_seg_index) |index| index + 1 else 0; | 2284 | var next_seg_id: u8 = if (self.pagezero_seg_index) |index| index + 1 else 0; |
| 2284 | for (slice.items(.header), slice.items(.segment_id)) |*header, seg_id| { | 2285 | for (slice.items(.header), slice.items(.segment_id)) |*header, seg_id| { |
| 2285 | if (mem.indexOf(u8, header.segName(), "ZIG")) |_| { | 2286 | defer next_seg_id = seg_id; |
| 2286 | vmaddr = header.addr + header.size; | | |
| 2287 | } else { | | |
| 2288 | if (seg_id != next_seg_id) { | | |
| 2289 | vmaddr = mem.alignForward(u64, vmaddr, page_size); | | |
| 2290 | fileoff = mem.alignForward(u32, fileoff, page_size); | | |
| 2291 | } | | |
| 2292 | | 2287 | |
| 2293 | const alignment = try math.powi(u32, 2, header.@"align"); | 2288 | if (mem.indexOf(u8, header.segName(), "ZIG")) |_| continue; |
| | 2289 | if (seg_id != next_seg_id) { |
| | 2290 | vmaddr = mem.alignForward(u64, vmaddr, page_size); |
| | 2291 | fileoff = mem.alignForward(u32, fileoff, page_size); |
| | 2292 | } |
| 2294 | | 2293 | |
| 2295 | vmaddr = mem.alignForward(u64, vmaddr, alignment); | 2294 | const alignment = try math.powi(u32, 2, header.@"align"); |
| 2296 | header.addr = vmaddr; | | |
| 2297 | vmaddr += header.size; | | |
| 2298 | | 2295 | |
| 2299 | if (!header.isZerofill()) { | 2296 | vmaddr = mem.alignForward(u64, vmaddr, alignment); |
| 2300 | fileoff = mem.alignForward(u32, fileoff, alignment); | 2297 | header.addr = vmaddr; |
| 2301 | header.offset = fileoff; | 2298 | vmaddr += header.size; |
| 2302 | fileoff += @intCast(header.size); | 2299 | |
| 2303 | } | 2300 | if (!header.isZerofill()) { |
| | 2301 | fileoff = mem.alignForward(u32, fileoff, alignment); |
| | 2302 | header.offset = fileoff; |
| | 2303 | fileoff += @intCast(header.size); |
| 2304 | } | 2304 | } |
| | 2305 | } |
| 2305 | | 2306 | |
| 2306 | next_seg_id = seg_id; | 2307 | // TODO iterate over sections again, but consider only zig sections |
| | 2308 | // and move them if they are allocated in file below page-aligned fileoff |
| | 2309 | fileoff = mem.alignForward(u32, fileoff, page_size); |
| | 2310 | for (slice.items(.header), slice.items(.segment_id)) |*header, seg_id| { |
| | 2311 | if (mem.indexOf(u8, header.segName(), "ZIG") == null) continue; |
| | 2312 | if (header.isZerofill()) continue; |
| | 2313 | if (header.offset < fileoff) { |
| | 2314 | const existing_size = header.size; |
| | 2315 | header.size = 0; |
| | 2316 | |
| | 2317 | // Must move the entire section. |
| | 2318 | const new_offset = self.findFreeSpace(existing_size, page_size); |
| | 2319 | |
| | 2320 | log.debug("new '{s},{s}' file offset 0x{x} to 0x{x}", .{ |
| | 2321 | header.segName(), |
| | 2322 | header.sectName(), |
| | 2323 | new_offset, |
| | 2324 | new_offset + existing_size, |
| | 2325 | }); |
| | 2326 | |
| | 2327 | const amt = try self.base.file.?.copyRangeAll(header.offset, self.base.file.?, new_offset, existing_size); |
| | 2328 | // TODO figure out what to about this error condition - how to communicate it up. |
| | 2329 | if (amt != existing_size) return error.InputOutput; |
| | 2330 | |
| | 2331 | header.offset = @intCast(new_offset); |
| | 2332 | header.size = existing_size; |
| | 2333 | self.segments.items[seg_id].fileoff = new_offset; |
| | 2334 | } |
| 2307 | } | 2335 | } |
| 2308 | } | 2336 | } |
| 2309 | | 2337 | |