diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile index 426e601f5d34d..4d9334dde8c55 100644 --- a/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile @@ -11,6 +11,7 @@ RUN sh /scripts/rustbuild-setup.sh WORKDIR /tmp COPY scripts/crosstool-ng-build.sh /scripts/ +COPY host-x86_64/dist-riscv64-linux/patches/ /tmp/patches/ COPY host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.defconfig /tmp/crosstool.defconfig RUN /scripts/crosstool-ng-build.sh diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/patches/gcc/8.5.0/0001-divdi3-div-zero.patch b/src/ci/docker/host-x86_64/dist-riscv64-linux/patches/gcc/8.5.0/0001-divdi3-div-zero.patch new file mode 100644 index 0000000000000..f688eaf8029ec --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-riscv64-linux/patches/gcc/8.5.0/0001-divdi3-div-zero.patch @@ -0,0 +1,37 @@ +From 4013baf99c38f7bca06a51f8301e8fb195ccfa33 Mon Sep 17 00:00:00 2001 +From: Jim Wilson +Date: Tue, 2 Jun 2020 11:19:39 -0700 +Subject: [PATCH] RISC-V: Make __divdi3 handle div by zero same as hardware. + +The ISA manual specifies that divide by zero always returns -1 as the result. +We were failing to do that when the dividend was negative. + +Original patch from Virginie Moser. + + libgcc/ + * config/riscv/div.S (__divdi3): For negative arguments, change bgez + to bgtz. +--- + libgcc/config/riscv/div.S | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/libgcc/config/riscv/div.S b/libgcc/config/riscv/div.S +index 151f8e273ac77..17234324c1e41 100644 +--- a/libgcc/config/riscv/div.S ++++ b/libgcc/config/riscv/div.S +@@ -107,10 +107,12 @@ FUNC_END (__umoddi3) + /* Handle negative arguments to __divdi3. */ + .L10: + neg a0, a0 +- bgez a1, .L12 /* Compute __udivdi3(-a0, a1), then negate the result. */ ++ /* Zero is handled as a negative so that the result will not be inverted. */ ++ bgtz a1, .L12 /* Compute __udivdi3(-a0, a1), then negate the result. */ ++ + neg a1, a1 +- j __udivdi3 /* Compute __udivdi3(-a0, -a1). */ +-.L11: /* Compute __udivdi3(a0, -a1), then negate the result. */ ++ j __udivdi3 /* Compute __udivdi3(-a0, -a1). */ ++.L11: /* Compute __udivdi3(a0, -a1), then negate the result. */ + neg a1, a1 + .L12: + move t0, ra diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/patches/gcc/8.5.0/0002-hidden-jump-target.patch b/src/ci/docker/host-x86_64/dist-riscv64-linux/patches/gcc/8.5.0/0002-hidden-jump-target.patch new file mode 100644 index 0000000000000..7ae4469428b13 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-riscv64-linux/patches/gcc/8.5.0/0002-hidden-jump-target.patch @@ -0,0 +1,117 @@ +From 45116f342057b7facecd3d05c2091ce3a77eda59 Mon Sep 17 00:00:00 2001 +From: Nelson Chu +Date: Mon, 29 Nov 2021 04:48:20 -0800 +Subject: [PATCH] RISC-V: jal cannot refer to a default visibility symbol for + shared object. + +This is the original binutils bugzilla report, +https://sourceware.org/bugzilla/show_bug.cgi?id=28509 + +And this is the first version of the proposed binutils patch, +https://sourceware.org/pipermail/binutils/2021-November/118398.html + +After applying the binutils patch, I get the the unexpected error when +building libgcc, + +/scratch/nelsonc/riscv-gnu-toolchain/riscv-gcc/libgcc/config/riscv/div.S:42: +/scratch/nelsonc/build-upstream/rv64gc-linux/build-install/riscv64-unknown-linux-gnu/bin/ld: relocation R_RISCV_JAL against `__udivdi3' which may bind externally can not be used when making a shared object; recompile with -fPIC + +Therefore, this patch add an extra hidden alias symbol for __udivdi3, and +then use HIDDEN_JUMPTARGET to target a non-preemptible symbol instead. +The solution is similar to glibc as follows, +https://sourceware.org/git/?p=glibc.git;a=commit;h=68389203832ab39dd0dbaabbc4059e7fff51c29b + +libgcc/ChangeLog: + + * config/riscv/div.S: Add the hidden alias symbol for __udivdi3, and + then use HIDDEN_JUMPTARGET to target it since it is non-preemptible. + * config/riscv/riscv-asm.h: Added new macros HIDDEN_JUMPTARGET and + HIDDEN_DEF. +--- + libgcc/config/riscv/div.S | 15 ++++++++------- + libgcc/config/riscv/riscv-asm.h | 6 ++++++ + 2 files changed, 14 insertions(+), 7 deletions(-) + +diff --git a/libgcc/config/riscv/div.S b/libgcc/config/riscv/div.S +index c9bd7879c1e36..723c3b82e48c6 100644 +--- a/libgcc/config/riscv/div.S ++++ b/libgcc/config/riscv/div.S +@@ -40,7 +40,7 @@ FUNC_BEGIN (__udivsi3) + sll a0, a0, 32 + sll a1, a1, 32 + move t0, ra +- jal __udivdi3 ++ jal HIDDEN_JUMPTARGET(__udivdi3) + sext.w a0, a0 + jr t0 + FUNC_END (__udivsi3) +@@ -52,7 +52,7 @@ FUNC_BEGIN (__umodsi3) + srl a0, a0, 32 + srl a1, a1, 32 + move t0, ra +- jal __udivdi3 ++ jal HIDDEN_JUMPTARGET(__udivdi3) + sext.w a0, a1 + jr t0 + FUNC_END (__umodsi3) +@@ -95,11 +95,12 @@ FUNC_BEGIN (__udivdi3) + .L5: + ret + FUNC_END (__udivdi3) ++HIDDEN_DEF (__udivdi3) + + FUNC_BEGIN (__umoddi3) + /* Call __udivdi3(a0, a1), then return the remainder, which is in a1. */ + move t0, ra +- jal __udivdi3 ++ jal HIDDEN_JUMPTARGET(__udivdi3) + move a0, a1 + jr t0 + FUNC_END (__umoddi3) +@@ -111,12 +112,12 @@ FUNC_END (__umoddi3) + bgtz a1, .L12 /* Compute __udivdi3(-a0, a1), then negate the result. */ + + neg a1, a1 +- j __udivdi3 /* Compute __udivdi3(-a0, -a1). */ ++ j HIDDEN_JUMPTARGET(__udivdi3) /* Compute __udivdi3(-a0, -a1). */ + .L11: /* Compute __udivdi3(a0, -a1), then negate the result. */ + neg a1, a1 + .L12: + move t0, ra +- jal __udivdi3 ++ jal HIDDEN_JUMPTARGET(__udivdi3) + neg a0, a0 + jr t0 + FUNC_END (__divdi3) +@@ -126,7 +127,7 @@ FUNC_BEGIN (__moddi3) + bltz a1, .L31 + bltz a0, .L32 + .L30: +- jal __udivdi3 /* The dividend is not negative. */ ++ jal HIDDEN_JUMPTARGET(__udivdi3) /* The dividend is not negative. */ + move a0, a1 + jr t0 + .L31: +@@ -134,7 +135,7 @@ FUNC_BEGIN (__moddi3) + bgez a0, .L30 + .L32: + neg a0, a0 +- jal __udivdi3 /* The dividend is hella negative. */ ++ jal HIDDEN_JUMPTARGET(__udivdi3) /* The dividend is hella negative. */ + neg a0, a1 + jr t0 + FUNC_END (__moddi3) +diff --git a/libgcc/config/riscv/riscv-asm.h b/libgcc/config/riscv/riscv-asm.h +index 8550707a4a26a..96dd85b0df2e5 100644 +--- a/libgcc/config/riscv/riscv-asm.h ++++ b/libgcc/config/riscv/riscv-asm.h +@@ -33,3 +33,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + #define FUNC_ALIAS(X,Y) \ + .globl X; \ + X = Y ++ ++#define CONCAT1(a, b) CONCAT2(a, b) ++#define CONCAT2(a, b) a ## b ++#define HIDDEN_JUMPTARGET(X) CONCAT1(__hidden_, X) ++#define HIDDEN_DEF(X) FUNC_ALIAS(HIDDEN_JUMPTARGET(X), X); \ ++ .hidden HIDDEN_JUMPTARGET(X) diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/patches/glibc/2.29/0001-hidden-jump-target.patch b/src/ci/docker/host-x86_64/dist-riscv64-linux/patches/glibc/2.29/0001-hidden-jump-target.patch new file mode 100644 index 0000000000000..d267b961d3472 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-riscv64-linux/patches/glibc/2.29/0001-hidden-jump-target.patch @@ -0,0 +1,58 @@ +From 68389203832ab39dd0dbaabbc4059e7fff51c29b Mon Sep 17 00:00:00 2001 +From: Fangrui Song +Date: Thu, 28 Oct 2021 11:39:49 -0700 +Subject: [PATCH] riscv: Fix incorrect jal with HIDDEN_JUMPTARGET + +A non-local STV_DEFAULT defined symbol is by default preemptible in a +shared object. j/jal cannot target a preemptible symbol. On other +architectures, such a jump instruction either causes PLT [BZ #18822], or +if short-ranged, sometimes rejected by the linker (but not by GNU ld's +riscv port [ld PR/28509]). + +Use HIDDEN_JUMPTARGET to target a non-preemptible symbol instead. + +With this patch, ld.so and libc.so can be linked with LLD if source +files are compiled/assembled with -mno-relax/-Wa,-mno-relax. + +Acked-by: Palmer Dabbelt +Reviewed-by: Adhemerval Zanella +--- + sysdeps/riscv/setjmp.S | 2 +- + sysdeps/unix/sysv/linux/riscv/setcontext.S | 5 +++-- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/sysdeps/riscv/setjmp.S b/sysdeps/riscv/setjmp.S +index 0b92016b311..bec7ff80f49 100644 +--- a/sysdeps/riscv/setjmp.S ++++ b/sysdeps/riscv/setjmp.S +@@ -21,7 +21,7 @@ + + ENTRY (_setjmp) + li a1, 0 +- j __sigsetjmp ++ j HIDDEN_JUMPTARGET (__sigsetjmp) + END (_setjmp) + ENTRY (setjmp) + li a1, 1 +diff --git a/sysdeps/unix/sysv/linux/riscv/setcontext.S b/sysdeps/unix/sysv/linux/riscv/setcontext.S +index 9510518750a..e44a68aad47 100644 +--- a/sysdeps/unix/sysv/linux/riscv/setcontext.S ++++ b/sysdeps/unix/sysv/linux/riscv/setcontext.S +@@ -95,6 +95,7 @@ LEAF (__setcontext) + 99: j __syscall_error + + END (__setcontext) ++libc_hidden_def (__setcontext) + weak_alias (__setcontext, setcontext) + + LEAF (__start_context) +@@ -108,7 +109,7 @@ LEAF (__start_context) + /* Invoke subsequent context if present, else exit(0). */ + mv a0, s2 + beqz s2, 1f +- jal __setcontext +-1: j exit ++ jal HIDDEN_JUMPTARGET (__setcontext) ++1: j HIDDEN_JUMPTARGET (exit) + + END (__start_context) diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.defconfig index 470cef1a84e18..f7c93a9d5fc88 100644 --- a/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.defconfig +++ b/src/ci/docker/host-x86_64/dist-riscv64-linux/riscv64-unknown-linux-gnu.defconfig @@ -3,6 +3,8 @@ CT_EXPERIMENTAL=y CT_PREFIX_DIR="/x-tools/${CT_TARGET}" CT_USE_MIRROR=y CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_PATCH_BUNDLED_LOCAL=y +CT_LOCAL_PATCH_DIR="/tmp/patches" CT_ARCH_RISCV=y # CT_DEMULTILIB is not set CT_ARCH_USE_MMU=y @@ -10,7 +12,7 @@ CT_ARCH_64=y CT_ARCH_ARCH="rv64gc" CT_KERNEL_LINUX=y CT_LINUX_V_4_20=y -CT_BINUTILS_V_2_36=y +CT_BINUTILS_V_2_40=y CT_GLIBC_V_2_29=y CT_GCC_V_8=y CT_CC_LANG_CXX=y