aboutsummaryrefslogtreecommitdiff
path: root/src/link
diff options
context:
space:
mode:
authorDavid Rubin <daviru007@icloud.com>2024-04-22 20:40:55 -0700
committerDavid Rubin <daviru007@icloud.com>2024-06-13 02:19:39 -0700
commitfcafaae747c0d032401ca7936b667f5dfcf0466b (patch)
treebfbf921a30a4cf275aaabb4012429e72709687e4 /src/link
parent004d0c8978d4b5e4212c06abb33d7a594930f8c5 (diff)
downloadzig-fcafaae747c0d032401ca7936b667f5dfcf0466b.tar.gz
zig-fcafaae747c0d032401ca7936b667f5dfcf0466b.zip
riscv: get basic libc interop
Diffstat (limited to 'src/link')
-rw-r--r--src/link/Elf.zig3
-rw-r--r--src/link/Elf/Atom.zig63
2 files changed, 48 insertions, 18 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
index 770d483e98..6464ac73e2 100644
--- a/src/link/Elf.zig
+++ b/src/link/Elf.zig
@@ -5842,7 +5842,8 @@ pub fn tpAddress(self: *Elf) i64 {
const addr = switch (self.getTarget().cpu.arch) {
.x86_64 => mem.alignForward(u64, phdr.p_vaddr + phdr.p_memsz, phdr.p_align),
.aarch64 => mem.alignBackward(u64, phdr.p_vaddr - 16, phdr.p_align),
- else => @panic("TODO implement getTpAddress for this arch"),
+ .riscv64 => phdr.p_vaddr,
+ else => |arch| std.debug.panic("TODO implement getTpAddress for {s}", .{@tagName(arch)}),
};
return @intCast(addr);
}
diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig
index 239186ffaa..1c303980c3 100644
--- a/src/link/Elf/Atom.zig
+++ b/src/link/Elf/Atom.zig
@@ -1409,11 +1409,11 @@ const x86_64 = struct {
.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);
+ try cwriter.writeInt(u32, @bitCast(@as(i32, @intCast(size + A))), .little);
},
.SIZE64 => {
const size = @as(i64, @intCast(target.elfSym(elf_file).st_size));
- try cwriter.writeInt(i64, @as(i64, @intCast(size + A)), .little);
+ try cwriter.writeInt(i64, @intCast(size + A), .little);
},
else => try atom.reportUnhandledRelocError(rel, elf_file),
}
@@ -2001,26 +2001,25 @@ const riscv = struct {
const r_type: elf.R_RISCV = @enumFromInt(rel.r_type());
switch (r_type) {
- .@"64" => {
- try atom.scanReloc(symbol, rel, dynAbsRelocAction(symbol, elf_file), elf_file);
- },
-
- .HI20 => {
- try atom.scanReloc(symbol, rel, absRelocAction(symbol, elf_file), elf_file);
- },
+ .@"32" => try atom.scanReloc(symbol, rel, absRelocAction(symbol, elf_file), elf_file),
+ .@"64" => try atom.scanReloc(symbol, rel, dynAbsRelocAction(symbol, elf_file), elf_file),
+ .HI20 => try atom.scanReloc(symbol, rel, absRelocAction(symbol, elf_file), elf_file),
.CALL_PLT => if (symbol.flags.import) {
symbol.flags.needs_plt = true;
},
+ .GOT_HI20 => symbol.flags.needs_got = true,
- .GOT_HI20 => {
- symbol.flags.needs_got = true;
- },
+ .TPREL_HI20,
+ .TPREL_LO12_I,
+ .TPREL_LO12_S,
+ .TPREL_ADD,
.PCREL_HI20,
.PCREL_LO12_I,
.PCREL_LO12_S,
.LO12_I,
+ .LO12_S,
.ADD32,
.SUB32,
=> {},
@@ -2058,6 +2057,8 @@ const riscv = struct {
switch (r_type) {
.NONE => unreachable,
+ .@"32" => try cwriter.writeInt(u32, @as(u32, @truncate(@as(u64, @intCast(S + A)))), .little),
+
.@"64" => {
try atom.resolveDynAbsReloc(
target,
@@ -2076,11 +2077,6 @@ const riscv = struct {
riscv_util.writeInstU(code[r_offset..][0..4], value);
},
- .LO12_I => {
- const value: u32 = @bitCast(math.cast(i32, S + A) orelse return error.Overflow);
- riscv_util.writeInstI(code[r_offset..][0..4], value);
- },
-
.GOT_HI20 => {
assert(target.flags.has_got);
const disp: u32 = @bitCast(math.cast(i32, G + GOT + A - P) orelse return error.Overflow);
@@ -2143,6 +2139,39 @@ const riscv = struct {
}
},
+ .LO12_I,
+ .LO12_S,
+ => {
+ const disp: u32 = @bitCast(math.cast(i32, S + A) orelse return error.Overflow);
+ switch (r_type) {
+ .LO12_I => riscv_util.writeInstI(code[r_offset..][0..4], disp),
+ .LO12_S => riscv_util.writeInstS(code[r_offset..][0..4], disp),
+ else => unreachable,
+ }
+ },
+
+ .TPREL_HI20 => {
+ const target_addr: u32 = @intCast(target.address(.{}, elf_file));
+ const val: i32 = @intCast(S + A - target_addr);
+ riscv_util.writeInstU(code[r_offset..][0..4], @bitCast(val));
+ },
+
+ .TPREL_LO12_I,
+ .TPREL_LO12_S,
+ => {
+ const target_addr: u32 = @intCast(target.address(.{}, elf_file));
+ const val: i32 = @intCast(S + A - target_addr);
+ switch (r_type) {
+ .TPREL_LO12_I => riscv_util.writeInstI(code[r_offset..][0..4], @bitCast(val)),
+ .TPREL_LO12_S => riscv_util.writeInstS(code[r_offset..][0..4], @bitCast(val)),
+ else => unreachable,
+ }
+ },
+
+ .TPREL_ADD => {
+ // TODO: annotates an ADD instruction that can be removed when TPREL is relaxed
+ },
+
else => |x| switch (@intFromEnum(x)) {
// Zig custom relocations
Elf.R_ZIG_GOT_HI20 => {