| ... | ... | @@ -1923,12 +1923,13 @@ fn getSegmentProt(segname: []const u8) macho.vm_prot_t { |
| 1923 | 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 | 1927 | if (mem.eql(u8, segname, "__PAGEZERO")) return 0x0; |
| 1928 | 1928 | if (mem.eql(u8, segname, "__TEXT")) return 0x1; |
| 1929 | 1929 | if (mem.eql(u8, segname, "__DATA_CONST")) return 0x2; |
| 1930 | 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 | 1933 | return 0x4; |
| 1933 | 1934 | } |
| 1934 | 1935 | |
| ... | ... | @@ -2282,28 +2283,55 @@ fn allocateSections(self: *MachO) !void { |
| 2282 | 2283 | |
| 2283 | 2284 | var next_seg_id: u8 = if (self.pagezero_seg_index) |index| index + 1 else 0; |
| 2284 | 2285 | for (slice.items(.header), slice.items(.segment_id)) |*header, seg_id| { |
| 2285 | | if (mem.indexOf(u8, header.segName(), "ZIG")) |_| { |
| 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 | | } |
| 2286 | defer next_seg_id = seg_id; |
| 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); |
| 2296 | | header.addr = vmaddr; |
| 2297 | | vmaddr += header.size; |
| 2294 | const alignment = try math.powi(u32, 2, header.@"align"); |
| 2298 | 2295 | |
| 2299 | | if (!header.isZerofill()) { |
| 2300 | | fileoff = mem.alignForward(u32, fileoff, alignment); |
| 2301 | | header.offset = fileoff; |
| 2302 | | fileoff += @intCast(header.size); |
| 2303 | | } |
| 2296 | vmaddr = mem.alignForward(u64, vmaddr, alignment); |
| 2297 | header.addr = vmaddr; |
| 2298 | vmaddr += header.size; |
| 2299 | |
| 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 | |