diff options
-rw-r--r-- | gas/ChangeLog | 12 | ||||
-rw-r--r-- | gas/config/tc-frv.h | 2 | ||||
-rw-r--r-- | gas/config/tc-hppa.h | 2 | ||||
-rw-r--r-- | gas/config/tc-mn10300.h | 2 | ||||
-rw-r--r-- | gas/config/tc-sh.h | 16 | ||||
-rw-r--r-- | gas/config/tc-sh64.h | 9 | ||||
-rw-r--r-- | gas/config/tc-xtensa.h | 2 | ||||
-rw-r--r-- | gas/doc/internals.texi | 6 | ||||
-rw-r--r-- | gas/write.c | 19 |
9 files changed, 45 insertions, 25 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 7b22d2f..e555580 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,17 @@ 2008-09-19 Alan Modra <amodra@bigpond.net.au> + * write.c (TC_FORCE_RELOCATION_SUB_LOCAL): Heed md_register_arithmetic. + (TC_VALIDATE_FIX_SUB): Likewise. + * config/tc-frv.h (TC_FORCE_RELOCATION_SUB_LOCAL): Likewise. + * config/tc-hppa.h (TC_FORCE_RELOCATION_SUB_LOCAL): Likewise. + * config/tc-mn10300.h (TC_VALIDATE_FIX_SUB): Likewise. + * config/tc-sh.h (TC_VALIDATE_FIX_SUB): Likewise. + (TC_FORCE_RELOCATION_SUB_LOCAL): Likewise. + * config/tc-sh64.h (TC_VALIDATE_FIX_SUB): Likewise. + * config/tc-xtensa.h (TC_VALIDATE_FIX_SUB): Likewise. + * doc/internals.texi (TC_FORCE_RELOCATION_SUB_ABS, + TC_FORCE_RELOCATION_SUB_LOCAL, TC_VALIDATE_FIX_SUB): Show new param. + * write.c (md_register_arithmetic): Define. (fixup_segment): Adjust TC_FORCE_RELOCATION_SUB_ABS invocation. Modify error message when registers involved. diff --git a/gas/config/tc-frv.h b/gas/config/tc-frv.h index ad7eee0..732dacd 100644 --- a/gas/config/tc-frv.h +++ b/gas/config/tc-frv.h @@ -61,7 +61,7 @@ extern int frv_force_relocation (struct fix *); /* If we simplify subtractions that aren't SUB_SAME or SUB_ABS, we end up with PCrel fixups, but since we don't have any PCrel relocs, we crash. Preventing simplification gets us a good, early error. */ -#define TC_FORCE_RELOCATION_SUB_LOCAL(fixP) 1 +#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) 1 #undef GAS_CGEN_MAX_FIXUPS #define GAS_CGEN_MAX_FIXUPS 1 diff --git a/gas/config/tc-hppa.h b/gas/config/tc-hppa.h index 498cb25..05168b1 100644 --- a/gas/config/tc-hppa.h +++ b/gas/config/tc-hppa.h @@ -155,7 +155,7 @@ int hppa_fix_adjustable (struct fix *); difference expression can't be used between text and data symbols, or between symbols in different executable modules. */ #define DIFF_EXPR_OK 1 -#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX) 1 +#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) 1 #define UNDEFINED_DIFFERENCE_OK #endif diff --git a/gas/config/tc-mn10300.h b/gas/config/tc-mn10300.h index 63ca74a..2fffaa3 100644 --- a/gas/config/tc-mn10300.h +++ b/gas/config/tc-mn10300.h @@ -70,7 +70,7 @@ void mn10300_cons_fix_new (fragS *, int, int, expressionS *); /* We validate subtract arguments within tc_gen_reloc(), so don't report errors at this point. */ -#define TC_VALIDATE_FIX_SUB(FIX) 1 +#define TC_VALIDATE_FIX_SUB(FIX, SEG) 1 /* Fixup debug sections since we will never relax them. Ideally, we could do away with this and instead check every single fixup with diff --git a/gas/config/tc-sh.h b/gas/config/tc-sh.h index a3187b3..51b6561 100644 --- a/gas/config/tc-sh.h +++ b/gas/config/tc-sh.h @@ -83,8 +83,9 @@ extern int sh_force_relocation (struct fix *); || (sh_relax && SWITCH_TABLE (FIX))) /* Don't complain when we leave fx_subsy around. */ -#define TC_VALIDATE_FIX_SUB(FIX) \ - (sh_relax && SWITCH_TABLE (FIX)) +#define TC_VALIDATE_FIX_SUB(FIX, SEG) \ + ((md_register_arithmetic || (SEG) != reg_section) \ + && sh_relax && SWITCH_TABLE (FIX)) #define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section (FIX, SEC) extern long md_pcrel_from_section (struct fix *, segT); @@ -207,7 +208,9 @@ extern bfd_boolean sh_fix_adjustable (struct fix *); || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPC \ || TC_FORCE_RELOCATION (FIX)) -#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX) (sh_relax && SWITCH_TABLE (FIX)) +#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) \ + ((!md_register_arithmetic && (SEG) == reg_section) \ + || (sh_relax && SWITCH_TABLE (FIX))) /* This keeps the subtracted symbol around, for use by PLT_PCREL relocs. */ @@ -217,9 +220,10 @@ extern bfd_boolean sh_fix_adjustable (struct fix *); /* Don't complain when we leave fx_subsy around. */ #undef TC_VALIDATE_FIX_SUB -#define TC_VALIDATE_FIX_SUB(FIX) \ - ((FIX)->fx_r_type == BFD_RELOC_32_PLT_PCREL \ - || (sh_relax && SWITCH_TABLE (FIX))) +#define TC_VALIDATE_FIX_SUB(FIX, SEG) \ + ((md_register_arithmetic || (SEG) != reg_section) \ + && ((FIX)->fx_r_type == BFD_RELOC_32_PLT_PCREL \ + || (sh_relax && SWITCH_TABLE (FIX)))) #define md_parse_name(name, exprP, mode, nextcharP) \ sh_parse_name ((name), (exprP), (mode), (nextcharP)) diff --git a/gas/config/tc-sh64.h b/gas/config/tc-sh64.h index 23e72f6..17f0900 100644 --- a/gas/config/tc-sh64.h +++ b/gas/config/tc-sh64.h @@ -115,10 +115,11 @@ extern int sh64_target_mach (void); /* Don't complain when we leave fx_subsy around. */ #undef TC_VALIDATE_FIX_SUB -#define TC_VALIDATE_FIX_SUB(FIX) \ - ((FIX)->fx_r_type == BFD_RELOC_32_PLT_PCREL \ - || (sh_relax && SWITCH_TABLE (FIX)) \ - || *symbol_get_tc ((FIX)->fx_addsy) != NULL) +#define TC_VALIDATE_FIX_SUB(FIX, SEG) \ + ((md_register_arithmetic || (SEG) != reg_section) \ + && ((FIX)->fx_r_type == BFD_RELOC_32_PLT_PCREL \ + || (sh_relax && SWITCH_TABLE (FIX)) \ + || *symbol_get_tc ((FIX)->fx_addsy) != NULL)) /* Note the kludge: we want to put back C, and we also want to consume the expression, since we have handled it ourselves. FIXME: What we really diff --git a/gas/config/tc-xtensa.h b/gas/config/tc-xtensa.h index 987b82a..dbb5267 100644 --- a/gas/config/tc-xtensa.h +++ b/gas/config/tc-xtensa.h @@ -335,7 +335,7 @@ extern char *xtensa_section_rename (char *); #define TC_FORCE_RELOCATION(fix) xtensa_force_relocation (fix) #define TC_FORCE_RELOCATION_SUB_SAME(fix, seg) \ (! SEG_NORMAL (seg) || xtensa_force_relocation (fix)) -#define TC_VALIDATE_FIX_SUB(fix) xtensa_validate_fix_sub (fix) +#define TC_VALIDATE_FIX_SUB(fix, seg) xtensa_validate_fix_sub (fix) #define NO_PSEUDO_DOT xtensa_check_inside_bundle () #define tc_canonicalize_symbol_name(s) xtensa_section_rename (s) #define tc_canonicalize_section_name(s) xtensa_section_rename (s) diff --git a/gas/doc/internals.texi b/gas/doc/internals.texi index cfb9a93..7c6172c 100644 --- a/gas/doc/internals.texi +++ b/gas/doc/internals.texi @@ -1309,17 +1309,17 @@ the subtrahend will be resolved and @code{fx_subsy} set to @code{NULL} for @w{@code{! SEG_NORMAL (@var{seg}) || TC_FORCE_RELOCATION (@var{fix})}} will be used. -@item TC_FORCE_RELOCATION_SUB_ABS (@var{fix}) +@item TC_FORCE_RELOCATION_SUB_ABS (@var{fix}, @var{seg) @cindex TC_FORCE_RELOCATION_SUB_ABS Like @code{TC_FORCE_RELOCATION_SUB_SAME}, but used when the subtrahend is an absolute symbol. If the macro is undefined a default of @code{0} is used. -@item TC_FORCE_RELOCATION_SUB_LOCAL (@var{fix}) +@item TC_FORCE_RELOCATION_SUB_LOCAL (@var{fix}, @var{seg) @cindex TC_FORCE_RELOCATION_SUB_LOCAL Like @code{TC_FORCE_RELOCATION_SUB_ABS}, but the subtrahend is a symbol in the same section as the fixup. -@item TC_VALIDATE_FIX_SUB (@var{fix}) +@item TC_VALIDATE_FIX_SUB (@var{fix}, @var{seg}) @cindex TC_VALIDATE_FIX_SUB This macro is evaluated for any fixup with a @code{fx_subsy} that @code{fixup_segment} cannot reduce to a number. If the macro returns diff --git a/gas/write.c b/gas/write.c index f03fcf3..1af81a7 100644 --- a/gas/write.c +++ b/gas/write.c @@ -65,20 +65,23 @@ #ifndef TC_FORCE_RELOCATION_SUB_LOCAL #ifdef DIFF_EXPR_OK -#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX) 0 +#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) \ + (!md_register_arithmetic && (SEG) == reg_section) #else -#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX) 1 +#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) 1 #endif #endif #ifndef TC_VALIDATE_FIX_SUB #ifdef UNDEFINED_DIFFERENCE_OK /* The PA needs this for PIC code generation. */ -#define TC_VALIDATE_FIX_SUB(FIX) 1 +#define TC_VALIDATE_FIX_SUB(FIX, SEG) \ + (md_register_arithmetic || (SEG) != reg_section) #else -#define TC_VALIDATE_FIX_SUB(FIX) \ - ((FIX)->fx_r_type == BFD_RELOC_GPREL32 \ - || (FIX)->fx_r_type == BFD_RELOC_GPREL16) +#define TC_VALIDATE_FIX_SUB(FIX, SEG) \ + ((md_register_arithmetic || (SEG) != reg_section) \ + && ((FIX)->fx_r_type == BFD_RELOC_GPREL32 \ + || (FIX)->fx_r_type == BFD_RELOC_GPREL16)) #endif #endif @@ -936,7 +939,7 @@ fixup_segment (fixS *fixP, segT this_segment) fixP->fx_subsy = NULL; } else if (sub_symbol_segment == this_segment - && !TC_FORCE_RELOCATION_SUB_LOCAL (fixP)) + && !TC_FORCE_RELOCATION_SUB_LOCAL (fixP, add_symbol_segment)) { add_number -= S_GET_VALUE (fixP->fx_subsy); fixP->fx_offset = (add_number + fixP->fx_dot_value @@ -958,7 +961,7 @@ fixup_segment (fixS *fixP, segT this_segment) fixP->fx_subsy = NULL; fixP->fx_pcrel = 1; } - else if (!TC_VALIDATE_FIX_SUB (fixP)) + else if (!TC_VALIDATE_FIX_SUB (fixP, add_symbol_segment)) { if (!md_register_arithmetic && (add_symbol_segment == reg_section |