static void __attribute__ ((noinline))
myfunc(long fp, long foo, long bar, long code, long thumb, long thumb2)
{
printf ("\tfp: 0x%lx\n", fp);
printf ("\tfoo: 0x%lx\n", foo);
printf ("\tbar: 0x%lx\n", bar);
printf ("\tcode: 0x%lx\n", code);
printf ("\tthumb: 0x%lx\n", thumb);
printf ("\tthumb2: 0x%lx\n", thumb2);
}
int main()
{
long fp = (long) myfunc;
long foo = fp & 0x1L;
long bar = getfp (myfunc);
long code = (long) myfunc & ~0x1L;
long thumb = (long) myfunc & 0x1L;
long thumb2 = getfp (myfunc) & 0x1L;
myfunc(fp, foo, bar, code, thumb, thumb2);
return 0;
}
I see a very similar issue even with -O0 when using GCC 4.5.2-8ubuntu1 on my ARM board.
Here is a simple test:
<snip>
$ cat test.c && gcc -O0 -Wall -Winline test.c -o test.bin && echo "O0:" && ./test.bin && gcc -O2 -Wall -Winline test.c -o test.bin && echo "O2:" && ./test.bin
#include <stdio.h>
static long __attribute__ ((noinline))
getfp (void *p)
{
return (long) p;
}
static void __attribute__ ((noinline))
myfunc(long fp, long foo, long bar, long code, long thumb, long thumb2)
{
printf ("\tfp: 0x%lx\n", fp);
printf ("\tfoo: 0x%lx\n", foo);
printf ("\tbar: 0x%lx\n", bar);
printf ("\tcode: 0x%lx\n", code);
printf ("\tthumb: 0x%lx\n", thumb);
printf ("\tthumb2: 0x%lx\n", thumb2);
}
int main()
{
long fp = (long) myfunc;
long foo = fp & 0x1L;
long bar = getfp (myfunc);
long code = (long) myfunc & ~0x1L;
long thumb = (long) myfunc & 0x1L;
long thumb2 = getfp (myfunc) & 0x1L;
myfunc(fp, foo, bar, code, thumb, thumb2);
return 0;
}
O0:
fp: 0x83b1
foo: 0x1
bar: 0x83b1
code: 0x83b0
thumb: 0x0
thumb2: 0x1
O2:
fp: 0x83a1
foo: 0x0
bar: 0x83a1
code: 0x83a0
thumb: 0x0
thumb2: 0x1
</snip>
The interesting thing is the " (long) myfunc & 0x1L".