aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen.zig')
-rw-r--r--src/codegen.zig51
1 files changed, 30 insertions, 21 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index 7cb7119f0d..5d57cf0728 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -2506,7 +2506,6 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
}) orelse unreachable;
break :blk got.addr + got_index * @sizeOf(u64);
};
- log.debug("got_addr = 0x{x}", .{got_addr});
switch (arch) {
.x86_64 => {
try self.genSetReg(inst.base.src, Type.initTag(.u64), .rax, .{ .memory = got_addr });
@@ -3864,19 +3863,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
.memory => |addr| {
if (self.bin_file.options.pie) {
// PC-relative displacement to the entry in the GOT table.
- // TODO we should come up with our own, backend independent relocation types
- // which each backend (Elf, MachO, etc.) would then translate into an actual
- // fixup when linking.
- // adrp reg, pages
- if (self.bin_file.cast(link.File.MachO)) |macho_file| {
- try macho_file.pie_fixups.append(self.bin_file.allocator, .{
- .target_addr = addr,
- .offset = self.code.items.len,
- .size = 4,
- });
- } else {
- return self.fail(src, "TODO implement genSetReg for PIE GOT indirection on this platform", .{});
- }
+ // adrp
+ const offset = @intCast(u32, self.code.items.len);
mem.writeIntLittle(
u32,
try self.code.addManyAsArray(4),
@@ -3889,6 +3877,26 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
.offset = Instruction.LoadStoreOffset.imm(0),
},
}).toU32());
+
+ if (self.bin_file.cast(link.File.MachO)) |macho_file| {
+ const decl = macho_file.active_decl.?;
+ // Page reloc for adrp instruction.
+ try decl.link.macho.relocs.append(self.bin_file.allocator, .{
+ .offset = offset,
+ .where = .local,
+ .where_index = decl.link.macho.local_sym_index,
+ .payload = .{ .page = .{ .kind = .got } },
+ });
+ // Pageoff reloc for adrp instruction.
+ try decl.link.macho.relocs.append(self.bin_file.allocator, .{
+ .offset = offset + 4,
+ .where = .local,
+ .where_index = decl.link.macho.local_sym_index,
+ .payload = .{ .page_off = .{ .kind = .got } },
+ });
+ } else {
+ return self.fail(src, "TODO implement genSetReg for PIE GOT indirection on this platform", .{});
+ }
} else {
// The value is in memory at a hard-coded address.
// If the type is a pointer, it means the pointer address is at this memory location.
@@ -4128,6 +4136,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
const abi_size = ty.abiSize(self.target.*);
const encoder = try X8664Encoder.init(self.code, 10);
+ const offset = @intCast(u32, self.code.items.len);
// LEA reg, [<offset>]
// We encode the instruction FIRST because prefixes may or may not appear.
@@ -4141,14 +4150,14 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
encoder.modRm_RIPDisp32(reg.low_id());
encoder.disp32(0);
- // TODO we should come up with our own, backend independent relocation types
- // which each backend (Elf, MachO, etc.) would then translate into an actual
- // fixup when linking.
if (self.bin_file.cast(link.File.MachO)) |macho_file| {
- try macho_file.pie_fixups.append(self.bin_file.allocator, .{
- .target_addr = x,
- .offset = self.code.items.len - 4,
- .size = 4,
+ const decl = macho_file.active_decl.?;
+ // Load reloc for LEA instruction.
+ try decl.link.macho.relocs.append(self.bin_file.allocator, .{
+ .offset = offset,
+ .where = .local,
+ .where_index = decl.link.macho.local_sym_index,
+ .payload = .{ .load = .{ .kind = .got } },
});
} else {
return self.fail(src, "TODO implement genSetReg for PIE GOT indirection on this platform", .{});