authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-07-31 11:43:47-07:00
committergravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-07-31 13:39:57-07:00
log9c7aade488c94ddd84477a6d29162ba6b03ce800
tree6664e840cb716cbc847731ee66d98edc5c7af291
parent00089347458b4c2544871666cc09570642b0d5b1
signaturelock-open Commit is signed but in an unrecognized format.

riscv: fix `.got` symbol loading


4 files changed, 55 insertions(+), 3 deletions(-)

src/arch/riscv64/Emit.zig+3
......@@ -63,6 +63,9 @@ pub fn emitMir(emit: *Emit) Error!void {
6363
6464 hi_r_type = Elf.R_ZIG_GOT_HI20;
6565 lo_r_type = Elf.R_ZIG_GOT_LO12;
66 } else if (sym.flags.needs_got) {
67 hi_r_type = Elf.R_GOT_HI20_STATIC; // TODO: rework this #20887
68 lo_r_type = Elf.R_GOT_LO12_I_STATIC; // TODO: rework this #20887
6669 }
6770
6871 try atom_ptr.addReloc(elf_file, .{
src/link/Elf.zig+30-1
......@@ -6059,11 +6059,40 @@ const RelaSection = struct {
60596059};
60606060const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection);
60616061
6062// TODO: add comptime check we don't clobber any reloc for any ISA
60636062pub const R_ZIG_GOT32: u32 = 0xff00;
60646063pub const R_ZIG_GOTPCREL: u32 = 0xff01;
60656064pub const R_ZIG_GOT_HI20: u32 = 0xff02;
60666065pub const R_ZIG_GOT_LO12: u32 = 0xff03;
6066pub const R_GOT_HI20_STATIC: u32 = 0xff04;
6067pub const R_GOT_LO12_I_STATIC: u32 = 0xff05;
6068
6069// Comptime asserts that no Zig relocs overlap with another ISA's reloc number
6070comptime {
6071 const zig_relocs = .{
6072 R_ZIG_GOT32,
6073 R_ZIG_GOT_HI20,
6074 R_ZIG_GOT_LO12,
6075 R_ZIG_GOTPCREL,
6076 R_GOT_HI20_STATIC,
6077 R_GOT_LO12_I_STATIC,
6078 };
6079
6080 const other_relocs = .{
6081 elf.R_X86_64,
6082 elf.R_AARCH64,
6083 elf.R_RISCV,
6084 elf.R_PPC64,
6085 };
6086
6087 @setEvalBranchQuota(@min(other_relocs.len * zig_relocs.len * 256, 6200));
6088 for (other_relocs) |relocs| {
6089 for (@typeInfo(relocs).Enum.fields) |reloc| {
6090 for (zig_relocs) |zig_reloc| {
6091 assert(reloc.value != zig_reloc);
6092 }
6093 }
6094 }
6095}
60676096
60686097fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 {
60696098 return switch (cpu_arch) {
src/link/Elf/Atom.zig+18-2
......@@ -2016,6 +2016,10 @@ const riscv = struct {
20162016 assert(symbol.flags.has_zig_got);
20172017 },
20182018
2019 Elf.R_GOT_HI20_STATIC,
2020 Elf.R_GOT_LO12_I_STATIC,
2021 => symbol.flags.needs_got = true,
2022
20192023 else => try atom.reportUnhandledRelocError(rel, elf_file),
20202024 },
20212025 }
......@@ -2161,16 +2165,28 @@ const riscv = struct {
21612165 // Zig custom relocations
21622166 Elf.R_ZIG_GOT_HI20 => {
21632167 assert(target.flags.has_zig_got);
2164 const disp: u32 = @bitCast(math.cast(i32, G + ZIG_GOT + A) orelse return error.Overflow);
2168 const disp: u32 = @bitCast(math.cast(i32, ZIG_GOT + A) orelse return error.Overflow);
21652169 riscv_util.writeInstU(code[r_offset..][0..4], disp);
21662170 },
21672171
21682172 Elf.R_ZIG_GOT_LO12 => {
21692173 assert(target.flags.has_zig_got);
2170 const value: u32 = @bitCast(math.cast(i32, G + ZIG_GOT + A) orelse return error.Overflow);
2174 const value: u32 = @bitCast(math.cast(i32, ZIG_GOT + A) orelse return error.Overflow);
21712175 riscv_util.writeInstI(code[r_offset..][0..4], value);
21722176 },
21732177
2178 Elf.R_GOT_HI20_STATIC => {
2179 assert(target.flags.has_got);
2180 const disp: u32 = @bitCast(math.cast(i32, G + GOT + A) orelse return error.Overflow);
2181 riscv_util.writeInstU(code[r_offset..][0..4], disp);
2182 },
2183
2184 Elf.R_GOT_LO12_I_STATIC => {
2185 assert(target.flags.has_got);
2186 const disp: u32 = @bitCast(math.cast(i32, G + GOT + A) orelse return error.Overflow);
2187 riscv_util.writeInstI(code[r_offset..][0..4], disp);
2188 },
2189
21742190 else => try atom.reportUnhandledRelocError(rel, elf_file),
21752191 },
21762192 }
src/link/Elf/relocation.zig+4
......@@ -115,6 +115,10 @@ fn formatRelocType(
115115 switch (r_type) {
116116 Elf.R_ZIG_GOT32 => try writer.writeAll("R_ZIG_GOT32"),
117117 Elf.R_ZIG_GOTPCREL => try writer.writeAll("R_ZIG_GOTPCREL"),
118 Elf.R_ZIG_GOT_HI20 => try writer.writeAll("R_ZIG_GOT_HI20"),
119 Elf.R_ZIG_GOT_LO12 => try writer.writeAll("R_ZIG_GOT_LO12"),
120 Elf.R_GOT_HI20_STATIC => try writer.writeAll("R_GOT_HI20_STATIC"),
121 Elf.R_GOT_LO12_I_STATIC => try writer.writeAll("R_GOT_LO12_I_STATIC"),
118122 else => switch (ctx.cpu_arch) {
119123 .x86_64 => try writer.print("R_X86_64_{s}", .{@tagName(@as(elf.R_X86_64, @enumFromInt(r_type)))}),
120124 .aarch64 => try writer.print("R_AARCH64_{s}", .{@tagName(@as(elf.R_AARCH64, @enumFromInt(r_type)))}),