Thumb pic bug with address of function
Richard Earnshaw
rearnsha@arm.com
Sun Mar 17 08:58:00 GMT 2002
Compiling the following program (from the gcc testsuites) shows a bug in
the
handling of Thumb pic code. It turns out that this is a linker/assembler
bug.
The problem is that the entry in the GOT for a thumb function should have
the bottom bit set, so that when it is added to the GOT address we get a
correct thumb function pointer. As it isn't, the call to the function
does not work correctly, and we end up trying to interpret the target
function as ARM code.
double
f(double x)
{
return x*x;
}
double
Int(double (*f)(double), double a)
{
return (*f)(a);
}
main()
{
if (Int(&f,2.0) != 4.0)
abort();
exit (0);
}
main:
push {lr}
ldr r3, .L7
mov sl, r3
.L6:
add sl, pc @ SL now points to the GOT
ldr r0, .L7+4 @ Load the offset for 'f'
add r0, r0, sl @ And add it to the GOT
ldr r1, .L7+8
ldr r2, .L7+12
bl Int
...
.L7:
.word _GLOBAL_OFFSET_TABLE_-(.L6+4)
.word f(GOTOFF)
...
When we execute this code, then SL is set to 0xb7a4 (Reasonable, since
this is the base of the GOT table) and r0 is set initially to -13848, when
we add the two together we get 0x818c which is the absolute address of
'f'. However, in oder to correctly call this code, the result should have
been 0x818d (ie have the bottom bit set).
Fix: Take the 'Thumb' bit into account when creating GOTOFF entries.
R.
More information about the Binutils
mailing list