Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
04d0d2a
add riscv syscalls implementations
mikhaylovilya Apr 10, 2024
11d16bd
add clone syscall implementation riscv
mikhaylovilya Apr 10, 2024
5c0cd62
fix macros
mikhaylovilya May 13, 2024
3007786
merge branch: master into host-riscv64
mikhaylovilya Oct 4, 2024
a300811
client: implement syscalls and funcions for rv64
mikhaylovilya Oct 6, 2024
3f3aacb
(WIP) patch assembly
mikhaylovilya Oct 9, 2024
d4534bf
client: patch assembly for rv64 (2)
mikhaylovilya Oct 23, 2024
22773f5
client: fix cc flags for rv64 host
mikhaylovilya Oct 23, 2024
dc24726
client: fix relasz in minilibc && CodeModel in codegenerator
mikhaylovilya Oct 23, 2024
5acbcde
(WIP) implement relocations and add test file
mikhaylovilya Nov 14, 2024
0d368e2
(wip stash)
mikhaylovilya Nov 28, 2024
dd92048
(wip) stash 2
mikhaylovilya Nov 28, 2024
03f9aa6
client: fix CALL_PLT relocation for rv64
mikhaylovilya Nov 30, 2024
4a0b790
client: fix PLT func size && plt entries
mikhaylovilya Dec 1, 2024
abf011e
client: add plt entries
mikhaylovilya Dec 5, 2024
979d992
client: cleaning
mikhaylovilya Dec 5, 2024
ea0b5d8
test: add small tests
mikhaylovilya Dec 5, 2024
368b3ad
client: attempt at enabling translation of dynamicaly-linked executables
mikhaylovilya Dec 27, 2024
cd5f8a2
client: cleaning & refactoring
mikhaylovilya Feb 18, 2025
13b0b05
client: cleaning & refactoring
mikhaylovilya Feb 18, 2025
406bb3c
Fix x86-64 host
mikhaylovilya Mar 11, 2025
d0f0496
CI: use jirutka instead of self-hosted runner
mikhaylovilya Apr 9, 2025
faa3d58
Update Rellume & Add clang-18 to ci.yml
mikhaylovilya Apr 10, 2025
04219fa
Add PLT entries for translation static x86 binaries
mikhaylovilya Apr 10, 2025
96bd553
client: add relocation deb info
mikhaylovilya Apr 30, 2025
f57663d
client: more verbose deb-info and add macros for deb printf
mikhaylovilya May 1, 2025
ce97bdd
client: (wip) add temp data struct for pending relocs
mikhaylovilya May 1, 2025
240cddf
client: (wip) add array of pending relocs
mikhaylovilya May 9, 2025
a3198b8
client: add processing of pending relocs
mikhaylovilya May 11, 2025
687c6c4
client: fix function name of __restore in minilibc
mikhaylovilya May 31, 2025
3cee6b4
client: implement rv64 cache flush via riscv_flush_icache syscall
mikhaylovilya Jun 4, 2025
58410e8
client: add native rv64 syscalls
mikhaylovilya Jun 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Alpine Test CI

on:
push:
branches:
- "tmp-host-riscv64"

jobs:
build:
runs-on: ubuntu-latest
# defaults:
# run:
# shell: alpine.sh {0}
steps:
- name: Update & Upgrade
run: sudo apt update && sudo apt upgrade --yes
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: 'true'
- name: Setup Alpine Linux v3.21 for riscv64
uses: jirutka/setup-alpine@v1
with:
arch: riscv64
branch: v3.21

- name: Run script inside Alpine chroot with riscv64 emulation
run: uname -m
shell: alpine.sh {0}
- name: Install dependencies
run: |
apk add build-base gcc g++ cmake meson llvm18-dev clang18-dev lld18-dev pkgconf libressl-dev
ln -s /usr/bin/clang-18 /usr/bin/clang
shell: alpine.sh --root {0}
- name: Build
run: |
meson setup build/ -Dbuildtype=release
ninja -C build
ninja -C build test
cat build/meson-logs/meson-log.txt
shell: alpine.sh {0}


19 changes: 19 additions & 0 deletions .test/gdb/.gdbinit
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
set history save
set breakpoint pending on
b connection.cc:197
run
del
n
set follow-exec-mode new
# b dispatch.c:55
# # b dispatch.c:77
# c
# # s
# # finish
# # b rtld.c:296
# # del 2
b dispatch.c:128
c
c
c

10 changes: 10 additions & 0 deletions client/dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@

// Prototype to make compilers happy. This is used in the assembly HHVM
// dispatcher on x86-64 below.

// #define DISPATCH_DEBUG

#if defined DISPATCH_DEBUG
static uint64_t hunk_count = 0;
#endif
uintptr_t resolve_func(struct CpuState*, uintptr_t, struct RtldPatchData*);

static void
Expand Down Expand Up @@ -119,6 +125,10 @@ inline void dispatch_cdecl(uint64_t* cpu_regs) {
uintptr_t addr = cpu_regs[0];
uintptr_t hash = QUICK_TLB_HASH(addr);

#if defined DISPATCH_DEBUG
printf("hunk: %u\n", hunk_count);
hunk_count++;
#endif
uintptr_t func = cpu_state->quick_tlb[hash][1];
if (UNLIKELY(cpu_state->quick_tlb[hash][0] != addr))
func = resolve_func(cpu_state, addr, NULL);
Expand Down
25 changes: 24 additions & 1 deletion client/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,9 @@ handle_clone(struct State* state, struct clone_args* uargs, size_t usize) {
// clone(flags, stack, parent_tid, tls, child_tid)
ssize_t res = syscall(__NR_clone, flags, 0, args.parent_tid, args.tls,
args.child_tid, 0);
#elif defined(__riscv)
ssize_t res = syscall(__NR_clone, flags, 0, args.parent_tid, args.tls,
args.child_tid, 0);
#else
#error "clone not implemented for target"
#endif
Expand Down Expand Up @@ -448,15 +451,20 @@ emulate_syscall(uint64_t* cpu_regs) {
case 230: nr = __NR_clock_nanosleep; goto native;
case 257: goto common_openat;
case 260: nr = __NR_fchownat; goto native;
case 263: nr = __NR_unlinkat; goto native;
case 267: nr = __NR_readlinkat; goto native;
case 268: nr = __NR_fchmodat; goto native;
case 269: nr = __NR_faccessat; goto native;
case 270: nr = __NR_pselect6; goto native;
case 271: nr = __NR_ppoll; goto native;
case 273: nr = __NR_set_robust_list; goto native;
case 274: nr = __NR_get_robust_list; goto native;
case 280: nr = __NR_utimensat; goto native;
case 292: nr = __NR_dup3; goto native;
case 293: nr = __NR_pipe2; goto native;
case 302: nr = __NR_prlimit64; goto native;
case 318: nr = __NR_getrandom; goto native;
case 439: nr = __NR_faccessat2; goto native;

// Some are too old to work on newer platforms, but have replacements.
case 2: // open
Expand All @@ -474,7 +482,11 @@ emulate_syscall(uint64_t* cpu_regs) {
res = syscall(__NR_pipe2, arg0, 0, 0, 0, 0, 0);
break;
case 82: // rename
#ifdef __riscv
res = syscall(__NR_renameat2, AT_FDCWD, arg0, AT_FDCWD, arg1, 0, 0);
#else
res = syscall(__NR_renameat, AT_FDCWD, arg0, AT_FDCWD, arg1, 0, 0);
#endif
break;
case 83: // mkdir
res = syscall(__NR_mkdirat, AT_FDCWD, arg0, arg1, 0, 0, 0);
Expand Down Expand Up @@ -751,7 +763,18 @@ emulate_syscall_generic(struct CpuState* cpu_state, uint64_t* resp, uint64_t nr,
}
case 29: nr = __NR_ioctl; goto native; // TODO: catch dangerous commands
case 35: nr = __NR_unlinkat; goto native;
case 38: nr = __NR_renameat; goto native;
case 38:
#ifdef __riscv
#ifdef SYS_renameat
nr = SYS_renameat;
#else
nr = __NR_renameat2;
arg5 = 0;
#endif
#else
nr = __NR_renameat;
#endif
goto native;
case 46: nr = __NR_ftruncate; goto native;
case 48: nr = __NR_faccessat; goto native;
case 49: nr = __NR_chdir; goto native;
Expand Down
2 changes: 2 additions & 0 deletions client/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ int main(int argc, char** argv) {
state.tsc.tsc_stack_alignment = 8;
#elif defined(__aarch64__)
state.tsc.tsc_host_arch = EM_AARCH64;
#elif defined(__riscv)
state.tsc.tsc_host_arch = EM_RISCV;
#else
#error "Unsupported architecture!"
#endif
Expand Down
2 changes: 2 additions & 0 deletions client/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ mem_write_code(void* dst, const void* src, size_t size) {
__asm__ volatile("dsb ish");
}
__asm__ volatile("isb");
#elif defined(__riscv)
syscall(__NR_riscv_flush_icache, (uintptr_t)dst, (uintptr_t)((uintptr_t)dst + size), 0, 0, 0, 0);
#else
#error "Implement ICache flush for unknown target"
#endif
Expand Down
15 changes: 11 additions & 4 deletions client/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@ endif

client_c_args = ['-D_GNU_SOURCE', '-nostdlib', '-fno-builtin',
'-fno-stack-protector', '-fomit-frame-pointer', '-fPIC']
client_link_args = ['-nostdlib', '-nostartfiles', '-lgcc']
client_link_args = ['-nostdlib', '-nostartfiles', '-lgcc', '-latomic']

cc = meson.get_compiler('c')
if cc.has_argument('-static-pie')
client_link_args += ['-static-pie']
if host_machine.cpu_family() == 'riscv64' and cc.get_id() == 'gcc' and cc.version() == '12'
client_link_args += ['-static-pie', '-Wl,-static', '-Wl,-pie', '-Wl,--no-dynamic-linker', '-Wl,-z,text']
else
client_link_args += ['-Wl,-static', '-Wl,-pie', '-Wl,--no-dynamic-linker', '-Wl,-z,text']
if cc.has_argument('-static-pie')
client_link_args += ['-static-pie']
else
client_link_args += ['-Wl,-static', '-Wl,-pie', '-Wl,--no-dynamic-linker', '-Wl,-z,text']
endif
endif

if host_machine.cpu_family() == 'x86_64'
Expand All @@ -45,3 +49,6 @@ client = executable('instrew-client', sources,
override_options: ['b_sanitize=none'])

test('mathlib', executable('test_mathlib', 'math.c', c_args: ['-DTEST', '-fno-builtin']), protocol: 'tap')
# test('rtldlib', executable('test_rtldlib',
# 'rtld.c', include_directories: include_directories('.'),
# c_args: client_c_args + '-DTEST', link_args: client_link_args), protocol: 'tap')
154 changes: 153 additions & 1 deletion client/minilibc.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,154 @@ get_thread_area(void) {
return tp;
}

#elif defined(__riscv)
#define R_RELATIVE R_RISCV_RELATIVE

//TODO: maybe put this def to common?
#ifndef SA_RESTORER
#define SA_RESTORER 0x04000000
#endif

ASM_BLOCK(
.text;
.type _start, %function;
.weak _DYNAMIC;
.hidden _DYNAMIC;
.globl _start;
_start:
mv fp, x0;
mv a0, sp;
lla a1, _DYNAMIC;
andi sp, sp, 0xfffffffffffffff0;
jal __start_main;
);

ASM_BLOCK(
.global __clone;
.type __clone, %function;
__clone:
// Save func and arg to stack
addi a1, a1, -16;
sd a0, 0(a1);
sd a3, 8(a1);

// Call SYS_clone
mv a0, a2;
mv a2, a4;
mv a3, a5;
mv a4, a6;
li a7, 220; // SYS_clone
ecall;

beqz a0, 1f;
// Parent
ret;

// Child
1: ld a1, 0(sp);
ld a0, 8(sp);
jalr a1;

// Exit
li a7, 93; // SYS_exit
ecall;
);

ASM_BLOCK(
.globl __restore;
.type __restore, %function;
__restore:
li a0, __NR_rt_sigreturn;
ecall;
);

static size_t syscall0(int n)
{
register size_t a7 __asm__("a7") = n;
register size_t a0 __asm__("a0");
__asm__ volatile ("ecall\n\t" : "+r"(a0) : "r"(a7) : "memory");
return a0;
}

static size_t syscall1(int n, size_t a)
{
register size_t a7 __asm__("a7") = n;
register size_t a0 __asm__("a0") = a;
__asm__ volatile ("ecall\n\t" : "+r"(a0) : "r"(a7), "0"(a0) : "memory");
return a0;
}

static size_t syscall2(int n, size_t a, size_t b)
{
register size_t a7 __asm__("a7") = n;
register size_t a0 __asm__("a0") = a;
register size_t a1 __asm__("a1") = b;
__asm__ volatile ("ecall\n\t" : "+r"(a0) : "r"(a7), "0"(a0), "r"(a1) : "memory");
return a0;
}

static size_t syscall3(int n, size_t a, size_t b, size_t c)
{
register size_t a7 __asm__("a7") = n;
register size_t a0 __asm__("a0") = a;
register size_t a1 __asm__("a1") = b;
register size_t a2 __asm__("a2") = c;
__asm__ volatile ("ecall\n\t" : "+r"(a0) : "r"(a7), "0"(a0), "r"(a1), "r"(a2) : "memory");
return a0;
}

static size_t syscall4(int n, size_t a, size_t b, size_t c, size_t d)
{
register size_t a7 __asm__("a7") = n;
register size_t a0 __asm__("a0") = a;
register size_t a1 __asm__("a1") = b;
register size_t a2 __asm__("a2") = c;
register size_t a3 __asm__("a3") = d;
__asm__ volatile ("ecall\n\t" : "+r"(a0) : "r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3) : "memory");
return a0;
}

static size_t syscall5(int n, size_t a, size_t b, size_t c, size_t d, size_t e)
{
register size_t a7 __asm__("a7") = n;
register size_t a0 __asm__("a0") = a;
register size_t a1 __asm__("a1") = b;
register size_t a2 __asm__("a2") = c;
register size_t a3 __asm__("a3") = d;
register size_t a4 __asm__("a4") = e;
__asm__ volatile ("ecall\n\t" : "+r"(a0) : "r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4) : "memory");
return a0;
}

static size_t syscall6(int n, size_t a, size_t b, size_t c, size_t d, size_t e, size_t f)
{
register size_t a7 __asm__("a7") = n;
register size_t a0 __asm__("a0") = a;
register size_t a1 __asm__("a1") = b;
register size_t a2 __asm__("a2") = c;
register size_t a3 __asm__("a3") = d;
register size_t a4 __asm__("a4") = e;
register size_t a5 __asm__("a5") = f;
__asm__ volatile ("ecall\n\t" : "+r"(a0) : "r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5) : "memory");
return a0;
}

int
set_thread_area(void* tp) {
__asm__ volatile ("mv %0, a0\n\t"
"li a0, 0\r\n" :: "r"(tp) : "memory");
return 0;
}

void* get_thread_area(void) {
#ifdef SYS_set_thread_area
void* tp;
syscall1(SYS_set_thread_area, tp);
#else
return (void*)-ENOSYS;
#endif
}

#else
#error
#endif
Expand Down Expand Up @@ -740,7 +888,9 @@ sigaction(int num, const struct sigaction* restrict act,
if (act) {
kact = *act;
kact.sa_flags |= SA_RESTORER;
kact.sa_restorer = __restore;
#ifndef __riscv
kact.sa_restorer = __restore;
#endif
act = &kact;
}
return syscall4(__NR_rt_sigaction, num, (uintptr_t) act, (uintptr_t) oact,
Expand Down Expand Up @@ -774,7 +924,9 @@ size_t getpagesize(void) {
}

// May be overriden by an architecture-specific implementation.
#ifndef __riscv
__attribute__((weak)) GNU_FORCE_EXTERN
#endif
void* memset(void* s, int c, size_t n) {
unsigned char* sptr = s;
for (; n > 0; n--, sptr++)
Expand Down
18 changes: 18 additions & 0 deletions client/plt.inc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,24 @@ PLT_ENTRY("__divti3", __divti3) // libgcc
PLT_ENTRY("__udivti3", __udivti3) // libgcc
PLT_ENTRY("__modti3", __modti3) // libgcc
PLT_ENTRY("__umodti3", __umodti3) // libgcc
#if defined(__riscv)
PLT_ENTRY("__muldi3", __muldi3) // libgcc
PLT_ENTRY("__multi3", __multi3) // libgcc
PLT_ENTRY("__umoddi3", __umoddi3) // libgcc
PLT_ENTRY("__udivdi3", __udivdi3) // libgcc
PLT_ENTRY("__divdi3", __divdi3) // libgcc
PLT_ENTRY("__moddi3", __moddi3) // libgcc
PLT_ENTRY("__atomic_fetch_add_4", __atomic_fetch_add_4)
PLT_ENTRY("__atomic_fetch_add_8", __atomic_fetch_add_8)
PLT_ENTRY("__atomic_fetch_sub_4", __atomic_fetch_sub_4)
PLT_ENTRY("__atomic_fetch_sub_8", __atomic_fetch_sub_8)
PLT_ENTRY("__atomic_fetch_or_4", __atomic_fetch_or_4)
PLT_ENTRY("__atomic_fetch_or_8", __atomic_fetch_or_8)
PLT_ENTRY("__atomic_exchange_4", __atomic_exchange_4)
PLT_ENTRY("__atomic_exchange_8", __atomic_exchange_8)
PLT_ENTRY("__atomic_compare_exchange_4", __atomic_compare_exchange_4)
PLT_ENTRY("__atomic_compare_exchange_8", __atomic_compare_exchange_8)
#endif //defined(__riscv)
PLT_ENTRY("floorf", floorf) // math.c
PLT_ENTRY("floor", floor) // math.c
PLT_ENTRY("ceilf", ceilf) // math.c
Expand Down
Loading