riscv-linux icon indicating copy to clipboard operation
riscv-linux copied to clipboard

linker issue undefined reference to __lshrti3

Open wbx-github opened this issue 6 years ago • 9 comments

Hi,

I am trying to compile Linux 4.15 branch and targeting Qemu. But the linking step fails with:

  • /Users/wbrodkorb/openadk/toolchain_qemu-riscv64_glibc/usr/bin/riscv64-openadk-linux-gnu-ld -melf64lriscv --build-id -o vmlinux -T ./arch/riscv/kernel/vmlinux.lds --whole-archive built-in.o --no-whole-archive --start-group lib/lib.a arch/riscv/lib/lib.a --end-group kernel/sched/fair.o: In function .L21': fair.c:(.text+0xdc): undefined reference to __lshrti3' kernel/time/timekeeping.o: In function read_persistent_clock64': timekeeping.c:(.text+0x1b0c): undefined reference to __lshrti3'

Looks like gcc emits some symbols not provided by the internal libgcc copy?

Self compiled toolchain with gcc 7.3.0. Happens with gcc 8.1.0, too. Binutils 2.30 + glib 2.27.

./toolchain_qemu-riscv64_glibc/usr/bin/riscv64-openadk-linux-gnu-gcc -v Using built-in specs. COLLECT_GCC=./toolchain_qemu-riscv64_glibc/usr/bin/riscv64-openadk-linux-gnu-gcc COLLECT_LTO_WRAPPER=/Users/wbrodkorb/openadk/toolchain_qemu-riscv64_glibc/usr/libexec/gcc/riscv64-openadk-linux-gnu/7.3.0/lto-wrapper Target: riscv64-openadk-linux-gnu Configured with: /Users/wbrodkorb/openadk/toolchain_build_qemu-riscv64_glibc/w-gcc-7.3.0-1/gcc-7.3.0/configure --prefix=/Users/wbrodkorb/openadk/toolchain_qemu-riscv64_glibc/usr --with-bugurl=https://openadk.org --build=x86_64-apple-darwin17.5.0 --host=x86_64-apple-darwin17.5.0 --target=riscv64-openadk-linux-gnu --with-gmp=/Users/wbrodkorb/openadk/host_x86_64-apple-darwin17.5.0/usr --with-mpfr=/Users/wbrodkorb/openadk/host_x86_64-apple-darwin17.5.0/usr --disable-__cxa_atexit --with-system-zlib --with-gnu-ld --with-gnu-as --disable-libsanitizer --disable-install-libiberty --disable-libitm --disable-libmudflap --disable-libgomp --disable-libcc1 --disable-libmpx --disable-libcilkrts --disable-libquadmath --disable-libquadmath-support --disable-decimal-float --disable-libstdcxx-pch --disable-ppl-version-check --disable-cloog-version-check --without-ppl --without-cloog --without-isl --disable-werror --disable-nls --disable-lto --with-arch=rv64imafdc --with-abi=lp64d --enable-tls --enable-threads --enable-libatomic --enable-shared --enable-cxx-flags=-fPIC --disable-libssp --disable-biarch --disable-multilib --enable-languages=c --with-build-sysroot='/../../target_qemu-riscv64_glibc' --with-sysroot='/../../target_qemu-riscv64_glibc' Thread model: posix gcc version 7.3.0 (GCC)

Any ideas?

wbx-github avatar May 10 '18 18:05 wbx-github

I'm not sure what's going on here. I'd expect that symbol to only end up necessary on a 32-bit kernel, as 64-bit builds can do 64-bit shifts with a single instruction. Our 32-bit port selects GENERIC_LSHRDI3 to get the symbol, and while that might make this go away you'll probably have some other problem.

palmer-dabbelt avatar May 25 '18 16:05 palmer-dabbelt

That is a 128-bit logical right shift. But it should still be expanded inline by a 64-bit compiler.

rohan:2050$ cat tmp.c
__uint128_t
sub (__uint128_t i)
{
  return i >> 10;
}
rohan:2051$ ./xgcc -B./ -O -S tmp.c
rohan:2052$ cat tmp.s
	.file	"tmp.c"
	.option nopic
	.text
	.align	1
	.globl	sub
	.type	sub, @function
sub:
	slli	a5,a1,54
	srli	a0,a0,10
	or	a0,a5,a0
	srli	a1,a1,10
	ret
	.size	sub, .-sub
	.ident	"GCC: (GNU) 9.0.0 20180518 (experimental) [trunk revision 260382]"

jim-wilson avatar May 25 '18 17:05 jim-wilson

Looks like it only happens when compiling the kernel with -Os. The problem disappears for me, when changing to -O2 and disable optimize for size in the kernel configuration.

wbx-github avatar May 25 '18 17:05 wbx-github

When right-shifting by a variable instead of a constant, it takes 10 instructions, so GCC emits a function call when optimizing for size. Same thing happens on AArch64. So the resolution is that this routine needs to be added to Linux...?

On Fri, May 25, 2018 at 10:48 AM, Waldemar Brodkorb < [email protected]> wrote:

Looks like it only happens when compiling the kernel with -Os. The problem disappears for me, when changing to -O2 and disable optimize for size in the kernel configuration.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/riscv/riscv-linux/issues/136#issuecomment-392132402, or mute the thread https://github.com/notifications/unsubscribe-auth/AA-7woKA2RWQ7rwzZJ4Fv3SkREUpN6rHks5t2EPygaJpZM4T6THl .

aswaterman avatar May 25 '18 18:05 aswaterman

I think so, same issue happened some time ago for mips64 and then the missing routine was added to libgcc inside the Linux kernel. See here for the problematic object file: https://debug.openadk.org/riscv/timekeeping.o

wbx-github avatar May 25 '18 18:05 wbx-github

Any update?

Still need -O2 instead of -Os.

xfguo avatar Jul 27 '18 11:07 xfguo

https://github.com/xfguo/riscv-linux/commit/c6666575617e390d9068aeb6b70768906592cb0c this works for me.

xfguo avatar Jul 29 '18 07:07 xfguo

@xfguo Do you want to submit that upstream, or should I?

palmer-dabbelt avatar Aug 03 '18 23:08 palmer-dabbelt

@palmer-dabbelt Sure, you can submit it to upstream. The implementation is from libgcc, you may need to check it manually.

xfguo avatar Aug 04 '18 01:08 xfguo