diff options
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 13 | ||||
-rw-r--r-- | gas/cgen.c | 3 | ||||
-rw-r--r-- | gas/config/tc-frv.c | 118 |
3 files changed, 130 insertions, 4 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 8b9aa3f..5cc7c42 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,16 @@ +2005-01-25 Alexandre Oliva <aoliva@redhat.com> + + * config/tc-frv.c (md_apply_fix3): Mark TLS symbols as such. + 2004-12-10 Alexandre Oliva <aoliva@redhat.com> + * config/tc-frv.c (frv_pic_ptr): Add tlsmoff support. + 2004-11-10 Alexandre Oliva <aoliva@redhat.com> + * cgen.c (gas_cgen_parse_operand): Handle + CGEN_PARSE_OPERAND_SYMBOLIC. + * config/tc-frv.c (md_cgen_lookup_reloc): Handle TLS relocations. + (frv_force_relocation): Likewise. Fix handling of PIC + relocations. + (md_apply_fix3): Likewise. + 2005-01-21 Ben Elliston <bje@au.ibm.com> * as.h: Remove #if 0'd code. @@ -372,6 +372,8 @@ gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP) *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR; break; case O_constant: + if (want == CGEN_PARSE_OPERAND_SYMBOLIC) + goto de_fault; *valueP = exp.X_add_number; *resultP = CGEN_PARSE_OPERAND_RESULT_NUMBER; break; @@ -379,6 +381,7 @@ gas_cgen_parse_operand (cd, want, strP, opindex, opinfo, resultP, valueP) *valueP = exp.X_add_number; *resultP = CGEN_PARSE_OPERAND_RESULT_REGISTER; break; + de_fault: default: queue_fixup (opindex, opinfo, &exp); *valueP = 0; diff --git a/gas/config/tc-frv.c b/gas/config/tc-frv.c index e85db95..c75018d 100644 --- a/gas/config/tc-frv.c +++ b/gas/config/tc-frv.c @@ -1380,12 +1380,18 @@ md_cgen_lookup_reloc (insn, operand, fixP) case FRV_OPERAND_LABEL24: fixP->fx_pcrel = TRUE; + + if (fixP->fx_cgen.opinfo != 0) + return fixP->fx_cgen.opinfo; + return BFD_RELOC_FRV_LABEL24; case FRV_OPERAND_UHI16: case FRV_OPERAND_ULO16: case FRV_OPERAND_SLO16: - + case FRV_OPERAND_CALLANN: + case FRV_OPERAND_LDANN: + case FRV_OPERAND_LDDANN: /* The relocation type should be recorded in opinfo */ if (fixP->fx_cgen.opinfo != 0) return fixP->fx_cgen.opinfo; @@ -1416,9 +1422,45 @@ int frv_force_relocation (fix) fixS * fix; { - if (fix->fx_r_type == BFD_RELOC_FRV_GPREL12 - || fix->fx_r_type == BFD_RELOC_FRV_GPRELU12) - return 1; + switch (fix->fx_r_type < BFD_RELOC_UNUSED + ? fix->fx_r_type + : fix->fx_cgen.opinfo) + { + case BFD_RELOC_FRV_GPREL12: + case BFD_RELOC_FRV_GPRELU12: + case BFD_RELOC_FRV_GPREL32: + case BFD_RELOC_FRV_GPRELHI: + case BFD_RELOC_FRV_GPRELLO: + case BFD_RELOC_FRV_GOT12: + case BFD_RELOC_FRV_GOTHI: + case BFD_RELOC_FRV_GOTLO: + case BFD_RELOC_FRV_FUNCDESC_VALUE: + case BFD_RELOC_FRV_FUNCDESC_GOTOFF12: + case BFD_RELOC_FRV_FUNCDESC_GOTOFFHI: + case BFD_RELOC_FRV_FUNCDESC_GOTOFFLO: + case BFD_RELOC_FRV_GOTOFF12: + case BFD_RELOC_FRV_GOTOFFHI: + case BFD_RELOC_FRV_GOTOFFLO: + case BFD_RELOC_FRV_GETTLSOFF: + case BFD_RELOC_FRV_TLSDESC_VALUE: + case BFD_RELOC_FRV_GOTTLSDESC12: + case BFD_RELOC_FRV_GOTTLSDESCHI: + case BFD_RELOC_FRV_GOTTLSDESCLO: + case BFD_RELOC_FRV_TLSMOFF12: + case BFD_RELOC_FRV_TLSMOFFHI: + case BFD_RELOC_FRV_TLSMOFFLO: + case BFD_RELOC_FRV_GOTTLSOFF12: + case BFD_RELOC_FRV_GOTTLSOFFHI: + case BFD_RELOC_FRV_GOTTLSOFFLO: + case BFD_RELOC_FRV_TLSOFF: + case BFD_RELOC_FRV_TLSDESC_RELAX: + case BFD_RELOC_FRV_GETTLSOFF_RELAX: + case BFD_RELOC_FRV_TLSOFF_RELAX: + return 1; + + default: + break; + } return generic_force_reloc (fix); } @@ -1440,6 +1482,64 @@ md_apply_fix3 (fixP, valP, seg) case BFD_RELOC_FRV_LO16: *valP &= 0xffff; break; + + /* We need relocations for these, even if their symbols reduce + to constants. */ + case BFD_RELOC_FRV_GPREL12: + case BFD_RELOC_FRV_GPRELU12: + case BFD_RELOC_FRV_GPREL32: + case BFD_RELOC_FRV_GPRELHI: + case BFD_RELOC_FRV_GPRELLO: + case BFD_RELOC_FRV_GOT12: + case BFD_RELOC_FRV_GOTHI: + case BFD_RELOC_FRV_GOTLO: + case BFD_RELOC_FRV_FUNCDESC_VALUE: + case BFD_RELOC_FRV_FUNCDESC_GOTOFF12: + case BFD_RELOC_FRV_FUNCDESC_GOTOFFHI: + case BFD_RELOC_FRV_FUNCDESC_GOTOFFLO: + case BFD_RELOC_FRV_GOTOFF12: + case BFD_RELOC_FRV_GOTOFFHI: + case BFD_RELOC_FRV_GOTOFFLO: + case BFD_RELOC_FRV_GETTLSOFF: + case BFD_RELOC_FRV_TLSDESC_VALUE: + case BFD_RELOC_FRV_GOTTLSDESC12: + case BFD_RELOC_FRV_GOTTLSDESCHI: + case BFD_RELOC_FRV_GOTTLSDESCLO: + case BFD_RELOC_FRV_TLSMOFF12: + case BFD_RELOC_FRV_TLSMOFFHI: + case BFD_RELOC_FRV_TLSMOFFLO: + case BFD_RELOC_FRV_GOTTLSOFF12: + case BFD_RELOC_FRV_GOTTLSOFFHI: + case BFD_RELOC_FRV_GOTTLSOFFLO: + case BFD_RELOC_FRV_TLSOFF: + case BFD_RELOC_FRV_TLSDESC_RELAX: + case BFD_RELOC_FRV_GETTLSOFF_RELAX: + case BFD_RELOC_FRV_TLSOFF_RELAX: + fixP->fx_addsy = expr_build_uconstant (0); + break; + } + else + switch (fixP->fx_cgen.opinfo) + { + case BFD_RELOC_FRV_GETTLSOFF: + case BFD_RELOC_FRV_TLSDESC_VALUE: + case BFD_RELOC_FRV_GOTTLSDESC12: + case BFD_RELOC_FRV_GOTTLSDESCHI: + case BFD_RELOC_FRV_GOTTLSDESCLO: + case BFD_RELOC_FRV_TLSMOFF12: + case BFD_RELOC_FRV_TLSMOFFHI: + case BFD_RELOC_FRV_TLSMOFFLO: + case BFD_RELOC_FRV_GOTTLSOFF12: + case BFD_RELOC_FRV_GOTTLSOFFHI: + case BFD_RELOC_FRV_GOTTLSOFFLO: + case BFD_RELOC_FRV_TLSOFF: + case BFD_RELOC_FRV_TLSDESC_RELAX: + case BFD_RELOC_FRV_GETTLSOFF_RELAX: + case BFD_RELOC_FRV_TLSOFF_RELAX: + /* Mark TLS symbols as such. */ + if (S_GET_SEGMENT (fixP->fx_addsy) != absolute_section) + S_SET_THREAD_LOCAL (fixP->fx_addsy); + break; } gas_cgen_md_apply_fix3 (fixP, valP, seg); @@ -1603,6 +1703,16 @@ frv_pic_ptr (nbytes) as_bad ("missing ')'"); reloc_type = BFD_RELOC_FRV_FUNCDESC; } + else if (strncasecmp (input_line_pointer, "tlsmoff(", 8) == 0) + { + input_line_pointer += 8; + expression (&exp); + if (*input_line_pointer == ')') + input_line_pointer++; + else + as_bad ("missing ')'"); + reloc_type = BFD_RELOC_FRV_TLSMOFF; + } else expression (&exp); |