summaryrefslogtreecommitdiff
path: root/gas/config/tc-xtensa.c
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2020-04-19 19:04:41 -0700
committerMax Filippov <jcmvbkbc@gmail.com>2020-04-22 18:46:45 -0700
commit30ce8e47fad9b057b6d7af9e1d43061126d34d20 (patch)
treef1c9ab86407f5a80c78bdf436f2178d2aacc96dd /gas/config/tc-xtensa.c
parente44f65e3c5c9473d0dd98efa8c142d361b1273d7 (diff)
downloadbinutils-gdb-30ce8e47fad9b057b6d7af9e1d43061126d34d20.tar.gz
xtensa: fix PR ld/25861
Introduce new relaxations XTENSA_PDIFF{8,16,32} for positive differences (subtracted symbol precedes diminished symbol) and XTENSA_NDIFF{8,16,32} for negative differences (subtracted symbol follows diminished symbol). Don't generate XTENSA_DIFF relocations in the assembler, generate XTENSA_PDIFF or XTENSA_NDIFF based on relative symbol position. Handle XTENSA_DIFF in BFD for compatibility with old object files. Handle XTENSA_PDIFF and XTENSA_NDIFF in BFD, treating difference value as unsigned. 2020-04-22 Max Filippov <jcmvbkbc@gmail.com> bfd/ * bfd-in2.h: Regenerated. * elf32-xtensa.c (elf_howto_table): New entries for R_XTENSA_PDIFF{8,16,32} and R_XTENSA_NDIFF{8,16,32}. (elf_xtensa_reloc_type_lookup, elf_xtensa_do_reloc) (relax_section): Add cases for R_XTENSA_PDIFF{8,16,32} and R_XTENSA_NDIFF{8,16,32}. * libbfd.h (bfd_reloc_code_real_names): Add names for BFD_RELOC_XTENSA_PDIFF{8,16,32} and BFD_RELOC_XTENSA_NDIFF{8,16,32}. * reloc.c: Add documentation for BFD_RELOC_XTENSA_PDIFF{8,16,32} and BFD_RELOC_XTENSA_NDIFF{8,16,32}. binutils/ * readelf.c (is_none_reloc): Recognize BFD_RELOC_XTENSA_PDIFF{8,16,32} and BFD_RELOC_XTENSA_NDIFF{8,16,32}. gas/ * config/tc-xtensa.c (md_apply_fix): Replace BFD_RELOC_XTENSA_DIFF{8,16,32} generation with BFD_RELOC_XTENSA_PDIFF{8,16,32} and BFD_RELOC_XTENSA_NDIFF{8,16,32} generation. * testsuite/gas/xtensa/loc.d: Replace BFD_RELOC_XTENSA_DIFF16 with BFD_RELOC_XTENSA_PDIFF16 in the expected output. include/ * elf/xtensa.h (elf_xtensa_reloc_type): New entries for R_XTENSA_PDIFF{8,16,32} and R_XTENSA_NDIFF{8,16,32}. ld/ * testsuite/ld-xtensa/relax-loc.d: New test definition. * testsuite/ld-xtensa/relax-loc.s: New test source. * testsuite/ld-xtensa/xtensa.exp (relax-loc): New test.
Diffstat (limited to 'gas/config/tc-xtensa.c')
-rw-r--r--gas/config/tc-xtensa.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
index 71d4d94a8d7..ee75c13548f 100644
--- a/gas/config/tc-xtensa.c
+++ b/gas/config/tc-xtensa.c
@@ -5974,18 +5974,24 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
case BFD_RELOC_8:
if (fixP->fx_subsy)
{
+ bfd_boolean neg = S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset
+ < S_GET_VALUE (fixP->fx_subsy);
+
switch (fixP->fx_r_type)
{
case BFD_RELOC_8:
- fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8;
+ fixP->fx_r_type = neg
+ ? BFD_RELOC_XTENSA_NDIFF8 : BFD_RELOC_XTENSA_PDIFF8;
fixP->fx_signed = 0;
break;
case BFD_RELOC_16:
- fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16;
+ fixP->fx_r_type = neg
+ ? BFD_RELOC_XTENSA_NDIFF16 : BFD_RELOC_XTENSA_PDIFF16;
fixP->fx_signed = 0;
break;
case BFD_RELOC_32:
- fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32;
+ fixP->fx_r_type = neg
+ ? BFD_RELOC_XTENSA_NDIFF32 : BFD_RELOC_XTENSA_PDIFF32;
fixP->fx_signed = 0;
break;
default: