diff options
author | Nick Clifton <nickc@redhat.com> | 2015-06-18 10:23:16 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2015-06-18 10:23:16 +0100 |
commit | c12d2c9d48cf18d818f79b89bffda934c354fdac (patch) | |
tree | ff33a5f7012f0b0999a2710342a4d96d224d8457 /gas/config | |
parent | 75c11999673ba32027eb17f6df9c37904622ed24 (diff) | |
download | binutils-c12d2c9d48cf18d818f79b89bffda934c354fdac.zip binutils-c12d2c9d48cf18d818f79b89bffda934c354fdac.tar.gz binutils-c12d2c9d48cf18d818f79b89bffda934c354fdac.tar.bz2 |
Add support for using the ADR alias in Thumb mode against nearby symbols.
PR gas/18541
gas * config/tc-arm.c (md_apply_fix): Add support for ADR in thumb
mode against a nearby symbol.
tests * gas/arm/thumb.s: Add test of ADR against a nearby symbol.
* gas/arm/thumb.d: Update expected output.
* gas/arm/thumb-eabi.d: Likewise.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-arm.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 9ccee40..1793965 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -23158,6 +23158,45 @@ md_apply_fix (fixS * fixP, } else if (rs == REG_PC || rs == REG_SP) { + /* PR gas/18541. If the addition is for a defined symbol + within range of an ADR instruction then accept it. */ + if (subtract + && value == 4 + && fixP->fx_addsy != NULL) + { + subtract = 0; + + if (! S_IS_DEFINED (fixP->fx_addsy) + || S_GET_SEGMENT (fixP->fx_addsy) != seg + || S_IS_WEAK (fixP->fx_addsy)) + { + as_bad_where (fixP->fx_file, fixP->fx_line, + _("address calculation needs a strongly defined nearby symbol")); + } + else + { + offsetT v = fixP->fx_where + fixP->fx_frag->fr_address; + + /* Round up to the next 4-byte boundary. */ + if (v & 3) + v = (v + 3) & ~ 3; + else + v += 4; + v = S_GET_VALUE (fixP->fx_addsy) - v; + + if (v & ~0x3fc) + { + as_bad_where (fixP->fx_file, fixP->fx_line, + _("symbol too far away")); + } + else + { + fixP->fx_done = 1; + value = v; + } + } + } + if (subtract || value & ~0x3fc) as_bad_where (fixP->fx_file, fixP->fx_line, _("invalid immediate for address calculation (value = 0x%08lX)"), |