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 |
2599d74 to
ee9db4a
Compare
ee9db4a to
de67942
Compare
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.
de67942 to
1af9140
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 (RELA + ABI‑compliant PLT/GOT) with a
__libc_start_mainentry path, and introducesELF_MACHINE_*macros to select REL (ARM) vs RELA (RISC‑V). CI now builds/tests static and dynamic for botharmandriscv, and an ABI test suite validates RV32 calling/stack rules.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.ELF_MACHINE_ARM32/ELF_MACHINE_RV32; REL (ARM) vs RELA (RV32); correct dynamic tags (RELA/RELASZ/RELAENT/JMPREL/PLTREL/PLTRELSZ);.gotinit honors reserved entries.__libc_start_mainthen returns via savedra; syscall trampoline kept for static; stack stays 16‑byte aligned.tests/riscv-abi.sh); RV32 dynamic snapshots (hello,fib); ABI checks forarmandriscv; CI matrix runs static+dynamic on both.Dependencies
mk/common.mkwith per‑archTOOLCHAIN_CANDIDATES; GitHub Actions installs a riscv32 glibc toolchain and adds/opt/riscv/bintoPATH;RUNNER_LD_PREFIXauto‑set under QEMU.Written for commit 1af9140. Summary will update on new commits.