[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug gas/4558] New: branch on register condition accepts relocations >=
From: |
davem at davemloft dot net |
Subject: |
[Bug gas/4558] New: branch on register condition accepts relocations >= 128K |
Date: |
28 May 2007 07:26:21 -0000 |
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 gas/4558] New: branch on register condition accepts relocations >= 128K,
davem at davemloft dot net <=