authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-26 13:35:50+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-01 21:09:35+02:00
logaf40bce08adf232c9f6b9016810a24f7d0260399
tree3933dcd1ea2016bb709b6a5bd3aba880f89dfaff
parent8e1421f19ef3daea9b8a414bd5783189bc292676

x86_64: emit R_X86_64_GOT32 for non-PIC GOT references


5 files changed, 66 insertions(+), 12 deletions(-)

src/arch/x86_64/CodeGen.zig+25-10
...@@ -8223,11 +8223,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier...@@ -8223,11 +8223,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
8223 const sym = elf_file.symbol(sym_index);8223 const sym = elf_file.symbol(sym_index);
8224 sym.flags.needs_got = true;8224 sym.flags.needs_got = true;
8225 _ = try sym.getOrCreateGotEntry(sym_index, elf_file);8225 _ = try sym.getOrCreateGotEntry(sym_index, elf_file);
8226 const got_addr = sym.gotAddress(elf_file);8226 _ = try self.addInst(.{
8227 try self.asmMemory(.{ ._, .call }, Memory.sib(.qword, .{8227 .tag = .call,
8228 .base = .{ .reg = .ds },8228 .ops = .direct_got_reloc,
8229 .disp = @intCast(got_addr),8229 .data = .{ .reloc = .{
8230 }));8230 .atom_index = try self.owner.getSymbolIndex(self),
8231 .sym_index = sym.esym_index,
8232 } },
8233 });
8231 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {8234 } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
8232 const atom = try coff_file.getOrCreateAtomForDecl(owner_decl);8235 const atom = try coff_file.getOrCreateAtomForDecl(owner_decl);
8233 const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;8236 const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;
...@@ -10290,12 +10293,24 @@ fn genLazySymbolRef(...@@ -10290,12 +10293,24 @@ fn genLazySymbolRef(
10290 const sym = elf_file.symbol(sym_index);10293 const sym = elf_file.symbol(sym_index);
10291 sym.flags.needs_got = true;10294 sym.flags.needs_got = true;
10292 _ = try sym.getOrCreateGotEntry(sym_index, elf_file);10295 _ = try sym.getOrCreateGotEntry(sym_index, elf_file);
10293 const got_addr = sym.gotAddress(elf_file);10296 const reloc = Mir.Reloc{
10294 const got_mem =10297 .atom_index = try self.owner.getSymbolIndex(self),
10295 Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = @intCast(got_addr) });10298 .sym_index = sym.esym_index,
10299 };
10296 switch (tag) {10300 switch (tag) {
10297 .lea, .mov => try self.asmRegisterMemory(.{ ._, .mov }, reg.to64(), got_mem),10301 .lea, .mov => _ = try self.addInst(.{
10298 .call => try self.asmMemory(.{ ._, .call }, got_mem),10302 .tag = .mov,
10303 .ops = .direct_got_reloc,
10304 .data = .{ .rx = .{
10305 .r1 = reg.to64(),
10306 .payload = try self.addExtra(reloc),
10307 } },
10308 }),
10309 .call => _ = try self.addInst(.{
10310 .tag = .call,
10311 .ops = .direct_got_reloc,
10312 .data = .{ .reloc = reloc },
10313 }),
10299 else => unreachable,10314 else => unreachable,
10300 }10315 }
10301 switch (tag) {10316 switch (tag) {
src/arch/x86_64/Emit.zig+13-1
...@@ -80,9 +80,21 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -80,9 +80,21 @@ pub fn emitMir(emit: *Emit) Error!void {
80 }),80 }),
81 .linker_got,81 .linker_got,
82 .linker_direct,82 .linker_direct,
83 .linker_direct_got,
83 .linker_import,84 .linker_import,
84 .linker_tlv,85 .linker_tlv,
85 => |symbol| if (emit.bin_file.cast(link.File.MachO)) |macho_file| {86 => |symbol| if (emit.bin_file.cast(link.File.Elf)) |elf_file| {
87 const r_type: u32 = switch (lowered_relocs[0].target) {
88 .linker_direct_got => std.elf.R_X86_64_GOT32,
89 else => unreachable,
90 };
91 const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;
92 try atom_ptr.addReloc(elf_file, .{
93 .r_offset = end_offset - 4,
94 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | r_type,
95 .r_addend = 0,
96 });
97 } else if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
86 const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = symbol.atom_index }).?;98 const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = symbol.atom_index }).?;
87 try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{99 try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
88 .type = switch (lowered_relocs[0].target) {100 .type = switch (lowered_relocs[0].target) {
src/arch/x86_64/Lower.zig+22-1
...@@ -52,6 +52,7 @@ pub const Reloc = struct {...@@ -52,6 +52,7 @@ pub const Reloc = struct {
52 linker_extern_fn: Mir.Reloc,52 linker_extern_fn: Mir.Reloc,
53 linker_got: Mir.Reloc,53 linker_got: Mir.Reloc,
54 linker_direct: Mir.Reloc,54 linker_direct: Mir.Reloc,
55 linker_direct_got: Mir.Reloc,
55 linker_import: Mir.Reloc,56 linker_import: Mir.Reloc,
56 linker_tlv: Mir.Reloc,57 linker_tlv: Mir.Reloc,
57 };58 };
...@@ -387,7 +388,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {...@@ -387,7 +388,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
387 .rrmi_sib, .rrmi_rip => inst.data.rrix.fixes,388 .rrmi_sib, .rrmi_rip => inst.data.rrix.fixes,
388 .mi_sib_u, .mi_rip_u, .mi_sib_s, .mi_rip_s => inst.data.x.fixes,389 .mi_sib_u, .mi_rip_u, .mi_sib_s, .mi_rip_s => inst.data.x.fixes,
389 .m_sib, .m_rip, .rax_moffs, .moffs_rax => inst.data.x.fixes,390 .m_sib, .m_rip, .rax_moffs, .moffs_rax => inst.data.x.fixes,
390 .extern_fn_reloc, .got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ._,391 .extern_fn_reloc, .got_reloc, .direct_reloc, .direct_got_reloc, .import_reloc, .tlv_reloc => ._,
391 else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}),392 else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}),
392 };393 };
393 try lower.emit(switch (fixes) {394 try lower.emit(switch (fixes) {
...@@ -511,6 +512,26 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {...@@ -511,6 +512,26 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
511 .extern_fn_reloc => &.{512 .extern_fn_reloc => &.{
512 .{ .imm = lower.reloc(.{ .linker_extern_fn = inst.data.reloc }) },513 .{ .imm = lower.reloc(.{ .linker_extern_fn = inst.data.reloc }) },
513 },514 },
515 .direct_got_reloc => ops: {
516 switch (inst.tag) {
517 .call => {
518 _ = lower.reloc(.{ .linker_direct_got = inst.data.reloc });
519 break :ops &.{
520 .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) },
521 };
522 },
523 .mov => {
524 const reg = inst.data.rx.r1;
525 const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;
526 _ = lower.reloc(.{ .linker_direct_got = extra });
527 break :ops &.{
528 .{ .reg = reg },
529 .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) },
530 };
531 },
532 else => unreachable,
533 }
534 },
514 .got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ops: {535 .got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ops: {
515 const reg = inst.data.rx.r1;536 const reg = inst.data.rx.r1;
516 const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;537 const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;
src/arch/x86_64/Mir.zig+3
...@@ -783,6 +783,9 @@ pub const Inst = struct {...@@ -783,6 +783,9 @@ pub const Inst = struct {
783 /// Linker relocation - threadlocal variable via GOT indirection.783 /// Linker relocation - threadlocal variable via GOT indirection.
784 /// Uses `rx` payload with extra data of type `Reloc`.784 /// Uses `rx` payload with extra data of type `Reloc`.
785 tlv_reloc,785 tlv_reloc,
786 /// Linker relocation - non-PIC direct reference to GOT cell.
787 /// Uses `reloc` payload if tag is `call`, `rx` otherwise.
788 direct_got_reloc,
786789
787 // Pseudo instructions:790 // Pseudo instructions:
788791
src/link/Elf/Atom.zig+3
...@@ -518,6 +518,9 @@ pub fn resolveRelocs(self: Atom, elf_file: *Elf, code: []u8) !void {...@@ -518,6 +518,9 @@ pub fn resolveRelocs(self: Atom, elf_file: *Elf, code: []u8) !void {
518 elf.R_X86_64_PC32,518 elf.R_X86_64_PC32,
519 => try cwriter.writeIntLittle(i32, @as(i32, @intCast(S + A - P))),519 => try cwriter.writeIntLittle(i32, @as(i32, @intCast(S + A - P))),
520520
521 elf.R_X86_64_GOT32 => try cwriter.writeIntLittle(u32, @as(u32, @intCast(G + GOT + A))),
522 elf.R_X86_64_GOT64 => try cwriter.writeIntLittle(u64, @as(u64, @intCast(G + GOT + A))),
523
521 elf.R_X86_64_GOTPCREL => try cwriter.writeIntLittle(i32, @as(i32, @intCast(G + GOT + A - P))),524 elf.R_X86_64_GOTPCREL => try cwriter.writeIntLittle(i32, @as(i32, @intCast(G + GOT + A - P))),
522 elf.R_X86_64_GOTPC32 => try cwriter.writeIntLittle(i32, @as(i32, @intCast(GOT + A - P))),525 elf.R_X86_64_GOTPC32 => try cwriter.writeIntLittle(i32, @as(i32, @intCast(GOT + A - P))),
523 elf.R_X86_64_GOTPC64 => try cwriter.writeIntLittle(i64, GOT + A - P),526 elf.R_X86_64_GOTPC64 => try cwriter.writeIntLittle(i64, GOT + A - P),