| author | |
| committer | |
| log | 17635e4f2ae78e358a7a997b161e64de71a01191 |
| tree | dc688f054c6a6c1ab7d7e96f3cfc1c3bb127e44e |
| parent | b3d98a4b88514b1e8d2cc07ef05c218f50f5f5d8 |
5 files changed, 92 insertions(+), 57 deletions(-)
src/arch/x86_64/CodeGen.zig+55-36| ... | ... | @@ -9190,14 +9190,19 @@ fn genCall(self: *Self, info: union(enum) { |
| 9190 | 9190 | const sym_index = try elf_file.getOrCreateMetadataForDecl(owner_decl); |
| 9191 | 9191 | const sym = elf_file.symbol(sym_index); |
| 9192 | 9192 | _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); |
| 9193 | _ = try self.addInst(.{ | |
| 9194 | .tag = .call, | |
| 9195 | .ops = .direct_got_reloc, | |
| 9196 | .data = .{ .reloc = .{ | |
| 9197 | .atom_index = try self.owner.getSymbolIndex(self), | |
| 9198 | .sym_index = sym.esym_index, | |
| 9199 | } }, | |
| 9200 | }); | |
| 9193 | if (self.bin_file.options.pic) { | |
| 9194 | try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym.esym_index }); | |
| 9195 | try self.asmRegister(.{ ._, .call }, .rax); | |
| 9196 | } else { | |
| 9197 | _ = try self.addInst(.{ | |
| 9198 | .tag = .call, | |
| 9199 | .ops = .direct_got_reloc, | |
| 9200 | .data = .{ .reloc = .{ | |
| 9201 | .atom_index = try self.owner.getSymbolIndex(self), | |
| 9202 | .sym_index = sym.esym_index, | |
| 9203 | } }, | |
| 9204 | }); | |
| 9205 | } | |
| 9201 | 9206 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { |
| 9202 | 9207 | const atom = try coff_file.getOrCreateAtomForDecl(owner_decl); |
| 9203 | 9208 | const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; |
| ... | ... | @@ -11637,34 +11642,48 @@ fn genLazySymbolRef( |
| 11637 | 11642 | return self.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 11638 | 11643 | const sym = elf_file.symbol(sym_index); |
| 11639 | 11644 | _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); |
| 11640 | const reloc = Mir.Reloc{ | |
| 11641 | .atom_index = try self.owner.getSymbolIndex(self), | |
| 11642 | .sym_index = sym.esym_index, | |
| 11643 | }; | |
| 11644 | switch (tag) { | |
| 11645 | .lea, .mov => _ = try self.addInst(.{ | |
| 11646 | .tag = .mov, | |
| 11647 | .ops = .direct_got_reloc, | |
| 11648 | .data = .{ .rx = .{ | |
| 11649 | .r1 = reg.to64(), | |
| 11650 | .payload = try self.addExtra(reloc), | |
| 11651 | } }, | |
| 11652 | }), | |
| 11653 | .call => _ = try self.addInst(.{ | |
| 11654 | .tag = .call, | |
| 11655 | .ops = .direct_got_reloc, | |
| 11656 | .data = .{ .reloc = reloc }, | |
| 11657 | }), | |
| 11658 | else => unreachable, | |
| 11659 | } | |
| 11660 | switch (tag) { | |
| 11661 | .lea, .call => {}, | |
| 11662 | .mov => try self.asmRegisterMemory( | |
| 11663 | .{ ._, tag }, | |
| 11664 | reg.to64(), | |
| 11665 | Memory.sib(.qword, .{ .base = .{ .reg = reg.to64() } }), | |
| 11666 | ), | |
| 11667 | else => unreachable, | |
| 11645 | ||
| 11646 | if (self.bin_file.options.pic) { | |
| 11647 | switch (tag) { | |
| 11648 | .lea, .call => try self.genSetReg(reg, Type.usize, .{ .lea_got = sym.esym_index }), | |
| 11649 | .mov => try self.genSetReg(reg, Type.usize, .{ .load_got = sym.esym_index }), | |
| 11650 | else => unreachable, | |
| 11651 | } | |
| 11652 | switch (tag) { | |
| 11653 | .lea, .mov => {}, | |
| 11654 | .call => try self.asmRegister(.{ ._, .call }, reg), | |
| 11655 | else => unreachable, | |
| 11656 | } | |
| 11657 | } else { | |
| 11658 | const reloc = Mir.Reloc{ | |
| 11659 | .atom_index = try self.owner.getSymbolIndex(self), | |
| 11660 | .sym_index = sym.esym_index, | |
| 11661 | }; | |
| 11662 | switch (tag) { | |
| 11663 | .lea, .mov => _ = try self.addInst(.{ | |
| 11664 | .tag = .mov, | |
| 11665 | .ops = .direct_got_reloc, | |
| 11666 | .data = .{ .rx = .{ | |
| 11667 | .r1 = reg.to64(), | |
| 11668 | .payload = try self.addExtra(reloc), | |
| 11669 | } }, | |
| 11670 | }), | |
| 11671 | .call => _ = try self.addInst(.{ | |
| 11672 | .tag = .call, | |
| 11673 | .ops = .direct_got_reloc, | |
| 11674 | .data = .{ .reloc = reloc }, | |
| 11675 | }), | |
| 11676 | else => unreachable, | |
| 11677 | } | |
| 11678 | switch (tag) { | |
| 11679 | .lea, .call => {}, | |
| 11680 | .mov => try self.asmRegisterMemory( | |
| 11681 | .{ ._, tag }, | |
| 11682 | reg.to64(), | |
| 11683 | Memory.sib(.qword, .{ .base = .{ .reg = reg.to64() } }), | |
| 11684 | ), | |
| 11685 | else => unreachable, | |
| 11686 | } | |
| 11668 | 11687 | } |
| 11669 | 11688 | } else if (self.bin_file.cast(link.File.Plan9)) |p9_file| { |
| 11670 | 11689 | const atom_index = p9_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err| |
src/arch/x86_64/Emit.zig+9-2| ... | ... | @@ -85,14 +85,21 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 85 | 85 | .linker_tlv, |
| 86 | 86 | => |symbol| if (emit.bin_file.cast(link.File.Elf)) |elf_file| { |
| 87 | 87 | const r_type: u32 = switch (lowered_relocs[0].target) { |
| 88 | .linker_direct_got => std.elf.R_X86_64_GOT32, | |
| 88 | .linker_direct_got => link.File.Elf.R_X86_64_ZIG_GOT32, | |
| 89 | .linker_got => link.File.Elf.R_X86_64_ZIG_GOTPCREL, | |
| 90 | .linker_direct => std.elf.R_X86_64_PC32, | |
| 91 | else => unreachable, | |
| 92 | }; | |
| 93 | const r_addend: i64 = switch (lowered_relocs[0].target) { | |
| 94 | .linker_direct_got => 0, | |
| 95 | .linker_got, .linker_direct => -4, | |
| 89 | 96 | else => unreachable, |
| 90 | 97 | }; |
| 91 | 98 | const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?; |
| 92 | 99 | try atom_ptr.addReloc(elf_file, .{ |
| 93 | 100 | .r_offset = end_offset - 4, |
| 94 | 101 | .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | r_type, |
| 95 | .r_addend = 0, | |
| 102 | .r_addend = r_addend, | |
| 96 | 103 | }); |
| 97 | 104 | } else if (emit.bin_file.cast(link.File.MachO)) |macho_file| { |
| 98 | 105 | const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = symbol.atom_index }).?; |
src/codegen.zig+11-2| ... | ... | @@ -890,7 +890,11 @@ fn genDeclRef( |
| 890 | 890 | const sym_index = try elf_file.getOrCreateMetadataForDecl(decl_index); |
| 891 | 891 | const sym = elf_file.symbol(sym_index); |
| 892 | 892 | _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file); |
| 893 | return GenResult.mcv(.{ .memory = sym.zigGotAddress(elf_file) }); | |
| 893 | if (bin_file.options.pic) { | |
| 894 | return GenResult.mcv(.{ .load_got = sym.esym_index }); | |
| 895 | } else { | |
| 896 | return GenResult.mcv(.{ .memory = sym.zigGotAddress(elf_file) }); | |
| 897 | } | |
| 894 | 898 | } else if (bin_file.cast(link.File.MachO)) |macho_file| { |
| 895 | 899 | const atom_index = try macho_file.getOrCreateAtomForDecl(decl_index); |
| 896 | 900 | const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; |
| ... | ... | @@ -925,7 +929,12 @@ fn genUnnamedConst( |
| 925 | 929 | return GenResult.fail(bin_file.allocator, src_loc, "lowering unnamed constant failed: {s}", .{@errorName(err)}); |
| 926 | 930 | }; |
| 927 | 931 | if (bin_file.cast(link.File.Elf)) |elf_file| { |
| 928 | return GenResult.mcv(.{ .memory = elf_file.symbol(local_sym_index).value }); | |
| 932 | const local = elf_file.symbol(local_sym_index); | |
| 933 | if (bin_file.options.pic) { | |
| 934 | return GenResult.mcv(.{ .load_direct = local.esym_index }); | |
| 935 | } else { | |
| 936 | return GenResult.mcv(.{ .memory = local.value }); | |
| 937 | } | |
| 929 | 938 | } else if (bin_file.cast(link.File.MachO)) |_| { |
| 930 | 939 | return GenResult.mcv(.{ .load_direct = local_sym_index }); |
| 931 | 940 | } else if (bin_file.cast(link.File.Coff)) |_| { |
src/link/Elf.zig+3| ... | ... | @@ -6074,6 +6074,9 @@ const SystemLib = struct { |
| 6074 | 6074 | path: []const u8, |
| 6075 | 6075 | }; |
| 6076 | 6076 | |
| 6077 | pub const R_X86_64_ZIG_GOT32 = elf.R_X86_64_NUM + 1; | |
| 6078 | pub const R_X86_64_ZIG_GOTPCREL = elf.R_X86_64_NUM + 2; | |
| 6079 | ||
| 6077 | 6080 | const std = @import("std"); |
| 6078 | 6081 | const build_options = @import("build_options"); |
| 6079 | 6082 | const builtin = @import("builtin"); |
src/link/Elf/Atom.zig+14-17| ... | ... | @@ -370,16 +370,6 @@ pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype |
| 370 | 370 | try self.scanReloc(symbol, rel, dynAbsRelocAction(symbol, elf_file), elf_file); |
| 371 | 371 | }, |
| 372 | 372 | |
| 373 | // TODO I have temporarily repurposed those for handling .zig.got indirection | |
| 374 | // but we should probably claim unused custom values for incremental linking | |
| 375 | // that get rewritten to standard relocs when lowering to a relocatable object | |
| 376 | // file. | |
| 377 | elf.R_X86_64_GOT32, | |
| 378 | elf.R_X86_64_GOT64, | |
| 379 | => { | |
| 380 | assert(symbol.flags.has_zig_got); | |
| 381 | }, | |
| 382 | ||
| 383 | 373 | elf.R_X86_64_GOTPC32, |
| 384 | 374 | elf.R_X86_64_GOTPC64, |
| 385 | 375 | elf.R_X86_64_GOTPCREL, |
| ... | ... | @@ -461,6 +451,13 @@ pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype |
| 461 | 451 | elf.R_X86_64_TLSDESC_CALL, |
| 462 | 452 | => {}, |
| 463 | 453 | |
| 454 | // Zig custom relocations | |
| 455 | Elf.R_X86_64_ZIG_GOT32, | |
| 456 | Elf.R_X86_64_ZIG_GOTPCREL, | |
| 457 | => { | |
| 458 | assert(symbol.flags.has_zig_got); | |
| 459 | }, | |
| 460 | ||
| 464 | 461 | else => try self.reportUnhandledRelocError(rel, elf_file), |
| 465 | 462 | } |
| 466 | 463 | } |
| ... | ... | @@ -813,13 +810,6 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) !void { |
| 813 | 810 | elf.R_X86_64_32 => try cwriter.writeIntLittle(u32, @as(u32, @truncate(@as(u64, @intCast(S + A))))), |
| 814 | 811 | elf.R_X86_64_32S => try cwriter.writeIntLittle(i32, @as(i32, @truncate(S + A))), |
| 815 | 812 | |
| 816 | // TODO I have temporarily repurposed those for handling .zig.got indirection | |
| 817 | // but we should probably claim unused custom values for incremental linking | |
| 818 | // that get rewritten to standard relocs when lowering to a relocatable object | |
| 819 | // file. | |
| 820 | elf.R_X86_64_GOT32 => try cwriter.writeIntLittle(u32, @as(u32, @intCast(ZIG_GOT + A))), | |
| 821 | elf.R_X86_64_GOT64 => try cwriter.writeIntLittle(u64, @as(u64, @intCast(ZIG_GOT + A))), | |
| 822 | ||
| 823 | 813 | elf.R_X86_64_TPOFF32 => try cwriter.writeIntLittle(i32, @as(i32, @truncate(S + A - TP))), |
| 824 | 814 | elf.R_X86_64_TPOFF64 => try cwriter.writeIntLittle(i64, S + A - TP), |
| 825 | 815 | |
| ... | ... | @@ -888,6 +878,10 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) !void { |
| 888 | 878 | } |
| 889 | 879 | }, |
| 890 | 880 | |
| 881 | // Zig custom relocations | |
| 882 | Elf.R_X86_64_ZIG_GOT32 => try cwriter.writeIntLittle(u32, @as(u32, @intCast(ZIG_GOT + A))), | |
| 883 | Elf.R_X86_64_ZIG_GOTPCREL => try cwriter.writeIntLittle(i32, @as(i32, @intCast(ZIG_GOT + A - P))), | |
| 884 | ||
| 891 | 885 | else => {}, |
| 892 | 886 | } |
| 893 | 887 | } |
| ... | ... | @@ -1136,6 +1130,9 @@ fn formatRelocType( |
| 1136 | 1130 | elf.R_X86_64_GOTPCRELX => "R_X86_64_GOTPCRELX", |
| 1137 | 1131 | elf.R_X86_64_REX_GOTPCRELX => "R_X86_64_REX_GOTPCRELX", |
| 1138 | 1132 | elf.R_X86_64_NUM => "R_X86_64_NUM", |
| 1133 | // Zig custom relocations | |
| 1134 | Elf.R_X86_64_ZIG_GOT32 => "R_X86_64_ZIG_GOT32", | |
| 1135 | Elf.R_X86_64_ZIG_GOTPCREL => "R_X86_64_ZIG_GOTPCREL", | |
| 1139 | 1136 | else => "R_X86_64_UNKNOWN", |
| 1140 | 1137 | }; |
| 1141 | 1138 | try writer.print("{s}", .{str}); |