If the displacement from a "br*" instruction to the target of the branch is 128K or more, gas writes garbace into the displacement field(s) instead of generating a relocation overflow error.
The branch on register condition instructions have a 16-bit signed displacement field, but it is split into two pieces of the instruction. The low 14 bits are at bits 0-13 of the instruction, bits 14 and 15 of the displacement are at bits 21-20 of the instruction. The test case is very simple: .text 1: nop .skip (128 * 1024) brz,pt %o0, 1b Build this with "as -Av9a -o test.o test.s". GAS allows this erroneously, instead of generating a relocation failure. You can look at the assembler of the object file with "objdump --disassemble test.o" you will see output like: 00000000 <.text>: 0: 01 00 00 00 nop ... 20004: 02 da 3f ff brz %o0, 0x40000 20008: 01 00 00 00 nop which is obviously bogus. sparc-opc.c uses 'k' character class for the relocation, this is handled in tc-sparc.c with: case 'k': the_insn.reloc = /* RELOC_WDISP2_14 */ BFD_RELOC_SPARC_WDISP16; the_insn.pcrel = 1; goto immediate; The comment reference to the mythical "RELOC_WDISP2_14" is quite curious :-) Later down in tc-sparc.c we have the handler for BFD_RELOC_SPARC_WDISP16: case BFD_RELOC_SPARC_WDISP16: /* FIXME: simplify. */ if (((val > 0) && (val & ~0x3fffc)) || ((val < 0) && (~(val - 1) & ~0x3fffc))) as_bad_where (fixP->fx_file, fixP->fx_line, _("relocation overflow")); /* FIXME: The +1 deserves a comment. */ val = (val >> 2) + 1; insn |= ((val & 0xc000) << 6) | (val & 0x3fff); break; And here we have the bug, the reloc range checking is wrong. The masks should be 0x1fffc instead of 0x3fffc. -- Summary: branch on register condition accepts relocations >= 128K Product: binutils Version: 2.18 (HEAD) Status: NEW Severity: normal Priority: P2 Component: gas AssignedTo: unassigned at sources dot redhat dot com ReportedBy: davem at davemloft dot net CC: bug-binutils at gnu dot org GCC build triplet: sparc-unknown-linux-gnu GCC host triplet: sparc-unknown-linux-gnu GCC target triplet: sparc-unknown-liunx-gnu http://sourceware.org/bugzilla/show_bug.cgi?id=4558 ------- You are receiving this mail because: ------- You are on the CC list for the bug, or are watching someone who is. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils