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 {
4949 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;
5050 const sym = zo.symbol(symbol.sym_index);
5151
52 var hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);
53 var lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);
54
55 if (sym.flags.needs_got) {
56 hi_r_type = Elf.R_GOT_HI20_STATIC; // TODO: rework this #20887
57 lo_r_type = Elf.R_GOT_LO12_I_STATIC; // TODO: rework this #20887
52 if (sym.flags.is_extern_ptr) blk: {
53 const name = sym.name(elf_file);
54 if (mem.eql(u8, "__init_array_start", name) or mem.eql(u8, "__init_array_end", name) or
55 mem.eql(u8, "__fini_array_start", name) or mem.eql(u8, "__fini_array_end", name))
56 break :blk;
57 return emit.fail("emit GOT relocation for symbol '{s}'", .{name});
5858 }
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
6063 try atom_ptr.addReloc(elf_file, .{
6164 .r_offset = start_offset,
6265 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | hi_r_type,
src/codegen.zig+1-1
......@@ -900,7 +900,7 @@ fn genNavRef(
900900 if (is_extern) {
901901 const sym_index = try elf_file.getGlobalSymbol(name.toSlice(ip), lib_name.toSlice(ip));
902902 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 });
904904 }
905905 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, nav_index);
906906 if (!single_threaded and is_threadlocal) {
src/link/Elf.zig-27
......@@ -5934,33 +5934,6 @@ const RelaSection = struct {
59345934};
59355935const 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
59645937fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 {
59655938 return switch (cpu_arch) {
59665939 .mips, .mipsel, .mips64, .mips64el => "__start",
src/link/Elf/Atom.zig+2-23
......@@ -1978,13 +1978,7 @@ const riscv = struct {
19781978 .SUB32,
19791979 => {},
19801980
1981 else => |x| switch (@intFromEnum(x)) {
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 },
1981 else => try atom.reportUnhandledRelocError(rel, elf_file),
19881982 }
19891983 }
19901984
......@@ -2121,22 +2115,7 @@ const riscv = struct {
21212115 // TODO: annotates an ADD instruction that can be removed when TPREL is relaxed
21222116 },
21232117
2124 else => |x| switch (@intFromEnum(x)) {
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 },
2118 else => try atom.reportUnhandledRelocError(rel, elf_file),
21402119 }
21412120 }
21422121
src/link/Elf/relocation.zig+5-9
......@@ -112,15 +112,11 @@ fn formatRelocType(
112112 _ = unused_fmt_string;
113113 _ = options;
114114 const r_type = ctx.r_type;
115 switch (r_type) {
116 Elf.R_GOT_HI20_STATIC => try writer.writeAll("R_GOT_HI20_STATIC"),
117 Elf.R_GOT_LO12_I_STATIC => try writer.writeAll("R_GOT_LO12_I_STATIC"),
118 else => switch (ctx.cpu_arch) {
119 .x86_64 => try writer.print("R_X86_64_{s}", .{@tagName(@as(elf.R_X86_64, @enumFromInt(r_type)))}),
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 },
115 switch (ctx.cpu_arch) {
116 .x86_64 => try writer.print("R_X86_64_{s}", .{@tagName(@as(elf.R_X86_64, @enumFromInt(r_type)))}),
117 .aarch64 => try writer.print("R_AARCH64_{s}", .{@tagName(@as(elf.R_AARCH64, @enumFromInt(r_type)))}),
118 .riscv64 => try writer.print("R_RISCV_{s}", .{@tagName(@as(elf.R_RISCV, @enumFromInt(r_type)))}),
119 else => unreachable,
124120 }
125121}
126122