aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2024-02-17 19:35:09 +0100
committerGitHub <noreply@github.com>2024-02-17 19:35:09 +0100
commit79e99c401ca32031d29aff77e43758ca0b67d5d9 (patch)
treef3edc8133467b6be6d7114a6fb0bec4105505c83 /src
parentdd4d320eb9663c7a0ef8dbe3aca220a64795d683 (diff)
parentd1429a8fa98f85c9fb8d2bd99b7c31eb9de38b38 (diff)
downloadzig-79e99c401ca32031d29aff77e43758ca0b67d5d9.tar.gz
zig-79e99c401ca32031d29aff77e43758ca0b67d5d9.zip
Merge pull request #18973 from ziglang/elf-riscv
lib/std/elf: refactor relocation types + add RISCV relocs
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86_64/Emit.zig26
-rw-r--r--src/link/Elf.zig5
-rw-r--r--src/link/Elf/Atom.zig199
-rw-r--r--src/link/Elf/eh_frame.zig11
-rw-r--r--src/link/Elf/relocation.zig285
5 files changed, 202 insertions, 324 deletions
diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig
index b78b56efed..0975104db3 100644
--- a/src/arch/x86_64/Emit.zig
+++ b/src/arch/x86_64/Emit.zig
@@ -43,9 +43,10 @@ pub fn emitMir(emit: *Emit) Error!void {
.linker_extern_fn => |symbol| if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| {
// Add relocation to the decl.
const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;
+ const r_type = @intFromEnum(std.elf.R_X86_64.PLT32);
try atom_ptr.addReloc(elf_file, .{
.r_offset = end_offset - 4,
- .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | std.elf.R_X86_64_PLT32,
+ .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | r_type,
.r_addend = -4,
});
} else if (emit.lower.bin_file.cast(link.File.MachO)) |macho_file| {
@@ -88,18 +89,20 @@ pub fn emitMir(emit: *Emit) Error!void {
.linker_tlsld => |data| {
const elf_file = emit.lower.bin_file.cast(link.File.Elf).?;
const atom = elf_file.symbol(data.atom_index).atom(elf_file).?;
+ const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD);
try atom.addReloc(elf_file, .{
.r_offset = end_offset - 4,
- .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | std.elf.R_X86_64_TLSLD,
+ .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type,
.r_addend = -4,
});
},
.linker_dtpoff => |data| {
const elf_file = emit.lower.bin_file.cast(link.File.Elf).?;
const atom = elf_file.symbol(data.atom_index).atom(elf_file).?;
+ const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32);
try atom.addReloc(elf_file, .{
.r_offset = end_offset - 4,
- .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | std.elf.R_X86_64_DTPOFF32,
+ .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type,
.r_addend = 0,
});
},
@@ -117,11 +120,11 @@ pub fn emitMir(emit: *Emit) Error!void {
}
if (emit.lower.pic) {
const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)
- link.File.Elf.R_X86_64_ZIG_GOTPCREL
+ link.File.Elf.R_ZIG_GOTPCREL
else if (sym.flags.needs_got)
- std.elf.R_X86_64_GOTPCREL
+ @intFromEnum(std.elf.R_X86_64.GOTPCREL)
else
- std.elf.R_X86_64_PC32;
+ @intFromEnum(std.elf.R_X86_64.PC32);
try atom.addReloc(elf_file, .{
.r_offset = end_offset - 4,
.r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type,
@@ -129,20 +132,21 @@ pub fn emitMir(emit: *Emit) Error!void {
});
} else {
if (lowered_inst.encoding.mnemonic == .call and sym.flags.needs_zig_got and is_obj_or_static_lib) {
+ const r_type = @intFromEnum(std.elf.R_X86_64.PC32);
try atom.addReloc(elf_file, .{
.r_offset = end_offset - 4,
- .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | std.elf.R_X86_64_PC32,
+ .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type,
.r_addend = -4,
});
} else {
const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)
- link.File.Elf.R_X86_64_ZIG_GOT32
+ link.File.Elf.R_ZIG_GOT32
else if (sym.flags.needs_got)
- std.elf.R_X86_64_GOT32
+ @intFromEnum(std.elf.R_X86_64.GOT32)
else if (sym.flags.is_tls)
- std.elf.R_X86_64_TPOFF32
+ @intFromEnum(std.elf.R_X86_64.TPOFF32)
else
- std.elf.R_X86_64_32;
+ @intFromEnum(std.elf.R_X86_64.@"32");
try atom.addReloc(elf_file, .{
.r_offset = end_offset - 4,
.r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type,
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
index 041db6c0d5..a6625556e6 100644
--- a/src/link/Elf.zig
+++ b/src/link/Elf.zig
@@ -6065,8 +6065,9 @@ const RelaSection = struct {
};
const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection);
-pub const R_X86_64_ZIG_GOT32 = elf.R_X86_64_NUM + 1;
-pub const R_X86_64_ZIG_GOTPCREL = elf.R_X86_64_NUM + 2;
+// 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;
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 72e7e6bcc0..3064fd6f74 100644
--- a/src/link/Elf/Atom.zig
+++ b/src/link/Elf/Atom.zig
@@ -336,7 +336,7 @@ pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.El
}
relocs_log.debug(" {s}: [{x} => {d}({s})] + {x}", .{
- relocation.fmtRelocType(r_type, cpu_arch),
+ relocation.fmtRelocType(rel.r_type(), cpu_arch),
r_offset,
r_sym,
target.name(elf_file),
@@ -384,7 +384,10 @@ pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) bool {
const cpu_arch = elf_file.getTarget().cpu.arch;
for (self.relocs(elf_file)) |rel| {
switch (cpu_arch) {
- .x86_64 => if (rel.r_type() == elf.R_X86_64_GOTTPOFF) return true,
+ .x86_64 => {
+ const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type());
+ if (r_type == .GOTTPOFF) return true;
+ },
else => {},
}
}
@@ -836,8 +839,9 @@ const x86_64 = struct {
var i: usize = 0;
while (i < rels.len) : (i += 1) {
const rel = rels[i];
+ const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type());
- if (rel.r_type() == elf.R_X86_64_NONE) continue;
+ if (r_type == .NONE) continue;
const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow;
@@ -869,41 +873,41 @@ const x86_64 = struct {
// While traversing relocations, mark symbols that require special handling such as
// pointer indirection via GOT, or a stub trampoline via PLT.
- switch (rel.r_type()) {
- elf.R_X86_64_64 => {
+ switch (r_type) {
+ .@"64" => {
try atom.scanReloc(symbol, rel, dynAbsRelocAction(symbol, elf_file), elf_file);
},
- elf.R_X86_64_32,
- elf.R_X86_64_32S,
+ .@"32",
+ .@"32S",
=> {
try atom.scanReloc(symbol, rel, dynAbsRelocAction(symbol, elf_file), elf_file);
},
- elf.R_X86_64_GOT32,
- elf.R_X86_64_GOTPC32,
- elf.R_X86_64_GOTPC64,
- elf.R_X86_64_GOTPCREL,
- elf.R_X86_64_GOTPCREL64,
- elf.R_X86_64_GOTPCRELX,
- elf.R_X86_64_REX_GOTPCRELX,
+ .GOT32,
+ .GOTPC32,
+ .GOTPC64,
+ .GOTPCREL,
+ .GOTPCREL64,
+ .GOTPCRELX,
+ .REX_GOTPCRELX,
=> {
symbol.flags.needs_got = true;
},
- elf.R_X86_64_PLT32,
- elf.R_X86_64_PLTOFF64,
+ .PLT32,
+ .PLTOFF64,
=> {
if (symbol.flags.import) {
symbol.flags.needs_plt = true;
}
},
- elf.R_X86_64_PC32 => {
+ .PC32 => {
try atom.scanReloc(symbol, rel, pcRelocAction(symbol, elf_file), elf_file);
},
- elf.R_X86_64_TLSGD => {
+ .TLSGD => {
// TODO verify followed by appropriate relocation such as PLT32 __tls_get_addr
if (is_static or (!symbol.flags.import and !is_dyn_lib)) {
@@ -918,7 +922,7 @@ const x86_64 = struct {
}
},
- elf.R_X86_64_TLSLD => {
+ .TLSLD => {
// TODO verify followed by appropriate relocation such as PLT32 __tls_get_addr
if (is_static or !is_dyn_lib) {
@@ -930,7 +934,7 @@ const x86_64 = struct {
}
},
- elf.R_X86_64_GOTTPOFF => {
+ .GOTTPOFF => {
const should_relax = blk: {
if (is_dyn_lib or symbol.flags.import) break :blk false;
if (!x86_64.canRelaxGotTpOff(code.?[r_offset - 3 ..])) break :blk false;
@@ -941,35 +945,37 @@ const x86_64 = struct {
}
},
- elf.R_X86_64_GOTPC32_TLSDESC => {
+ .GOTPC32_TLSDESC => {
const should_relax = is_static or (!is_dyn_lib and !symbol.flags.import);
if (!should_relax) {
symbol.flags.needs_tlsdesc = true;
}
},
- elf.R_X86_64_TPOFF32,
- elf.R_X86_64_TPOFF64,
+ .TPOFF32,
+ .TPOFF64,
=> {
if (is_dyn_lib) try atom.reportPicError(symbol, rel, elf_file);
},
- elf.R_X86_64_GOTOFF64,
- elf.R_X86_64_DTPOFF32,
- elf.R_X86_64_DTPOFF64,
- elf.R_X86_64_SIZE32,
- elf.R_X86_64_SIZE64,
- elf.R_X86_64_TLSDESC_CALL,
+ .GOTOFF64,
+ .DTPOFF32,
+ .DTPOFF64,
+ .SIZE32,
+ .SIZE64,
+ .TLSDESC_CALL,
=> {},
- // Zig custom relocations
- Elf.R_X86_64_ZIG_GOT32,
- Elf.R_X86_64_ZIG_GOTPCREL,
- => {
- assert(symbol.flags.has_zig_got);
- },
+ else => |x| switch (@intFromEnum(x)) {
+ // Zig custom relocations
+ Elf.R_ZIG_GOT32,
+ Elf.R_ZIG_GOTPCREL,
+ => {
+ assert(symbol.flags.has_zig_got);
+ },
- else => try atom.reportUnhandledRelocError(rel, elf_file),
+ else => try atom.reportUnhandledRelocError(rel, elf_file),
+ },
}
}
}
@@ -983,8 +989,8 @@ const x86_64 = struct {
var i: usize = 0;
while (i < rels.len) : (i += 1) {
const rel = rels[i];
- const r_type = rel.r_type();
- if (r_type == elf.R_X86_64_NONE) continue;
+ const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type());
+ if (r_type == .NONE) continue;
const target = switch (file_ptr) {
.zig_object => |x| elf_file.symbol(x.symbol(rel.r_sym())),
@@ -1022,7 +1028,7 @@ const x86_64 = struct {
const DTP = @as(i64, @intCast(elf_file.dtpAddress()));
relocs_log.debug(" {s}: {x}: [{x} => {x}] G({x}) ZG({x}) ({s})", .{
- relocation.fmtRelocType(r_type, .x86_64),
+ relocation.fmtRelocType(rel.r_type(), .x86_64),
r_offset,
P,
S + A,
@@ -1033,10 +1039,10 @@ const x86_64 = struct {
try stream.seekTo(r_offset);
- switch (rel.r_type()) {
- elf.R_X86_64_NONE => unreachable,
+ switch (r_type) {
+ .NONE => unreachable,
- elf.R_X86_64_64 => {
+ .@"64" => {
try atom.resolveDynAbsReloc(
target,
rel,
@@ -1046,15 +1052,15 @@ const x86_64 = struct {
);
},
- elf.R_X86_64_PLT32,
- elf.R_X86_64_PC32,
+ .PLT32,
+ .PC32,
=> try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little),
- elf.R_X86_64_GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little),
- elf.R_X86_64_GOTPC32 => try cwriter.writeInt(i32, @as(i32, @intCast(GOT + A - P)), .little),
- elf.R_X86_64_GOTPC64 => try cwriter.writeInt(i64, GOT + A - P, .little),
+ .GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little),
+ .GOTPC32 => try cwriter.writeInt(i32, @as(i32, @intCast(GOT + A - P)), .little),
+ .GOTPC64 => try cwriter.writeInt(i64, GOT + A - P, .little),
- elf.R_X86_64_GOTPCRELX => {
+ .GOTPCRELX => {
if (!target.flags.import and !target.isIFunc(elf_file) and !target.isAbs(elf_file)) blk: {
x86_64.relaxGotpcrelx(code[r_offset - 2 ..]) catch break :blk;
try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little);
@@ -1063,7 +1069,7 @@ const x86_64 = struct {
try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little);
},
- elf.R_X86_64_REX_GOTPCRELX => {
+ .REX_GOTPCRELX => {
if (!target.flags.import and !target.isIFunc(elf_file) and !target.isAbs(elf_file)) blk: {
x86_64.relaxRexGotpcrelx(code[r_offset - 3 ..]) catch break :blk;
try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little);
@@ -1072,16 +1078,16 @@ const x86_64 = struct {
try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little);
},
- elf.R_X86_64_32 => try cwriter.writeInt(u32, @as(u32, @truncate(@as(u64, @intCast(S + A)))), .little),
- elf.R_X86_64_32S => try cwriter.writeInt(i32, @as(i32, @truncate(S + A)), .little),
+ .@"32" => try cwriter.writeInt(u32, @as(u32, @truncate(@as(u64, @intCast(S + A)))), .little),
+ .@"32S" => try cwriter.writeInt(i32, @as(i32, @truncate(S + A)), .little),
- elf.R_X86_64_TPOFF32 => try cwriter.writeInt(i32, @as(i32, @truncate(S + A - TP)), .little),
- elf.R_X86_64_TPOFF64 => try cwriter.writeInt(i64, S + A - TP, .little),
+ .TPOFF32 => try cwriter.writeInt(i32, @as(i32, @truncate(S + A - TP)), .little),
+ .TPOFF64 => try cwriter.writeInt(i64, S + A - TP, .little),
- elf.R_X86_64_DTPOFF32 => try cwriter.writeInt(i32, @as(i32, @truncate(S + A - DTP)), .little),
- elf.R_X86_64_DTPOFF64 => try cwriter.writeInt(i64, S + A - DTP, .little),
+ .DTPOFF32 => try cwriter.writeInt(i32, @as(i32, @truncate(S + A - DTP)), .little),
+ .DTPOFF64 => try cwriter.writeInt(i64, S + A - DTP, .little),
- elf.R_X86_64_TLSGD => {
+ .TLSGD => {
if (target.flags.has_tlsgd) {
const S_ = @as(i64, @intCast(target.tlsGdAddress(elf_file)));
try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little);
@@ -1101,7 +1107,7 @@ const x86_64 = struct {
}
},
- elf.R_X86_64_TLSLD => {
+ .TLSLD => {
if (elf_file.got.tlsld_index) |entry_index| {
const tlsld_entry = elf_file.got.entries.items[entry_index];
const S_ = @as(i64, @intCast(tlsld_entry.address(elf_file)));
@@ -1118,7 +1124,7 @@ const x86_64 = struct {
}
},
- elf.R_X86_64_GOTPC32_TLSDESC => {
+ .GOTPC32_TLSDESC => {
if (target.flags.has_tlsdesc) {
const S_ = @as(i64, @intCast(target.tlsDescAddress(elf_file)));
try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little);
@@ -1128,12 +1134,12 @@ const x86_64 = struct {
}
},
- elf.R_X86_64_TLSDESC_CALL => if (!target.flags.has_tlsdesc) {
+ .TLSDESC_CALL => if (!target.flags.has_tlsdesc) {
// call -> nop
try cwriter.writeAll(&.{ 0x66, 0x90 });
},
- elf.R_X86_64_GOTTPOFF => {
+ .GOTTPOFF => {
if (target.flags.has_gottp) {
const S_ = @as(i64, @intCast(target.gotTpAddress(elf_file)));
try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little);
@@ -1143,13 +1149,15 @@ const x86_64 = struct {
}
},
- elf.R_X86_64_GOT32 => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A)), .little),
+ .GOT32 => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A)), .little),
- // Zig custom relocations
- Elf.R_X86_64_ZIG_GOT32 => try cwriter.writeInt(u32, @as(u32, @intCast(ZIG_GOT + A)), .little),
- Elf.R_X86_64_ZIG_GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(ZIG_GOT + A - P)), .little),
+ else => |x| switch (@intFromEnum(x)) {
+ // Zig custom relocations
+ Elf.R_ZIG_GOT32 => try cwriter.writeInt(u32, @as(u32, @intCast(ZIG_GOT + A)), .little),
+ Elf.R_ZIG_GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(ZIG_GOT + A - P)), .little),
- else => {},
+ else => {},
+ },
}
}
}
@@ -1163,8 +1171,8 @@ const x86_64 = struct {
var i: usize = 0;
while (i < rels.len) : (i += 1) {
const rel = rels[i];
- const r_type = rel.r_type();
- if (r_type == elf.R_X86_64_NONE) continue;
+ const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type());
+ if (r_type == .NONE) continue;
const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow;
@@ -1210,8 +1218,8 @@ const x86_64 = struct {
// Address of the dynamic thread pointer.
const DTP = @as(i64, @intCast(elf_file.dtpAddress()));
- relocs_log.debug(" {s}: {x}: [{x} => {x}] ({s})", .{
- relocation.fmtRelocType(r_type, .x86_64),
+ relocs_log.debug(" {}: {x}: [{x} => {x}] ({s})", .{
+ relocation.fmtRelocType(rel.r_type(), .x86_64),
rel.r_offset,
P,
S + A,
@@ -1221,21 +1229,21 @@ const x86_64 = struct {
try stream.seekTo(r_offset);
switch (r_type) {
- elf.R_X86_64_NONE => unreachable,
- elf.R_X86_64_8 => try cwriter.writeInt(u8, @as(u8, @bitCast(@as(i8, @intCast(S + A)))), .little),
- elf.R_X86_64_16 => try cwriter.writeInt(u16, @as(u16, @bitCast(@as(i16, @intCast(S + A)))), .little),
- elf.R_X86_64_32 => try cwriter.writeInt(u32, @as(u32, @bitCast(@as(i32, @intCast(S + A)))), .little),
- elf.R_X86_64_32S => try cwriter.writeInt(i32, @as(i32, @intCast(S + A)), .little),
- elf.R_X86_64_64 => try cwriter.writeInt(i64, S + A, .little),
- elf.R_X86_64_DTPOFF32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - DTP)), .little),
- elf.R_X86_64_DTPOFF64 => try cwriter.writeInt(i64, S + A - DTP, .little),
- elf.R_X86_64_GOTOFF64 => try cwriter.writeInt(i64, S + A - GOT, .little),
- elf.R_X86_64_GOTPC64 => try cwriter.writeInt(i64, GOT + A, .little),
- elf.R_X86_64_SIZE32 => {
+ .NONE => unreachable,
+ .@"8" => try cwriter.writeInt(u8, @as(u8, @bitCast(@as(i8, @intCast(S + A)))), .little),
+ .@"16" => try cwriter.writeInt(u16, @as(u16, @bitCast(@as(i16, @intCast(S + A)))), .little),
+ .@"32" => try cwriter.writeInt(u32, @as(u32, @bitCast(@as(i32, @intCast(S + A)))), .little),
+ .@"32S" => try cwriter.writeInt(i32, @as(i32, @intCast(S + A)), .little),
+ .@"64" => try cwriter.writeInt(i64, S + A, .little),
+ .DTPOFF32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - DTP)), .little),
+ .DTPOFF64 => try cwriter.writeInt(i64, S + A - DTP, .little),
+ .GOTOFF64 => try cwriter.writeInt(i64, S + A - GOT, .little),
+ .GOTPC64 => try cwriter.writeInt(i64, GOT + A, .little),
+ .SIZE32 => {
const size = @as(i64, @intCast(target.elfSym(elf_file).st_size));
try cwriter.writeInt(u32, @as(u32, @bitCast(@as(i32, @intCast(size + A)))), .little);
},
- elf.R_X86_64_SIZE64 => {
+ .SIZE64 => {
const size = @as(i64, @intCast(target.elfSym(elf_file).st_size));
try cwriter.writeInt(i64, @as(i64, @intCast(size + A)), .little);
},
@@ -1283,9 +1291,10 @@ const x86_64 = struct {
) !void {
assert(rels.len == 2);
const writer = stream.writer();
- switch (rels[1].r_type()) {
- elf.R_X86_64_PC32,
- elf.R_X86_64_PLT32,
+ const rel: elf.R_X86_64 = @enumFromInt(rels[1].r_type());
+ switch (rel) {
+ .PC32,
+ .PLT32,
=> {
var insts = [_]u8{
0x64, 0x48, 0x8b, 0x04, 0x25, 0, 0, 0, 0, // movq %fs:0,%rax
@@ -1320,9 +1329,10 @@ const x86_64 = struct {
) !void {
assert(rels.len == 2);
const writer = stream.writer();
- switch (rels[1].r_type()) {
- elf.R_X86_64_PC32,
- elf.R_X86_64_PLT32,
+ const rel: elf.R_X86_64 = @enumFromInt(rels[1].r_type());
+ switch (rel) {
+ .PC32,
+ .PLT32,
=> {
var insts = [_]u8{
0x31, 0xc0, // xor %eax, %eax
@@ -1334,8 +1344,8 @@ const x86_64 = struct {
try writer.writeAll(&insts);
},
- elf.R_X86_64_GOTPCREL,
- elf.R_X86_64_GOTPCRELX,
+ .GOTPCREL,
+ .GOTPCRELX,
=> {
var insts = [_]u8{
0x31, 0xc0, // xor %eax, %eax
@@ -1419,11 +1429,12 @@ const x86_64 = struct {
) !void {
assert(rels.len == 2);
const writer = stream.writer();
- switch (rels[1].r_type()) {
- elf.R_X86_64_PC32,
- elf.R_X86_64_PLT32,
- elf.R_X86_64_GOTPCREL,
- elf.R_X86_64_GOTPCRELX,
+ const rel: elf.R_X86_64 = @enumFromInt(rels[1].r_type());
+ switch (rel) {
+ .PC32,
+ .PLT32,
+ .GOTPCREL,
+ .GOTPCRELX,
=> {
var insts = [_]u8{
0x64, 0x48, 0x8b, 0x04, 0x25, 0, 0, 0, 0, // movq %fs:0,%rax
diff --git a/src/link/Elf/eh_frame.zig b/src/link/Elf/eh_frame.zig
index bc4f07279c..6e8e08fab1 100644
--- a/src/link/Elf/eh_frame.zig
+++ b/src/link/Elf/eh_frame.zig
@@ -541,11 +541,12 @@ const EH_PE = struct {
const x86_64 = struct {
fn resolveReloc(rel: elf.Elf64_Rela, source: i64, target: i64, data: []u8) void {
- switch (rel.r_type()) {
- elf.R_X86_64_32 => std.mem.writeInt(i32, data[0..4], @as(i32, @truncate(target)), .little),
- elf.R_X86_64_64 => std.mem.writeInt(i64, data[0..8], target, .little),
- elf.R_X86_64_PC32 => std.mem.writeInt(i32, data[0..4], @as(i32, @intCast(target - source)), .little),
- elf.R_X86_64_PC64 => std.mem.writeInt(i64, data[0..8], target - source, .little),
+ const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type());
+ switch (r_type) {
+ .@"32" => std.mem.writeInt(i32, data[0..4], @as(i32, @truncate(target)), .little),
+ .@"64" => std.mem.writeInt(i64, data[0..8], target, .little),
+ .PC32 => std.mem.writeInt(i32, data[0..4], @as(i32, @intCast(target - source)), .little),
+ .PC64 => std.mem.writeInt(i64, data[0..8], target - source, .little),
else => unreachable,
}
}
diff --git a/src/link/Elf/relocation.zig b/src/link/Elf/relocation.zig
index 5441663948..a63187925f 100644
--- a/src/link/Elf/relocation.zig
+++ b/src/link/Elf/relocation.zig
@@ -11,54 +11,78 @@ pub const Kind = enum {
tlsdesc,
};
-const x86_64_relocs = [_]struct { Kind, u32 }{
- .{ .abs, elf.R_X86_64_64 },
- .{ .copy, elf.R_X86_64_COPY },
- .{ .rel, elf.R_X86_64_RELATIVE },
- .{ .irel, elf.R_X86_64_IRELATIVE },
- .{ .glob_dat, elf.R_X86_64_GLOB_DAT },
- .{ .jump_slot, elf.R_X86_64_JUMP_SLOT },
- .{ .dtpmod, elf.R_X86_64_DTPMOD64 },
- .{ .dtpoff, elf.R_X86_64_DTPOFF64 },
- .{ .tpoff, elf.R_X86_64_TPOFF64 },
- .{ .tlsdesc, elf.R_X86_64_TLSDESC },
-};
+fn Table(comptime len: comptime_int, comptime RelType: type, comptime mapping: [len]struct { Kind, RelType }) type {
+ return struct {
+ fn decode(r_type: u32) ?Kind {
+ inline for (mapping) |entry| {
+ if (@intFromEnum(entry[1]) == r_type) return entry[0];
+ }
+ return null;
+ }
-const aarch64_relocs = [_]struct { Kind, u32 }{
- .{ .abs, elf.R_AARCH64_ABS64 },
- .{ .copy, elf.R_AARCH64_COPY },
- .{ .rel, elf.R_AARCH64_RELATIVE },
- .{ .irel, elf.R_AARCH64_IRELATIVE },
- .{ .glob_dat, elf.R_AARCH64_GLOB_DAT },
- .{ .jump_slot, elf.R_AARCH64_JUMP_SLOT },
- .{ .dtpmod, elf.R_AARCH64_TLS_DTPMOD },
- .{ .dtpoff, elf.R_AARCH64_TLS_DTPREL },
- .{ .tpoff, elf.R_AARCH64_TLS_TPREL },
- .{ .tlsdesc, elf.R_AARCH64_TLSDESC },
-};
+ fn encode(comptime kind: Kind) u32 {
+ inline for (mapping) |entry| {
+ if (entry[0] == kind) return @intFromEnum(entry[1]);
+ }
+ unreachable;
+ }
+ };
+}
+
+const x86_64_relocs = Table(10, elf.R_X86_64, .{
+ .{ .abs, .@"64" },
+ .{ .copy, .COPY },
+ .{ .rel, .RELATIVE },
+ .{ .irel, .IRELATIVE },
+ .{ .glob_dat, .GLOB_DAT },
+ .{ .jump_slot, .JUMP_SLOT },
+ .{ .dtpmod, .DTPMOD64 },
+ .{ .dtpoff, .DTPOFF64 },
+ .{ .tpoff, .TPOFF64 },
+ .{ .tlsdesc, .TLSDESC },
+});
+
+const aarch64_relocs = Table(10, elf.R_AARCH64, .{
+ .{ .abs, .ABS64 },
+ .{ .copy, .COPY },
+ .{ .rel, .RELATIVE },
+ .{ .irel, .IRELATIVE },
+ .{ .glob_dat, .GLOB_DAT },
+ .{ .jump_slot, .JUMP_SLOT },
+ .{ .dtpmod, .TLS_DTPMOD },
+ .{ .dtpoff, .TLS_DTPREL },
+ .{ .tpoff, .TLS_TPREL },
+ .{ .tlsdesc, .TLSDESC },
+});
+
+const riscv64_relocs = Table(9, elf.R_RISCV, .{
+ .{ .abs, .@"64" },
+ .{ .copy, .COPY },
+ .{ .rel, .RELATIVE },
+ .{ .irel, .IRELATIVE },
+ .{ .jump_slot, .JUMP_SLOT },
+ .{ .dtpmod, .TLS_DTPMOD64 },
+ .{ .dtpoff, .TLS_DTPREL64 },
+ .{ .tpoff, .TLS_TPREL64 },
+ .{ .tlsdesc, .TLSDESC },
+});
pub fn decode(r_type: u32, cpu_arch: std.Target.Cpu.Arch) ?Kind {
- const relocs = switch (cpu_arch) {
- .x86_64 => &x86_64_relocs,
- .aarch64 => &aarch64_relocs,
+ return switch (cpu_arch) {
+ .x86_64 => x86_64_relocs.decode(r_type),
+ .aarch64 => aarch64_relocs.decode(r_type),
+ .riscv64 => riscv64_relocs.decode(r_type),
else => @panic("TODO unhandled cpu arch"),
};
- inline for (relocs) |entry| {
- if (entry[1] == r_type) return entry[0];
- }
- return null;
}
pub fn encode(comptime kind: Kind, cpu_arch: std.Target.Cpu.Arch) u32 {
- const relocs = switch (cpu_arch) {
- .x86_64 => &x86_64_relocs,
- .aarch64 => &aarch64_relocs,
+ return switch (cpu_arch) {
+ .x86_64 => x86_64_relocs.encode(kind),
+ .aarch64 => aarch64_relocs.encode(kind),
+ .riscv64 => riscv64_relocs.encode(kind),
else => @panic("TODO unhandled cpu arch"),
};
- inline for (relocs) |entry| {
- if (entry[0] == kind) return entry[1];
- }
- unreachable;
}
const FormatRelocTypeCtx = struct {
@@ -82,183 +106,20 @@ fn formatRelocType(
_ = unused_fmt_string;
_ = options;
const r_type = ctx.r_type;
- const str = switch (ctx.cpu_arch) {
- .x86_64 => switch (r_type) {
- elf.R_X86_64_NONE => "R_X86_64_NONE",
- elf.R_X86_64_64 => "R_X86_64_64",
- elf.R_X86_64_PC32 => "R_X86_64_PC32",
- elf.R_X86_64_GOT32 => "R_X86_64_GOT32",
- elf.R_X86_64_PLT32 => "R_X86_64_PLT32",
- elf.R_X86_64_COPY => "R_X86_64_COPY",
- elf.R_X86_64_GLOB_DAT => "R_X86_64_GLOB_DAT",
- elf.R_X86_64_JUMP_SLOT => "R_X86_64_JUMP_SLOT",
- elf.R_X86_64_RELATIVE => "R_X86_64_RELATIVE",
- elf.R_X86_64_GOTPCREL => "R_X86_64_GOTPCREL",
- elf.R_X86_64_32 => "R_X86_64_32",
- elf.R_X86_64_32S => "R_X86_64_32S",
- elf.R_X86_64_16 => "R_X86_64_16",
- elf.R_X86_64_PC16 => "R_X86_64_PC16",
- elf.R_X86_64_8 => "R_X86_64_8",
- elf.R_X86_64_PC8 => "R_X86_64_PC8",
- elf.R_X86_64_DTPMOD64 => "R_X86_64_DTPMOD64",
- elf.R_X86_64_DTPOFF64 => "R_X86_64_DTPOFF64",
- elf.R_X86_64_TPOFF64 => "R_X86_64_TPOFF64",
- elf.R_X86_64_TLSGD => "R_X86_64_TLSGD",
- elf.R_X86_64_TLSLD => "R_X86_64_TLSLD",
- elf.R_X86_64_DTPOFF32 => "R_X86_64_DTPOFF32",
- elf.R_X86_64_GOTTPOFF => "R_X86_64_GOTTPOFF",
- elf.R_X86_64_TPOFF32 => "R_X86_64_TPOFF32",
- elf.R_X86_64_PC64 => "R_X86_64_PC64",
- elf.R_X86_64_GOTOFF64 => "R_X86_64_GOTOFF64",
- elf.R_X86_64_GOTPC32 => "R_X86_64_GOTPC32",
- elf.R_X86_64_GOT64 => "R_X86_64_GOT64",
- elf.R_X86_64_GOTPCREL64 => "R_X86_64_GOTPCREL64",
- elf.R_X86_64_GOTPC64 => "R_X86_64_GOTPC64",
- elf.R_X86_64_GOTPLT64 => "R_X86_64_GOTPLT64",
- elf.R_X86_64_PLTOFF64 => "R_X86_64_PLTOFF64",
- elf.R_X86_64_SIZE32 => "R_X86_64_SIZE32",
- elf.R_X86_64_SIZE64 => "R_X86_64_SIZE64",
- elf.R_X86_64_GOTPC32_TLSDESC => "R_X86_64_GOTPC32_TLSDESC",
- elf.R_X86_64_TLSDESC_CALL => "R_X86_64_TLSDESC_CALL",
- elf.R_X86_64_TLSDESC => "R_X86_64_TLSDESC",
- elf.R_X86_64_IRELATIVE => "R_X86_64_IRELATIVE",
- elf.R_X86_64_RELATIVE64 => "R_X86_64_RELATIVE64",
- elf.R_X86_64_GOTPCRELX => "R_X86_64_GOTPCRELX",
- elf.R_X86_64_REX_GOTPCRELX => "R_X86_64_REX_GOTPCRELX",
- elf.R_X86_64_NUM => "R_X86_64_NUM",
- else => "R_X86_64_UNKNOWN",
- },
- .aarch64 => switch (r_type) {
- elf.R_AARCH64_NONE => "R_AARCH64_NONE",
- elf.R_AARCH64_ABS64 => "R_AARCH64_ABS64",
- elf.R_AARCH64_ABS32 => "R_AARCH64_ABS32",
- elf.R_AARCH64_ABS16 => "R_AARCH64_ABS16",
- elf.R_AARCH64_PREL64 => "R_AARCH64_PREL64",
- elf.R_AARCH64_PREL32 => "R_AARCH64_PREL32",
- elf.R_AARCH64_PREL16 => "R_AARCH64_PREL16",
- elf.R_AARCH64_MOVW_UABS_G0 => "R_AARCH64_MOVW_UABS_G0",
- elf.R_AARCH64_MOVW_UABS_G0_NC => "R_AARCH64_MOVW_UABS_G0_NC",
- elf.R_AARCH64_MOVW_UABS_G1 => "R_AARCH64_MOVW_UABS_G1",
- elf.R_AARCH64_MOVW_UABS_G1_NC => "R_AARCH64_MOVW_UABS_G1_NC",
- elf.R_AARCH64_MOVW_UABS_G2 => "R_AARCH64_MOVW_UABS_G2",
- elf.R_AARCH64_MOVW_UABS_G2_NC => "R_AARCH64_MOVW_UABS_G2_NC",
- elf.R_AARCH64_MOVW_UABS_G3 => "R_AARCH64_MOVW_UABS_G3",
- elf.R_AARCH64_MOVW_SABS_G0 => "R_AARCH64_MOVW_SABS_G0",
- elf.R_AARCH64_MOVW_SABS_G1 => "R_AARCH64_MOVW_SABS_G1",
- elf.R_AARCH64_MOVW_SABS_G2 => "R_AARCH64_MOVW_SABS_G2",
- elf.R_AARCH64_LD_PREL_LO19 => "R_AARCH64_LD_PREL_LO19",
- elf.R_AARCH64_ADR_PREL_LO21 => "R_AARCH64_ADR_PREL_LO21",
- elf.R_AARCH64_ADR_PREL_PG_HI21 => "R_AARCH64_ADR_PREL_PG_HI21",
- elf.R_AARCH64_ADR_PREL_PG_HI21_NC => "R_AARCH64_ADR_PREL_PG_HI21_NC",
- elf.R_AARCH64_ADD_ABS_LO12_NC => "R_AARCH64_ADD_ABS_LO12_NC",
- elf.R_AARCH64_LDST8_ABS_LO12_NC => "R_AARCH64_LDST8_ABS_LO12_NC",
- elf.R_AARCH64_TSTBR14 => "R_AARCH64_TSTBR14",
- elf.R_AARCH64_CONDBR19 => "R_AARCH64_CONDBR19",
- elf.R_AARCH64_JUMP26 => "R_AARCH64_JUMP26",
- elf.R_AARCH64_CALL26 => "R_AARCH64_CALL26",
- elf.R_AARCH64_LDST16_ABS_LO12_NC => "R_AARCH64_LDST16_ABS_LO12_NC",
- elf.R_AARCH64_LDST32_ABS_LO12_NC => "R_AARCH64_LDST32_ABS_LO12_NC",
- elf.R_AARCH64_LDST64_ABS_LO12_NC => "R_AARCH64_LDST64_ABS_LO12_NC",
- elf.R_AARCH64_MOVW_PREL_G0 => "R_AARCH64_MOVW_PREL_G0",
- elf.R_AARCH64_MOVW_PREL_G0_NC => "R_AARCH64_MOVW_PREL_G0_NC",
- elf.R_AARCH64_MOVW_PREL_G1 => "R_AARCH64_MOVW_PREL_G1",
- elf.R_AARCH64_MOVW_PREL_G1_NC => "R_AARCH64_MOVW_PREL_G1_NC",
- elf.R_AARCH64_MOVW_PREL_G2 => "R_AARCH64_MOVW_PREL_G2",
- elf.R_AARCH64_MOVW_PREL_G2_NC => "R_AARCH64_MOVW_PREL_G2_NC",
- elf.R_AARCH64_MOVW_PREL_G3 => "R_AARCH64_MOVW_PREL_G3",
- elf.R_AARCH64_LDST128_ABS_LO12_NC => "R_AARCH64_LDST128_ABS_LO12_NC",
- elf.R_AARCH64_MOVW_GOTOFF_G0 => "R_AARCH64_MOVW_GOTOFF_G0",
- elf.R_AARCH64_MOVW_GOTOFF_G0_NC => "R_AARCH64_MOVW_GOTOFF_G0_NC",
- elf.R_AARCH64_MOVW_GOTOFF_G1 => "R_AARCH64_MOVW_GOTOFF_G1",
- elf.R_AARCH64_MOVW_GOTOFF_G1_NC => "R_AARCH64_MOVW_GOTOFF_G1_NC",
- elf.R_AARCH64_MOVW_GOTOFF_G2 => "R_AARCH64_MOVW_GOTOFF_G2",
- elf.R_AARCH64_MOVW_GOTOFF_G2_NC => "R_AARCH64_MOVW_GOTOFF_G2_NC",
- elf.R_AARCH64_MOVW_GOTOFF_G3 => "R_AARCH64_MOVW_GOTOFF_G3",
- elf.R_AARCH64_GOTREL64 => "R_AARCH64_GOTREL64",
- elf.R_AARCH64_GOTREL32 => "R_AARCH64_GOTREL32",
- elf.R_AARCH64_GOT_LD_PREL19 => "R_AARCH64_GOT_LD_PREL19",
- elf.R_AARCH64_LD64_GOTOFF_LO15 => "R_AARCH64_LD64_GOTOFF_LO15",
- elf.R_AARCH64_ADR_GOT_PAGE => "R_AARCH64_ADR_GOT_PAGE",
- elf.R_AARCH64_LD64_GOT_LO12_NC => "R_AARCH64_LD64_GOT_LO12_NC",
- elf.R_AARCH64_LD64_GOTPAGE_LO15 => "R_AARCH64_LD64_GOTPAGE_LO15",
- elf.R_AARCH64_TLSGD_ADR_PREL21 => "R_AARCH64_TLSGD_ADR_PREL21",
- elf.R_AARCH64_TLSGD_ADR_PAGE21 => "R_AARCH64_TLSGD_ADR_PAGE21",
- elf.R_AARCH64_TLSGD_ADD_LO12_NC => "R_AARCH64_TLSGD_ADD_LO12_NC",
- elf.R_AARCH64_TLSGD_MOVW_G1 => "R_AARCH64_TLSGD_MOVW_G1",
- elf.R_AARCH64_TLSGD_MOVW_G0_NC => "R_AARCH64_TLSGD_MOVW_G0_NC",
- elf.R_AARCH64_TLSLD_ADR_PREL21 => "R_AARCH64_TLSLD_ADR_PREL21",
- elf.R_AARCH64_TLSLD_ADR_PAGE21 => "R_AARCH64_TLSLD_ADR_PAGE21",
- elf.R_AARCH64_TLSLD_ADD_LO12_NC => "R_AARCH64_TLSLD_ADD_LO12_NC",
- elf.R_AARCH64_TLSLD_MOVW_G1 => "R_AARCH64_TLSLD_MOVW_G1",
- elf.R_AARCH64_TLSLD_MOVW_G0_NC => "R_AARCH64_TLSLD_MOVW_G0_NC",
- elf.R_AARCH64_TLSLD_LD_PREL19 => "R_AARCH64_TLSLD_LD_PREL19",
- elf.R_AARCH64_TLSLD_MOVW_DTPREL_G2 => "R_AARCH64_TLSLD_MOVW_DTPREL_G2",
- elf.R_AARCH64_TLSLD_MOVW_DTPREL_G1 => "R_AARCH64_TLSLD_MOVW_DTPREL_G1",
- elf.R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC => "R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC",
- elf.R_AARCH64_TLSLD_MOVW_DTPREL_G0 => "R_AARCH64_TLSLD_MOVW_DTPREL_G0",
- elf.R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC => "R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC",
- elf.R_AARCH64_TLSLD_ADD_DTPREL_HI12 => "R_AARCH64_TLSLD_ADD_DTPREL_HI12",
- elf.R_AARCH64_TLSLD_ADD_DTPREL_LO12 => "R_AARCH64_TLSLD_ADD_DTPREL_LO12",
- elf.R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC => "R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC",
- elf.R_AARCH64_TLSLD_LDST8_DTPREL_LO12 => "R_AARCH64_TLSLD_LDST8_DTPREL_LO12",
- elf.R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC => "R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC",
- elf.R_AARCH64_TLSLD_LDST16_DTPREL_LO12 => "R_AARCH64_TLSLD_LDST16_DTPREL_LO12",
- elf.R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC => "R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC",
- elf.R_AARCH64_TLSLD_LDST32_DTPREL_LO12 => "R_AARCH64_TLSLD_LDST32_DTPREL_LO12",
- elf.R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC => "R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC",
- elf.R_AARCH64_TLSLD_LDST64_DTPREL_LO12 => "R_AARCH64_TLSLD_LDST64_DTPREL_LO12",
- elf.R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC => "R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC",
- elf.R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 => "R_AARCH64_TLSIE_MOVW_GOTTPREL_G1",
- elf.R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC => "R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC",
- elf.R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 => "R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21",
- elf.R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC => "R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC",
- elf.R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 => "R_AARCH64_TLSIE_LD_GOTTPREL_PREL19",
- elf.R_AARCH64_TLSLE_MOVW_TPREL_G2 => "R_AARCH64_TLSLE_MOVW_TPREL_G2",
- elf.R_AARCH64_TLSLE_MOVW_TPREL_G1 => "R_AARCH64_TLSLE_MOVW_TPREL_G1",
- elf.R_AARCH64_TLSLE_MOVW_TPREL_G1_NC => "R_AARCH64_TLSLE_MOVW_TPREL_G1_NC",
- elf.R_AARCH64_TLSLE_MOVW_TPREL_G0 => "R_AARCH64_TLSLE_MOVW_TPREL_G0",
- elf.R_AARCH64_TLSLE_MOVW_TPREL_G0_NC => "R_AARCH64_TLSLE_MOVW_TPREL_G0_NC",
- elf.R_AARCH64_TLSLE_ADD_TPREL_HI12 => "R_AARCH64_TLSLE_ADD_TPREL_HI12",
- elf.R_AARCH64_TLSLE_ADD_TPREL_LO12 => "R_AARCH64_TLSLE_ADD_TPREL_LO12",
- elf.R_AARCH64_TLSLE_ADD_TPREL_LO12_NC => "R_AARCH64_TLSLE_ADD_TPREL_LO12_NC",
- elf.R_AARCH64_TLSLE_LDST8_TPREL_LO12 => "R_AARCH64_TLSLE_LDST8_TPREL_LO12",
- elf.R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC => "R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC",
- elf.R_AARCH64_TLSLE_LDST16_TPREL_LO12 => "R_AARCH64_TLSLE_LDST16_TPREL_LO12",
- elf.R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC => "R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC",
- elf.R_AARCH64_TLSLE_LDST32_TPREL_LO12 => "R_AARCH64_TLSLE_LDST32_TPREL_LO12",
- elf.R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC => "R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC",
- elf.R_AARCH64_TLSLE_LDST64_TPREL_LO12 => "R_AARCH64_TLSLE_LDST64_TPREL_LO12",
- elf.R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC => "R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC",
- elf.R_AARCH64_TLSDESC_LD_PREL19 => "R_AARCH64_TLSDESC_LD_PREL19",
- elf.R_AARCH64_TLSDESC_ADR_PREL21 => "R_AARCH64_TLSDESC_ADR_PREL21",
- elf.R_AARCH64_TLSDESC_ADR_PAGE21 => "R_AARCH64_TLSDESC_ADR_PAGE21",
- elf.R_AARCH64_TLSDESC_LD64_LO12 => "R_AARCH64_TLSDESC_LD64_LO12",
- elf.R_AARCH64_TLSDESC_ADD_LO12 => "R_AARCH64_TLSDESC_ADD_LO12",
- elf.R_AARCH64_TLSDESC_OFF_G1 => "R_AARCH64_TLSDESC_OFF_G1",
- elf.R_AARCH64_TLSDESC_OFF_G0_NC => "R_AARCH64_TLSDESC_OFF_G0_NC",
- elf.R_AARCH64_TLSDESC_LDR => "R_AARCH64_TLSDESC_LDR",
- elf.R_AARCH64_TLSDESC_ADD => "R_AARCH64_TLSDESC_ADD",
- elf.R_AARCH64_TLSDESC_CALL => "R_AARCH64_TLSDESC_CALL",
- elf.R_AARCH64_TLSLE_LDST128_TPREL_LO12 => "R_AARCH64_TLSLE_LDST128_TPREL_LO12",
- elf.R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC => "R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC",
- elf.R_AARCH64_TLSLD_LDST128_DTPREL_LO12 => "R_AARCH64_TLSLD_LDST128_DTPREL_LO12",
- elf.R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC => "R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC",
- elf.R_AARCH64_COPY => "R_AARCH64_COPY",
- elf.R_AARCH64_GLOB_DAT => "R_AARCH64_GLOB_DAT",
- elf.R_AARCH64_JUMP_SLOT => "R_AARCH64_JUMP_SLOT",
- elf.R_AARCH64_RELATIVE => "R_AARCH64_RELATIVE",
- elf.R_AARCH64_TLS_DTPMOD => "R_AARCH64_TLS_DTPMOD",
- elf.R_AARCH64_TLS_DTPREL => "R_AARCH64_TLS_DTPREL",
- elf.R_AARCH64_TLS_TPREL => "R_AARCH64_TLS_TPREL",
- elf.R_AARCH64_TLSDESC => "R_AARCH64_TLSDESC",
- elf.R_AARCH64_IRELATIVE => "R_AARCH64_IRELATIVE",
- else => "R_AARCH64_UNKNOWN",
+ switch (r_type) {
+ Elf.R_ZIG_GOT32 => try writer.writeAll("R_ZIG_GOT32"),
+ Elf.R_ZIG_GOTPCREL => try writer.writeAll("R_ZIG_GOTPCREL"),
+ 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,
},
- else => unreachable,
- };
- try writer.print("{s}", .{str});
+ }
}
const assert = std.debug.assert;
const elf = std.elf;
const std = @import("std");
+
+const Elf = @import("../Elf.zig");