Bug 248 - "ignoring least significant bits in branch offset"
Summary: "ignoring least significant bits in branch offset"
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: gas (show other bugs)
Version: 2.15
: P2 enhancement
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-07-01 15:35 UTC by Hollis Blanchard
Modified: 2004-07-02 07:50 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Hollis Blanchard 2004-07-01 15:35:01 UTC
Affected versions:
GNU assembler version 2.15.90.0.3 (powerpc64-unknown-linux-gnu) using BFD
version 2.15.90.0.3 20040415
GNU assembler version 2.14 (powerpc-linux) using BFD version 2.14 20030612
GNU assembler version 2.13.90.0.18 (ppc-yellowdog-linux) using BFD version
2.13.90.0.18 20030206

cat > testcase.S << EOF
        .text
        .byte 0xa5
        b foo
                                                                                
        .align 2
foo:
        b .
EOF

as testcase.S -Z -o testcase.o

Actual Results:
testcase.S: Assembler messages:
testcase.S:3: Error: ignoring least significant bits in branch offset

Expected Results:
The error message implies that the branch target is not 4-byte aligned, which is
not the case.

The error we want (if any) would probably be something like "misaligned
instruction".

Additional Information:
This affects ppc64 and ppc32, and seems to have been present for a long time.

The original problem (aside from the misleading error message) was an inline
assembly .byte in C code. Perhaps the "asm" statement could issue a .align
after its code...?
Comment 1 Alan Modra 2004-07-02 00:41:52 UTC
The error message is correct as is.  A problem with an offset might be due to
either source or destination, or both.

Really, what you're asking for is a check that powerpc insns are always properly
aligned.  I agree that this might be useful, but it's not trivial to implement.
The trouble is that at parsing and insn forming stage of gas we don't have much
idea of where the insn addresses happen to be.  Gas uses a data structure called
a frag when packaging insns.  frags don't make it easy to keep track of
addresses.  By the time you *do* know the address, it's too late to fix, since a
frag can easily contain many data and insn bytes intermixed.

See http://lists.gnu.org/archive/html/bug-binutils/2004-06/msg00103.html for
Jim's analysis of a similar request for ia64.

An approach that might work without introducing too much overhead or using
fragile schemes such as the alpha one is:
a) In the back-end, check that each emitted insn is at a proper offset from the
start of a frag.  You can get the offset with frag_now_fix ().
b) Have the back-end mark a frag as code-bearing when it contains insns.
c) Add a hook to the end of cvt_frag_to_fill that allows a back-end to check the
start address of code-bearing frags.

To handle weird code like
 .space 3
 .byte 0
 nop
you'd need to store insn offset mod 4 in step a) and complain if some other
remainder was used in the same frag.

This won't magically fix code, but it should allow a suitable error message to
be given.
Comment 2 Alan Modra 2004-07-02 07:50:18 UTC
I went ahead and implemented my proposed fix.