This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH][ARM] ADR/ADRL insns broken
- From: Andrew Stubbs <ams at codesourcery dot com>
- To: binutils at sourceware dot org
- Date: Wed, 18 Mar 2009 14:11:10 +0000
- Subject: [PATCH][ARM] ADR/ADRL insns broken
The problem is that the ADR and ADRL should not accept operands in
another section, but they do.
This patch adds a new test. It does not change assembler output for
correct code.
Example:
.text
start:
adr r0, var
.data
.globl var
var:
.word 0x00000000
Before the patch, the assembler mis-assembles the code and puts in a
constant offset of -8, which is probably just the PC adjustment.
After the patch, the assembler gives the following message:
t.s: Assembler messages:
t.s:3: Error: symbol var is in a different section
The ADRL instruction is similarly adjusted. This instruction also failed
to check that the symbol was defined. I've copied the code from the ADR
instruction to fix this.
OK?
Andrew
2009-03-17 Andrew Stubbs <ams@codesourcery.com>
gas/
* config/tc-arm.c (md_apply_fix): Check BFD_RELOC_ARM_IMMEDIATE and
BFD_RELOC_ARM_ADRL_IMMEDIATE value is in the correct section.
Check BFD_RELOC_ARM_ADRL_IMMEDIATE has a defined symbol.
gas/testsuites/
* gas/arm/adr-invalid.d: New file.
* gas/arm/adr-invalid.l: New file.
* gas/arm/adr-invalid.s: New file.
---
src/binutils-mainline/gas/config/tc-arm.c | 27 ++++++++++++++
src/binutils-mainline/gas/testsuite/gas/arm/adr-invalid.d | 2 +
src/binutils-mainline/gas/testsuite/gas/arm/adr-invalid.l | 5 ++
src/binutils-mainline/gas/testsuite/gas/arm/adr-invalid.s | 12 ++++++
4 files changed, 46 insertions(+)
Index: src/binutils-mainline/gas/config/tc-arm.c
===================================================================
--- src/binutils-mainline/gas/config/tc-arm.c.orig
+++ src/binutils-mainline/gas/config/tc-arm.c
@@ -18537,6 +18537,15 @@ md_apply_fix (fixS * fixP,
break;
}
+ if (fixP->fx_addsy
+ && S_GET_SEGMENT (fixP->fx_addsy) != seg)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("symbol %s is in a different section"),
+ S_GET_NAME (fixP->fx_addsy));
+ break;
+ }
+
newimm = encode_arm_immediate (value);
temp = md_chars_to_number (buf, INSN_SIZE);
@@ -18560,6 +18569,24 @@ md_apply_fix (fixS * fixP,
unsigned int highpart = 0;
unsigned int newinsn = 0xe1a00000; /* nop. */
+ if (fixP->fx_addsy
+ && ! S_IS_DEFINED (fixP->fx_addsy))
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("undefined symbol %s used as an immediate value"),
+ S_GET_NAME (fixP->fx_addsy));
+ break;
+ }
+
+ if (fixP->fx_addsy
+ && S_GET_SEGMENT (fixP->fx_addsy) != seg)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("symbol %s is in a different section"),
+ S_GET_NAME (fixP->fx_addsy));
+ break;
+ }
+
newimm = encode_arm_immediate (value);
temp = md_chars_to_number (buf, INSN_SIZE);
Index: src/binutils-mainline/gas/testsuite/gas/arm/adr-invalid.d
===================================================================
--- /dev/null
+++ src/binutils-mainline/gas/testsuite/gas/arm/adr-invalid.d
@@ -0,0 +1,2 @@
+# name: Invalid use of ADR and ADRL
+# error-output: adr-invalid.l
Index: src/binutils-mainline/gas/testsuite/gas/arm/adr-invalid.l
===================================================================
--- /dev/null
+++ src/binutils-mainline/gas/testsuite/gas/arm/adr-invalid.l
@@ -0,0 +1,5 @@
+[^:]*: Assembler messages:
+[^:]*:3: Error: symbol var is in a different section
+[^:]*:4: Error: undefined symbol undefinedvar used as an immediate value
+[^:]*:5: Error: symbol var is in a different section
+[^:]*:6: Error: undefined symbol undefinedvar used as an immediate value
Index: src/binutils-mainline/gas/testsuite/gas/arm/adr-invalid.s
===================================================================
--- /dev/null
+++ src/binutils-mainline/gas/testsuite/gas/arm/adr-invalid.s
@@ -0,0 +1,12 @@
+ .text
+start:
+ adr r0, var
+ adr r0, undefinedvar
+ adrl r1, var
+ adrl r1, undefinedvar
+
+ .data
+ .globl var
+var:
+ .word 0x00000000
+