diff options
| author | David Rubin <daviru007@icloud.com> | 2024-07-31 11:43:47 -0700 |
|---|---|---|
| committer | David Rubin <daviru007@icloud.com> | 2024-07-31 13:39:57 -0700 |
| commit | 9c7aade488c94ddd84477a6d29162ba6b03ce800 (patch) | |
| tree | 6664e840cb716cbc847731ee66d98edc5c7af291 /src | |
| parent | 00089347458b4c2544871666cc09570642b0d5b1 (diff) | |
| download | zig-9c7aade488c94ddd84477a6d29162ba6b03ce800.tar.gz zig-9c7aade488c94ddd84477a6d29162ba6b03ce800.zip | |
riscv: fix `.got` symbol loading
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/riscv64/Emit.zig | 3 | ||||
| -rw-r--r-- | src/link/Elf.zig | 31 | ||||
| -rw-r--r-- | src/link/Elf/Atom.zig | 20 | ||||
| -rw-r--r-- | src/link/Elf/relocation.zig | 4 |
4 files changed, 55 insertions, 3 deletions
diff --git a/src/arch/riscv64/Emit.zig b/src/arch/riscv64/Emit.zig index 6c04988e78..beb232b776 100644 --- a/src/arch/riscv64/Emit.zig +++ b/src/arch/riscv64/Emit.zig @@ -63,6 +63,9 @@ pub fn emitMir(emit: *Emit) Error!void { hi_r_type = Elf.R_ZIG_GOT_HI20; lo_r_type = Elf.R_ZIG_GOT_LO12; + } else 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 } try atom_ptr.addReloc(elf_file, .{ diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 982015f61f..469e8da345 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -6059,11 +6059,40 @@ const RelaSection = struct { }; const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection); -// TODO: add comptime check we don't clobber any reloc for any ISA pub const R_ZIG_GOT32: u32 = 0xff00; pub const R_ZIG_GOTPCREL: u32 = 0xff01; pub const R_ZIG_GOT_HI20: u32 = 0xff02; pub const R_ZIG_GOT_LO12: u32 = 0xff03; +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_ZIG_GOT32, + R_ZIG_GOT_HI20, + R_ZIG_GOT_LO12, + R_ZIG_GOTPCREL, + 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) { diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig index 30285f204a..b91b546103 100644 --- a/src/link/Elf/Atom.zig +++ b/src/link/Elf/Atom.zig @@ -2016,6 +2016,10 @@ const riscv = struct { assert(symbol.flags.has_zig_got); }, + Elf.R_GOT_HI20_STATIC, + Elf.R_GOT_LO12_I_STATIC, + => symbol.flags.needs_got = true, + else => try atom.reportUnhandledRelocError(rel, elf_file), }, } @@ -2161,16 +2165,28 @@ const riscv = struct { // Zig custom relocations Elf.R_ZIG_GOT_HI20 => { assert(target.flags.has_zig_got); - const disp: u32 = @bitCast(math.cast(i32, G + ZIG_GOT + A) orelse return error.Overflow); + const disp: u32 = @bitCast(math.cast(i32, ZIG_GOT + A) orelse return error.Overflow); riscv_util.writeInstU(code[r_offset..][0..4], disp); }, Elf.R_ZIG_GOT_LO12 => { assert(target.flags.has_zig_got); - const value: u32 = @bitCast(math.cast(i32, G + ZIG_GOT + A) orelse return error.Overflow); + const value: u32 = @bitCast(math.cast(i32, ZIG_GOT + A) orelse return error.Overflow); riscv_util.writeInstI(code[r_offset..][0..4], value); }, + 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), }, } diff --git a/src/link/Elf/relocation.zig b/src/link/Elf/relocation.zig index 3c8afa3c12..5f6810d6f9 100644 --- a/src/link/Elf/relocation.zig +++ b/src/link/Elf/relocation.zig @@ -115,6 +115,10 @@ fn formatRelocType( switch (r_type) { Elf.R_ZIG_GOT32 => try writer.writeAll("R_ZIG_GOT32"), Elf.R_ZIG_GOTPCREL => try writer.writeAll("R_ZIG_GOTPCREL"), + Elf.R_ZIG_GOT_HI20 => try writer.writeAll("R_ZIG_GOT_HI20"), + Elf.R_ZIG_GOT_LO12 => try writer.writeAll("R_ZIG_GOT_LO12"), + 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)))}), |
