| ... | @@ -511,15 +511,14 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No | ... | @@ -511,15 +511,14 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 511 | | 511 | |
| 512 | try self.createMhExecuteHeaderSymbol(); | 512 | try self.createMhExecuteHeaderSymbol(); |
| 513 | try self.resolveDyldStubBinder(); | 513 | try self.resolveDyldStubBinder(); |
| | 514 | try self.createDyldPrivateAtom(); |
| | 515 | try self.createStubHelperPreambleAtom(); |
| 514 | try self.resolveSymbolsInDylibs(); | 516 | try self.resolveSymbolsInDylibs(); |
| 515 | | 517 | |
| 516 | if (self.unresolved.count() > 0) { | 518 | if (self.unresolved.count() > 0) { |
| 517 | return error.UndefinedSymbolReference; | 519 | return error.UndefinedSymbolReference; |
| 518 | } | 520 | } |
| 519 | | 521 | |
| 520 | try self.createDyldPrivateAtom(); | | |
| 521 | try self.createStubHelperPreambleAtom(); | | |
| 522 | | | |
| 523 | try self.allocateSpecialSymbols(); | 522 | try self.allocateSpecialSymbols(); |
| 524 | | 523 | |
| 525 | if (build_options.enable_logging) { | 524 | if (build_options.enable_logging) { |
| ... | @@ -589,7 +588,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No | ... | @@ -589,7 +588,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 589 | } else null; | 588 | } else null; |
| 590 | | 589 | |
| 591 | var headers_buf = std.ArrayList(u8).init(arena); | 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 | try self.base.file.?.pwriteAll(headers_buf.items, @sizeOf(macho.mach_header_64)); | 593 | try self.base.file.?.pwriteAll(headers_buf.items, @sizeOf(macho.mach_header_64)); |
| 595 | try self.base.file.?.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64) + headers_buf.items.len); | 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,7 +1202,7 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) |
| 1203 | } else null; | 1202 | } else null; |
| 1204 | | 1203 | |
| 1205 | var headers_buf = std.ArrayList(u8).init(arena); | 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 | try self.base.file.?.pwriteAll(headers_buf.items, @sizeOf(macho.mach_header_64)); | 1207 | try self.base.file.?.pwriteAll(headers_buf.items, @sizeOf(macho.mach_header_64)); |
| 1209 | try self.base.file.?.pwriteAll(lc_buffer.items, @sizeOf(macho.mach_header_64) + headers_buf.items.len); | 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,7 +3862,9 @@ pub fn deleteExport(self: *MachO, exp: Export) void { |
| 3863 | fn freeUnnamedConsts(self: *MachO, decl_index: Module.Decl.Index) void { | 3862 | fn freeUnnamedConsts(self: *MachO, decl_index: Module.Decl.Index) void { |
| 3864 | const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return; | 3863 | const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return; |
| 3865 | for (unnamed_consts.items) |atom| { | 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 | self.freeAtom(atom, sect_id, true); | 3868 | self.freeAtom(atom, sect_id, true); |
| 3868 | self.locals_free_list.append(self.base.allocator, atom.sym_index) catch {}; | 3869 | self.locals_free_list.append(self.base.allocator, atom.sym_index) catch {}; |
| 3869 | self.locals.items[atom.sym_index].n_type = 0; | 3870 | self.locals.items[atom.sym_index].n_type = 0; |
| ... | @@ -4402,8 +4403,6 @@ fn initSection( | ... | @@ -4402,8 +4403,6 @@ fn initSection( |
| 4402 | const index = try self.insertSection(segment_id, .{ | 4403 | const index = try self.insertSection(segment_id, .{ |
| 4403 | .sectname = makeStaticString(sectname), | 4404 | .sectname = makeStaticString(sectname), |
| 4404 | .segname = seg.segname, | 4405 | .segname = seg.segname, |
| 4405 | .size = if (self.mode == .incremental) @intCast(u32, size) else 0, | | |
| 4406 | .@"align" = alignment, | | |
| 4407 | .flags = opts.flags, | 4406 | .flags = opts.flags, |
| 4408 | .reserved1 = opts.reserved1, | 4407 | .reserved1 = opts.reserved1, |
| 4409 | .reserved2 = opts.reserved2, | 4408 | .reserved2 = opts.reserved2, |
| ... | @@ -4413,6 +4412,9 @@ fn initSection( | ... | @@ -4413,6 +4412,9 @@ fn initSection( |
| 4413 | | 4412 | |
| 4414 | if (self.mode == .incremental) { | 4413 | if (self.mode == .incremental) { |
| 4415 | const header = &self.sections.items(.header)[index]; | 4414 | const header = &self.sections.items(.header)[index]; |
| | 4415 | header.size = size; |
| | 4416 | header.@"align" = alignment; |
| | 4417 | |
| 4416 | const prev_end_off = if (index > 0) blk: { | 4418 | const prev_end_off = if (index > 0) blk: { |
| 4417 | const prev_section = self.sections.get(index - 1); | 4419 | const prev_section = self.sections.get(index - 1); |
| 4418 | if (prev_section.segment_index == segment_id) { | 4420 | if (prev_section.segment_index == segment_id) { |
| ... | @@ -4421,15 +4423,25 @@ fn initSection( | ... | @@ -4421,15 +4423,25 @@ fn initSection( |
| 4421 | } else break :blk seg.fileoff; | 4423 | } else break :blk seg.fileoff; |
| 4422 | } else 0; | 4424 | } else 0; |
| 4423 | const alignment_pow_2 = try math.powi(u32, 2, alignment); | 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 | const off = mem.alignForwardGeneric(u64, padding + prev_end_off, alignment_pow_2); | 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 | if (!header.isZerofill()) { | 4431 | if (!header.isZerofill()) { |
| 4431 | header.offset = @intCast(u32, off); | 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 | self.updateSectionOrdinals(index + 1); | 4446 | self.updateSectionOrdinals(index + 1); |
| 4435 | } | 4447 | } |
| ... | @@ -4494,7 +4506,7 @@ fn updateSectionOrdinals(self: *MachO, start: u8) void { | ... | @@ -4494,7 +4506,7 @@ fn updateSectionOrdinals(self: *MachO, start: u8) void { |
| 4494 | | 4506 | |
| 4495 | const slice = self.sections.slice(); | 4507 | const slice = self.sections.slice(); |
| 4496 | for (slice.items(.last_atom)[start..]) |last_atom| { | 4508 | for (slice.items(.last_atom)[start..]) |last_atom| { |
| 4497 | var atom = last_atom.?; | 4509 | var atom = last_atom orelse continue; |
| 4498 | | 4510 | |
| 4499 | while (true) { | 4511 | while (true) { |
| 4500 | const sym = atom.getSymbolPtr(self); | 4512 | const sym = atom.getSymbolPtr(self); |
| ... | @@ -4536,17 +4548,6 @@ fn shiftLocalsByOffset(self: *MachO, sect_id: u8, offset: i64) !void { | ... | @@ -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 | fn growSegment(self: *MachO, segment_index: u8, new_size: u64) !void { | 4551 | fn growSegment(self: *MachO, segment_index: u8, new_size: u64) !void { |
| 4551 | const segment = &self.segments.items[segment_index]; | 4552 | const segment = &self.segments.items[segment_index]; |
| 4552 | const new_segment_size = mem.alignForwardGeneric(u64, new_size, self.page_size); | 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,14 +4886,14 @@ fn getSegmentAllocBase(self: MachO, indices: []const ?u8) struct { vmaddr: u64, |
| 4885 | return .{ .vmaddr = 0, .fileoff = 0 }; | 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 | fn writeSegmentHeaders(self: *MachO, ncmds: *u32, writer: anytype) !void { |
| 4889 | for (self.segments.items[start..end]) |seg, i| { | 4890 | for (self.segments.items) |seg, i| { |
| 4890 | if (seg.nsects == 0 and | 4891 | if (seg.nsects == 0 and |
| 4891 | (mem.eql(u8, seg.segName(), "__DATA_CONST") or | 4892 | (mem.eql(u8, seg.segName(), "__DATA_CONST") or |
| 4892 | mem.eql(u8, seg.segName(), "__DATA"))) continue; | 4893 | mem.eql(u8, seg.segName(), "__DATA"))) continue; |
| 4893 | try writer.writeStruct(seg); | 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 | for (self.sections.items(.header)[indexes.start..indexes.end]) |header| { | 4897 | for (self.sections.items(.header)[indexes.start..indexes.end]) |header| { |
| 4897 | try writer.writeStruct(header); | 4898 | try writer.writeStruct(header); |
| 4898 | } | 4899 | } |
| ... | @@ -5718,7 +5719,7 @@ pub fn getSectionByName(self: MachO, segname: []const u8, sectname: []const u8) | ... | @@ -5718,7 +5719,7 @@ pub fn getSectionByName(self: MachO, segname: []const u8, sectname: []const u8) |
| 5718 | } else return null; | 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 | var start: u8 = 0; | 5723 | var start: u8 = 0; |
| 5723 | const nsects = for (self.segments.items) |seg, i| { | 5724 | const nsects = for (self.segments.items) |seg, i| { |
| 5724 | if (i == segment_index) break @intCast(u8, seg.nsects); | 5725 | if (i == segment_index) break @intCast(u8, seg.nsects); |