[PATCH] arm: ensure symbol is a thumb symbol in new binutils
Chen-Yu Tsai
wens at csie.org
Tue Jan 16 00:43:43 PST 2018
On Wed, Nov 22, 2017 at 1:27 AM, Jason A. Donenfeld <Jason at zx2c4.com> wrote:
> On older versions of binutils, \sym points to an aligned address. On
> newer versions of binutils, \sym sometimes points to the unaligned thumb
> address in mysterious and buggy circumstances. In order to homogenize
> this behavior, rather than adding 1, we simply OR in 1, so that already
> unaligned instructions don't change. This fix is required for a
> pedestrian THUMB2_KERNEL to boot without crashing when built with
> non-old binutils.
>
> While it works, the downside is that we have to add an `orr` instruction
> to a fast path. The assembler can't do this at assemble time via "|1"
> because "invalid operands (.text and *ABS* sections) for `|'", so we're
> forced to do this. A better solution would be to have consistent
> binutils behavior, or to have some kind of \sym feature detection that
> won't turn into a maze of version comparisons. However, it's at the
> moment unclear how to achieve this.
>
> The rest of this commit message contains all of the relevant
> information.
>
> My tests concerned these versions:
> broken: GNU ld (Gentoo 2.29.1 p3) 2.29.1
> working: GNU ld (GNU Binutils for Ubuntu) 2.26.1
>
> These produced the following code:
> --- broken 2017-11-21 17:44:14.523416082 +0100
> +++ working 2017-11-21 17:44:44.548461234 +0100
> @@ -133,7 +133,7 @@
> 160: f01a 0ff0 tst.w sl, #240 ; 0xf0
> 164: d111 bne.n 18a <__sys_trace>
> 166: f5b7 7fc8 cmp.w r7, #400 ; 0x190
> - 16a: f2af 1e6a subw lr, pc, #362 ; 0x16a
> + 16a: f2af 1e6b subw lr, pc, #363 ; 0x16b
> 16e: bf38 it cc
> 170: f858 f027 ldrcc.w pc, [r8, r7, lsl #2]
> 174: a902 add r1, sp, #8
>
> The differing instruction corresponds with this actual line in
> arch/arm/kernel/entry-common.S:
> badr lr, ret_fast_syscall @ return address
>
> Running the broken kernel results in a runtime OOPS with:
> PC is at ret_fast_syscall+0x4/0x52
> LR is at ret_fast_syscall+0x2/0x52
>
> The disassembly of that function for the crashing kernel is:
> .text:00000000 ret_fast_syscall ; CODE XREF: sys_syscall+1C↓j
> .text:00000000 CPSID I ; jumptable 00000840 cases 15,18-376
> .text:00000002
> .text:00000002 loc_2 ; DATA XREF: sys_syscall-6BA↓o
> .text:00000002 LDR.W R2, [R9,#8]
> .text:00000006 CMP.W R2, #0xBF000000
>
> Signed-off-by: Jason A. Donenfeld <Jason at zx2c4.com>
> Cc: stable at vger.kernel.org
FWIW, this patch fixes things for me. Never occurred to me that
it was binutils that was at fault.
Tested-by: Chen-Yu Tsai <wens at csie.org>
with
$ arm-linux-gnueabihf-ld -v
GNU ld (GNU Binutils for Debian) 2.29.1
$ arm-linux-gnueabihf-gcc -v
Using built-in specs.
COLLECT_GCC=/usr/bin/arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/arm-linux-gnueabihf/7/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Debian
7.2.0-11' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs
--enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++ --prefix=/usr
--with-gcc-major-version-only --program-suffix=-7 --enable-shared
--enable-linker-build-id --libexecdir=/usr/lib
--without-included-gettext --enable-threads=posix --libdir=/usr/lib
--enable-nls --with-sysroot=/ --enable-clocale=gnu
--enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-gnu-unique-object
--disable-libitm --disable-libquadmath --enable-plugin
--enable-default-pie --with-system-zlib --with-target-system-zlib
--enable-multiarch --disable-sjlj-exceptions --with-arch=armv7-a
--with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb
--disable-werror --enable-checking=release --build=x86_64-linux-gnu
--host=x86_64-linux-gnu --target=arm-linux-gnueabihf
--program-prefix=arm-linux-gnueabihf-
--includedir=/usr/arm-linux-gnueabihf/include
Thread model: posix
gcc version 7.2.0 (Debian 7.2.0-11)
ChenYu
More information about the linux-arm-kernel
mailing list