X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fread.c;h=8e1b06edf6bdad5e0f412bc1b22de8f57ef4ac1c;hb=6be47f0c48cbd58921a25e7493ca79a6f596dffe;hp=08b129f0805309dc4acebff3c2bc9aff5a19b824;hpb=2e6976a881711242cc151971b83e36844edbc310;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/read.c b/gas/read.c index 08b129f080..8e1b06edf6 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,14 @@ 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_CONS_FIX_CHECK + fixS **cur_fix = &frchain_now->fix_tail; + + if (*cur_fix != NULL) + cur_fix = &(*cur_fix)->fx_next; +#endif + #ifdef TC_M68K if (flag_m68k_mri) parse_mri_cons (&exp, (unsigned int) nbytes); @@ -3926,7 +3937,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 +3947,10 @@ 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); +#ifdef TC_CONS_FIX_CHECK + TC_CONS_FIX_CHECK (&exp, nbytes, *cur_fix); +#endif ++c; } while (*input_line_pointer++ == ','); @@ -4079,6 +4093,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 +4243,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 +4407,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 ATTRIBUTE_UNUSED) { - 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; + + reloc_howto = bfd_reloc_type_lookup (stdoutput, r); + size = bfd_get_reloc_size (reloc_howto); - switch (nbytes) + 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 +4459,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 +4599,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] != '\''