[Pkg-bluetooth-maintainers] Bug#856487: libsbc1: compiling with gcc > 4.9 causes stack corruption
Paul Brook
paul at nowt.org
Mon Apr 17 16:02:32 UTC 2017
Package: libsbc1
Version: 1.3-1+b2
Followup-For: Bug #856487
Not a stack corruption.
This is miscompilation of sbc_analyze_4b_8s_armv6. gcc appears to look
into the asm function and decides that it does not clobber r3 (which the
normal ARM ABI says is call clobbered). The last out += out_stride ends
up incrementing the pointer by an arbitrary amount.
The attached patch works around the bug.
I'm not entirely sure whether this is a gcc bug or not, but at best it's
surprising behavior from gcc. I've attached a reduced testcase for the toolchain
folks to argue over (compile with gcc -O2, tested with gcc 6.3.0-2 from
sid).
Paul
diff -ur clean/sbc/sbc_primitives_armv6.c sbc-1.3/sbc/sbc_primitives_armv6.c
--- clean/sbc/sbc_primitives_armv6.c 2013-04-30 17:19:23.000000000 +0100
+++ sbc-1.3/sbc/sbc_primitives_armv6.c 2017-04-17 16:43:49.918809345 +0100
@@ -102,6 +102,7 @@
"pop {r8-r11}\n"
"stmia r1, {r4, r5, r6, r7}\n"
"pop {r1, r4-r7, pc}\n"
+ :::"r0", "r2", "r3", "ip"
);
}
@@ -258,6 +259,7 @@
"pop {r8-r11}\n"
"stmia r1!, {r4, r5, r6, r7}\n"
"pop {r1, r4-r7, pc}\n"
+ :::"r0", "r2", "r3", "ip"
);
}
-------------- next part --------------
/* Compile with -O2 on arm */
#include <stdint.h>
#include <stdlib.h>
static void __attribute__((naked)) frob(int16_t *a, int32_t *b, const int16_t *c)
{
/* The explicit clobber of r3 should not be necessary because that it is implied by the function call?
gcc6 seems to look into the naked function and assume r3 is preserved accross the call. */
__asm__ volatile ("mov r3, #0x80000000\n\t"
"str r3, [r1]\n\t"
"bx lr"
#if 0
:::"r3"
#endif
);
}
int16_t c[4];
struct sbc_encoder_state;
void test(struct sbc_encoder_state *state,
int16_t *x, int32_t *out, int out_stride)
{
frob(x + 24, out, c);
out += out_stride;
frob(x + 16, out, c);
out += out_stride;
frob(x + 8, out, c);
out += out_stride;
frob(x + 0, out, c);
}
int main()
{
static int16_t a[32];
static int32_t b[32];
test(NULL, a, b, 8);
return 0;
}
More information about the Pkg-bluetooth-maintainers
mailing list