This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
A problem with AIX gas cross-csect (bl) references
- To: binutils at sources dot redhat dot com
- Subject: A problem with AIX gas cross-csect (bl) references
- From: Ira Ruben <ira at apple dot com>
- Date: Mon, 20 Nov 2000 15:53:20 -0800
There appaears to be a bug in the way AIX gas generates cross csect
calls. Here's a gas -a listing for a small example:
1 .csect .A[PR]
2 0000 4E800020 .A: blr
3
4 .csect .B[PR]
5 0004 4E800020 .B: blr
6
7 .csect .C[PR]
8 0008 48000001 .C: bl .B
9
10 .csect .D[PR]
11 000c 60000000 .D: nop
12 0010 4BFFFFF9 bl .B
13
14 .globl .A
15 .globl .B
16 .globl .C
The problem is the bl .B calls from .C and .D. For the call from .C
the generated code, 0x48000001. The call from .D is 0x4BFFFFF9.
Both of these are wrong!
PowerPC bl's are pc-relative instructions. The relocation
information for these are R_BR's which is generated correctly. The
offset in the call from .C is assembled as 0 (the low-order 1 is just
the link bit). The offset for the .D call is 0xFFFFFFF8, i.e, -8.
But the .C call the pc-relative offset should be 4-8 = -4 and the one
from .D should be 4-16 = -12. Thus the correct assembled code should
have been:
For the .C call: 4BFFFFFD (offset = -4)
For the .D call: 4BFFFFF5 (offset = -12)
What appears to be happening is that gas is assembling these branches
as the pc-relative location of what's branched to PLUS the offset of
that target in the file. Both branches here are to file offset 4.
So both end up branching to .B+4, not .B!
Note, they are not both just off by 4. That's just the example I've
shown. I first encountered this problem while working on a gcc AIX
cross compiler and trying generate each function in its own csect
(since the linker I am using dead code strips at the function, i.e.,
csect, level). The test cases were branching into the middle of no
where!
Is this a known problem? If so is there a patch for it?
Ira Ruben
Apple Computer, Inc.