[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