authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-15 10:21:20+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-15 10:21:20+02:00
log0fd0b11bc43a6053c68f649e1e1a1e23b995a266
tree2826a6066d838f456b3cc537aa199e9f11e9a8fe
parent8a0cb7002e6b8f7b50fdf7ee40311ce93fbef009

riscv: do not emit GOT relocations for special linker symbols


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

src/arch/riscv64/Emit.zig+9-6
...@@ -49,14 +49,17 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -49,14 +49,17 @@ pub fn emitMir(emit: *Emit) Error!void {
49 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;49 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;
50 const sym = zo.symbol(symbol.sym_index);50 const sym = zo.symbol(symbol.sym_index);
5151
52 var hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);52 if (sym.flags.is_extern_ptr) blk: {
53 var lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);53 const name = sym.name(elf_file);
5454 if (mem.eql(u8, "__init_array_start", name) or mem.eql(u8, "__init_array_end", name) or
55 if (sym.flags.needs_got) {55 mem.eql(u8, "__fini_array_start", name) or mem.eql(u8, "__fini_array_end", name))
56 hi_r_type = Elf.R_GOT_HI20_STATIC; // TODO: rework this #2088756 break :blk;
57 lo_r_type = Elf.R_GOT_LO12_I_STATIC; // TODO: rework this #2088757 return emit.fail("emit GOT relocation for symbol '{s}'", .{name});
58 }58 }
5959
60 const hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);
61 const lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);
62
60 try atom_ptr.addReloc(elf_file, .{63 try atom_ptr.addReloc(elf_file, .{
61 .r_offset = start_offset,64 .r_offset = start_offset,
62 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | hi_r_type,65 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | hi_r_type,
src/codegen.zig+1-1
...@@ -900,7 +900,7 @@ fn genNavRef(...@@ -900,7 +900,7 @@ fn genNavRef(
900 if (is_extern) {900 if (is_extern) {
901 const sym_index = try elf_file.getGlobalSymbol(name.toSlice(ip), lib_name.toSlice(ip));901 const sym_index = try elf_file.getGlobalSymbol(name.toSlice(ip), lib_name.toSlice(ip));
902 zo.symbol(sym_index).flags.is_extern_ptr = true;902 zo.symbol(sym_index).flags.is_extern_ptr = true;
903 return GenResult.mcv(.{ .load_symbol = sym_index });903 return GenResult.mcv(.{ .lea_symbol = sym_index });
904 }904 }
905 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, nav_index);905 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, nav_index);
906 if (!single_threaded and is_threadlocal) {906 if (!single_threaded and is_threadlocal) {
src/link/Elf.zig-27
...@@ -5934,33 +5934,6 @@ const RelaSection = struct {...@@ -5934,33 +5934,6 @@ const RelaSection = struct {
5934};5934};
5935const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection);5935const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection);
59365936
5937pub const R_GOT_HI20_STATIC: u32 = 0xff04;
5938pub const R_GOT_LO12_I_STATIC: u32 = 0xff05;
5939
5940// Comptime asserts that no Zig relocs overlap with another ISA's reloc number
5941comptime {
5942 const zig_relocs = .{
5943 R_GOT_HI20_STATIC,
5944 R_GOT_LO12_I_STATIC,
5945 };
5946
5947 const other_relocs = .{
5948 elf.R_X86_64,
5949 elf.R_AARCH64,
5950 elf.R_RISCV,
5951 elf.R_PPC64,
5952 };
5953
5954 @setEvalBranchQuota(@min(other_relocs.len * zig_relocs.len * 256, 6200));
5955 for (other_relocs) |relocs| {
5956 for (@typeInfo(relocs).Enum.fields) |reloc| {
5957 for (zig_relocs) |zig_reloc| {
5958 assert(reloc.value != zig_reloc);
5959 }
5960 }
5961 }
5962}
5963
5964fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 {5937fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 {
5965 return switch (cpu_arch) {5938 return switch (cpu_arch) {
5966 .mips, .mipsel, .mips64, .mips64el => "__start",5939 .mips, .mipsel, .mips64, .mips64el => "__start",
src/link/Elf/Atom.zig+2-23
...@@ -1978,13 +1978,7 @@ const riscv = struct {...@@ -1978,13 +1978,7 @@ const riscv = struct {
1978 .SUB32,1978 .SUB32,
1979 => {},1979 => {},
19801980
1981 else => |x| switch (@intFromEnum(x)) {1981 else => try atom.reportUnhandledRelocError(rel, elf_file),
1982 Elf.R_GOT_HI20_STATIC,
1983 Elf.R_GOT_LO12_I_STATIC,
1984 => symbol.flags.needs_got = true,
1985
1986 else => try atom.reportUnhandledRelocError(rel, elf_file),
1987 },
1988 }1982 }
1989 }1983 }
19901984
...@@ -2121,22 +2115,7 @@ const riscv = struct {...@@ -2121,22 +2115,7 @@ const riscv = struct {
2121 // TODO: annotates an ADD instruction that can be removed when TPREL is relaxed2115 // TODO: annotates an ADD instruction that can be removed when TPREL is relaxed
2122 },2116 },
21232117
2124 else => |x| switch (@intFromEnum(x)) {2118 else => try atom.reportUnhandledRelocError(rel, elf_file),
2125 // Zig custom relocations
2126 Elf.R_GOT_HI20_STATIC => {
2127 assert(target.flags.has_got);
2128 const disp: u32 = @bitCast(math.cast(i32, G + GOT + A) orelse return error.Overflow);
2129 riscv_util.writeInstU(code[r_offset..][0..4], disp);
2130 },
2131
2132 Elf.R_GOT_LO12_I_STATIC => {
2133 assert(target.flags.has_got);
2134 const disp: u32 = @bitCast(math.cast(i32, G + GOT + A) orelse return error.Overflow);
2135 riscv_util.writeInstI(code[r_offset..][0..4], disp);
2136 },
2137
2138 else => try atom.reportUnhandledRelocError(rel, elf_file),
2139 },
2140 }2119 }
2141 }2120 }
21422121
src/link/Elf/relocation.zig+5-9
...@@ -112,15 +112,11 @@ fn formatRelocType(...@@ -112,15 +112,11 @@ fn formatRelocType(
112 _ = unused_fmt_string;112 _ = unused_fmt_string;
113 _ = options;113 _ = options;
114 const r_type = ctx.r_type;114 const r_type = ctx.r_type;
115 switch (r_type) {115 switch (ctx.cpu_arch) {
116 Elf.R_GOT_HI20_STATIC => try writer.writeAll("R_GOT_HI20_STATIC"),116 .x86_64 => try writer.print("R_X86_64_{s}", .{@tagName(@as(elf.R_X86_64, @enumFromInt(r_type)))}),
117 Elf.R_GOT_LO12_I_STATIC => try writer.writeAll("R_GOT_LO12_I_STATIC"),117 .aarch64 => try writer.print("R_AARCH64_{s}", .{@tagName(@as(elf.R_AARCH64, @enumFromInt(r_type)))}),
118 else => switch (ctx.cpu_arch) {118 .riscv64 => try writer.print("R_RISCV_{s}", .{@tagName(@as(elf.R_RISCV, @enumFromInt(r_type)))}),
119 .x86_64 => try writer.print("R_X86_64_{s}", .{@tagName(@as(elf.R_X86_64, @enumFromInt(r_type)))}),119 else => unreachable,
120 .aarch64 => try writer.print("R_AARCH64_{s}", .{@tagName(@as(elf.R_AARCH64, @enumFromInt(r_type)))}),
121 .riscv64 => try writer.print("R_RISCV_{s}", .{@tagName(@as(elf.R_RISCV, @enumFromInt(r_type)))}),
122 else => unreachable,
123 },
124 }120 }
125}121}
126122