Skip to content

Commit

Permalink
Support riscv64.
Browse files Browse the repository at this point in the history
  • Loading branch information
yugr committed Mar 29, 2024
1 parent 6167855 commit fc3b149
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 2 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,13 @@ jobs:
run: sudo apt-get update && sudo apt-get install qemu-user gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu binutils-powerpc64le-linux-gnu libc6-ppc64el-cross libc6-dev-ppc64el-cross
- name: Run tests
run: scripts/travis.sh
riscv64:
runs-on: ubuntu-latest
env:
ARCH: riscv64-linux-gnu
steps:
- uses: actions/checkout@v3
- name: Install deps
run: sudo apt-get update && sudo apt-get install qemu-user gcc-riscv64-linux-gnu g++-riscv64-linux-gnu binutils-riscv64-linux-gnu libc6-riscv64-cross libc6-dev-riscv64-cross
- name: Run tests
run: scripts/travis.sh
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ where `TARGET` can be any of
* e2k-linux-gnu
* powerpc64le-linux-gnu
* powerpc64-linux-gnu (limited support)
* riscv64-linux-gnu

Script generates two files: `libxyz.so.tramp.S` and `libxyz.so.init.c` which need to be linked to your application (instead of `-lxyz`):

Expand Down Expand Up @@ -162,9 +163,7 @@ The tool does not transparently support all features of POSIX shared libraries.
The tool also lacks the following important features:
* proper support for multi-threading
* symbol versions are not handled at all
* support OSX and RISC-V
* keep fast paths of shims together to reduce I$ pressure
(none should be hard to add so let me know if you need it).

Finally, there are some minor TODOs in code.

Expand Down
3 changes: 3 additions & 0 deletions arch/riscv64/config.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[Arch]
PointerSize = 8
SymbolReloc = R_RISCV_64
127 changes: 127 additions & 0 deletions arch/riscv64/table.S.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
* Copyright 2024 Yury Gribov
*
* The MIT License (MIT)
*
* Use of this source code is governed by MIT license that can be
* found in the LICENSE.txt file.
*/

.section .note.GNU-stack,"",@progbits

.data

.globl _${lib_suffix}_tramp_table
.hidden _${lib_suffix}_tramp_table
.align 8
_${lib_suffix}_tramp_table:
.zero $table_size

.text

.globl _${lib_suffix}_tramp_resolve
.hidden _${lib_suffix}_tramp_resolve

.globl _${lib_suffix}_save_regs_and_resolve
.hidden _${lib_suffix}_save_regs_and_resolve
.type _${lib_suffix}_save_regs_and_resolve, %function
_${lib_suffix}_save_regs_and_resolve:
.cfi_startproc

// Slow path which calls dlsym, taken only on first call.
// Registers are saved according to "Procedure Call Standard for the Arm® 64-bit Architecture".
// For DWARF directives, read https://www.imperialviolet.org/2017/01/18/cfi.html.

// TODO: cfi_offset/cfi_restore

addi sp, sp, -144
.cfi_adjust_cfa_offset 144

sd ra, 0(sp)
.cfi_rel_offset ra, 0

sd a0, 8(sp)
.cfi_rel_offset a0, 8
sd a1, 16(sp)
.cfi_rel_offset a1, 16
sd a2, 24(sp)
.cfi_rel_offset a2, 24
sd a3, 32(sp)
.cfi_rel_offset a3, 32
sd a4, 40(sp)
.cfi_rel_offset a4, 40
sd a5, 48(sp)
.cfi_rel_offset a5, 48
sd a6, 56(sp)
.cfi_rel_offset a6, 56
sd a7, 64(sp)
.cfi_rel_offset a7, 64

fsd fa0, 72(sp)
.cfi_rel_offset fa0, 72
fsd fa1, 80(sp)
.cfi_rel_offset fa1, 80
fsd fa2, 88(sp)
.cfi_rel_offset fa2, 88
fsd fa3, 96(sp)
.cfi_rel_offset fa3, 96
fsd fa4, 104(sp)
.cfi_rel_offset fa4, 104
fsd fa5, 112(sp)
.cfi_rel_offset fa5, 112
fsd fa6, 120(sp)
.cfi_rel_offset fa6, 120
fsd fa7, 128(sp)
.cfi_rel_offset fa7, 128

ld a0, 144(sp)

// TODO: vector arguments

// Stack is aligned at 16 bytes

call _${lib_suffix}_tramp_resolve

fld fa7, 128(sp)
.cfi_restore fa7
fld fa6, 120(sp)
.cfi_restore fa6
fld fa5, 112(sp)
.cfi_restore fa5
fld fa4, 104(sp)
.cfi_restore fa4
fld fa3, 96(sp)
.cfi_restore fa3
fld fa2, 88(sp)
.cfi_restore fa2
fld fa1, 80(sp)
.cfi_restore fa1
fld fa0, 72(sp)
.cfi_restore fa0

ld a7, 64(sp)
.cfi_restore a7
ld a6, 56(sp)
.cfi_restore a6
ld a5, 48(sp)
.cfi_restore a5
ld a4, 40(sp)
.cfi_restore a4
ld a3, 32(sp)
.cfi_restore a3
ld a2, 24(sp)
.cfi_restore a2
ld a1, 16(sp)
.cfi_restore a1
ld a0, 8(sp)
.cfi_restore a0

ld ra, 0(sp)
.cfi_restore ra

addi sp, sp, 144
.cfi_def_cfa_offset 0

jr ra

.cfi_endproc
53 changes: 53 additions & 0 deletions arch/riscv64/trampoline.S.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2024 Yury Gribov
*
* The MIT License (MIT)
*
* Use of this source code is governed by MIT license that can be
* found in the LICENSE.txt file.
*/

.globl $sym
.p2align 4
.type $sym, %function
#ifndef IMPLIB_EXPORT_SHIMS
.hidden $sym
#endif
$sym:
.cfi_startproc

1:
// Load address

lla t0, _${lib_suffix}_tramp_table+$offset
ld t0, 0(t0)

beq t0, zero, 2f

// Fast path
jr t0

2:
// Slow path

addi sp, sp, -16
.cfi_adjust_cfa_offset 16

sd ra, 8(sp)
.cfi_rel_offset ra, 8

li t0, $number
sd t0, 0(sp)

// TODO: cfi_offset/cfi_restore

call _${lib_suffix}_save_regs_and_resolve

ld ra, 8(sp)
.cfi_restore ra

addi sp, sp, 16
.cfi_def_cfa_offset 0

j 1b
.cfi_endproc
2 changes: 2 additions & 0 deletions implib-gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,8 @@ def main():
target = 'powerpc64le'
elif args.target.startswith('ppc64'):
target = 'powerpc64'
elif args.target.startswith('rv64'):
target = 'riscv64'
else:
target = args.target.split('-')[0]
quiet = args.quiet
Expand Down
5 changes: 5 additions & 0 deletions tests/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ else
PREFIX=powerpc64le-linux-gnu-
INTERP="qemu-ppc64le -L /usr/powerpc64le-linux-gnu -E LD_LIBRARY_PATH=.${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
;;
rv64 | riscv4 | riscv64-*)
TARGET=riscv64
PREFIX=riscv64-linux-gnu-
INTERP="qemu-riscv64 -L /usr/riscv64-linux-gnu -E LD_LIBRARY_PATH=.${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
;;
*)
echo >&2 "Unsupported target: $ARCH"
exit 1
Expand Down

0 comments on commit fc3b149

Please sign in to comment.