diff options
| author | David Rubin <daviru007@icloud.com> | 2024-04-22 20:40:55 -0700 |
|---|---|---|
| committer | David Rubin <daviru007@icloud.com> | 2024-06-13 02:19:39 -0700 |
| commit | fcafaae747c0d032401ca7936b667f5dfcf0466b (patch) | |
| tree | bfbf921a30a4cf275aaabb4012429e72709687e4 /src/link | |
| parent | 004d0c8978d4b5e4212c06abb33d7a594930f8c5 (diff) | |
| download | zig-fcafaae747c0d032401ca7936b667f5dfcf0466b.tar.gz zig-fcafaae747c0d032401ca7936b667f5dfcf0466b.zip | |
riscv: get basic libc interop
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/Elf.zig | 3 | ||||
| -rw-r--r-- | src/link/Elf/Atom.zig | 63 |
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 => { |
