diff options
author | Tamar Christina <tamar.christina@arm.com> | 2021-05-25 16:04:04 +0100 |
---|---|---|
committer | Tamar Christina <tamar.christina@arm.com> | 2021-05-25 16:04:52 +0100 |
commit | d3e52e120b68bf19552743fbc078e0a759f48cb7 (patch) | |
tree | eaf641175d369046e8213b1eefd887d899202950 /gas/config/tc-arm.c | |
parent | 74fd118fb91f49377b63931d092b6d42dd8b3b3c (diff) | |
download | gdb-d3e52e120b68bf19552743fbc078e0a759f48cb7.zip gdb-d3e52e120b68bf19552743fbc078e0a759f48cb7.tar.gz gdb-d3e52e120b68bf19552743fbc078e0a759f48cb7.tar.bz2 |
Arm: Fix forward thumb references [PR gas/25235]
When assembling a forward reference the symbol will be unknown and so during
do_t_adr we cannot set the thumb bit. The bit it set so early to prevent
relaxations that are invalid. i.e. relaxing a Thumb2 to Thumb1 insn when the
symbol is Thumb.
But because it's done so early we miss the case for forward references.
This patch changes it so that we additionally check the thumb bit during the
internal relocation processing.
In principle we should be able to only set the bit during reloc processing but
that would require changes to the other relocations that the instruction could
be relaxed to.
This approach still allows early relaxations (which means that we have less
iteration of internal reloc processing) while still fixing the forward reference
case.
gas/ChangeLog:
2021-05-24 Tamar Christina <tamar.christina@arm.com>
PR gas/25235
* config/tc-arm.c (md_convert_frag): Set LSB when Thumb symbol.
(relax_adr): Thumb symbols 4 bytes.
* testsuite/gas/arm/pr25235.d: New test.
* testsuite/gas/arm/pr25235.s: New test.
Diffstat (limited to 'gas/config/tc-arm.c')
-rw-r--r-- | gas/config/tc-arm.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 9229dd0..1e2ac65 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -26827,6 +26827,14 @@ md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp) pc_rel = (opcode == T_MNEM_ldr_pc2); break; case T_MNEM_adr: + /* Thumb bits should be set in the frag handling so we process them + after all symbols have been seen. PR gas/25235. */ + if (exp.X_op == O_symbol + && exp.X_add_symbol != NULL + && S_IS_DEFINED (exp.X_add_symbol) + && THUMB_IS_FUNC (exp.X_add_symbol)) + exp.X_add_number |= 1; + if (fragp->fr_var == 4) { insn = THUMB_OP32 (opcode); @@ -27024,7 +27032,8 @@ relax_adr (fragS *fragp, asection *sec, long stretch) if (fragp->fr_symbol == NULL || !S_IS_DEFINED (fragp->fr_symbol) || sec != S_GET_SEGMENT (fragp->fr_symbol) - || S_IS_WEAK (fragp->fr_symbol)) + || S_IS_WEAK (fragp->fr_symbol) + || THUMB_IS_FUNC (fragp->fr_symbol)) return 4; val = relaxed_symbol_addr (fragp, stretch); |