Skip to content

Commit

Permalink
macho: addend for unsigned needs to be written to code buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
kubkon committed Jan 3, 2024
1 parent d20dc30 commit 5f8e747
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 9 deletions.
11 changes: 9 additions & 2 deletions src/MachO/Atom.zig
Original file line number Diff line number Diff line change
Expand Up @@ -684,12 +684,13 @@ pub fn calcNumRelocs(self: Atom, macho_file: *MachO) u32 {
}
}

pub fn writeRelocs(self: Atom, macho_file: *MachO, buffer: *std.ArrayList(macho.relocation_info)) !void {
pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: *std.ArrayList(macho.relocation_info)) !void {
const tracy = trace(@src());
defer tracy.end();

const cpu_arch = macho_file.options.cpu_arch.?;
const relocs = self.getRelocs(macho_file);
var stream = std.io.fixedBufferStream(code);

for (relocs) |rel| {
const rel_offset = rel.offset - self.off;
Expand All @@ -704,9 +705,15 @@ pub fn writeRelocs(self: Atom, macho_file: *MachO, buffer: *std.ArrayList(macho.
const r_extern = rel.tag == .@"extern";
const addend = rel.addend + rel.getRelocAddend(cpu_arch);

try stream.seekTo(rel_offset);

switch (cpu_arch) {
.aarch64 => {
if (addend > 0 and rel.type != .unsigned) {
if (rel.type == .unsigned) switch (rel.meta.length) {
0, 1 => unreachable,
2 => try stream.writer().writeInt(i32, @truncate(addend), .little),
3 => try stream.writer().writeInt(i64, addend, .little),
} else if (addend > 0) {
buffer.appendAssumeCapacity(.{
.r_address = r_address,
.r_symbolnum = @bitCast(math.cast(i24, addend) orelse return error.Overflow),
Expand Down
6 changes: 6 additions & 0 deletions src/MachO/eh_frame.zig
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,12 @@ pub fn write(macho_file: *MachO, buffer: []u8) void {
}
}

pub fn writeRelocs(macho_file: *MachO, relocs: *std.ArrayList(macho.relocation_info)) void {
_ = macho_file;
_ = relocs;
@panic("TODO eh_frame.writeRelocs");
}

pub const EH_PE = struct {
pub const absptr = 0x00;
pub const uleb128 = 0x01;
Expand Down
20 changes: 13 additions & 7 deletions src/MachO/relocatable.zig
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,7 @@ fn writeAtoms(macho_file: *MachO) !void {
assert(atom.flags.alive);
const off = atom.value - header.addr;
@memcpy(code[off..][0..atom.size], atom.getCode(macho_file));

try atom.writeRelocs(macho_file, &relocs);
try atom.writeRelocs(macho_file, code, &relocs);
}

// TODO scattered writes?
Expand Down Expand Up @@ -274,11 +273,18 @@ fn writeEhFrame(macho_file: *MachO) !void {
const sect_index = macho_file.eh_frame_sect_index orelse return;
const gpa = macho_file.base.allocator;
const header = macho_file.sections.items(.header)[sect_index];
const buffer = try gpa.alloc(u8, header.size);
defer gpa.free(buffer);
eh_frame.write(macho_file, buffer);
try macho_file.base.file.pwriteAll(buffer, header.offset);
// TODO write relocs

const code = try gpa.alloc(u8, header.size);
defer gpa.free(code);
eh_frame.write(macho_file, code);

var relocs = try std.ArrayList(macho.relocation_info).initCapacity(gpa, header.nreloc);
defer relocs.deinit();
eh_frame.writeRelocs(macho_file, &relocs);

// TODO scattered writes?
try macho_file.base.file.pwriteAll(code, header.offset);
try macho_file.base.file.pwriteAll(mem.sliceAsBytes(relocs.items), header.reloff);
}

fn writeDataInCode(macho_file: *MachO, off: u32) !u32 {
Expand Down

0 comments on commit 5f8e747

Please sign in to comment.