Implement RISC-V dynamic linking#323
Conversation
|
As the The updated GitHub Actions also downloads the 32-bit variant to validate RISC-V dynamic linking. |
Evaluate Run 32-bit applications on 64-bit Linux kernel, which is exactly RV32-on-RV64 userspace compatibility, not emulation. |
I'm not sure whether I understand correctly. Do you mean that the proposed changes should be verified on a RISC-V machine? |
See sysprog21/kbox#18 |
Introduce ELF_MACHINE_ARM32 (0x28) and ELF_MACHINE_RV32 (0xf3) to support architecture-specific logic in future developments.
446b538 to
44f2f47
Compare
|
RISE RISC-V Runners' documentation explicitly states that binaries must be compiled for riscv64. According to the FAQ - What architectures are supported?.
I created another branch ( Based on both the documentation and my test, it appears that RISE RISC-V runners lack support for 32-bit executables. |
|
RISC-V calling convention:
Item 1: is done by the register allocation phase.The register allocator uses virtual registers (vreg0-vreg7) to allocate reigsters for arguments when encountering a function call. vreg0-vreg7 will be mapped to a0-a7, so first eight arguments are naturally passed to these registers. Since the current shecc only supports up to 8 arguments, no extra arguments need to be passed to the stack. Thus, we can skip this handling. Item 2: is ensured by the RISC-V code generator.When handling the stack pointer, the code generator will guarantee that Item 3:
Therefore, this item can also be considered complete. Further details and explanations can be found in |
This commit primarily improves the ELF handling and code generator to
enable the compiler to produce a dynamically linked executable targeting
the RISC-V architecture.
- Allow the ELF handling to generate RELA relocation table.
- Use REL relocation when the target architecture is Arm. Othereise,
use RELA relocation for RISC-V.
- Improve GOT generation process.
- Arm: reserve three entries.
- RISC-V: reserve two entries.
- Implement PLT generation for RISC-V.
- The generation process follows the RISC-V ABI. The first PLT entry
uses 8 instructions to call '_dl_runtime_resolve'. The subsequent
entry uses 4 instructions to perform an indirect function call via
GOT.
- Refine the function call handling for the RISC-V code generator.
- Perform a direct call for internal functions
- Otherwise, use PLT table to peform an indirect call for external
functions.
- Enhance the build system:
- Allow the build system to generate dynamically linked compilers when
targeting the RISC-V architecture.
- Detect the sysroot path of the RISC-V GNU toolchain automatically.
Modify the 'update-snapshots' and 'check-snapshots' make targets to include generation and validation of new snapshots for the RISC-V architecture using dynamic linking.
The update workflow now downloads a RISC-V GNU toolchain to provide necessary dependencies and validate the dynamically linked compiler targeting the RISC-V architecture.
Because two architecture-specific makefile fragments contain similar snippets for locating the cross-compilation toolchain path, this commit consolidates them into a shared build logic, thereby reducing code duplication.
A new shell script is introduced to validate whether generated executables targeting RISC-V correct comply with the RISC-V ABI. The tests include: - Parameter Passing: tests function calls with different numbers of arguments. - Stack Alignment: validates whether the stack is always 16-byte aligned when calling a function. - Return Values: confirms if the return value is correct after a function returns. - External Calls: verifies whether dynamically linked programs can call external functions. - Register Preservation: verify whether the contents of function argument registers are properly preserved when calling a function. - Structure Passing: validates if a small structure object can be passed correctly.
2599d74 to
ee9db4a
Compare
The proposed changes primarily improve the ELF generation and the RISC-V backend, enabling the build system to generate a dynamically linked shecc targeting the RISC-V architecture.
Although the current changes allow both bootstrapping and test suite to complete successfully, this is still a work in progress. The TODO items are listed as follows:
riscv-abi.sh) to validate the RISC-V ABI.arm.mkandriscv.mkinto a common build logic (e.g.: configureRUNNER_LD_PREFIX).Summary by cubic
Implements RV32 dynamic linking with RELA, an ABI-compliant PLT/GOT, and a
__libc_start_mainstartup path; external calls route via PLT and the stack stays 16-byte aligned. Adds a RISC-V ABI test suite and expands CI to validate static/dynamic builds forarmandriscvwith auto-detected toolchains.New Features
.rela.plt; PLT0=32B, stubs=16B; per-archRESERVED_GOT_NUM(RV32=2, ARM=3);DYN_LINKER/lib/ld-linux-riscv32-ilp32d.so.1.use_relapltandELF_MACHINE_*; correct dynamic tags (RELA/RELASZ/RELAENT/JMPREL/PLTREL/PLTRELSZ); GOT init honors reserved entries.__libc_start_main; preservera; keep syscall trampoline for static.tests/riscv-abi.sh; RV32 dynamic snapshots (hello,fib).Dependencies
mk/common.mkwith per-archTOOLCHAIN_CANDIDATES; CI downloads a RISC-V glibc toolchain and adds/opt/riscv/binto PATH; static/dynamic matrices run forarmandriscvwithRUNNER_LD_PREFIXauto-set under QEMU.Written for commit ee9db4a. Summary will update on new commits.