This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Thumb pic bug with address of function
- From: Richard Earnshaw <rearnsha at arm dot com>
- To: binutils at sources dot redhat dot com
- Cc: Richard dot Earnshaw at arm dot com
- Date: Sun, 17 Mar 2002 16:57:41 +0000
- Subject: Thumb pic bug with address of function
- Organization: ARM Ltd.
- Reply-to: Richard dot Earnshaw at arm dot com
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.