From: Alan Modra Date: Tue, 8 Apr 2014 05:08:22 +0000 (+0930) Subject: gas TC_PARSE_CONS_EXPRESSION communication with TC_CONS_FIX_NEW X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=62ebcb5cbedf0fdc0b5faaa05e46aa43ced2aa68;p=binutils-gdb.git gas TC_PARSE_CONS_EXPRESSION communication with TC_CONS_FIX_NEW A number of targets pass extra information from TC_PARSE_CONS_EXPRESSION to TC_CONS_FIX_NEW via static variables. That's OK, but not best practice. tc-ppc.c goes further in implementing its own replacement for cons(), because the generic one doesn't allow relocation modifiers on constants. This patch fixes both of these warts. * gas/config/tc-alpha.h (TC_CONS_FIX_NEW): Add RELOC parameter. * gas/config/tc-arc.c (arc_cons_fix_new): Add reloc parameter. * gas/config/tc-arc.h (arc_cons_fix_new): Update prototype. (TC_CONS_FIX_NEW): Add RELOC parameter. * gas/config/tc-arm.c (cons_fix_new_arm): Similarly * gas/config/tc-arm.h (cons_fix_new_arm, TC_CONS_FIX_NEW): Similarly. * gas/config/tc-cr16.c (cr16_cons_fix_new): Similarly. * gas/config/tc-cr16.h (cr16_cons_fix_new, TC_CONS_FIX_NEW): Similarly. * gas/config/tc-crx.h (TC_CONS_FIX_NEW): Similarly. * gas/config/tc-m32c.c (m32c_cons_fix_new): Similarly. * gas/config/tc-m32c.h (m32c_cons_fix_new, TC_CONS_FIX_NEW): Similarly. * gas/config/tc-mn10300.c (mn10300_cons_fix_new): Similarly. * gas/config/tc-mn10300.h (mn10300_cons_fix_new, TC_CONS_FIX_NEW): Similarly. * gas/config/tc-ns32k.c (cons_fix_new_ns32k): Similarly. * gas/config/tc-ns32k.h (cons_fix_new_ns32k): Similarly. * gas/config/tc-pj.c (pj_cons_fix_new_pj): Similarly. * gas/config/tc-pj.h (pj_cons_fix_new_pj, TC_CONS_FIX_NEW): Similarly. * gas/config/tc-rx.c (rx_cons_fix_new): Similarly. * gas/config/tc-rx.h (rx_cons_fix_new, TC_CONS_FIX_NEW): Similarly. * gas/config/tc-sh.c (sh_cons_fix_new): Similarly. * gas/config/tc-sh.h (sh_cons_fix_new, TC_CONS_FIX_NEW): Similarly. * gas/config/tc-tic54x.c (tic54x_cons_fix_new): Similarly. * gas/config/tc-tic54x.h (tic54x_cons_fix_new, TC_CONS_FIX_NEW): Similarly. * gas/config/tc-tic6x.c (tic6x_cons_fix_new): Similarly. * gas/config/tc-tic6x.h (tic6x_cons_fix_new, TC_CONS_FIX_NEW): Similarly. * gas/config/tc-arc.c (arc_parse_cons_expression): Return reloc. * gas/config/tc-arc.h (arc_parse_cons_expression): Update proto. * gas/config/tc-avr.c (exp_mod_data): Make global. (pexp_mod_data): Delete. (avr_parse_cons_expression): Return exp_mod_data pointer. (avr_cons_fix_new): Add exp_mod_data_t pointer param. (exp_mod_data_t): Move typedef.. * gas/config/tc-avr.h: ..to here. (exp_mod_data): Declare. (TC_PARSE_CONS_RETURN_TYPE, TC_PARSE_CONS_RETURN_NONE): Define. (avr_parse_cons_expression, avr_cons_fix_new): Update prototype. (TC_CONS_FIX_NEW): Update. * gas/config/tc-hppa.c (hppa_field_selector): Delete static var. (cons_fix_new_hppa): Add hppa_field_selector param. (fix_new_hppa): Adjust. (parse_cons_expression_hppa): Return field selector. * gas/config/tc-hppa.h (parse_cons_expression_hppa): Update proto. (cons_fix_new_hppa): Likewise. (TC_PARSE_CONS_RETURN_TYPE, TC_PARSE_CONS_RETURN_NONE): Define. * gas/config/tc-i386.c (got_reloc): Delete static var. (x86_cons_fix_new): Add reloc param. (x86_cons): Return got reloc. * gas/config/tc-i386.h (x86_cons, x86_cons_fix_new): Update proto. (TC_CONS_FIX_NEW): Add RELOC param. * gas/config/tc-ia64.c (ia64_cons_fix_new): Add reloc param. Adjust calls. * gas/config/tc-ia64.h (ia64_cons_fix_new): Update prototype. (TC_CONS_FIX_NEW): Add reloc param. * gas/config/tc-microblaze.c (parse_cons_expression_microblaze): Return reloc. (cons_fix_new_microblaze): Add reloc param. * gas/config/tc-microblaze.h: Formatting. (parse_cons_expression_microblaze): Update proto. (cons_fix_new_microblaze): Likewise. * gas/config/tc-nios2.c (nios2_tls_ldo_reloc): Delete static var. (nios2_cons): Return ldo reloc. (nios2_cons_fix_new): Delete. * gas/config/tc-nios2.h (nios2_cons): Update prototype. (nios2_cons_fix_new, TC_CONS_FIX_NEW): Delete. * gas/config/tc-ppc.c (md_pseudo_table): Remove quad, long, word, short. Make llong use cons. (ppc_elf_suffix): Return BFD_RELOC_NONE rather than BFD_RELOC_UNUSED. (ppc_elf_cons): Delete. (ppc_elf_parse_cons): New function. (ppc_elf_validate_fix): Don't check for BFD_RELOC_UNUSED. (md_assemble): Use BFD_RELOC_NONE rather than BFD_RELOC_UNUSED. * gas/config/tc-ppc.h (TC_PARSE_CONS_EXPRESSION): Define (ppc_elf_parse_cons): Declare. * gas/config/tc-sparc.c (sparc_cons_special_reloc): Delete static var. (sparc_cons): Return reloc specifier. (cons_fix_new_sparc): Add reloc specifier param. (sparc_cfi_emit_pcrel_expr): Use emit_expr_with_reloc. * gas/config/tc-sparc.h (TC_PARSE_CONS_RETURN_TYPE): Define. (TC_PARSE_CONS_RETURN_NONE): Define. (sparc_cons, cons_fix_new_sparc): Update prototype. * gas/config/tc-v850.c (hold_cons_reloc): Delete static var. (v850_reloc_prefix): Use BFD_RELOC_NONE rather than BFD_RELOC_UNUSED. (md_assemble): Likewise. (parse_cons_expression_v850): Return reloc. (cons_fix_new_v850): Add reloc parameter. * gas/config/tc-v850.h (parse_cons_expression_v850): Update proto. (cons_fix_new_v850): Likewise. * gas/config/tc-vax.c (vax_cons_special_reloc): Delete static var. (vax_cons): Return reloc. (vax_cons_fix_new): Add reloc parameter. * gas/config/tc-vax.h (vax_cons, vax_cons_fix_new): Update proto. * gas/config/tc-xstormy16.c (xstormy16_cons_fix_new): Add reloc param. * gas/config/tc-xstormy16.h (xstormy16_cons_fix_new): Update proto. * gas/dwarf2dbg.c (TC_PARSE_CONS_RETURN_NONE): Provide default. (emit_fixed_inc_line_addr): Adjust exmit_expr_fix calls. * gas/read.c (TC_PARSE_CONS_EXPRESSION): Return value. (do_parse_cons_expression): Adjust. (cons_worker): Pass return value from TC_PARSE_CONS_EXPRESSION to emit_expr_with_reloc. (emit_expr_with_reloc): New function handling reloc, mostly extracted from.. (emit_expr): ..here. (emit_expr_fix): Add reloc param. Adjust TC_CONS_FIX_NEW invocation. Handle reloc. (parse_mri_cons): Convert to ISO. * gas/read.h (TC_PARSE_CONS_RETURN_TYPE): Define. (TC_PARSE_CONS_RETURN_NONE): Define. (emit_expr_with_reloc): Declare. (emit_expr_fix): Update prototype. * gas/write.c (write_object_file): Update TC_CONS_FIX_NEW invocation. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index 8ccea2e0493..36242a88aff 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,119 @@ +2014-04-09 Alan Modra + + * gas/config/tc-alpha.h (TC_CONS_FIX_NEW): Add RELOC parameter. + * gas/config/tc-arc.c (arc_cons_fix_new): Add reloc parameter. + * gas/config/tc-arc.h (arc_cons_fix_new): Update prototype. + (TC_CONS_FIX_NEW): Add RELOC parameter. + * gas/config/tc-arm.c (cons_fix_new_arm): Similarly + * gas/config/tc-arm.h (cons_fix_new_arm, TC_CONS_FIX_NEW): Similarly. + * gas/config/tc-cr16.c (cr16_cons_fix_new): Similarly. + * gas/config/tc-cr16.h (cr16_cons_fix_new, TC_CONS_FIX_NEW): Similarly. + * gas/config/tc-crx.h (TC_CONS_FIX_NEW): Similarly. + * gas/config/tc-m32c.c (m32c_cons_fix_new): Similarly. + * gas/config/tc-m32c.h (m32c_cons_fix_new, TC_CONS_FIX_NEW): Similarly. + * gas/config/tc-mn10300.c (mn10300_cons_fix_new): Similarly. + * gas/config/tc-mn10300.h (mn10300_cons_fix_new, TC_CONS_FIX_NEW): + Similarly. + * gas/config/tc-ns32k.c (cons_fix_new_ns32k): Similarly. + * gas/config/tc-ns32k.h (cons_fix_new_ns32k): Similarly. + * gas/config/tc-pj.c (pj_cons_fix_new_pj): Similarly. + * gas/config/tc-pj.h (pj_cons_fix_new_pj, TC_CONS_FIX_NEW): Similarly. + * gas/config/tc-rx.c (rx_cons_fix_new): Similarly. + * gas/config/tc-rx.h (rx_cons_fix_new, TC_CONS_FIX_NEW): Similarly. + * gas/config/tc-sh.c (sh_cons_fix_new): Similarly. + * gas/config/tc-sh.h (sh_cons_fix_new, TC_CONS_FIX_NEW): Similarly. + * gas/config/tc-tic54x.c (tic54x_cons_fix_new): Similarly. + * gas/config/tc-tic54x.h (tic54x_cons_fix_new, TC_CONS_FIX_NEW): + Similarly. + * gas/config/tc-tic6x.c (tic6x_cons_fix_new): Similarly. + * gas/config/tc-tic6x.h (tic6x_cons_fix_new, TC_CONS_FIX_NEW): + Similarly. + * gas/config/tc-arc.c (arc_parse_cons_expression): Return reloc. + * gas/config/tc-arc.h (arc_parse_cons_expression): Update proto. + * gas/config/tc-avr.c (exp_mod_data): Make global. + (pexp_mod_data): Delete. + (avr_parse_cons_expression): Return exp_mod_data pointer. + (avr_cons_fix_new): Add exp_mod_data_t pointer param. + (exp_mod_data_t): Move typedef.. + * gas/config/tc-avr.h: ..to here. + (exp_mod_data): Declare. + (TC_PARSE_CONS_RETURN_TYPE, TC_PARSE_CONS_RETURN_NONE): Define. + (avr_parse_cons_expression, avr_cons_fix_new): Update prototype. + (TC_CONS_FIX_NEW): Update. + * gas/config/tc-hppa.c (hppa_field_selector): Delete static var. + (cons_fix_new_hppa): Add hppa_field_selector param. + (fix_new_hppa): Adjust. + (parse_cons_expression_hppa): Return field selector. + * gas/config/tc-hppa.h (parse_cons_expression_hppa): Update proto. + (cons_fix_new_hppa): Likewise. + (TC_PARSE_CONS_RETURN_TYPE, TC_PARSE_CONS_RETURN_NONE): Define. + * gas/config/tc-i386.c (got_reloc): Delete static var. + (x86_cons_fix_new): Add reloc param. + (x86_cons): Return got reloc. + * gas/config/tc-i386.h (x86_cons, x86_cons_fix_new): Update proto. + (TC_CONS_FIX_NEW): Add RELOC param. + * gas/config/tc-ia64.c (ia64_cons_fix_new): Add reloc param. Adjust + calls. + * gas/config/tc-ia64.h (ia64_cons_fix_new): Update prototype. + (TC_CONS_FIX_NEW): Add reloc param. + * gas/config/tc-microblaze.c (parse_cons_expression_microblaze): + Return reloc. + (cons_fix_new_microblaze): Add reloc param. + * gas/config/tc-microblaze.h: Formatting. + (parse_cons_expression_microblaze): Update proto. + (cons_fix_new_microblaze): Likewise. + * gas/config/tc-nios2.c (nios2_tls_ldo_reloc): Delete static var. + (nios2_cons): Return ldo reloc. + (nios2_cons_fix_new): Delete. + * gas/config/tc-nios2.h (nios2_cons): Update prototype. + (nios2_cons_fix_new, TC_CONS_FIX_NEW): Delete. + * gas/config/tc-ppc.c (md_pseudo_table): Remove quad, long, word, + short. Make llong use cons. + (ppc_elf_suffix): Return BFD_RELOC_NONE rather than BFD_RELOC_UNUSED. + (ppc_elf_cons): Delete. + (ppc_elf_parse_cons): New function. + (ppc_elf_validate_fix): Don't check for BFD_RELOC_UNUSED. + (md_assemble): Use BFD_RELOC_NONE rather than BFD_RELOC_UNUSED. + * gas/config/tc-ppc.h (TC_PARSE_CONS_EXPRESSION): Define + (ppc_elf_parse_cons): Declare. + * gas/config/tc-sparc.c (sparc_cons_special_reloc): Delete static var. + (sparc_cons): Return reloc specifier. + (cons_fix_new_sparc): Add reloc specifier param. + (sparc_cfi_emit_pcrel_expr): Use emit_expr_with_reloc. + * gas/config/tc-sparc.h (TC_PARSE_CONS_RETURN_TYPE): Define. + (TC_PARSE_CONS_RETURN_NONE): Define. + (sparc_cons, cons_fix_new_sparc): Update prototype. + * gas/config/tc-v850.c (hold_cons_reloc): Delete static var. + (v850_reloc_prefix): Use BFD_RELOC_NONE rather than BFD_RELOC_UNUSED. + (md_assemble): Likewise. + (parse_cons_expression_v850): Return reloc. + (cons_fix_new_v850): Add reloc parameter. + * gas/config/tc-v850.h (parse_cons_expression_v850): Update proto. + (cons_fix_new_v850): Likewise. + * gas/config/tc-vax.c (vax_cons_special_reloc): Delete static var. + (vax_cons): Return reloc. + (vax_cons_fix_new): Add reloc parameter. + * gas/config/tc-vax.h (vax_cons, vax_cons_fix_new): Update proto. + * gas/config/tc-xstormy16.c (xstormy16_cons_fix_new): Add reloc param. + * gas/config/tc-xstormy16.h (xstormy16_cons_fix_new): Update proto. + * gas/dwarf2dbg.c (TC_PARSE_CONS_RETURN_NONE): Provide default. + (emit_fixed_inc_line_addr): Adjust exmit_expr_fix calls. + * gas/read.c (TC_PARSE_CONS_EXPRESSION): Return value. + (do_parse_cons_expression): Adjust. + (cons_worker): Pass return value from TC_PARSE_CONS_EXPRESSION + to emit_expr_with_reloc. + (emit_expr_with_reloc): New function handling reloc, mostly + extracted from.. + (emit_expr): ..here. + (emit_expr_fix): Add reloc param. Adjust TC_CONS_FIX_NEW invocation. + Handle reloc. + (parse_mri_cons): Convert to ISO. + * gas/read.h (TC_PARSE_CONS_RETURN_TYPE): Define. + (TC_PARSE_CONS_RETURN_NONE): Define. + (emit_expr_with_reloc): Declare. + (emit_expr_fix): Update prototype. + * gas/write.c (write_object_file): Update TC_CONS_FIX_NEW invocation. + 2014-04-03 Ilya Tocar * config/tc-i386.c (cpu_arch): Add .se1. diff --git a/gas/config/tc-alpha.h b/gas/config/tc-alpha.h index 443eff4c345..98f81f591ec 100644 --- a/gas/config/tc-alpha.h +++ b/gas/config/tc-alpha.h @@ -71,7 +71,8 @@ extern valueT alpha_gp_value; #define tc_canonicalize_symbol_name evax_shorten_name -#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) \ +#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP,RELOC) \ + (void) RELOC, \ fix_new_exp (FRAG, OFF, (int)LEN, EXP, 0, \ LEN == 2 ? BFD_RELOC_16 \ : LEN == 4 ? BFD_RELOC_32 \ diff --git a/gas/config/tc-arc.c b/gas/config/tc-arc.c index e8de1bb5ce6..5499d88e340 100644 --- a/gas/config/tc-arc.c +++ b/gas/config/tc-arc.c @@ -1160,7 +1160,7 @@ md_undefined_symbol (char *name ATTRIBUTE_UNUSED) Values for the status register are specified with %st(label). `label' will be right shifted by 2. */ -void +bfd_reloc_code_real_type arc_parse_cons_expression (expressionS *exp, unsigned int nbytes ATTRIBUTE_UNUSED) { @@ -1179,6 +1179,7 @@ arc_parse_cons_expression (expressionS *exp, arc_code_symbol (exp); input_line_pointer = p; } + return BFD_RELOC_NONE; } /* Record a fixup for a cons expression. */ @@ -1187,7 +1188,8 @@ void arc_cons_fix_new (fragS *frag, int where, int nbytes, - expressionS *exp) + expressionS *exp, + bfd_reloc_code_real_type r ATTRIBUTE_UNUSED) { if (nbytes == 4) { diff --git a/gas/config/tc-arc.h b/gas/config/tc-arc.h index 63cf826d36a..a2789e683fd 100644 --- a/gas/config/tc-arc.h +++ b/gas/config/tc-arc.h @@ -54,13 +54,15 @@ extern const char * arc_target_format; /* The ARC needs to parse reloc specifiers in .word. */ -extern void arc_parse_cons_expression (struct expressionS *, unsigned); +extern bfd_reloc_code_real_type arc_parse_cons_expression (struct expressionS *, + unsigned); #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \ arc_parse_cons_expression (EXP, NBYTES) -extern void arc_cons_fix_new (struct frag *, int, int, struct expressionS *); -#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \ - arc_cons_fix_new (FRAG, WHERE, NBYTES, EXP) +extern void arc_cons_fix_new (struct frag *, int, int, struct expressionS *, + bfd_reloc_code_real_type); +#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP, RELOC) \ + arc_cons_fix_new (FRAG, WHERE, NBYTES, EXP, RELOC) #define DWARF2_LINE_MIN_INSN_LENGTH 4 diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 1795d3765a9..9ccacbc32f1 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -23159,9 +23159,9 @@ void cons_fix_new_arm (fragS * frag, int where, int size, - expressionS * exp) + expressionS * exp, + bfd_reloc_code_real_type reloc) { - bfd_reloc_code_real_type type; int pcrel = 0; /* Pick a reloc. @@ -23169,17 +23169,17 @@ cons_fix_new_arm (fragS * frag, switch (size) { case 1: - type = BFD_RELOC_8; + reloc = BFD_RELOC_8; break; case 2: - type = BFD_RELOC_16; + reloc = BFD_RELOC_16; break; case 4: default: - type = BFD_RELOC_32; + reloc = BFD_RELOC_32; break; case 8: - type = BFD_RELOC_64; + reloc = BFD_RELOC_64; break; } @@ -23187,11 +23187,11 @@ cons_fix_new_arm (fragS * frag, if (exp->X_op == O_secrel) { exp->X_op = O_symbol; - type = BFD_RELOC_32_SECREL; + reloc = BFD_RELOC_32_SECREL; } #endif - fix_new_exp (frag, where, (int) size, exp, pcrel, type); + fix_new_exp (frag, where, size, exp, pcrel, reloc); } #if defined (OBJ_COFF) diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h index f88fa297611..a7a0cd0d6ec 100644 --- a/gas/config/tc-arm.h +++ b/gas/config/tc-arm.h @@ -348,7 +348,8 @@ extern int arm_data_in_code (void); extern char * arm_canonicalize_symbol_name (char *); extern void arm_adjust_symtab (void); extern void armelf_frob_symbol (symbolS *, int *); -extern void cons_fix_new_arm (fragS *, int, int, expressionS *); +extern void cons_fix_new_arm (fragS *, int, int, expressionS *, + bfd_reloc_code_real_type); extern void arm_init_frag (struct frag *, int); extern void arm_handle_align (struct frag *); extern bfd_boolean arm_fix_adjustable (struct fix *); diff --git a/gas/config/tc-avr.c b/gas/config/tc-avr.c index 5049d11b9d5..ce9708ee904 100644 --- a/gas/config/tc-avr.c +++ b/gas/config/tc-avr.c @@ -1521,22 +1521,7 @@ md_assemble (char *str) } } -typedef struct -{ - /* Name of the expression modifier allowed with .byte, .word, etc. */ - const char *name; - - /* Only allowed with n bytes of data. */ - int nbytes; - - /* Associated RELOC. */ - bfd_reloc_code_real_type reloc; - - /* Part of the error message. */ - const char *error; -} exp_mod_data_t; - -static const exp_mod_data_t exp_mod_data[] = +const exp_mod_data_t exp_mod_data[] = { /* Default, must be first. */ { "", 0, BFD_RELOC_16, "" }, @@ -1557,21 +1542,16 @@ static const exp_mod_data_t exp_mod_data[] = { NULL, 0, 0, NULL } }; -/* Data to pass between `avr_parse_cons_expression' and `avr_cons_fix_new'. */ -static const exp_mod_data_t *pexp_mod_data = &exp_mod_data[0]; - /* Parse special CONS expression: pm (expression) or alternatively gs (expression). These are used for addressing program memory. Moreover, define lo8 (expression), hi8 (expression) and hlo8 (expression). */ -void +const exp_mod_data_t * avr_parse_cons_expression (expressionS *exp, int nbytes) { const exp_mod_data_t *pexp = &exp_mod_data[0]; char *tmp; - pexp_mod_data = pexp; - tmp = input_line_pointer = skip_space (input_line_pointer); /* The first entry of exp_mod_data[] contains an entry if no @@ -1589,18 +1569,18 @@ avr_parse_cons_expression (expressionS *exp, int nbytes) if (*input_line_pointer == '(') { input_line_pointer = skip_space (input_line_pointer + 1); - pexp_mod_data = pexp; expression (exp); if (*input_line_pointer == ')') - ++input_line_pointer; + { + ++input_line_pointer; + return pexp; + } else { as_bad (_("`)' required")); - pexp_mod_data = &exp_mod_data[0]; + return &exp_mod_data[0]; } - - return; } input_line_pointer = tmp; @@ -1610,13 +1590,15 @@ avr_parse_cons_expression (expressionS *exp, int nbytes) } expression (exp); + return &exp_mod_data[0]; } void avr_cons_fix_new (fragS *frag, int where, int nbytes, - expressionS *exp) + expressionS *exp, + const exp_mod_data_t *pexp_mod_data) { int bad = 0; @@ -1646,8 +1628,6 @@ avr_cons_fix_new (fragS *frag, if (bad) as_bad (_("illegal %srelocation size: %d"), pexp_mod_data->error, nbytes); - - pexp_mod_data = &exp_mod_data[0]; } static bfd_boolean diff --git a/gas/config/tc-avr.h b/gas/config/tc-avr.h index caa058fdec0..df75ac721c9 100644 --- a/gas/config/tc-avr.h +++ b/gas/config/tc-avr.h @@ -50,16 +50,36 @@ will point to the start of the expression. */ #define md_operand(x) +typedef struct +{ + /* Name of the expression modifier allowed with .byte, .word, etc. */ + const char *name; + + /* Only allowed with n bytes of data. */ + int nbytes; + + /* Associated RELOC. */ + bfd_reloc_code_real_type reloc; + + /* Part of the error message. */ + const char *error; +} exp_mod_data_t; + +extern const exp_mod_data_t exp_mod_data[]; +#define TC_PARSE_CONS_RETURN_TYPE const exp_mod_data_t * +#define TC_PARSE_CONS_RETURN_NONE exp_mod_data + /* You may define this macro to parse an expression used in a data allocation pseudo-op such as `.word'. You can use this to recognize relocation directives that may appear in such directives. */ #define TC_PARSE_CONS_EXPRESSION(EXPR,N) avr_parse_cons_expression (EXPR, N) -extern void avr_parse_cons_expression (expressionS *, int); +extern const exp_mod_data_t *avr_parse_cons_expression (expressionS *, int); /* You may define this macro to generate a fixup for a data allocation pseudo-op. */ -#define TC_CONS_FIX_NEW(FRAG,WHERE,N,EXP) avr_cons_fix_new (FRAG, WHERE, N, EXP) -extern void avr_cons_fix_new (fragS *,int, int, expressionS *); +#define TC_CONS_FIX_NEW avr_cons_fix_new +extern void avr_cons_fix_new (fragS *,int, int, expressionS *, + const exp_mod_data_t *); /* This should just call either `number_to_chars_bigendian' or `number_to_chars_littleendian', whichever is appropriate. On diff --git a/gas/config/tc-cr16.c b/gas/config/tc-cr16.c index 4aed8a7cfed..bcdf9781c09 100644 --- a/gas/config/tc-cr16.c +++ b/gas/config/tc-cr16.c @@ -492,10 +492,9 @@ cr16_force_relocation (fixS *fix) /* Record a fixup for a cons expression. */ void -cr16_cons_fix_new (fragS *frag, int offset, int len, expressionS *exp) +cr16_cons_fix_new (fragS *frag, int offset, int len, expressionS *exp, + bfd_reloc_code_real_type rtype) { - int rtype = BFD_RELOC_UNUSED; - switch (len) { default: rtype = BFD_RELOC_NONE; break; diff --git a/gas/config/tc-cr16.h b/gas/config/tc-cr16.h index 68671918591..9da8cb78c2d 100644 --- a/gas/config/tc-cr16.h +++ b/gas/config/tc-cr16.h @@ -57,12 +57,13 @@ extern int cr16_force_relocation (struct fix *); of two bytes long. */ #define DWARF2_LINE_MIN_INSN_LENGTH 2 -extern void cr16_cons_fix_new (struct frag *, int, int, struct expressionS *); +extern void cr16_cons_fix_new (struct frag *, int, int, struct expressionS *, + bfd_reloc_code_real_type); /* This is called by emit_expr when creating a reloc for a cons. We could use the definition there, except that we want to handle the CR16 reloc type specially, rather than the BFD_RELOC type. */ -#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP) \ - cr16_cons_fix_new (FRAG, OFF, LEN, EXP) +#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC) \ + cr16_cons_fix_new (FRAG, OFF, LEN, EXP, RELOC) /* Give an error if a frag containing code is not aligned to a 2-byte boundary. */ diff --git a/gas/config/tc-crx.h b/gas/config/tc-crx.h index 1777ab0611b..da6d710215c 100644 --- a/gas/config/tc-crx.h +++ b/gas/config/tc-crx.h @@ -60,7 +60,8 @@ extern int crx_force_relocation (struct fix *); /* This is called by emit_expr when creating a reloc for a cons. We could use the definition there, except that we want to handle the CRX reloc type specially, rather than the BFD_RELOC type. */ -#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP) \ +#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC) \ + (void) RELOC, \ fix_new_exp (FRAG, OFF, (int) LEN, EXP, 0, \ LEN == 1 ? BFD_RELOC_CRX_NUM8 \ : LEN == 2 ? BFD_RELOC_CRX_NUM16 \ diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c index cc5ea9afe07..5ee7f72644d 100644 --- a/gas/config/tc-hppa.c +++ b/gas/config/tc-hppa.c @@ -606,9 +606,6 @@ static int within_procedure; seen in each subspace. */ static label_symbol_struct *label_symbols_rootp = NULL; -/* Holds the last field selector. */ -static int hppa_field_selector; - /* Nonzero when strict matching is enabled. Zero otherwise. Each opcode in the table has a flag which indicates whether or @@ -1263,7 +1260,8 @@ fix_new_hppa (fragS *frag, hppa_field_selector is set by the parse_cons_expression_hppa. */ void -cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp) +cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp, + int hppa_field_selector) { unsigned int rel_type; @@ -1300,9 +1298,6 @@ cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp) fix_new_hppa (frag, where, size, (symbolS *) NULL, (offsetT) 0, exp, 0, rel_type, hppa_field_selector, size * 8, 0, 0); - - /* Reset field selector to its default state. */ - hppa_field_selector = 0; } /* Mark (via expr_end) the end of an expression (I think). FIXME. */ @@ -2517,11 +2512,12 @@ pa_chk_field_selector (char **str) /* Parse a .byte, .word, .long expression for the HPPA. Called by cons via the TC_PARSE_CONS_EXPRESSION macro. */ -void +int parse_cons_expression_hppa (expressionS *exp) { - hppa_field_selector = pa_chk_field_selector (&input_line_pointer); + int hppa_field_selector = pa_chk_field_selector (&input_line_pointer); expression (exp); + return hppa_field_selector; } /* Evaluate an absolute expression EXP which may be modified by diff --git a/gas/config/tc-hppa.h b/gas/config/tc-hppa.h index a31ebf8a50e..4277e10d7dc 100644 --- a/gas/config/tc-hppa.h +++ b/gas/config/tc-hppa.h @@ -90,8 +90,8 @@ /* pa_define_label gets used outside of tc-hppa.c via tc_frob_label. */ extern void pa_define_label (symbolS *); -extern void parse_cons_expression_hppa (expressionS *); -extern void cons_fix_new_hppa (fragS *, int, int, expressionS *); +extern int parse_cons_expression_hppa (expressionS *); +extern void cons_fix_new_hppa (fragS *, int, int, expressionS *, int); extern int hppa_force_relocation (struct fix *); /* This gets called before writing the object file to make sure @@ -112,6 +112,8 @@ extern const char hppa_symbol_chars[]; #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \ parse_cons_expression_hppa (EXP) #define TC_CONS_FIX_NEW cons_fix_new_hppa +#define TC_PARSE_CONS_RETURN_TYPE int +#define TC_PARSE_CONS_RETURN_NONE e_fsel /* On the PA, an exclamation point can appear in an instruction. It is used in FP comparison instructions and as an end of line marker. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 38857ccba7d..cb62cf5409b 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -7334,16 +7334,13 @@ output_imm (fragS *insn_start_frag, offsetT insn_start_off) /* x86_cons_fix_new is called via the expression parsing code when a reloc is needed. We use this hook to get the correct .got reloc. */ -static enum bfd_reloc_code_real got_reloc = NO_RELOC; static int cons_sign = -1; void x86_cons_fix_new (fragS *frag, unsigned int off, unsigned int len, - expressionS *exp) + expressionS *exp, bfd_reloc_code_real_type r) { - enum bfd_reloc_code_real r = reloc (len, 0, cons_sign, 0, got_reloc); - - got_reloc = NO_RELOC; + r = reloc (len, 0, cons_sign, 0, r); #ifdef TE_PE if (exp->X_op == O_secrel) @@ -7639,9 +7636,11 @@ lex_got (enum bfd_reloc_code_real *rel ATTRIBUTE_UNUSED, #endif /* TE_PE */ -void +bfd_reloc_code_real_type x86_cons (expressionS *exp, int size) { + bfd_reloc_code_real_type got_reloc = NO_RELOC; + intel_syntax = -intel_syntax; exp->X_md = 0; @@ -7688,6 +7687,8 @@ x86_cons (expressionS *exp, int size) if (intel_syntax) i386_intel_simplify (exp); + + return got_reloc; } static void diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h index 17be2685ca2..8b5c7d7c1ed 100644 --- a/gas/config/tc-i386.h +++ b/gas/config/tc-i386.h @@ -132,11 +132,12 @@ extern const char *i386_comment_chars; #if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) && !defined (LEX_AT) #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) x86_cons (EXP, NBYTES) #endif -extern void x86_cons (expressionS *, int); +extern bfd_reloc_code_real_type x86_cons (expressionS *, int); -#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) x86_cons_fix_new(FRAG, OFF, LEN, EXP) +#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC) \ + x86_cons_fix_new(FRAG, OFF, LEN, EXP, RELOC) extern void x86_cons_fix_new - (fragS *, unsigned int, unsigned int, expressionS *); +(fragS *, unsigned int, unsigned int, expressionS *, bfd_reloc_code_real_type); #define TC_ADDRESS_BYTES x86_address_bytes extern int x86_address_bytes (void); diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c index e6da5355554..38b6b67306b 100644 --- a/gas/config/tc-ia64.c +++ b/gas/config/tc-ia64.c @@ -4466,14 +4466,15 @@ dot_endp (int dummy ATTRIBUTE_UNUSED) symbol_get_frag (unwind.proc_pending.sym)); else e.X_add_symbol = unwind.proc_pending.sym; - ia64_cons_fix_new (frag_now, where, bytes_per_address, &e); + ia64_cons_fix_new (frag_now, where, bytes_per_address, &e, + BFD_RELOC_NONE); e.X_op = O_pseudo_fixup; e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym; e.X_add_number = 0; e.X_add_symbol = proc_end; ia64_cons_fix_new (frag_now, where + bytes_per_address, - bytes_per_address, &e); + bytes_per_address, &e, BFD_RELOC_NONE); if (unwind.info) { @@ -4482,7 +4483,7 @@ dot_endp (int dummy ATTRIBUTE_UNUSED) e.X_add_number = 0; e.X_add_symbol = unwind.info; ia64_cons_fix_new (frag_now, where + (bytes_per_address * 2), - bytes_per_address, &e); + bytes_per_address, &e, BFD_RELOC_NONE); } } subseg_set (saved_seg, saved_subseg); @@ -11056,9 +11057,9 @@ ia64_dwarf2_emit_offset (symbolS *symbol, unsigned int size) fixup. We pick the right reloc code depending on the byteorder currently in effect. */ void -ia64_cons_fix_new (fragS *f, int where, int nbytes, expressionS *exp) +ia64_cons_fix_new (fragS *f, int where, int nbytes, expressionS *exp, + bfd_reloc_code_real_type code) { - bfd_reloc_code_real_type code; fixS *fix; switch (nbytes) diff --git a/gas/config/tc-ia64.h b/gas/config/tc-ia64.h index c6cc29f5513..6884c59ed71 100644 --- a/gas/config/tc-ia64.h +++ b/gas/config/tc-ia64.h @@ -106,7 +106,8 @@ extern void ia64_cons_align (int); extern void ia64_flush_insns (void); extern int ia64_fix_adjustable (struct fix *); extern int ia64_force_relocation (struct fix *); -extern void ia64_cons_fix_new (fragS *, int, int, expressionS *); +extern void ia64_cons_fix_new (fragS *, int, int, expressionS *, + bfd_reloc_code_real_type); extern void ia64_validate_fix (struct fix *); extern char * ia64_canonicalize_symbol_name (char *); extern bfd_vma ia64_elf_section_letter (int, char **); @@ -148,7 +149,7 @@ extern void ia64_convert_frag (fragS *); #define md_elf_section_flags ia64_elf_section_flags #define TC_FIX_TYPE struct ia64_fix #define TC_INIT_FIX_DATA(f) { f->tc_fix_data.opnd = 0; } -#define TC_CONS_FIX_NEW(f,o,l,e) ia64_cons_fix_new (f, o, l, e) +#define TC_CONS_FIX_NEW(f,o,l,e,r) ia64_cons_fix_new (f, o, l, e, r) #define TC_VALIDATE_FIX(fix,seg,skip) ia64_validate_fix (fix) #define MD_PCREL_FROM_SECTION(fix,sec) ia64_pcrel_from_section (fix, sec) #define md_section_align(seg,size) (size) diff --git a/gas/config/tc-m32c.c b/gas/config/tc-m32c.c index 664b167d3dd..8e24edbf089 100644 --- a/gas/config/tc-m32c.c +++ b/gas/config/tc-m32c.c @@ -1019,10 +1019,9 @@ void m32c_cons_fix_new (fragS * frag, int where, int size, - expressionS *exp) + expressionS *exp, + bfd_reloc_code_real_type type) { - bfd_reloc_code_real_type type; - switch (size) { case 1: diff --git a/gas/config/tc-m32c.h b/gas/config/tc-m32c.h index 0534603b8a9..3af0092b861 100644 --- a/gas/config/tc-m32c.h +++ b/gas/config/tc-m32c.h @@ -57,9 +57,10 @@ extern bfd_boolean m32c_fix_adjustable (struct fix *); #define TC_FORCE_RELOCATION(fix) m32c_force_relocation (fix) extern int m32c_force_relocation (struct fix *); -#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \ - m32c_cons_fix_new (FRAG, WHERE, NBYTES, EXP) -extern void m32c_cons_fix_new (fragS *, int, int, expressionS *); +#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP, RELOC) \ + m32c_cons_fix_new (FRAG, WHERE, NBYTES, EXP, RELOC) +extern void m32c_cons_fix_new (fragS *, int, int, expressionS *, + bfd_reloc_code_real_type); extern const struct relax_type md_relax_table[]; #define TC_GENERIC_RELAX_TABLE md_relax_table diff --git a/gas/config/tc-microblaze.c b/gas/config/tc-microblaze.c index 13f9f8443ff..cf4ee44f099 100644 --- a/gas/config/tc-microblaze.c +++ b/gas/config/tc-microblaze.c @@ -802,7 +802,7 @@ check_got (int * got_type, int * got_len) return tmpbuf; } -extern void +extern bfd_reloc_code_real_type parse_cons_expression_microblaze (expressionS *exp, int size) { if (size == 4) @@ -828,6 +828,7 @@ parse_cons_expression_microblaze (expressionS *exp, int size) } else expression (exp); + return BFD_RELOC_NONE; } /* This is the guts of the machine-dependent assembler. STR points to a @@ -2485,11 +2486,9 @@ void cons_fix_new_microblaze (fragS * frag, int where, int size, - expressionS *exp) + expressionS *exp, + bfd_reloc_code_real_type r) { - - bfd_reloc_code_real_type r; - if ((exp->X_op == O_subtract) && (exp->X_add_symbol) && (exp->X_op_symbol) && (now_seg != absolute_section) && (size == 4) && (!S_IS_LOCAL (exp->X_op_symbol))) diff --git a/gas/config/tc-microblaze.h b/gas/config/tc-microblaze.h index 91a9a216eb9..d44f2fae1d2 100644 --- a/gas/config/tc-microblaze.h +++ b/gas/config/tc-microblaze.h @@ -36,8 +36,10 @@ relocs for such expressions as -relax in linker can change the value of such expressions */ #define TC_CONS_FIX_NEW cons_fix_new_microblaze -#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_cons_expression_microblaze (EXP, NBYTES) -extern void parse_cons_expression_microblaze (expressionS *, int); +#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \ + parse_cons_expression_microblaze (EXP, NBYTES) +extern bfd_reloc_code_real_type parse_cons_expression_microblaze + (expressionS *, int); #define TC_FORCE_RELOCATION_SECTION(FIXP,SEG) 1 #define UNDEFINED_DIFFERENCE_OK 1 @@ -108,7 +110,9 @@ extern void md_number_to_chars (char *, valueT, int); extern valueT md_section_align (segT, valueT); extern long md_pcrel_from_section (fixS *, segT); extern arelent * tc_gen_reloc (asection *, fixS *); -extern void cons_fix_new_microblaze (fragS *, int, int, expressionS *); +extern void cons_fix_new_microblaze (fragS *, int, int, + expressionS *, + bfd_reloc_code_real_type); extern void md_apply_fix3 (fixS *, valueT *, segT); #define EXTERN_FORCE_RELOC -1 diff --git a/gas/config/tc-mn10300.c b/gas/config/tc-mn10300.c index 2fce19c6b3f..3d159b18561 100644 --- a/gas/config/tc-mn10300.c +++ b/gas/config/tc-mn10300.c @@ -1013,7 +1013,8 @@ mn10300_check_fixup (struct mn10300_fixup *fixup) } void -mn10300_cons_fix_new (fragS *frag, int off, int size, expressionS *exp) +mn10300_cons_fix_new (fragS *frag, int off, int size, expressionS *exp, + bfd_reloc_code_real_type r ATTRIBUTE_UNUSED) { struct mn10300_fixup fixup; diff --git a/gas/config/tc-mn10300.h b/gas/config/tc-mn10300.h index 4a89f746510..d502430af02 100644 --- a/gas/config/tc-mn10300.h +++ b/gas/config/tc-mn10300.h @@ -39,9 +39,10 @@ extern bfd_boolean mn10300_force_relocation (struct fix *); mn10300_parse_name ((NAME), (EXPRP), (MODE), (NEXTCHARP)) int mn10300_parse_name (char const *, expressionS *, enum expr_mode, char *); -#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP) \ - mn10300_cons_fix_new ((FRAG), (OFF), (LEN), (EXP)) -void mn10300_cons_fix_new (fragS *, int, int, expressionS *); +#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC) \ + mn10300_cons_fix_new ((FRAG), (OFF), (LEN), (EXP), (RELOC)) +void mn10300_cons_fix_new (fragS *, int, int, expressionS *, + bfd_reloc_code_real_type); /* This is used to construct expressions out of @GOTOFF, @PLT and @GOT symbols. The relocation type is stored in X_md. */ diff --git a/gas/config/tc-nios2.c b/gas/config/tc-nios2.c index 9cb290dbdb2..754947cfcf2 100644 --- a/gas/config/tc-nios2.c +++ b/gas/config/tc-nios2.c @@ -3003,12 +3003,10 @@ nios2_elf_section_flags (flagword flags, int attr, int type ATTRIBUTE_UNUSED) } /* Implement TC_PARSE_CONS_EXPRESSION to handle %tls_ldo(...) */ -static int nios2_tls_ldo_reloc; - -void +bfd_reloc_code_real_type nios2_cons (expressionS *exp, int size) { - nios2_tls_ldo_reloc = 0; + bfd_reloc_code_real_type nios2_tls_ldo_reloc = BFD_RELOC_NONE; SKIP_WHITESPACE (); if (input_line_pointer[0] == '%') @@ -3021,10 +3019,10 @@ nios2_cons (expressionS *exp, int size) else { input_line_pointer += 8; - nios2_tls_ldo_reloc = 1; + nios2_tls_ldo_reloc = BFD_RELOC_NIOS2_TLS_DTPREL; } } - if (nios2_tls_ldo_reloc) + if (nios2_tls_ldo_reloc != BFD_RELOC_NONE) { SKIP_WHITESPACE (); if (input_line_pointer[0] != '(') @@ -3066,26 +3064,9 @@ nios2_cons (expressionS *exp, int size) } } } - if (!nios2_tls_ldo_reloc) + if (nios2_tls_ldo_reloc == BFD_RELOC_NONE) expression (exp); -} - -/* Implement TC_CONS_FIX_NEW. */ -void -nios2_cons_fix_new (fragS *frag, int where, unsigned int nbytes, - expressionS *exp) -{ - bfd_reloc_code_real_type r; - - r = (nbytes == 1 ? BFD_RELOC_8 - : (nbytes == 2 ? BFD_RELOC_16 - : (nbytes == 4 ? BFD_RELOC_32 : BFD_RELOC_64))); - - if (nios2_tls_ldo_reloc) - r = BFD_RELOC_NIOS2_TLS_DTPREL; - - fix_new_exp (frag, where, (int) nbytes, exp, 0, r); - nios2_tls_ldo_reloc = 0; + return nios2_tls_ldo_reloc; } /* Implement HANDLE_ALIGN. */ diff --git a/gas/config/tc-nios2.h b/gas/config/tc-nios2.h index 433264904bd..82bb624711f 100644 --- a/gas/config/tc-nios2.h +++ b/gas/config/tc-nios2.h @@ -107,11 +107,7 @@ extern flagword nios2_elf_section_flags (flagword, int, int); #define CFI_DIFF_EXPR_OK 0 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) nios2_cons (EXP, NBYTES) -extern void nios2_cons (expressionS *exp, int size); - -#define TC_CONS_FIX_NEW nios2_cons_fix_new -extern void nios2_cons_fix_new (struct frag *frag, int where, - unsigned int nbytes, struct expressionS *exp); +extern bfd_reloc_code_real_type nios2_cons (expressionS *exp, int size); /* We want .cfi_* pseudo-ops for generating unwind info. */ #define TARGET_USE_CFIPOP 1 diff --git a/gas/config/tc-ns32k.c b/gas/config/tc-ns32k.c index d66a06267db..1c97d434e45 100644 --- a/gas/config/tc-ns32k.c +++ b/gas/config/tc-ns32k.c @@ -2181,7 +2181,8 @@ void cons_fix_new_ns32k (fragS *frag, /* Which frag? */ int where, /* Where in that frag? */ int size, /* 1, 2 or 4 usually. */ - expressionS *exp) /* Expression. */ + expressionS *exp, /* Expression. */ + bfd_reloc_code_real_type r ATTRIBUTE_UNUSED) { fix_new_ns32k_exp (frag, where, size, exp, 0, 2, 0, 0, 0, 0); diff --git a/gas/config/tc-ns32k.h b/gas/config/tc-ns32k.h index 7b093ec6ede..02d71966a2d 100644 --- a/gas/config/tc-ns32k.h +++ b/gas/config/tc-ns32k.h @@ -54,7 +54,8 @@ extern int md_pcrel_adjust (fragS *); #define ARG_LEN 50 #define TC_CONS_FIX_NEW cons_fix_new_ns32k -extern void cons_fix_new_ns32k (fragS *, int, int, expressionS *); +extern void cons_fix_new_ns32k (fragS *, int, int, expressionS *, + bfd_reloc_code_real_type); /* The NS32x32 has a non 0 nop instruction which should be used in aligns. */ #define NOP_OPCODE 0xa2 diff --git a/gas/config/tc-pj.c b/gas/config/tc-pj.c index 408dde6ec22..dba4cbcc5fc 100644 --- a/gas/config/tc-pj.c +++ b/gas/config/tc-pj.c @@ -96,7 +96,8 @@ parse_exp_save_ilp (char *s, expressionS *op) we want to handle magic pending reloc expressions specially. */ void -pj_cons_fix_new_pj (fragS *frag, int where, int nbytes, expressionS *exp) +pj_cons_fix_new_pj (fragS *frag, int where, int nbytes, expressionS *exp, + bfd_reloc_code_real_type r ATTRIBUTE_UNUSED) { static int rv[5][2] = { { 0, 0 }, diff --git a/gas/config/tc-pj.h b/gas/config/tc-pj.h index 522db5b1501..eda1792fb64 100644 --- a/gas/config/tc-pj.h +++ b/gas/config/tc-pj.h @@ -31,7 +31,8 @@ ? "Pico Java GAS Big Endian" \ : "Pico Java GAS Little Endian") -void pj_cons_fix_new_pj (struct frag *, int, int, expressionS *); +void pj_cons_fix_new_pj (struct frag *, int, int, expressionS *, + bfd_reloc_code_real_type); arelent *tc_gen_reloc (asection *, struct fix *); #define md_section_align(SEGMENT, SIZE) (SIZE) @@ -45,8 +46,8 @@ arelent *tc_gen_reloc (asection *, struct fix *); #define md_pcrel_from(FIX) \ ((FIX)->fx_where + (FIX)->fx_frag->fr_address - 1) -#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \ - pj_cons_fix_new_pj (FRAG, WHERE, NBYTES, EXP) +#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP, RELOC) \ + pj_cons_fix_new_pj (FRAG, WHERE, NBYTES, EXP, RELOC) /* No shared lib support, so we don't need to ensure externally visible symbols can be overridden. */ diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 9f24f3f54b3..5cfe1db19a4 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -129,7 +129,6 @@ static void ppc_vbyte (int); #endif #ifdef OBJ_ELF -static void ppc_elf_cons (int); static void ppc_elf_rdata (int); static void ppc_elf_lcomm (int); static void ppc_elf_localentry (int); @@ -257,11 +256,7 @@ const pseudo_typeS md_pseudo_table[] = #endif #ifdef OBJ_ELF - { "llong", ppc_elf_cons, 8 }, - { "quad", ppc_elf_cons, 8 }, - { "long", ppc_elf_cons, 4 }, - { "word", ppc_elf_cons, 2 }, - { "short", ppc_elf_cons, 2 }, + { "llong", cons, 8 }, { "rdata", ppc_elf_rdata, 0 }, { "rodata", ppc_elf_rdata, 0 }, { "lcomm", ppc_elf_lcomm, 0 }, @@ -1957,11 +1952,11 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p) MAP64 ("tprel@highera", BFD_RELOC_PPC64_TPREL16_HIGHERA), MAP64 ("tprel@highest", BFD_RELOC_PPC64_TPREL16_HIGHEST), MAP64 ("tprel@highesta", BFD_RELOC_PPC64_TPREL16_HIGHESTA), - { (char *) 0, 0, 0, 0, BFD_RELOC_UNUSED } + { (char *) 0, 0, 0, 0, BFD_RELOC_NONE } }; if (*str++ != '@') - return BFD_RELOC_UNUSED; + return BFD_RELOC_NONE; for (ch = *str, str2 = ident; (str2 < ident + sizeof (ident) - 1 @@ -2047,63 +2042,18 @@ ppc_elf_suffix (char **str_p, expressionS *exp_p) return (bfd_reloc_code_real_type) reloc; } - return BFD_RELOC_UNUSED; + return BFD_RELOC_NONE; } -/* Like normal .long/.short/.word, except support @got, etc. - Clobbers input_line_pointer, checks end-of-line. */ -static void -ppc_elf_cons (int nbytes /* 1=.byte, 2=.word, 4=.long, 8=.llong */) -{ - expressionS exp; - bfd_reloc_code_real_type reloc; - - if (is_it_end_of_statement ()) - { - demand_empty_rest_of_line (); - return; - } - - do - { - expression (&exp); - if (*input_line_pointer == '@' - && (reloc = ppc_elf_suffix (&input_line_pointer, - &exp)) != BFD_RELOC_UNUSED) - { - reloc_howto_type *reloc_howto; - int size; +/* Support @got, etc. on constants emitted via .short, .int etc. */ - reloc_howto = bfd_reloc_type_lookup (stdoutput, reloc); - size = bfd_get_reloc_size (reloc_howto); - - if (size > nbytes) - { - as_bad (_("%s relocations do not fit in %d bytes\n"), - reloc_howto->name, nbytes); - } - else - { - char *p; - int offset; - - p = frag_more (nbytes); - memset (p, 0, nbytes); - offset = 0; - if (target_big_endian) - offset = nbytes - size; - fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size, - &exp, 0, reloc); - } - } - else - emit_expr (&exp, (unsigned int) nbytes); - } - while (*input_line_pointer++ == ','); - - /* Put terminator back into stream. */ - input_line_pointer--; - demand_empty_rest_of_line (); +bfd_reloc_code_real_type +ppc_elf_parse_cons (expressionS *exp, unsigned int nbytes) +{ + expression (exp); + if (nbytes >= 2 && *input_line_pointer == '@') + return ppc_elf_suffix (&input_line_pointer, exp); + return BFD_RELOC_NONE; } /* Solaris pseduo op to change to the .rodata section. */ @@ -2338,8 +2288,7 @@ ppc_elf_validate_fix (fixS *fixp, segT seg) return; case SHLIB_MRELOCATABLE: - if (fixp->fx_r_type <= BFD_RELOC_UNUSED - && fixp->fx_r_type != BFD_RELOC_16_GOTOFF + if (fixp->fx_r_type != BFD_RELOC_16_GOTOFF && fixp->fx_r_type != BFD_RELOC_HI16_GOTOFF && fixp->fx_r_type != BFD_RELOC_LO16_GOTOFF && fixp->fx_r_type != BFD_RELOC_HI16_S_GOTOFF @@ -2839,12 +2788,12 @@ md_assemble (char *str) /* FIXME: these next two specifically specify 32/64 bit toc entries. We don't support them today. Is this the right way to say that? */ - toc_reloc = BFD_RELOC_UNUSED; + toc_reloc = BFD_RELOC_NONE; as_bad (_("unimplemented toc32 expression modifier")); break; case must_be_64: /* FIXME: see above. */ - toc_reloc = BFD_RELOC_UNUSED; + toc_reloc = BFD_RELOC_NONE; as_bad (_("unimplemented toc64 expression modifier")); break; default: @@ -2914,7 +2863,7 @@ md_assemble (char *str) bfd_reloc_code_real_type reloc; char *orig_str = str; - if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED) + if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_NONE) switch (reloc) { default: @@ -3000,7 +2949,7 @@ md_assemble (char *str) } else { - bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED; + bfd_reloc_code_real_type reloc = BFD_RELOC_NONE; #ifdef OBJ_ELF if (ex.X_op == O_symbol && str[0] == '(') { @@ -3017,7 +2966,7 @@ md_assemble (char *str) expression (&tls_exp); if (tls_exp.X_op == O_symbol) { - reloc = BFD_RELOC_UNUSED; + reloc = BFD_RELOC_NONE; if (strncasecmp (input_line_pointer, "@tlsgd)", 7) == 0) { reloc = BFD_RELOC_PPC_TLSGD; @@ -3028,7 +2977,7 @@ md_assemble (char *str) reloc = BFD_RELOC_PPC_TLSLD; input_line_pointer += 7; } - if (reloc != BFD_RELOC_UNUSED) + if (reloc != BFD_RELOC_NONE) { SKIP_WHITESPACE (); str = input_line_pointer; @@ -3045,7 +2994,7 @@ md_assemble (char *str) } } - if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_UNUSED) + if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_NONE) { /* Some TLS tweaks. */ switch (reloc) @@ -3144,7 +3093,7 @@ md_assemble (char *str) } #endif /* OBJ_ELF */ - if (reloc != BFD_RELOC_UNUSED) + if (reloc != BFD_RELOC_NONE) ; /* Determine a BFD reloc value based on the operand information. We are only prepared to turn a few of the operands into @@ -3405,7 +3354,7 @@ md_assemble (char *str) for (i = 0; i < fc; i++) { fixS *fixP; - if (fixups[i].reloc != BFD_RELOC_UNUSED) + if (fixups[i].reloc != BFD_RELOC_NONE) { reloc_howto_type *reloc_howto; int size; @@ -3438,7 +3387,7 @@ md_assemble (char *str) insn_length, &fixups[i].exp, (operand->flags & PPC_OPERAND_RELATIVE) != 0, - BFD_RELOC_UNUSED); + BFD_RELOC_NONE); } fixP->fx_pcrel_adjust = fixups[i].opindex; } @@ -6462,7 +6411,7 @@ ppc_handle_align (struct frag *fragP) fixups we generated by the calls to fix_new_exp, above. */ void -md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) +md_apply_fix (fixS *fixP, valueT *valP, segT seg) { valueT value = * valP; offsetT fieldval; @@ -6810,7 +6759,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) return; gas_assert (fixP->fx_addsy != NULL); - if (fixP->fx_r_type == BFD_RELOC_UNUSED) + if (fixP->fx_r_type == BFD_RELOC_NONE) { char *sfile; unsigned int sline; diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h index 09eb88978d3..a5e69ca7b95 100644 --- a/gas/config/tc-ppc.h +++ b/gas/config/tc-ppc.h @@ -231,6 +231,10 @@ extern int ppc_fix_adjustable (struct fix *); /* Values passed to md_apply_fix don't include symbol values. */ #define MD_APPLY_SYM_VALUE(FIX) 0 +#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \ + ppc_elf_parse_cons (EXP, NBYTES) +extern bfd_reloc_code_real_type ppc_elf_parse_cons (expressionS *, + unsigned int); #define tc_frob_file_before_adjust ppc_frob_file_before_adjust extern void ppc_frob_file_before_adjust (void); diff --git a/gas/config/tc-rx.c b/gas/config/tc-rx.c index 87b1e099675..c4842f9aecf 100644 --- a/gas/config/tc-rx.c +++ b/gas/config/tc-rx.c @@ -2170,10 +2170,9 @@ void rx_cons_fix_new (fragS * frag, int where, int size, - expressionS * exp) + expressionS * exp, + bfd_reloc_code_real_type type) { - bfd_reloc_code_real_type type; - switch (size) { case 1: diff --git a/gas/config/tc-rx.h b/gas/config/tc-rx.h index 937af2520b6..b82812d65be 100644 --- a/gas/config/tc-rx.h +++ b/gas/config/tc-rx.h @@ -68,9 +68,10 @@ extern long md_pcrel_from_section (struct fix *, segT); rx_validate_fix_sub (FIX) extern int rx_validate_fix_sub (struct fix *); -#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP) \ - rx_cons_fix_new (FRAG, WHERE, NBYTES, EXP) -extern void rx_cons_fix_new (fragS *, int, int, expressionS *); +#define TC_CONS_FIX_NEW(FRAG, WHERE, NBYTES, EXP, RELOC) \ + rx_cons_fix_new (FRAG, WHERE, NBYTES, EXP, RELOC) +extern void rx_cons_fix_new (fragS *, int, int, expressionS *, + bfd_reloc_code_real_type); #define tc_fix_adjustable(x) 0 diff --git a/gas/config/tc-sh.c b/gas/config/tc-sh.c index da7d84a3a6e..a0cd212641e 100644 --- a/gas/config/tc-sh.c +++ b/gas/config/tc-sh.c @@ -765,9 +765,10 @@ sh_check_fixup (expressionS *main_exp, bfd_reloc_code_real_type *r_type_p) /* Add expression EXP of SIZE bytes to offset OFF of fragment FRAG. */ void -sh_cons_fix_new (fragS *frag, int off, int size, expressionS *exp) +sh_cons_fix_new (fragS *frag, int off, int size, expressionS *exp, + bfd_reloc_code_real_type r_type) { - bfd_reloc_code_real_type r_type = BFD_RELOC_UNUSED; + r_type = BFD_RELOC_UNUSED; if (sh_check_fixup (exp, &r_type)) as_bad (_("Invalid PIC expression.")); diff --git a/gas/config/tc-sh.h b/gas/config/tc-sh.h index 40d80569b45..97b6b6d5733 100644 --- a/gas/config/tc-sh.h +++ b/gas/config/tc-sh.h @@ -232,9 +232,10 @@ extern bfd_boolean sh_fix_adjustable (struct fix *); int sh_parse_name (char const *, expressionS *, enum expr_mode, char *); -#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP) \ - sh_cons_fix_new ((FRAG), (OFF), (LEN), (EXP)) -void sh_cons_fix_new (fragS *, int, int, expressionS *); +#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC) \ + sh_cons_fix_new ((FRAG), (OFF), (LEN), (EXP), (RELOC)) +void sh_cons_fix_new (fragS *, int, int, expressionS *, + bfd_reloc_code_real_type); /* This is used to construct expressions out of @GOTOFF, @PLT and @GOT symbols. The relocation type is stored in X_md. */ diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c index fdc2f0386d3..5b0baad975a 100644 --- a/gas/config/tc-sparc.c +++ b/gas/config/tc-sparc.c @@ -4268,11 +4268,6 @@ s_proc (int ignore ATTRIBUTE_UNUSED) static int sparc_no_align_cons = 0; -/* This static variable is set by sparc_cons to emit requested types - of relocations in cons_fix_new_sparc. */ - -static const char *sparc_cons_special_reloc; - /* This handles the unaligned space allocation pseudo-ops, such as .uaword. .uaword is just like .word, but the value does not need to be aligned. */ @@ -4540,13 +4535,13 @@ sparc_elf_final_processing (void) elf_elfheader (stdoutput)->e_flags |= EF_SPARC_SUN_US1|EF_SPARC_SUN_US3; } -void +const char * sparc_cons (expressionS *exp, int size) { char *save; + const char *sparc_cons_special_reloc = NULL; SKIP_WHITESPACE (); - sparc_cons_special_reloc = NULL; save = input_line_pointer; if (input_line_pointer[0] == '%' && input_line_pointer[1] == 'r' @@ -4673,6 +4668,7 @@ sparc_cons (expressionS *exp, int size) } if (sparc_cons_special_reloc == NULL) expression (exp); + return sparc_cons_special_reloc; } #endif @@ -4685,7 +4681,8 @@ void cons_fix_new_sparc (fragS *frag, int where, unsigned int nbytes, - expressionS *exp) + expressionS *exp, + const char *sparc_cons_special_reloc) { bfd_reloc_code_real_type r; @@ -4734,7 +4731,6 @@ cons_fix_new_sparc (fragS *frag, } fix_new_exp (frag, where, (int) nbytes, exp, 0, r); - sparc_cons_special_reloc = NULL; } void @@ -4788,9 +4784,7 @@ sparc_regname_to_dw2regnum (char *regname) void sparc_cfi_emit_pcrel_expr (expressionS *exp, unsigned int nbytes) { - sparc_cons_special_reloc = "disp"; sparc_no_align_cons = 1; - emit_expr (exp, nbytes); + emit_expr_with_reloc (exp, nbytes, "disp"); sparc_no_align_cons = 0; - sparc_cons_special_reloc = NULL; } diff --git a/gas/config/tc-sparc.h b/gas/config/tc-sparc.h index 10d4522b85b..ef76c0b9633 100644 --- a/gas/config/tc-sparc.h +++ b/gas/config/tc-sparc.h @@ -155,14 +155,17 @@ extern void sparc_md_end (void); #endif +#define TC_PARSE_CONS_RETURN_TYPE const char * +#define TC_PARSE_CONS_RETURN_NONE NULL + #ifdef OBJ_ELF #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) sparc_cons (EXP, NBYTES) -extern void sparc_cons (expressionS *, int); +extern const char *sparc_cons (expressionS *, int); #endif #define TC_CONS_FIX_NEW cons_fix_new_sparc extern void cons_fix_new_sparc - (struct frag *, int, unsigned int, struct expressionS *); +(struct frag *, int, unsigned int, struct expressionS *, const char *); #define TC_FIX_TYPE valueT diff --git a/gas/config/tc-tic54x.c b/gas/config/tc-tic54x.c index 27a21114072..bba743ccf71 100644 --- a/gas/config/tc-tic54x.c +++ b/gas/config/tc-tic54x.c @@ -5121,10 +5121,9 @@ tc_gen_reloc (asection *section, fixS *fixP) /* Handle cons expressions. */ void -tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *expn) +tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *expn, + bfd_reloc_code_real_type r) { - bfd_reloc_code_real_type r; - switch (octets) { default: diff --git a/gas/config/tc-tic54x.h b/gas/config/tc-tic54x.h index 84f343f19ed..3fe8be886c3 100644 --- a/gas/config/tc-tic54x.h +++ b/gas/config/tc-tic54x.h @@ -69,8 +69,10 @@ struct bit_info extern int tic54x_start_label (int, char *); /* custom handling for relocations in cons expressions */ -#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) tic54x_cons_fix_new(FRAG,OFF,LEN,EXP) -extern void tic54x_cons_fix_new (fragS *,int,int,expressionS *); +#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC) \ + tic54x_cons_fix_new (FRAG, OFF, LEN, EXP, RELOC) +extern void tic54x_cons_fix_new (fragS *, int, int, expressionS *, + bfd_reloc_code_real_type); /* Define md_number_to_chars as the appropriate standard big endian or little endian function. Mostly littleendian, but longwords and floats are diff --git a/gas/config/tc-tic6x.c b/gas/config/tc-tic6x.c index 1ffbb685fbd..aca07d3ac82 100644 --- a/gas/config/tc-tic6x.c +++ b/gas/config/tc-tic6x.c @@ -2012,10 +2012,9 @@ tic6x_fix_new_exp (fragS *frag, int where, int size, expressionS *exp, go through the error checking in tic6x_fix_new_exp. */ void -tic6x_cons_fix_new (fragS *frag, int where, int size, expressionS *exp) +tic6x_cons_fix_new (fragS *frag, int where, int size, expressionS *exp, + bfd_reloc_code_real_type r_type) { - bfd_reloc_code_real_type r_type; - switch (size) { case 1: diff --git a/gas/config/tc-tic6x.h b/gas/config/tc-tic6x.h index 2612aab0320..dc110e890d7 100644 --- a/gas/config/tc-tic6x.h +++ b/gas/config/tc-tic6x.h @@ -184,10 +184,10 @@ extern long tic6x_pcrel_from_section (struct fix *fixp, segT sec); #define md_start_line_hook() tic6x_start_line_hook () extern void tic6x_start_line_hook (void); -#define TC_CONS_FIX_NEW(frag, where, size, exp) \ - tic6x_cons_fix_new (frag, where, size, exp) -extern void tic6x_cons_fix_new (fragS *frag, int where, int size, - expressionS *exp); +#define TC_CONS_FIX_NEW(frag, where, size, exp, reloc) \ + tic6x_cons_fix_new (frag, where, size, exp, reloc) +extern void tic6x_cons_fix_new (fragS *, int, int, expressionS *, + bfd_reloc_code_real_type); #define tc_fix_adjustable(FIX) tic6x_fix_adjustable (FIX) extern bfd_boolean tic6x_fix_adjustable (struct fix *); diff --git a/gas/config/tc-v850.c b/gas/config/tc-v850.c index d7bd99a6435..d5b9d7ab264 100644 --- a/gas/config/tc-v850.c +++ b/gas/config/tc-v850.c @@ -27,9 +27,6 @@ /* Sign-extend a 16-bit number. */ #define SEXT16(x) ((((x) & 0xffff) ^ (~0x7fff)) + 0x8000) -/* Temporarily holds the reloc in a cons expression. */ -static bfd_reloc_code_real_type hold_cons_reloc = BFD_RELOC_UNUSED; - /* Set to TRUE if we want to be pedantic about signed overflows. */ static bfd_boolean warn_signed_overflows = FALSE; static bfd_boolean warn_unsigned_overflows = FALSE; @@ -2156,7 +2153,7 @@ v850_reloc_prefix (const struct v850_operand *operand, const char **errmsg) if (paren_skipped) --input_line_pointer; - return BFD_RELOC_UNUSED; + return BFD_RELOC_NONE; } /* Insert an operand value into an instruction. */ @@ -2407,7 +2404,7 @@ md_assemble (char *str) input_line_pointer = str; /* lo(), hi(), hi0(), etc... */ - if ((reloc = v850_reloc_prefix (operand, &errmsg)) != BFD_RELOC_UNUSED) + if ((reloc = v850_reloc_prefix (operand, &errmsg)) != BFD_RELOC_NONE) { /* This is a fake reloc, used to indicate an error condition. */ if (reloc == BFD_RELOC_64) @@ -2977,7 +2974,7 @@ md_assemble (char *str) fixups[fc].exp = ex; fixups[fc].opindex = *opindex_ptr; - fixups[fc].reloc = BFD_RELOC_UNUSED; + fixups[fc].reloc = BFD_RELOC_NONE; ++fc; break; } @@ -3239,7 +3236,7 @@ md_assemble (char *str) reloc = fixups[i].reloc; - if (reloc != BFD_RELOC_UNUSED) + if (reloc != BFD_RELOC_NONE) { reloc_howto_type *reloc_howto = bfd_reloc_type_lookup (stdoutput, reloc); @@ -3634,15 +3631,18 @@ md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED) /* Parse a cons expression. We have to handle hi(), lo(), etc on the v850. */ -void +bfd_reloc_code_real_type parse_cons_expression_v850 (expressionS *exp) { const char *errmsg; + bfd_reloc_code_real_type r; + /* See if there's a reloc prefix like hi() we have to handle. */ - hold_cons_reloc = v850_reloc_prefix (NULL, &errmsg); + r = v850_reloc_prefix (NULL, &errmsg); /* Do normal expression parsing. */ expression (exp); + return r; } /* Create a fixup for a cons expression. If parse_cons_expression_v850 @@ -3653,24 +3653,23 @@ void cons_fix_new_v850 (fragS *frag, int where, int size, - expressionS *exp) + expressionS *exp, + bfd_reloc_code_real_type r) { - if (hold_cons_reloc == BFD_RELOC_UNUSED) + if (r == BFD_RELOC_NONE) { if (size == 4) - hold_cons_reloc = BFD_RELOC_32; + r = BFD_RELOC_32; if (size == 2) - hold_cons_reloc = BFD_RELOC_16; + r = BFD_RELOC_16; if (size == 1) - hold_cons_reloc = BFD_RELOC_8; + r = BFD_RELOC_8; } if (exp != NULL) - fix_new_exp (frag, where, size, exp, 0, hold_cons_reloc); + fix_new_exp (frag, where, size, exp, 0, r); else - fix_new (frag, where, size, NULL, 0, 0, hold_cons_reloc); - - hold_cons_reloc = BFD_RELOC_UNUSED; + fix_new (frag, where, size, NULL, 0, 0, r); } bfd_boolean diff --git a/gas/config/tc-v850.h b/gas/config/tc-v850.h index 1030ef3a82a..a0aeeb4f6bb 100644 --- a/gas/config/tc-v850.h +++ b/gas/config/tc-v850.h @@ -58,10 +58,11 @@ extern int v850_force_relocation (struct fix *); /* We need to handle lo(), hi(), etc etc in .hword, .word, etc directives, so we have to parse "cons" expressions ourselves. */ #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_cons_expression_v850 (EXP) -extern void parse_cons_expression_v850 (expressionS *); +extern bfd_reloc_code_real_type parse_cons_expression_v850 (expressionS *); #define TC_CONS_FIX_NEW cons_fix_new_v850 -extern void cons_fix_new_v850 (fragS *, int, int, expressionS *); +extern void cons_fix_new_v850 (fragS *, int, int, expressionS *, + bfd_reloc_code_real_type); #define TC_GENERIC_RELAX_TABLE md_relax_table extern const struct relax_type md_relax_table[]; diff --git a/gas/config/tc-vax.c b/gas/config/tc-vax.c index 7a9ef0b15b8..0740a9b2890 100644 --- a/gas/config/tc-vax.c +++ b/gas/config/tc-vax.c @@ -3264,12 +3264,11 @@ md_begin (void) } } -static char *vax_cons_special_reloc; - -void +bfd_reloc_code_real_type vax_cons (expressionS *exp, int size) { char *save; + char *vax_cons_special_reloc; SKIP_WHITESPACE (); vax_cons_special_reloc = NULL; @@ -3373,35 +3372,29 @@ vax_cons (expressionS *exp, int size) } if (vax_cons_special_reloc == NULL) expression (exp); + else + switch (size) + { + case 1: return BFD_RELOC_8_PCREL; + case 2: return BFD_RELOC_16_PCREL; + case 4: return BFD_RELOC_32_PCREL; + } + return BFD_RELOC_NONE; } /* This is called by emit_expr via TC_CONS_FIX_NEW when creating a reloc for a cons. */ void -vax_cons_fix_new (fragS *frag, int where, unsigned int nbytes, expressionS *exp) +vax_cons_fix_new (fragS *frag, int where, unsigned int nbytes, expressionS *exp, + bfd_reloc_code_real_type r) { - bfd_reloc_code_real_type r; - - r = (nbytes == 1 ? BFD_RELOC_8 : - (nbytes == 2 ? BFD_RELOC_16 : BFD_RELOC_32)); - - if (vax_cons_special_reloc) - { - if (*vax_cons_special_reloc == 'p') - { - switch (nbytes) - { - case 1: r = BFD_RELOC_8_PCREL; break; - case 2: r = BFD_RELOC_16_PCREL; break; - case 4: r = BFD_RELOC_32_PCREL; break; - default: abort (); - } - } - } + if (r == BFD_RELOC_NONE) + r = (nbytes == 1 ? BFD_RELOC_8 + : nbytes == 2 ? BFD_RELOC_16 + : BFD_RELOC_32); fix_new_exp (frag, where, (int) nbytes, exp, 0, r); - vax_cons_special_reloc = NULL; } char * diff --git a/gas/config/tc-vax.h b/gas/config/tc-vax.h index b242fe0ac11..cc94bb2252c 100644 --- a/gas/config/tc-vax.h +++ b/gas/config/tc-vax.h @@ -49,8 +49,9 @@ #ifdef OBJ_ELF #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) vax_cons (EXP, NBYTES) #define TC_CONS_FIX_NEW vax_cons_fix_new -void vax_cons (expressionS *, int); -void vax_cons_fix_new (struct frag *, int, unsigned int, struct expressionS *); +bfd_reloc_code_real_type vax_cons (expressionS *, int); +void vax_cons_fix_new (struct frag *, int, unsigned int, struct expressionS *, + bfd_reloc_code_real_type); #endif extern const struct relax_type md_relax_table[]; diff --git a/gas/config/tc-xstormy16.c b/gas/config/tc-xstormy16.c index 1d57d60e269..e8eba894be9 100644 --- a/gas/config/tc-xstormy16.c +++ b/gas/config/tc-xstormy16.c @@ -193,10 +193,9 @@ void xstormy16_cons_fix_new (fragS *f, int where, int nbytes, - expressionS *exp) + expressionS *exp, + bfd_reloc_code_real_type code) { - bfd_reloc_code_real_type code; - if (exp->X_op == O_fptr_symbol) { switch (nbytes) diff --git a/gas/config/tc-xstormy16.h b/gas/config/tc-xstormy16.h index 31ec16c8f9b..064a85cb107 100644 --- a/gas/config/tc-xstormy16.h +++ b/gas/config/tc-xstormy16.h @@ -57,7 +57,8 @@ extern int xstormy16_force_relocation (struct fix *); extern long md_pcrel_from_section (struct fix *, segT); #define TC_CONS_FIX_NEW xstormy16_cons_fix_new -extern void xstormy16_cons_fix_new (fragS *f, int, int, expressionS *); +extern void xstormy16_cons_fix_new (fragS *f, int, int, expressionS *, + bfd_reloc_code_real_type); #define md_cgen_record_fixup_exp xstormy16_cgen_record_fixup_exp diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c index 4e9b654b8df..5cc466237c8 100644 --- a/gas/dwarf2dbg.c +++ b/gas/dwarf2dbg.c @@ -158,6 +158,10 @@ /* The maximum address skip amount that can be encoded with a special op. */ #define MAX_SPECIAL_ADDR_DELTA SPECIAL_ADDR(255) +#ifndef TC_PARSE_CONS_RETURN_NONE +#define TC_PARSE_CONS_RETURN_NONE BFD_RELOC_NONE +#endif + struct line_entry { struct line_entry *next; symbolS *label; @@ -1144,13 +1148,13 @@ emit_fixed_inc_line_addr (int line_delta, addressT addr_delta, fragS *frag, exp.X_op = O_symbol; exp.X_add_symbol = to_sym; exp.X_add_number = 0; - emit_expr_fix (&exp, sizeof_address, frag, p); + emit_expr_fix (&exp, sizeof_address, frag, p, TC_PARSE_CONS_RETURN_NONE); p += sizeof_address; } else { *p++ = DW_LNS_fixed_advance_pc; - emit_expr_fix (pexp, 2, frag, p); + emit_expr_fix (pexp, 2, frag, p, TC_PARSE_CONS_RETURN_NONE); p += 2; } diff --git a/gas/read.c b/gas/read.c index 08b129f0805..306f7eca57e 100644 --- a/gas/read.c +++ b/gas/read.c @@ -3851,19 +3851,22 @@ parse_mri_cons (expressionS *exp, unsigned int nbytes); #ifndef TC_PARSE_CONS_EXPRESSION #ifdef BITFIELD_CONS_EXPRESSIONS -#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_bitfield_cons (EXP, NBYTES) +#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \ + (parse_bitfield_cons (EXP, NBYTES), TC_PARSE_CONS_RETURN_NONE) static void parse_bitfield_cons (expressionS *exp, unsigned int nbytes); #endif #ifdef REPEAT_CONS_EXPRESSIONS -#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_repeat_cons (EXP, NBYTES) +#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \ + (parse_repeat_cons (EXP, NBYTES), TC_PARSE_CONS_RETURN_NONE) static void parse_repeat_cons (expressionS *exp, unsigned int nbytes); #endif /* If we haven't gotten one yet, just call expression. */ #ifndef TC_PARSE_CONS_EXPRESSION -#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) expression (EXP) +#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \ + (expression (EXP), TC_PARSE_CONS_RETURN_NONE) #endif #endif @@ -3871,7 +3874,7 @@ void do_parse_cons_expression (expressionS *exp, int nbytes ATTRIBUTE_UNUSED) { - TC_PARSE_CONS_EXPRESSION (exp, nbytes); + (void) TC_PARSE_CONS_EXPRESSION (exp, nbytes); } @@ -3914,6 +3917,8 @@ cons_worker (int nbytes, /* 1=.byte, 2=.word, 4=.long. */ c = 0; do { + TC_PARSE_CONS_RETURN_TYPE ret = TC_PARSE_CONS_RETURN_NONE; + #ifdef TC_M68K if (flag_m68k_mri) parse_mri_cons (&exp, (unsigned int) nbytes); @@ -3926,7 +3931,7 @@ cons_worker (int nbytes, /* 1=.byte, 2=.word, 4=.long. */ ignore_rest_of_line (); return; } - TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes); + ret = TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes); } if (rva) @@ -3936,7 +3941,7 @@ cons_worker (int nbytes, /* 1=.byte, 2=.word, 4=.long. */ else as_fatal (_("rva without symbol")); } - emit_expr (&exp, (unsigned int) nbytes); + emit_expr_with_reloc (&exp, (unsigned int) nbytes, ret); ++c; } while (*input_line_pointer++ == ','); @@ -4079,6 +4084,14 @@ s_reloc (int ignore ATTRIBUTE_UNUSED) void emit_expr (expressionS *exp, unsigned int nbytes) +{ + emit_expr_with_reloc (exp, nbytes, TC_PARSE_CONS_RETURN_NONE); +} + +void +emit_expr_with_reloc (expressionS *exp, + unsigned int nbytes, + TC_PARSE_CONS_RETURN_TYPE reloc) { operatorT op; char *p; @@ -4221,6 +4234,12 @@ emit_expr (expressionS *exp, unsigned int nbytes) p = frag_more ((int) nbytes); + if (reloc != TC_PARSE_CONS_RETURN_NONE) + { + emit_expr_fix (exp, nbytes, frag_now, p, reloc); + return; + } + #ifndef WORKING_DOT_WORD /* If we have the difference of two symbols in a word, save it on the broken_words list. See the code in write.c. */ @@ -4379,23 +4398,41 @@ emit_expr (expressionS *exp, unsigned int nbytes) } } else - emit_expr_fix (exp, nbytes, frag_now, p); + emit_expr_fix (exp, nbytes, frag_now, p, TC_PARSE_CONS_RETURN_NONE); } void -emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p) +emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p, + TC_PARSE_CONS_RETURN_TYPE r) { - memset (p, 0, nbytes); + int offset = 0; + unsigned int size = nbytes; + + memset (p, 0, size); /* Generate a fixS to record the symbol value. */ #ifdef TC_CONS_FIX_NEW - TC_CONS_FIX_NEW (frag, p - frag->fr_literal, nbytes, exp); + TC_CONS_FIX_NEW (frag, p - frag->fr_literal + offset, size, exp, r); #else - { - bfd_reloc_code_real_type r; + if (r != TC_PARSE_CONS_RETURN_NONE) + { + reloc_howto_type *reloc_howto; - switch (nbytes) + reloc_howto = bfd_reloc_type_lookup (stdoutput, r); + size = bfd_get_reloc_size (reloc_howto); + + if (size > nbytes) + { + as_bad (_("%s relocations do not fit in %u bytes\n"), + reloc_howto->name, nbytes); + return; + } + else if (target_big_endian) + offset = nbytes - size; + } + else + switch (size) { case 1: r = BFD_RELOC_8; @@ -4413,13 +4450,11 @@ emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p) r = BFD_RELOC_64; break; default: - as_bad (_("unsupported BFD relocation size %u"), nbytes); - r = BFD_RELOC_32; - break; + as_bad (_("unsupported BFD relocation size %u"), size); + return; } - fix_new_exp (frag, p - frag->fr_literal, (int) nbytes, exp, - 0, r); - } + fix_new_exp (frag, p - frag->fr_literal + offset, size, + exp, 0, r); #endif } @@ -4555,9 +4590,7 @@ parse_bitfield_cons (exp, nbytes) #ifdef TC_M68K static void -parse_mri_cons (exp, nbytes) - expressionS *exp; - unsigned int nbytes; +parse_mri_cons (expressionS *exp, unsigned int nbytes) { if (*input_line_pointer != '\'' && (input_line_pointer[1] != '\'' diff --git a/gas/read.h b/gas/read.h index 59c00274205..b85d3a9a145 100644 --- a/gas/read.h +++ b/gas/read.h @@ -93,6 +93,11 @@ enum linkonce_type { extern char original_case_string[]; #endif +#ifndef TC_PARSE_CONS_RETURN_TYPE +#define TC_PARSE_CONS_RETURN_TYPE bfd_reloc_code_real_type +#define TC_PARSE_CONS_RETURN_NONE BFD_RELOC_NONE +#endif + extern void pop_insert (const pseudo_typeS *); extern unsigned int get_stab_string_offset (const char *string, const char *stabstr_secname); @@ -109,7 +114,10 @@ extern void add_include_dir (char *path); extern void cons (int nbytes); extern void demand_empty_rest_of_line (void); extern void emit_expr (expressionS *exp, unsigned int nbytes); -extern void emit_expr_fix (expressionS *, unsigned int, fragS *, char *); +extern void emit_expr_with_reloc (expressionS *exp, unsigned int nbytes, + TC_PARSE_CONS_RETURN_TYPE); +extern void emit_expr_fix (expressionS *, unsigned int, fragS *, char *, + TC_PARSE_CONS_RETURN_TYPE); extern void equals (char *sym_name, int reassign); extern void float_cons (int float_type); extern void ignore_rest_of_line (void); diff --git a/gas/write.c b/gas/write.c index c974121b21c..4ab275d89df 100644 --- a/gas/write.c +++ b/gas/write.c @@ -1883,7 +1883,7 @@ write_object_file (void) #ifdef TC_CONS_FIX_NEW TC_CONS_FIX_NEW (lie->frag, lie->word_goes_here - lie->frag->fr_literal, - 2, &exp); + 2, &exp, TC_PARSE_CONS_RETURN_NONE); #else fix_new_exp (lie->frag, lie->word_goes_here - lie->frag->fr_literal,