mirror of
https://github.com/ziglang/zig.git
synced 2026-02-20 16:24:51 +00:00
coff: generate relocations for branch, GOT, direct refs
This commit is contained in:
parent
62ae365308
commit
53a9661c1a
@ -674,13 +674,14 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
assert(emit.mir.instructions.items(.tag)[inst] == .call_extern);
|
||||
const relocation = emit.mir.instructions.items(.data)[inst].relocation;
|
||||
|
||||
const offset = blk: {
|
||||
const offset = @intCast(u32, emit.code.items.len);
|
||||
// bl
|
||||
try emit.writeInstruction(Instruction.bl(0));
|
||||
break :blk offset;
|
||||
};
|
||||
|
||||
if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
const offset = blk: {
|
||||
const offset = @intCast(u32, emit.code.items.len);
|
||||
// bl
|
||||
try emit.writeInstruction(Instruction.bl(0));
|
||||
break :blk offset;
|
||||
};
|
||||
// Add relocation to the decl.
|
||||
const atom = macho_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;
|
||||
const target = macho_file.getGlobalByIndex(relocation.sym_index);
|
||||
@ -692,8 +693,20 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
.pcrel = true,
|
||||
.length = 2,
|
||||
});
|
||||
} else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {
|
||||
// Add relocation to the decl.
|
||||
const atom = coff_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;
|
||||
const target = coff_file.getGlobalByIndex(relocation.sym_index);
|
||||
try atom.addRelocation(coff_file, .{
|
||||
.@"type" = .branch_26,
|
||||
.target = target,
|
||||
.offset = offset,
|
||||
.addend = 0,
|
||||
.pcrel = true,
|
||||
.length = 2,
|
||||
});
|
||||
} else {
|
||||
return emit.fail("Implement call_extern for linking backends != MachO", .{});
|
||||
return emit.fail("Implement call_extern for linking backends != {{ COFF, MachO }}", .{});
|
||||
}
|
||||
}
|
||||
|
||||
@ -926,6 +939,40 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
else => unreachable,
|
||||
},
|
||||
});
|
||||
} else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {
|
||||
const atom = coff_file.getAtomForSymbol(.{ .sym_index = data.atom_index, .file = null }).?;
|
||||
try atom.addRelocation(coff_file, .{
|
||||
.target = .{ .sym_index = data.sym_index, .file = null },
|
||||
.offset = offset,
|
||||
.addend = 0,
|
||||
.pcrel = true,
|
||||
.length = 2,
|
||||
.@"type" = switch (tag) {
|
||||
.load_memory_got,
|
||||
.load_memory_ptr_got,
|
||||
=> .got_page,
|
||||
.load_memory_direct,
|
||||
.load_memory_ptr_direct,
|
||||
=> .page,
|
||||
else => unreachable,
|
||||
},
|
||||
});
|
||||
try atom.addRelocation(coff_file, .{
|
||||
.target = .{ .sym_index = data.sym_index, .file = null },
|
||||
.offset = offset + 4,
|
||||
.addend = 0,
|
||||
.pcrel = false,
|
||||
.length = 2,
|
||||
.@"type" = switch (tag) {
|
||||
.load_memory_got,
|
||||
.load_memory_ptr_got,
|
||||
=> .got_pageoff,
|
||||
.load_memory_direct,
|
||||
.load_memory_ptr_direct,
|
||||
=> .pageoff,
|
||||
else => unreachable,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
return emit.fail("TODO implement load_memory for PIE GOT indirection on this platform", .{});
|
||||
}
|
||||
|
||||
@ -125,9 +125,17 @@ const Entry = struct {
|
||||
|
||||
pub const Reloc = struct {
|
||||
@"type": enum {
|
||||
// x86, x86_64
|
||||
got,
|
||||
direct,
|
||||
import,
|
||||
|
||||
// aarch64
|
||||
branch_26,
|
||||
got_page,
|
||||
got_pageoff,
|
||||
page,
|
||||
pageoff,
|
||||
},
|
||||
target: SymbolWithLoc,
|
||||
offset: u32,
|
||||
@ -139,8 +147,17 @@ pub const Reloc = struct {
|
||||
/// Returns an Atom which is the target node of this relocation edge (if any).
|
||||
fn getTargetAtom(self: Reloc, coff_file: *Coff) ?*Atom {
|
||||
switch (self.@"type") {
|
||||
.got => return coff_file.getGotAtomForSymbol(self.target),
|
||||
.direct => return coff_file.getAtomForSymbol(self.target),
|
||||
.got,
|
||||
.got_page,
|
||||
.got_pageoff,
|
||||
=> return coff_file.getGotAtomForSymbol(self.target),
|
||||
|
||||
.direct,
|
||||
.branch_26,
|
||||
.page,
|
||||
.pageoff,
|
||||
=> return coff_file.getAtomForSymbol(self.target),
|
||||
|
||||
.import => return coff_file.getImportAtomForSymbol(self.target),
|
||||
}
|
||||
}
|
||||
@ -878,6 +895,15 @@ fn resolveRelocs(self: *Coff, atom: *Atom) !void {
|
||||
file_offset + reloc.offset,
|
||||
});
|
||||
|
||||
switch (reloc.@"type") {
|
||||
.branch_26 => @panic("TODO branch26"),
|
||||
.got_page => @panic("TODO got_page"),
|
||||
.got_pageoff => @panic("TODO got_pageoff"),
|
||||
.page => @panic("TODO page"),
|
||||
.pageoff => @panic("TODO pageoff"),
|
||||
else => {},
|
||||
}
|
||||
|
||||
reloc.dirty = false;
|
||||
|
||||
if (reloc.pcrel) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user