| ... | ... | @@ -511,15 +511,14 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 511 | 511 | |
| 512 | 512 | try self.createMhExecuteHeaderSymbol(); |
| 513 | 513 | try self.resolveDyldStubBinder(); |
| 514 | try self.createDyldPrivateAtom(); |
| 515 | try self.createStubHelperPreambleAtom(); |
| 514 | 516 | try self.resolveSymbolsInDylibs(); |
| 515 | 517 | |
| 516 | 518 | if (self.unresolved.count() > 0) { |
| 517 | 519 | return error.UndefinedSymbolReference; |
| 518 | 520 | } |
| 519 | 521 | |
| 520 | | try self.createDyldPrivateAtom(); |
| 521 | | try self.createStubHelperPreambleAtom(); |
| 522 | | |
| 523 | 522 | try self.allocateSpecialSymbols(); |
| 524 | 523 | |
| 525 | 524 | if (build_options.enable_logging) { |
| ... | ... | @@ -589,7 +588,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 589 | 588 | } else null; |
| 590 | 589 | |
| 591 | 590 | var headers_buf = std.ArrayList(u8).init(arena); |
| 592 | | try self.writeSegmentHeaders(0, self.segments.items.len, &ncmds, headers_buf.writer()); |
| 591 | try self.writeSegmentHeaders(&ncmds, headers_buf.writer()); |
| 593 | 592 | |
| 594 | 593 | try self.base.file.?.pwriteAll(headers_buf.items, @sizeOf(macho.mach_header_64)); |
| 595 | 594 | try self.base.file.?.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64) + headers_buf.items.len); |
| ... | ... | @@ -1203,7 +1202,7 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) |
| 1203 | 1202 | } else null; |
| 1204 | 1203 | |
| 1205 | 1204 | var headers_buf = std.ArrayList(u8).init(arena); |
| 1206 | | try self.writeSegmentHeaders(0, self.segments.items.len, &ncmds, headers_buf.writer()); |
| 1205 | try self.writeSegmentHeaders(&ncmds, headers_buf.writer()); |
| 1207 | 1206 | |
| 1208 | 1207 | try self.base.file.?.pwriteAll(headers_buf.items, @sizeOf(macho.mach_header_64)); |
| 1209 | 1208 | try self.base.file.?.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64) + headers_buf.items.len); |
| ... | ... | @@ -3863,7 +3862,9 @@ pub fn deleteExport(self: *MachO, exp: Export) void { |
| 3863 | 3862 | fn freeUnnamedConsts(self: *MachO, decl_index: Module.Decl.Index) void { |
| 3864 | 3863 | const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return; |
| 3865 | 3864 | for (unnamed_consts.items) |atom| { |
| 3866 | | const sect_id = atom.getSymbol(self).n_sect; |
| 3865 | // TODO |
| 3866 | // const sect_id = atom.getSymbol(self).n_sect; |
| 3867 | const sect_id = self.getSectionByName("__TEXT", "__const").?; |
| 3867 | 3868 | self.freeAtom(atom, sect_id, true); |
| 3868 | 3869 | self.locals_free_list.append(self.base.allocator, atom.sym_index) catch {}; |
| 3869 | 3870 | self.locals.items[atom.sym_index].n_type = 0; |
| ... | ... | @@ -4402,8 +4403,6 @@ fn initSection( |
| 4402 | 4403 | const index = try self.insertSection(segment_id, .{ |
| 4403 | 4404 | .sectname = makeStaticString(sectname), |
| 4404 | 4405 | .segname = seg.segname, |
| 4405 | | .size = if (self.mode == .incremental) @intCast(u32, size) else 0, |
| 4406 | | .@"align" = alignment, |
| 4407 | 4406 | .flags = opts.flags, |
| 4408 | 4407 | .reserved1 = opts.reserved1, |
| 4409 | 4408 | .reserved2 = opts.reserved2, |
| ... | ... | @@ -4413,6 +4412,9 @@ fn initSection( |
| 4413 | 4412 | |
| 4414 | 4413 | if (self.mode == .incremental) { |
| 4415 | 4414 | const header = &self.sections.items(.header)[index]; |
| 4415 | header.size = size; |
| 4416 | header.@"align" = alignment; |
| 4417 | |
| 4416 | 4418 | const prev_end_off = if (index > 0) blk: { |
| 4417 | 4419 | const prev_section = self.sections.get(index - 1); |
| 4418 | 4420 | if (prev_section.segment_index == segment_id) { |
| ... | ... | @@ -4421,15 +4423,25 @@ fn initSection( |
| 4421 | 4423 | } else break :blk seg.fileoff; |
| 4422 | 4424 | } else 0; |
| 4423 | 4425 | const alignment_pow_2 = try math.powi(u32, 2, alignment); |
| 4424 | | const padding: u64 = if (index == 0) try self.calcMinHeaderPad() else 0; |
| 4426 | // TODO better prealloc for __text section |
| 4427 | // const padding: u64 = if (index == 0) try self.calcMinHeaderPad() else 0; |
| 4428 | const padding: u64 = if (index == 0) 0x1000 else 0; |
| 4425 | 4429 | const off = mem.alignForwardGeneric(u64, padding + prev_end_off, alignment_pow_2); |
| 4426 | | log.debug("allocating {s},{s} section at 0x{x}", .{ header.segName(), header.sectName(), off }); |
| 4427 | | |
| 4428 | | header.addr = seg.vmaddr + off - seg.fileoff; |
| 4429 | 4430 | |
| 4430 | 4431 | if (!header.isZerofill()) { |
| 4431 | 4432 | header.offset = @intCast(u32, off); |
| 4432 | 4433 | } |
| 4434 | header.addr = seg.vmaddr + off - seg.fileoff; |
| 4435 | |
| 4436 | // TODO this will break if we are inserting section that is not the last section |
| 4437 | // in a segment. |
| 4438 | const max_size = self.allocatedSize(segment_id, off); |
| 4439 | |
| 4440 | if (size > max_size) { |
| 4441 | try self.growSection(index, @intCast(u32, size)); |
| 4442 | } |
| 4443 | |
| 4444 | log.debug("allocating {s},{s} section at 0x{x}", .{ header.segName(), header.sectName(), off }); |
| 4433 | 4445 | |
| 4434 | 4446 | self.updateSectionOrdinals(index + 1); |
| 4435 | 4447 | } |
| ... | ... | @@ -4494,7 +4506,7 @@ fn updateSectionOrdinals(self: *MachO, start: u8) void { |
| 4494 | 4506 | |
| 4495 | 4507 | const slice = self.sections.slice(); |
| 4496 | 4508 | for (slice.items(.last_atom)[start..]) |last_atom| { |
| 4497 | | var atom = last_atom.?; |
| 4509 | var atom = last_atom orelse continue; |
| 4498 | 4510 | |
| 4499 | 4511 | while (true) { |
| 4500 | 4512 | const sym = atom.getSymbolPtr(self); |
| ... | ... | @@ -4536,17 +4548,6 @@ fn shiftLocalsByOffset(self: *MachO, sect_id: u8, offset: i64) !void { |
| 4536 | 4548 | } |
| 4537 | 4549 | } |
| 4538 | 4550 | |
| 4539 | | fn findFreeSpace(self: MachO, segment_id: u8, alignment: u64, start: ?u64) u64 { |
| 4540 | | const seg = self.segments.items[segment_id]; |
| 4541 | | const indexes = self.getSectionIndexes(segment_id); |
| 4542 | | if (indexes.end - indexes.start == 0) { |
| 4543 | | return if (start) |v| v else seg.fileoff; |
| 4544 | | } |
| 4545 | | const last_sect = self.sections.items(.header)[indexes.end - 1]; |
| 4546 | | const final_off = last_sect.offset + padToIdeal(last_sect.size); |
| 4547 | | return mem.alignForwardGeneric(u64, final_off, alignment); |
| 4548 | | } |
| 4549 | | |
| 4550 | 4551 | fn growSegment(self: *MachO, segment_index: u8, new_size: u64) !void { |
| 4551 | 4552 | const segment = &self.segments.items[segment_index]; |
| 4552 | 4553 | const new_segment_size = mem.alignForwardGeneric(u64, new_size, self.page_size); |
| ... | ... | @@ -4885,14 +4886,14 @@ fn getSegmentAllocBase(self: MachO, indices: []const ?u8) struct { vmaddr: u64, |
| 4885 | 4886 | return .{ .vmaddr = 0, .fileoff = 0 }; |
| 4886 | 4887 | } |
| 4887 | 4888 | |
| 4888 | | pub fn writeSegmentHeaders(self: *MachO, start: usize, end: usize, ncmds: *u32, writer: anytype) !void { |
| 4889 | | for (self.segments.items[start..end]) |seg, i| { |
| 4889 | fn writeSegmentHeaders(self: *MachO, ncmds: *u32, writer: anytype) !void { |
| 4890 | for (self.segments.items) |seg, i| { |
| 4890 | 4891 | if (seg.nsects == 0 and |
| 4891 | 4892 | (mem.eql(u8, seg.segName(), "__DATA_CONST") or |
| 4892 | 4893 | mem.eql(u8, seg.segName(), "__DATA"))) continue; |
| 4893 | 4894 | try writer.writeStruct(seg); |
| 4894 | 4895 | |
| 4895 | | const indexes = self.getSectionIndexes(@intCast(u8, start + i)); |
| 4896 | const indexes = self.getSectionIndexes(@intCast(u8, i)); |
| 4896 | 4897 | for (self.sections.items(.header)[indexes.start..indexes.end]) |header| { |
| 4897 | 4898 | try writer.writeStruct(header); |
| 4898 | 4899 | } |
| ... | ... | @@ -5718,7 +5719,7 @@ pub fn getSectionByName(self: MachO, segname: []const u8, sectname: []const u8) |
| 5718 | 5719 | } else return null; |
| 5719 | 5720 | } |
| 5720 | 5721 | |
| 5721 | | fn getSectionIndexes(self: MachO, segment_index: u8) struct { start: u8, end: u8 } { |
| 5722 | pub fn getSectionIndexes(self: MachO, segment_index: u8) struct { start: u8, end: u8 } { |
| 5722 | 5723 | var start: u8 = 0; |
| 5723 | 5724 | const nsects = for (self.segments.items) |seg, i| { |
| 5724 | 5725 | if (i == segment_index) break @intCast(u8, seg.nsects); |