authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-17 00:14:52+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-18 09:13:09+02:00
log3bdbf81a3f574c0cf538b443825558e45bceecee
tree209fbc0c5a940ebaf9cb376bb833aaa45a62ddb6
parent34f34dbe3246547d4586d284cf44510e3f8feaa2

macho: fix emitting data-in-code entries


2 files changed, 31 insertions(+), 8 deletions(-)

src/link/MachO.zig+5-1
...@@ -2521,8 +2521,12 @@ fn writeDyldInfo(self: *MachO) !void {...@@ -2521,8 +2521,12 @@ fn writeDyldInfo(self: *MachO) !void {
2521pub fn writeDataInCode(self: *MachO) !void {2521pub fn writeDataInCode(self: *MachO) !void {
2522 const tracy = trace(@src());2522 const tracy = trace(@src());
2523 defer tracy.end();2523 defer tracy.end();
2524 const gpa = self.base.comp.gpa;
2524 const cmd = self.data_in_code_cmd;2525 const cmd = self.data_in_code_cmd;
2525 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.data_in_code.entries.items), cmd.dataoff);2526 var buffer = try std.ArrayList(u8).initCapacity(gpa, self.data_in_code.size());
2527 defer buffer.deinit();
2528 try self.data_in_code.write(self, buffer.writer());
2529 try self.base.file.?.pwriteAll(buffer.items, cmd.dataoff);
2526}2530}
25272531
2528fn writeIndsymtab(self: *MachO) !void {2532fn writeIndsymtab(self: *MachO) !void {
src/link/MachO/synthetic.zig+26-7
...@@ -656,7 +656,7 @@ pub const Indsymtab = struct {...@@ -656,7 +656,7 @@ pub const Indsymtab = struct {
656};656};
657657
658pub const DataInCode = struct {658pub const DataInCode = struct {
659 entries: std.ArrayListUnmanaged(macho.data_in_code_entry) = .{},659 entries: std.ArrayListUnmanaged(Entry) = .{},
660660
661 pub fn deinit(dice: *DataInCode, allocator: Allocator) void {661 pub fn deinit(dice: *DataInCode, allocator: Allocator) void {
662 dice.entries.deinit(allocator);662 dice.entries.deinit(allocator);
...@@ -668,10 +668,6 @@ pub const DataInCode = struct {...@@ -668,10 +668,6 @@ pub const DataInCode = struct {
668668
669 pub fn updateSize(dice: *DataInCode, macho_file: *MachO) !void {669 pub fn updateSize(dice: *DataInCode, macho_file: *MachO) !void {
670 const gpa = macho_file.base.comp.gpa;670 const gpa = macho_file.base.comp.gpa;
671 const base_address = if (!macho_file.base.isRelocatable())
672 macho_file.getTextSegment().vmaddr
673 else
674 0;
675671
676 for (macho_file.objects.items) |index| {672 for (macho_file.objects.items) |index| {
677 const object = macho_file.getFile(index).?.object;673 const object = macho_file.getFile(index).?.object;
...@@ -683,7 +679,6 @@ pub const DataInCode = struct {...@@ -683,7 +679,6 @@ pub const DataInCode = struct {
683 for (object.getAtoms()) |atom_index| {679 for (object.getAtoms()) |atom_index| {
684 if (next_dice >= dices.len) break;680 if (next_dice >= dices.len) break;
685 const atom = object.getAtom(atom_index) orelse continue;681 const atom = object.getAtom(atom_index) orelse continue;
686 if (!atom.flags.alive) continue;
687 const start_off = atom.getInputAddress(macho_file);682 const start_off = atom.getInputAddress(macho_file);
688 const end_off = start_off + atom.size;683 const end_off = start_off + atom.size;
689 const start_dice = next_dice;684 const start_dice = next_dice;
...@@ -696,7 +691,8 @@ pub const DataInCode = struct {...@@ -696,7 +691,8 @@ pub const DataInCode = struct {
696691
697 if (atom.flags.alive) for (dices[start_dice..next_dice]) |d| {692 if (atom.flags.alive) for (dices[start_dice..next_dice]) |d| {
698 dice.entries.appendAssumeCapacity(.{693 dice.entries.appendAssumeCapacity(.{
699 .offset = @intCast(atom.getAddress(macho_file) + d.offset - start_off - base_address),694 .atom_ref = .{ .index = atom_index, .file = index },
695 .offset = @intCast(d.offset - start_off),
700 .length = d.length,696 .length = d.length,
701 .kind = d.kind,697 .kind = d.kind,
702 });698 });
...@@ -706,6 +702,29 @@ pub const DataInCode = struct {...@@ -706,6 +702,29 @@ pub const DataInCode = struct {
706702
707 macho_file.data_in_code_cmd.datasize = math.cast(u32, dice.size()) orelse return error.Overflow;703 macho_file.data_in_code_cmd.datasize = math.cast(u32, dice.size()) orelse return error.Overflow;
708 }704 }
705
706 pub fn write(dice: DataInCode, macho_file: *MachO, writer: anytype) !void {
707 const base_address = if (!macho_file.base.isRelocatable())
708 macho_file.getTextSegment().vmaddr
709 else
710 0;
711 for (dice.entries.items) |entry| {
712 const atom_address = entry.atom_ref.getAtom(macho_file).?.getAddress(macho_file);
713 const offset = atom_address + entry.offset - base_address;
714 try writer.writeStruct(macho.data_in_code_entry{
715 .offset = @intCast(offset),
716 .length = entry.length,
717 .kind = entry.kind,
718 });
719 }
720 }
721
722 const Entry = struct {
723 atom_ref: MachO.Ref,
724 offset: u32,
725 length: u16,
726 kind: u16,
727 };
709};728};
710729
711const aarch64 = @import("../aarch64.zig");730const aarch64 = @import("../aarch64.zig");