Does anybody know what flags are used to build glibc?
A recent upgrade crashes software that is using glibc when calling vsnprintf() due to a SIGBUS signal. The signal happens due to an unaligned load into NEON registers, which the kernel does NOT fix.
The crash happens in _IO_str_init_static_internal(), whose instructions follow:
$this->bbcode_second_pass_code('', '
000767a8 <_IO_str_init_static_internal>:
767a8: e92d40f0 push {r4, r5, r6, r7, lr}
767ac: e3a0ca01 mov ip, #4096 ; 0x1000
767b0: e04dc00c sub ip, sp, ip
767b4: e58c0fd8 str r0, [ip, #4056] ; 0xfd8
767b8: e1a05001 mov r5, r1
767bc: e24dd014 sub sp, sp, #20
767c0: e1a06000 mov r6, r0
767c4: e1a07003 mov r7, r3
767c8: e2521000 subs r1, r2, #0
767cc: 1a000018 bne 76834 <_IO_str_init_static_internal+0x8c>
767d0: e1a00005 mov r0, r5
767d4: eb008131 bl 96ca0 <__rawmemchr>
767d8: e1a04000 mov r4, r0
767dc: e1a01005 mov r1, r5
767e0: e1a02004 mov r2, r4
767e4: e3a03000 mov r3, #0
767e8: e1a00006 mov r0, r6
767ec: ebfff91a bl 74c5c <_IO_setb>
767f0: e3570000 cmp r7, #0
767f4: 01a07004 moveq r7, r4
767f8: e88d00a0 stm sp, {r5, r7}
767fc: e58d5008 str r5, [sp, #8]
76800: e2862004 add r2, r6, #4
76804: e58d500c str r5, [sp, #12]
76808: 01a01005 moveq r1, r5
7680c: f46d0adf vld1.64 {d16-d17}, [sp :64]
76810: 01a04005 moveq r4, r5
76814: 11a01007 movne r1, r7
76818: e3a03000 mov r3, #0
7681c: e5861014 str r1, [r6, #20]
76820: e5864018 str r4, [r6, #24]
76824: f4420a8f vst1.32 {d16-d17}, [r2]
76828: e58630a0 str r3, [r6, #160] ; 0xa0
7682c: e28dd014 add sp, sp, #20
76830: e8bd80f0 pop {r4, r5, r6, r7, pc}
76834: e0852001 add r2, r5, r1
76838: e1550002 cmp r5, r2
7683c: 31a04002 movcc r4, r2
76840: 23e04000 mvncs r4, #0
76844: eaffffe4 b 767dc <_IO_str_init_static_internal+0x34>
')
The issue happens because the following instruction performs an unaligned load (which is NOT fixed by the kernel).
$this->bbcode_second_pass_code('', '
vld1.64 {d16-d17}, [sp :64]
')
The SP register happens to contain an address that is only aligned to 4 bytes, but the vld1.64 instruction requires 8 bytes alignment.
As far as I could find out, passing the GCC parameter -mno-unaligned-access avoids this issue, even when enabling -O3 optimizations.