authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-01-19 08:58:51+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-01-19 08:58:51+01:00
logd5b0a963d1bf3399e3d8b63b03ea61f7d771adbd
tree4ae07939bc49274fb769cf91416ee002c8b66ebf
parent30a824cb9e148adb0799a0a81721160c0d474b50
parenta2ebe3c82c89084a3672593cb34f259fca5a5e30
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #7818 from kubkon/macho-more-cleanup

Macho more cleanup

3 files changed, 59 insertions(+), 39 deletions(-)

src/Module.zig+4-2
......@@ -1617,8 +1617,10 @@ pub fn analyzeContainer(self: *Module, container_scope: *Scope.Container) !void
16171617 // in `Decl` to notice that the line number did not change.
16181618 self.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl });
16191619 },
1620 .macho => {
1621 // TODO Implement for MachO
1620 .macho => if (decl.fn_link.macho.len != 0) {
1621 // TODO Look into detecting when this would be unnecessary by storing enough state
1622 // in `Decl` to notice that the line number did not change.
1623 self.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl });
16221624 },
16231625 .c, .wasm => {},
16241626 }
src/link/MachO.zig+51-35
......@@ -2232,6 +2232,7 @@ pub fn makeStaticString(comptime bytes: []const u8) [16]u8 {
22322232fn makeString(self: *MachO, bytes: []const u8) !u32 {
22332233 try self.string_table.ensureCapacity(self.base.allocator, self.string_table.items.len + bytes.len + 1);
22342234 const offset = @intCast(u32, self.string_table.items.len);
2235 log.debug("writing '{s}' into the string table at offset 0x{x}", .{ bytes, offset });
22352236 self.string_table.appendSliceAssumeCapacity(bytes);
22362237 self.string_table.appendAssumeCapacity(0);
22372238 self.string_table_dirty = true;
......@@ -2257,6 +2258,7 @@ pub fn addExternSymbol(self: *MachO, name: []const u8) !u32 {
22572258 const index = @intCast(u32, self.extern_lazy_symbols.items().len);
22582259 const offset = try self.makeString(name);
22592260 const sym_name = try self.base.allocator.dupe(u8, name);
2261 const dylib_ordinal = 1; // TODO this is now hardcoded, since we only support libSystem.
22602262 try self.extern_lazy_symbols.putNoClobber(self.base.allocator, sym_name, .{
22612263 .inner = .{
22622264 .n_strx = offset,
......@@ -2265,8 +2267,9 @@ pub fn addExternSymbol(self: *MachO, name: []const u8) !u32 {
22652267 .n_desc = macho.REFERENCE_FLAG_UNDEFINED_NON_LAZY | macho.N_SYMBOL_RESOLVER,
22662268 .n_value = 0,
22672269 },
2268 .dylib_ordinal = 1, // TODO this is now hardcoded, since we only support libSystem.
2270 .dylib_ordinal = dylib_ordinal,
22692271 });
2272 log.debug("adding new extern symbol '{s}' with dylib ordinal '{}'", .{ name, dylib_ordinal });
22702273 return index;
22712274}
22722275
......@@ -2639,6 +2642,11 @@ fn writeAllGlobalAndUndefSymbols(self: *MachO) !void {
26392642}
26402643
26412644fn writeIndirectSymbolTable(self: *MachO) !void {
2645 // TODO figure out a way not to rewrite the table every time if
2646 // no new undefs are not added.
2647 const tracy = trace(@src());
2648 defer tracy.end();
2649
26422650 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;
26432651 const stubs = &text_segment.sections.items[self.stubs_section_index.?];
26442652 const data_const_seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
......@@ -2646,42 +2654,53 @@ fn writeIndirectSymbolTable(self: *MachO) !void {
26462654 const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
26472655 const la_symbol_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?];
26482656 const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab;
2649 dysymtab.nindirectsyms = 0;
2650 // TODO check if we have allocated enough size.
26512657
2652 var buf: [@sizeOf(u32)]u8 = undefined;
2653 var off = dysymtab.indirectsymoff;
2658 const lazy = self.extern_lazy_symbols.items();
2659 const nonlazy = self.extern_nonlazy_symbols.items();
2660 const allocated_size = self.allocatedSizeLinkedit(dysymtab.indirectsymoff);
2661 const nindirectsyms = @intCast(u32, lazy.len * 2 + nonlazy.len);
2662 const needed_size = @intCast(u32, nindirectsyms * @sizeOf(u32));
2663
2664 if (needed_size > allocated_size) {
2665 dysymtab.nindirectsyms = 0;
2666 dysymtab.indirectsymoff = @intCast(u32, self.findFreeSpaceLinkedit(needed_size, @sizeOf(u32), null));
2667 }
2668 dysymtab.nindirectsyms = nindirectsyms;
2669 log.debug("writing indirect symbol table from 0x{x} to 0x{x}", .{
2670 dysymtab.indirectsymoff,
2671 dysymtab.indirectsymoff + needed_size,
2672 });
2673
2674 var buf = try self.base.allocator.alloc(u8, needed_size);
2675 defer self.base.allocator.free(buf);
2676 var stream = std.io.fixedBufferStream(buf);
2677 var writer = stream.writer();
26542678
26552679 stubs.reserved1 = 0;
26562680 for (self.extern_lazy_symbols.items()) |_, i| {
26572681 const symtab_idx = @intCast(u32, dysymtab.iundefsym + i);
2658 mem.writeIntLittle(u32, &buf, symtab_idx);
2659 try self.base.file.?.pwriteAll(&buf, off);
2660 off += @sizeOf(u32);
2661 dysymtab.nindirectsyms += 1;
2682 try writer.writeIntLittle(u32, symtab_idx);
26622683 }
26632684
2664 const base_id = @intCast(u32, self.extern_lazy_symbols.items().len);
2685 const base_id = @intCast(u32, lazy.len);
26652686 got.reserved1 = base_id;
26662687 for (self.extern_nonlazy_symbols.items()) |_, i| {
26672688 const symtab_idx = @intCast(u32, dysymtab.iundefsym + i + base_id);
2668 mem.writeIntLittle(u32, &buf, symtab_idx);
2669 try self.base.file.?.pwriteAll(&buf, off);
2670 off += @sizeOf(u32);
2671 dysymtab.nindirectsyms += 1;
2689 try writer.writeIntLittle(u32, symtab_idx);
26722690 }
26732691
2674 la_symbol_ptr.reserved1 = got.reserved1 + @intCast(u32, self.extern_nonlazy_symbols.items().len);
2692 la_symbol_ptr.reserved1 = got.reserved1 + @intCast(u32, nonlazy.len);
26752693 for (self.extern_lazy_symbols.items()) |_, i| {
26762694 const symtab_idx = @intCast(u32, dysymtab.iundefsym + i);
2677 mem.writeIntLittle(u32, &buf, symtab_idx);
2678 try self.base.file.?.pwriteAll(&buf, off);
2679 off += @sizeOf(u32);
2680 dysymtab.nindirectsyms += 1;
2695 try writer.writeIntLittle(u32, symtab_idx);
26812696 }
2697
2698 try self.base.file.?.pwriteAll(buf, dysymtab.indirectsymoff);
2699 self.load_commands_dirty = true;
26822700}
26832701
26842702fn writeCodeSignaturePadding(self: *MachO) !void {
2703 // TODO figure out how not to rewrite padding every single time.
26852704 const tracy = trace(@src());
26862705 defer tracy.end();
26872706
......@@ -2693,22 +2712,19 @@ fn writeCodeSignaturePadding(self: *MachO) !void {
26932712 fileoff,
26942713 self.page_size,
26952714 );
2696
2697 if (code_sig_cmd.datasize < needed_size) {
2698 code_sig_cmd.dataoff = @intCast(u32, fileoff);
2699 code_sig_cmd.datasize = needed_size;
2700
2701 // Advance size of __LINKEDIT segment
2702 linkedit_segment.inner.filesize += needed_size;
2703 if (linkedit_segment.inner.vmsize < linkedit_segment.inner.filesize) {
2704 linkedit_segment.inner.vmsize = mem.alignForwardGeneric(u64, linkedit_segment.inner.filesize, self.page_size);
2705 }
2706 log.debug("writing code signature padding from 0x{x} to 0x{x}", .{ fileoff, fileoff + needed_size });
2707 // Pad out the space. We need to do this to calculate valid hashes for everything in the file
2708 // except for code signature data.
2709 try self.base.file.?.pwriteAll(&[_]u8{0}, fileoff + needed_size - 1);
2710 self.load_commands_dirty = true;
2711 }
2715 code_sig_cmd.dataoff = @intCast(u32, fileoff);
2716 code_sig_cmd.datasize = needed_size;
2717
2718 // Advance size of __LINKEDIT segment
2719 linkedit_segment.inner.filesize += needed_size;
2720 if (linkedit_segment.inner.vmsize < linkedit_segment.inner.filesize) {
2721 linkedit_segment.inner.vmsize = mem.alignForwardGeneric(u64, linkedit_segment.inner.filesize, self.page_size);
2722 }
2723 log.debug("writing code signature padding from 0x{x} to 0x{x}", .{ fileoff, fileoff + needed_size });
2724 // Pad out the space. We need to do this to calculate valid hashes for everything in the file
2725 // except for code signature data.
2726 try self.base.file.?.pwriteAll(&[_]u8{0}, fileoff + needed_size - 1);
2727 self.load_commands_dirty = true;
27122728}
27132729
27142730fn writeCodeSignature(self: *MachO) !void {
src/link/MachO/DebugSymbols.zig+4-2
......@@ -1079,7 +1079,8 @@ pub fn commitDeclDebugInfo(
10791079 const debug_line_sect = &dwarf_segment.sections.items[self.debug_line_section_index.?];
10801080 const src_fn = &decl.fn_link.macho;
10811081 src_fn.len = @intCast(u32, dbg_line_buffer.items.len);
1082 if (self.dbg_line_fn_last) |last| {
1082 if (self.dbg_line_fn_last) |last| blk: {
1083 if (src_fn == last) break :blk;
10831084 if (src_fn.next) |next| {
10841085 // Update existing function - non-last item.
10851086 if (src_fn.off + src_fn.len + min_nop_size > next.off) {
......@@ -1238,7 +1239,8 @@ fn updateDeclDebugInfoAllocation(
12381239 const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment;
12391240 const debug_info_sect = &dwarf_segment.sections.items[self.debug_info_section_index.?];
12401241 text_block.dbg_info_len = len;
1241 if (self.dbg_info_decl_last) |last| {
1242 if (self.dbg_info_decl_last) |last| blk: {
1243 if (text_block == last) break :blk;
12421244 if (text_block.dbg_info_next) |next| {
12431245 // Update existing Decl - non-last item.
12441246 if (text_block.dbg_info_off + text_block.dbg_info_len + min_nop_size > next.dbg_info_off) {