From 1cd1c99be6bbc691878b2a8713f4e75dd41bf206 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sat, 15 Jul 2000 12:57:14 +0000 Subject: [PATCH] (hppa_fix_adjustable): Don't reduce certain symbols to section syms. --- gas/ChangeLog | 7 +++++++ gas/config/tc-hppa.c | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 36bad5494f..41113b8111 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2000-07-15 Alan Modra + + * config/tc-hppa.c (hppa_fix_adjustable): Use the same checks for + ELF as are used for SOM (except the 32-bit reloc one) to decide + whether a symbol can be reduced to a section symbol. Expand on + the comment for symbols involved in LR% and RR% expressions. + 2000-07-14 Nick Clifton * config/tc-mips.c (mips_disable_float_construction): New diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c index 313b22930a..67eb611b82 100644 --- a/gas/config/tc-hppa.c +++ b/gas/config/tc-hppa.c @@ -4431,7 +4431,7 @@ md_apply_fix (fixP, valp) } #endif - insn = bfd_get_32 (stdoutput, (unsigned char *)buf); + insn = bfd_get_32 (stdoutput, (unsigned char *) buf); /* There should have been an HPPA specific fixup associated with the GAS fixup. */ if (hppa_fixP) @@ -8342,6 +8342,7 @@ hppa_fix_adjustable (fixp) /* Reject reductions of symbols in 32bit relocs. */ if (fixp->fx_r_type == R_HPPA && hppa_fix->fx_r_format == 32) return 0; +#endif /* Reject reductions of symbols in sym1-sym2 expressions when the fixup will occur in a CODE subspace. @@ -8359,12 +8360,38 @@ hppa_fix_adjustable (fixp) } /* We can't adjust any relocs that use LR% and RR% field selectors. - That confuses the HP linker. */ + + If a symbol is reduced to a section symbol, the assembler will + adjust the addend unless the symbol happens to reside right at + the start of the section. Additionally, the linker has no choice + but to manipulate the addends when coalescing input sections for + "ld -r". Since an LR% field selector is defined to round the + addend, we can't change the addend without risking that a LR% and + it's corresponding (possible multiple) RR% field will no longer + sum to the right value. + + eg. Suppose we have + . ldil LR%foo+0,%r21 + . ldw RR%foo+0(%r21),%r26 + . ldw RR%foo+10(%r21),%r25 + + If foo is at address 4090 (decimal) in section `sect', then after + reducing to the section symbol, we get + . LR%sect+4090 == L%sect+0 + . RR%sect+4090 == R%sect+4090 + . RR%sect+4100 == R%sect-4092 (4100 - 8192) + and the last address loses. + + Obviously, in cases where the LR% expression is identical to the + RR% one we will never have a problem, but is so happens that gcc + rounds addends involved in LR% field selectors to work around a + HP linker bug. ie. We often have addresses like the last case + above where the LR% expression is offset from the RR% one. */ + if (hppa_fix->fx_r_field == e_lrsel || hppa_fix->fx_r_field == e_rrsel || hppa_fix->fx_r_field == e_nlrsel) return 0; -#endif /* Reject reductions of symbols in DLT relative relocs, relocations with plabels. */