aboutsummaryrefslogtreecommitdiff
path: root/src/link/Elf/relocation.zig
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2024-02-17 11:29:06 +0100
committerJakub Konka <kubkon@jakubkonka.com>2024-02-17 11:29:06 +0100
commit975862aca9a68f1d6fa786b6cef19bcc7b1aec2a (patch)
treebd0c4783671214faa562fd29956ff00bae8b3e5b /src/link/Elf/relocation.zig
parent601aa10b82a43a9d566e8de3cb784929185411b4 (diff)
downloadzig-975862aca9a68f1d6fa786b6cef19bcc7b1aec2a.tar.gz
zig-975862aca9a68f1d6fa786b6cef19bcc7b1aec2a.zip
elf: add riscv dynamic relocs
Diffstat (limited to 'src/link/Elf/relocation.zig')
-rw-r--r--src/link/Elf/relocation.zig53
1 files changed, 32 insertions, 21 deletions
diff --git a/src/link/Elf/relocation.zig b/src/link/Elf/relocation.zig
index 4cfdd031e1..10a7d25871 100644
--- a/src/link/Elf/relocation.zig
+++ b/src/link/Elf/relocation.zig
@@ -11,7 +11,25 @@ pub const Kind = enum {
tlsdesc,
};
-const x86_64_relocs = [_]struct { Kind, elf.R_X86_64 }{
+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;
+ }
+
+ 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, .R_X86_64_64 },
.{ .copy, .R_X86_64_COPY },
.{ .rel, .R_X86_64_RELATIVE },
@@ -22,9 +40,9 @@ const x86_64_relocs = [_]struct { Kind, elf.R_X86_64 }{
.{ .dtpoff, .R_X86_64_DTPOFF64 },
.{ .tpoff, .R_X86_64_TPOFF64 },
.{ .tlsdesc, .R_X86_64_TLSDESC },
-};
+});
-const aarch64_relocs = [_]struct { Kind, elf.R_AARCH64 }{
+const aarch64_relocs = Table(10, elf.R_AARCH64, .{
.{ .abs, .R_AARCH64_ABS64 },
.{ .copy, .R_AARCH64_COPY },
.{ .rel, .R_AARCH64_RELATIVE },
@@ -35,9 +53,9 @@ const aarch64_relocs = [_]struct { Kind, elf.R_AARCH64 }{
.{ .dtpoff, .R_AARCH64_TLS_DTPREL },
.{ .tpoff, .R_AARCH64_TLS_TPREL },
.{ .tlsdesc, .R_AARCH64_TLSDESC },
-};
+});
-const riscv64_relocs = [_]struct { Kind, elf.R_RISCV }{
+const riscv64_relocs = Table(8, elf.R_RISCV, .{
.{ .abs, .R_RISCV_64 },
.{ .copy, .R_RISCV_COPY },
.{ .rel, .R_RISCV_RELATIVE },
@@ -46,31 +64,24 @@ const riscv64_relocs = [_]struct { Kind, elf.R_RISCV }{
.{ .dtpmod, .R_RISCV_TLS_DTPMOD64 },
.{ .dtpoff, .R_RISCV_TLS_DTPREL64 },
.{ .tpoff, .R_RISCV_TLS_TPREL64 },
- .{ .tpoff, .R_RISCV_TLS_TPREL64 },
-};
+});
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 {