Commit 0fd0b11bc4

Jakub Konka <kubkon@jakubkonka.com>
2024-08-15 10:21:20
riscv: do not emit GOT relocations for special linker symbols
1 parent 8a0cb70
Changed files (5)
src/arch/riscv64/Emit.zig
@@ -49,14 +49,17 @@ pub fn emitMir(emit: *Emit) Error!void {
                     const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;
                     const sym = zo.symbol(symbol.sym_index);
 
-                    var hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);
-                    var lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);
-
-                    if (sym.flags.needs_got) {
-                        hi_r_type = Elf.R_GOT_HI20_STATIC; // TODO: rework this #20887
-                        lo_r_type = Elf.R_GOT_LO12_I_STATIC; // TODO: rework this #20887
+                    if (sym.flags.is_extern_ptr) blk: {
+                        const name = sym.name(elf_file);
+                        if (mem.eql(u8, "__init_array_start", name) or mem.eql(u8, "__init_array_end", name) or
+                            mem.eql(u8, "__fini_array_start", name) or mem.eql(u8, "__fini_array_end", name))
+                            break :blk;
+                        return emit.fail("emit GOT relocation for symbol '{s}'", .{name});
                     }
 
+                    const hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);
+                    const lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);
+
                     try atom_ptr.addReloc(elf_file, .{
                         .r_offset = start_offset,
                         .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | hi_r_type,
src/link/Elf/Atom.zig
@@ -1978,13 +1978,7 @@ const riscv = struct {
             .SUB32,
             => {},
 
-            else => |x| switch (@intFromEnum(x)) {
-                Elf.R_GOT_HI20_STATIC,
-                Elf.R_GOT_LO12_I_STATIC,
-                => symbol.flags.needs_got = true,
-
-                else => try atom.reportUnhandledRelocError(rel, elf_file),
-            },
+            else => try atom.reportUnhandledRelocError(rel, elf_file),
         }
     }
 
@@ -2121,22 +2115,7 @@ const riscv = struct {
                 // TODO: annotates an ADD instruction that can be removed when TPREL is relaxed
             },
 
-            else => |x| switch (@intFromEnum(x)) {
-                // Zig custom relocations
-                Elf.R_GOT_HI20_STATIC => {
-                    assert(target.flags.has_got);
-                    const disp: u32 = @bitCast(math.cast(i32, G + GOT + A) orelse return error.Overflow);
-                    riscv_util.writeInstU(code[r_offset..][0..4], disp);
-                },
-
-                Elf.R_GOT_LO12_I_STATIC => {
-                    assert(target.flags.has_got);
-                    const disp: u32 = @bitCast(math.cast(i32, G + GOT + A) orelse return error.Overflow);
-                    riscv_util.writeInstI(code[r_offset..][0..4], disp);
-                },
-
-                else => try atom.reportUnhandledRelocError(rel, elf_file),
-            },
+            else => try atom.reportUnhandledRelocError(rel, elf_file),
         }
     }
 
src/link/Elf/relocation.zig
@@ -112,15 +112,11 @@ fn formatRelocType(
     _ = unused_fmt_string;
     _ = options;
     const r_type = ctx.r_type;
-    switch (r_type) {
-        Elf.R_GOT_HI20_STATIC => try writer.writeAll("R_GOT_HI20_STATIC"),
-        Elf.R_GOT_LO12_I_STATIC => try writer.writeAll("R_GOT_LO12_I_STATIC"),
-        else => switch (ctx.cpu_arch) {
-            .x86_64 => try writer.print("R_X86_64_{s}", .{@tagName(@as(elf.R_X86_64, @enumFromInt(r_type)))}),
-            .aarch64 => try writer.print("R_AARCH64_{s}", .{@tagName(@as(elf.R_AARCH64, @enumFromInt(r_type)))}),
-            .riscv64 => try writer.print("R_RISCV_{s}", .{@tagName(@as(elf.R_RISCV, @enumFromInt(r_type)))}),
-            else => unreachable,
-        },
+    switch (ctx.cpu_arch) {
+        .x86_64 => try writer.print("R_X86_64_{s}", .{@tagName(@as(elf.R_X86_64, @enumFromInt(r_type)))}),
+        .aarch64 => try writer.print("R_AARCH64_{s}", .{@tagName(@as(elf.R_AARCH64, @enumFromInt(r_type)))}),
+        .riscv64 => try writer.print("R_RISCV_{s}", .{@tagName(@as(elf.R_RISCV, @enumFromInt(r_type)))}),
+        else => unreachable,
     }
 }
 
src/link/Elf.zig
@@ -5934,33 +5934,6 @@ const RelaSection = struct {
 };
 const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection);
 
-pub const R_GOT_HI20_STATIC: u32 = 0xff04;
-pub const R_GOT_LO12_I_STATIC: u32 = 0xff05;
-
-// Comptime asserts that no Zig relocs overlap with another ISA's reloc number
-comptime {
-    const zig_relocs = .{
-        R_GOT_HI20_STATIC,
-        R_GOT_LO12_I_STATIC,
-    };
-
-    const other_relocs = .{
-        elf.R_X86_64,
-        elf.R_AARCH64,
-        elf.R_RISCV,
-        elf.R_PPC64,
-    };
-
-    @setEvalBranchQuota(@min(other_relocs.len * zig_relocs.len * 256, 6200));
-    for (other_relocs) |relocs| {
-        for (@typeInfo(relocs).Enum.fields) |reloc| {
-            for (zig_relocs) |zig_reloc| {
-                assert(reloc.value != zig_reloc);
-            }
-        }
-    }
-}
-
 fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 {
     return switch (cpu_arch) {
         .mips, .mipsel, .mips64, .mips64el => "__start",
src/codegen.zig
@@ -900,7 +900,7 @@ fn genNavRef(
         if (is_extern) {
             const sym_index = try elf_file.getGlobalSymbol(name.toSlice(ip), lib_name.toSlice(ip));
             zo.symbol(sym_index).flags.is_extern_ptr = true;
-            return GenResult.mcv(.{ .load_symbol = sym_index });
+            return GenResult.mcv(.{ .lea_symbol = sym_index });
         }
         const sym_index = try zo.getOrCreateMetadataForNav(elf_file, nav_index);
         if (!single_threaded and is_threadlocal) {