diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2023-10-14 09:04:08 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2023-10-16 19:33:06 +0200 |
| commit | 17635e4f2ae78e358a7a997b161e64de71a01191 (patch) | |
| tree | dc688f054c6a6c1ab7d7e96f3cfc1c3bb127e44e /src/arch/x86_64/CodeGen.zig | |
| parent | b3d98a4b88514b1e8d2cc07ef05c218f50f5f5d8 (diff) | |
| download | zig-17635e4f2ae78e358a7a997b161e64de71a01191.tar.gz zig-17635e4f2ae78e358a7a997b161e64de71a01191.zip | |
x86_64: add -fPIC support targeting ELF
Diffstat (limited to 'src/arch/x86_64/CodeGen.zig')
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 91 |
1 files changed, 55 insertions, 36 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 4e568e294f..c488209366 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -9190,14 +9190,19 @@ fn genCall(self: *Self, info: union(enum) { const sym_index = try elf_file.getOrCreateMetadataForDecl(owner_decl); const sym = elf_file.symbol(sym_index); _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); - _ = try self.addInst(.{ - .tag = .call, - .ops = .direct_got_reloc, - .data = .{ .reloc = .{ - .atom_index = try self.owner.getSymbolIndex(self), - .sym_index = sym.esym_index, - } }, - }); + if (self.bin_file.options.pic) { + try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym.esym_index }); + try self.asmRegister(.{ ._, .call }, .rax); + } else { + _ = try self.addInst(.{ + .tag = .call, + .ops = .direct_got_reloc, + .data = .{ .reloc = .{ + .atom_index = try self.owner.getSymbolIndex(self), + .sym_index = sym.esym_index, + } }, + }); + } } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { const atom = try coff_file.getOrCreateAtomForDecl(owner_decl); const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; @@ -11637,34 +11642,48 @@ fn genLazySymbolRef( return self.fail("{s} creating lazy symbol", .{@errorName(err)}); const sym = elf_file.symbol(sym_index); _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); - const reloc = Mir.Reloc{ - .atom_index = try self.owner.getSymbolIndex(self), - .sym_index = sym.esym_index, - }; - switch (tag) { - .lea, .mov => _ = try self.addInst(.{ - .tag = .mov, - .ops = .direct_got_reloc, - .data = .{ .rx = .{ - .r1 = reg.to64(), - .payload = try self.addExtra(reloc), - } }, - }), - .call => _ = try self.addInst(.{ - .tag = .call, - .ops = .direct_got_reloc, - .data = .{ .reloc = reloc }, - }), - else => unreachable, - } - switch (tag) { - .lea, .call => {}, - .mov => try self.asmRegisterMemory( - .{ ._, tag }, - reg.to64(), - Memory.sib(.qword, .{ .base = .{ .reg = reg.to64() } }), - ), - else => unreachable, + + if (self.bin_file.options.pic) { + switch (tag) { + .lea, .call => try self.genSetReg(reg, Type.usize, .{ .lea_got = sym.esym_index }), + .mov => try self.genSetReg(reg, Type.usize, .{ .load_got = sym.esym_index }), + else => unreachable, + } + switch (tag) { + .lea, .mov => {}, + .call => try self.asmRegister(.{ ._, .call }, reg), + else => unreachable, + } + } else { + const reloc = Mir.Reloc{ + .atom_index = try self.owner.getSymbolIndex(self), + .sym_index = sym.esym_index, + }; + switch (tag) { + .lea, .mov => _ = try self.addInst(.{ + .tag = .mov, + .ops = .direct_got_reloc, + .data = .{ .rx = .{ + .r1 = reg.to64(), + .payload = try self.addExtra(reloc), + } }, + }), + .call => _ = try self.addInst(.{ + .tag = .call, + .ops = .direct_got_reloc, + .data = .{ .reloc = reloc }, + }), + else => unreachable, + } + switch (tag) { + .lea, .call => {}, + .mov => try self.asmRegisterMemory( + .{ ._, tag }, + reg.to64(), + Memory.sib(.qword, .{ .base = .{ .reg = reg.to64() } }), + ), + else => unreachable, + } } } else if (self.bin_file.cast(link.File.Plan9)) |p9_file| { const atom_index = p9_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err| |
