Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 4 additions & 8 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,7 @@ jobs:
matrix:
compiler: [gcc, clang]
architecture: [arm, riscv]
link_mode: [static]
include:
- compiler: gcc
architecture: arm
link_mode: dynamic
- compiler: clang
architecture: arm
link_mode: dynamic
link_mode: [static, dynamic]
steps:
- name: Checkout code
uses: actions/checkout@v4
Expand All @@ -27,6 +20,9 @@ jobs:
sudo apt-get install -q -y qemu-user
sudo apt-get install -q -y build-essential
sudo apt-get install -q -y gcc-arm-linux-gnueabihf
sudo wget -q https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2026.04.05/riscv32-glibc-ubuntu-24.04-gcc.tar.xz
sudo tar Jxf riscv32-glibc-ubuntu-24.04-gcc.tar.xz -C /opt
echo "/opt/riscv/bin" >> "$GITHUB_PATH"
- name: Determine static or dynamic linking mode
id: determine-mode
run: |
Expand Down
12 changes: 6 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,6 @@ STAGE0_FLAGS ?= --dump-ir
STAGE1_FLAGS ?=
DYNLINK ?= 0
ifeq ($(DYNLINK),1)
ifeq ($(ARCH),riscv)
# TODO: implement dynamic linking for RISC-V.
$(error "Dynamic linking mode is not implemented for RISC-V")
endif
STAGE0_FLAGS += --dynlink
STAGE1_FLAGS += --dynlink
endif
Expand Down Expand Up @@ -108,8 +104,10 @@ check-sanitizer: $(OUT)/$(STAGE0)-sanitizer tests/driver.sh
$(Q)rm $(OUT)/shecc

check-snapshots: $(OUT)/$(STAGE0) $(SNAPSHOTS) tests/check-snapshots.sh
# static linking
$(Q)$(foreach SNAPSHOT_ARCH, $(ARCHS), $(MAKE) distclean config check-snapshot ARCH=$(SNAPSHOT_ARCH) DYNLINK=0 --silent;)
$(Q)$(MAKE) distclean config check-snapshot ARCH=arm DYNLINK=1 --silent
# dynamic linking
$(Q)$(foreach SNAPSHOT_ARCH, $(ARCHS), $(MAKE) distclean config check-snapshot ARCH=$(SNAPSHOT_ARCH) DYNLINK=1 --silent;)
$(VECHO) "Switching backend back to %s (DYNLINK=0)\n" arm
$(Q)$(MAKE) distclean config ARCH=arm DYNLINK=0 --silent

Expand All @@ -134,8 +132,10 @@ check-abi-stage2: $(OUT)/$(STAGE2)
fi

update-snapshots: tests/update-snapshots.sh
# static linking
$(Q)$(foreach SNAPSHOT_ARCH, $(ARCHS), $(MAKE) distclean config update-snapshot ARCH=$(SNAPSHOT_ARCH) DYNLINK=0 --silent;)
$(Q)$(MAKE) distclean config update-snapshot ARCH=arm DYNLINK=1 --silent
# dynamic linking
$(Q)$(foreach SNAPSHOT_ARCH, $(ARCHS), $(MAKE) distclean config update-snapshot ARCH=$(SNAPSHOT_ARCH) DYNLINK=1 --silent;)
$(VECHO) "Switching backend back to %s (DYNLINK=0)\n" arm
$(Q)$(MAKE) distclean config ARCH=arm DYNLINK=0 --silent

Expand Down
1 change: 1 addition & 0 deletions mk/arm.mk
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ ARCH_DEFS = \
\#define LIBC_SO \"libc.so.6\"\n$\
\#define PLT_FIXUP_SIZE 20\n$\
\#define PLT_ENT_SIZE 12\n$\
\#define RESERVED_GOT_NUM 3\n$\
\#define R_ARCH_JUMP_SLOT 0x16\n$\
\#define MAX_ARGS_IN_REG 4\n$\
"
Expand Down
37 changes: 32 additions & 5 deletions mk/riscv.mk
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,40 @@ ARCH_DEFS = \
\#define ARCH_PREDEFINED \"__riscv\" /* Older versions of the GCC toolchain defined __riscv__ */\n$\
\#define ELF_MACHINE 0xf3\n$\
\#define ELF_FLAGS 0\n$\
\#define DYN_LINKER \"/lib/ld-linux.so.3\"\n$\
\#define DYN_LINKER \"/lib/ld-linux-riscv32-ilp32d.so.1\"\n$\
\#define LIBC_SO \"libc.so.6\"\n$\
\#define PLT_FIXUP_SIZE 20\n$\
\#define PLT_ENT_SIZE 12\n$\
\#define PLT_FIXUP_SIZE 32\n$\
\#define PLT_ENT_SIZE 16\n$\
\#define RESERVED_GOT_NUM 2\n$\
\#define R_ARCH_JUMP_SLOT 0x5\n$\
\#define MAX_ARGS_IN_REG 8\n$\
"

# TODO: Set this variable for RISC-V architecture
RUNNER_LD_PREFIX=
ifeq ($(USE_QEMU),1)
ifeq ($(DYNLINK),1)
CROSS_COMPILE = riscv32-unknown-linux-gnu-
RISCV_CC = $(CROSS_COMPILE)gcc
RISCV_CC := $(shell which $(RISCV_CC))
ifndef RISCV_CC
$(error "Unable to find ARM GNU toolchain.")
endif

LD_LINUX_PATH := $(shell cd $(shell $(RISCV_CC) --print-sysroot) 2>/dev/null && pwd)
ifeq ("$(LD_LINUX_PATH)","/")
LD_LINUX_PATH := $(shell dirname "$(shell which $(RISCV_CC))")/..
LD_LINUX_PATH := $(shell cd $(LD_LINUX_PATH) 2>/dev/null && pwd)
LD_LINUX_PATH := $(LD_LINUX_PATH)/$(shell echo $(CROSS_COMPILE) | sed s'/.$$//')/libc
LD_LINUX_PATH := $(shell cd $(LD_LINUX_PATH) 2>/dev/null && pwd)
ifndef LD_LINUX_PATH
LD_LINUX_PATH = /usr/$(shell echo $(CROSS_COMPILE) | sed s'/.$$//')
LD_LINUX_PATH := $(shell cd $(LD_LINUX_PATH) 2>/dev/null && pwd)
endif
endif

ifndef LD_LINUX_PATH
$(error "Dynamic linking mode requires ld-linux.so")
endif

RUNNER_LD_PREFIX = -L $(LD_LINUX_PATH)
endif
endif
4 changes: 2 additions & 2 deletions src/arch-lower.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ void riscv_lower(void)
/* Entry point: dispatch to the active architecture. */
void arch_lower(void)
{
#if ELF_MACHINE == 0x28 /* ARM */
#if ELF_MACHINE == ELF_MACHINE_ARM32
arm_lower();
#elif ELF_MACHINE == 0xf3 /* RISC-V */
#elif ELF_MACHINE == ELF_MACHINE_RV32
riscv_lower();
#else
/* Unknown architecture: keep behavior as-is. */
Expand Down
23 changes: 23 additions & 0 deletions src/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#define MAX_DYNSYM 1024
#define MAX_DYNSTR 1024
#define MAX_RELPLT 1024
#define MAX_RELAPLT 1024
#define MAX_PLT 1024
#define MAX_GOTPLT 1024
#define MAX_CONSTANTS 1024
Expand Down Expand Up @@ -101,6 +102,9 @@
#define ALIGN_UP(val, align) (((val) + (align) - 1) & ~((align) - 1))
#endif

#define ELF_MACHINE_ARM32 0x28
#define ELF_MACHINE_RV32 0xf3

/* Common data structures */
typedef struct arena_block {
char *memory;
Expand Down Expand Up @@ -682,15 +686,28 @@ typedef struct {
strbuf_t *elf_dynsym;
strbuf_t *elf_dynstr;
strbuf_t *elf_relplt;
strbuf_t *elf_relaplt;
strbuf_t *elf_plt;
strbuf_t *elf_got;
int elf_interp_start;
int elf_relplt_start;
int elf_relaplt_start;
int elf_plt_start;
int elf_got_start;
int relplt_size;
int relaplt_size;
int plt_size;
int got_size;

/* Currently, we don't consider the scenarios involving
* a mixture of REL and RELA relocation entries.
*
* Therefore, use a flag to determine the type of
* relocation entries to be processed:
* - true: use RELA relocation entries
* - false: use REL relocation entries
*/
bool use_relaplt;
} dynamic_sections_t;

/* For .dynsym section. */
Expand All @@ -709,6 +726,12 @@ typedef struct {
int r_info;
} elf32_rel_t;

typedef struct {
int r_offset;
int r_info;
int r_addend;
} elf32_rela_t;

/* For .dynamic section */
typedef struct {
int d_tag;
Expand Down
Loading
Loading