fix access by setjmp and longjmp to __hwcap on arm built as thumb2
authorRich Felker <dalias@aerifal.cx>
Fri, 13 Oct 2017 14:23:48 +0000 (10:23 -0400)
committerRich Felker <dalias@aerifal.cx>
Fri, 13 Oct 2017 14:28:52 +0000 (10:28 -0400)
this is a subtle issue with how the assembler/linker work. for the adr
pseudo-instruction used to find __hwcap, the assembler in thumb mode
generates a 16-bit thumb add instruction which can only represent
word-aligned addresses, despite not knowing the alignment of the
label. if the setjmp function is assigned a non-multiple-of-4 address
at link time, the load then loads from the wrong address (the last
instruction rather than the data containing the offset) and ends up
reading nonsense instead of the value of __hwcap. this in turn causes
the checks for floating-point/vector register sets (e.g. IWMMX) to
evaluate incorrectly, crashing when setjmp/longjmp try to save/restore
those registers.

fix based on bug report by Felix Hädicke.

src/setjmp/arm/longjmp.s
src/setjmp/arm/setjmp.s

index 6191ab26b8ab7109b1961479b8577fd36cb32fe6..76cc2920a3c9f0654fde5a9c6006afb9169f3666 100644 (file)
@@ -39,4 +39,5 @@ longjmp:
 3:     bx lr
 
 .hidden __hwcap
+.align 2
 1:     .word __hwcap-1b
index c6fe1bb230f171a41056213b98e7355b4ce04dc7..011315b70f94b2e3d5cdc5d86d2333a34a1fb442 100644 (file)
@@ -41,4 +41,5 @@ setjmp:
 3:     bx lr
 
 .hidden __hwcap
+.align 2
 1:     .word __hwcap-1b