riscv: fix .got symbol loading

This commit is contained in:
David Rubin 2024-07-31 11:43:47 -07:00
parent 0008934745
commit 9c7aade488
No known key found for this signature in database
GPG Key ID: A4390FEB5F00C0A5
4 changed files with 55 additions and 3 deletions

View File

@ -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, .{

View File

@ -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) {

View File

@ -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),
},
}

View File

@ -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)))}),