riscv: do not emit GOT relocations for special linker symbols

This commit is contained in:
Jakub Konka 2024-08-15 10:21:20 +02:00
parent 8a0cb7002e
commit 0fd0b11bc4
5 changed files with 17 additions and 66 deletions

View File

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

View File

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

View File

@ -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",

View File

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

View File

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