X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fread.c;h=d51835e3cecfcc22f8f5af4d7c62f438a0533eb2;hb=9622b051cf36414e121c0c2e63c099e588801e0e;hp=b99c01162465cdb334099de2df2698c67ba5cab5;hpb=87c245cccce4a84d53381ea7a8247330608eba7f;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/read.c b/gas/read.c index b99c011624..d51835e3ce 100644 --- a/gas/read.c +++ b/gas/read.c @@ -1,6 +1,6 @@ /* read.c - read a source file - Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 + 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -17,8 +17,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ +Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA +02110-1301, USA. */ /* If your chars aren't 8 bits, you will change this a bit (eg. to 0xFF). But then, GNU isn't spozed to run on your machine anyway. @@ -72,7 +72,6 @@ die horribly; #endif #ifndef LEX_AT -/* The m88k unfortunately uses @ as a label beginner. */ #define LEX_AT 0 #endif @@ -98,7 +97,6 @@ die horribly; #endif #ifndef LEX_DOLLAR -/* The a29k assembler does not permits labels to start with $. */ #define LEX_DOLLAR 3 #endif @@ -221,6 +219,7 @@ static segT get_known_segmented_expression (expressionS * expP); static void pobegin (void); static int get_line_sb (sb *); static void generate_file_debug (void); +static char *_find_end_of_line (char *, int, int); void read_begin (void) @@ -245,7 +244,6 @@ read_begin (void) } #ifndef TC_ADDRESS_BYTES -#ifdef BFD_ASSEMBLER #define TC_ADDRESS_BYTES address_bytes static inline int @@ -260,7 +258,6 @@ address_bytes (void) return n; } #endif -#endif /* Set up pseudo-op tables. */ @@ -326,6 +323,7 @@ static const pseudo_typeS potable[] = { /* endef */ {"equ", s_set, 0}, {"equiv", s_set, 1}, + {"eqv", s_set, -1}, {"err", s_err, 0}, {"error", s_errwarn, 1}, {"exitm", s_mexit, 0}, @@ -343,6 +341,7 @@ static const pseudo_typeS potable[] = { {"globl", s_globl, 0}, {"hword", cons, 2}, {"if", s_if, (int) O_ne}, + {"ifb", s_ifb, 1}, {"ifc", s_ifc, 0}, {"ifdef", s_ifdef, 0}, {"ifeq", s_if, (int) O_eq}, @@ -351,6 +350,7 @@ static const pseudo_typeS potable[] = { {"ifgt", s_if, (int) O_gt}, {"ifle", s_if, (int) O_le}, {"iflt", s_if, (int) O_lt}, + {"ifnb", s_ifb, 0}, {"ifnc", s_ifc, 1}, {"ifndef", s_ifdef, 1}, {"ifne", s_if, (int) O_ne}, @@ -434,6 +434,7 @@ static const pseudo_typeS potable[] = { {"xref", s_ignore, 0}, {"xstabs", s_xstab, 's'}, {"warning", s_errwarn, 0}, + {"weakref", s_weakref, 0}, {"word", cons, 2}, {"zero", s_space, 0}, {NULL, NULL, 0} /* End sentinel. */ @@ -442,7 +443,7 @@ static const pseudo_typeS potable[] = { static offsetT get_absolute_expr (expressionS *exp) { - expression (exp); + expression_and_evaluate (exp); if (exp->X_op != O_constant) { if (exp->X_op != O_absent) @@ -517,9 +518,11 @@ pobegin (void) #define HANDLE_CONDITIONAL_ASSEMBLY() \ if (ignore_input ()) \ { \ - while (!is_end_of_line[(unsigned char) *input_line_pointer++]) \ - if (input_line_pointer == buffer_limit) \ - break; \ + char *eol = find_end_of_line (input_line_pointer, flag_m68k_mri); \ + input_line_pointer = (input_line_pointer <= buffer_limit \ + && eol >= buffer_limit) \ + ? buffer_limit \ + : eol + 1; \ continue; \ } @@ -717,9 +720,7 @@ read_a_source_file (char *name) int len; /* Find the end of the current expanded macro line. */ - for (s = input_line_pointer - 1; *s; ++s) - if (is_end_of_line[(unsigned char) *s]) - break; + s = find_end_of_line (input_line_pointer - 1, flag_m68k_mri); if (s != last_eol) { @@ -788,6 +789,14 @@ read_a_source_file (char *name) /* Input_line_pointer->after ':'. */ SKIP_WHITESPACE (); } + else if (input_line_pointer[1] == '=' + && (c == '=' + || ((c == ' ' || c == '\t') + && input_line_pointer[2] == '='))) + { + equals (s, -1); + demand_empty_rest_of_line (); + } else if ((c == '=' || ((c == ' ' || c == '\t') && input_line_pointer[1] == '=')) @@ -820,8 +829,8 @@ read_a_source_file (char *name) #endif if (NO_PSEUDO_DOT || flag_m68k_mri) { - /* The MRI assembler and the m88k use pseudo-ops - without a period. */ + /* The MRI assembler uses pseudo-ops without + a period. */ pop = (pseudo_typeS *) hash_find (po_hash, s); if (pop != NULL && pop->poc_handler == NULL) pop = NULL; @@ -909,34 +918,10 @@ read_a_source_file (char *name) } else { - int inquote = 0; -#ifdef QUOTES_IN_INSN - int inescape = 0; -#endif - /* WARNING: c has char, which may be end-of-line. */ /* Also: input_line_pointer->`\0` where c was. */ *input_line_pointer = c; - while (!is_end_of_line[(unsigned char) *input_line_pointer] - || inquote -#ifdef TC_EOL_IN_INSN - || TC_EOL_IN_INSN (input_line_pointer) -#endif - ) - { - if (flag_m68k_mri && *input_line_pointer == '\'') - inquote = !inquote; -#ifdef QUOTES_IN_INSN - if (inescape) - inescape = 0; - else if (*input_line_pointer == '"') - inquote = !inquote; - else if (*input_line_pointer == '\\') - inescape = 1; -#endif - input_line_pointer++; - } - + input_line_pointer = _find_end_of_line (input_line_pointer, flag_m68k_mri, 1); c = *input_line_pointer; *input_line_pointer = '\0'; @@ -1286,11 +1271,7 @@ do_align (int n, char *fill, int len, int max) fill pattern. BYTES_P is non-zero if the alignment value should be interpreted as the byte boundary, rather than the power of 2. */ -#ifdef BFD_ASSEMBLER #define ALIGN_LIMIT (stdoutput->arch_info->bits_per_address - 1) -#else -#define ALIGN_LIMIT 15 -#endif static void s_align (int arg, int bytes_p) @@ -1457,7 +1438,7 @@ s_comm_internal (int param, if (name == p) { as_bad (_("expected symbol name")); - discard_rest_of_line (); + ignore_rest_of_line (); goto out; } @@ -1470,9 +1451,7 @@ s_comm_internal (int param, temp = get_absolute_expr (&exp); size = temp; -#ifdef BFD_ASSEMBLER size &= ((offsetT) 2 << (stdoutput->arch_info->bits_per_address - 1)) - 1; -#endif if (exp.X_op == O_absent) { as_bad (_("missing size expression")); @@ -1488,13 +1467,22 @@ s_comm_internal (int param, *p = 0; symbolP = symbol_find_or_make (name); - if (S_IS_DEFINED (symbolP) && !S_IS_COMMON (symbolP)) + if ((S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP)) + && !S_IS_COMMON (symbolP)) { - symbolP = NULL; - as_bad (_("symbol `%s' is already defined"), name); - *p = c; - ignore_rest_of_line (); - goto out; + if (!S_IS_VOLATILE (symbolP)) + { + symbolP = NULL; + as_bad (_("symbol `%s' is already defined"), name); + *p = c; + ignore_rest_of_line (); + goto out; + } + symbolP = symbol_clone (symbolP, 1); + S_SET_SEGMENT (symbolP, undefined_section); + S_SET_VALUE (symbolP, 0); + symbol_set_frag (symbolP, &zero_address_frag); + S_CLEAR_VOLATILE (symbolP); } size = S_GET_VALUE (symbolP); @@ -1511,6 +1499,7 @@ s_comm_internal (int param, { S_SET_VALUE (symbolP, (valueT) size); S_SET_EXTERNAL (symbolP); + S_SET_SEGMENT (symbolP, bfd_com_section_ptr); #ifdef OBJ_VMS { extern int flag_one; @@ -1604,6 +1593,7 @@ s_mri_common (int small ATTRIBUTE_UNUSED) } S_SET_EXTERNAL (sym); + S_SET_SEGMENT (sym, bfd_com_section_ptr); mri_common_symbol = sym; #ifdef S_SET_ALIGN @@ -1719,9 +1709,17 @@ s_app_line (int ignore ATTRIBUTE_UNUSED) /* The given number is that of the next line. */ l = get_absolute_expression () - 1; - if (l < 0) + + if (l < -1) /* Some of the back ends can't deal with non-positive line numbers. - Besides, it's silly. */ + Besides, it's silly. GCC however will generate a line number of + zero when it is pre-processing builtins for assembler-with-cpp files: + + # 0 "" + + We do not want to barf on this, especially since such files are used + in the GCC and GDB testsuites. So we check for negative line numbers + rather than non-positive line numbers. */ as_warn (_("line numbers must be positive; line number %d rejected"), l + 1); else @@ -1783,7 +1781,7 @@ s_errwarn (int err) { as_bad (_("%s argument must be a string"), err ? ".error" : ".warning"); - discard_rest_of_line (); + ignore_rest_of_line (); return; } @@ -1964,7 +1962,7 @@ s_globl (int ignore ATTRIBUTE_UNUSED) void s_irp (int irpc) { - char *file; + char *file, *eol; unsigned int line; sb s; const char *err; @@ -1973,8 +1971,9 @@ s_irp (int irpc) as_where (&file, &line); sb_new (&s); - while (!is_end_of_line[(unsigned char) *input_line_pointer]) - sb_add_char (&s, *input_line_pointer++); + eol = find_end_of_line (input_line_pointer, 0); + sb_add_buffer (&s, input_line_pointer, eol - input_line_pointer); + input_line_pointer = eol; sb_new (&out); @@ -2027,7 +2026,6 @@ s_linkonce (int ignore ATTRIBUTE_UNUSED) #ifdef obj_handle_link_once obj_handle_link_once (type); #else /* ! defined (obj_handle_link_once) */ -#ifdef BFD_ASSEMBLER { flagword flags; @@ -2057,9 +2055,6 @@ s_linkonce (int ignore ATTRIBUTE_UNUSED) as_bad (_("bfd_set_section_flags: %s"), bfd_errmsg (bfd_get_error ())); } -#else /* ! defined (BFD_ASSEMBLER) */ - as_warn (_(".linkonce is not supported for this object file format")); -#endif /* ! defined (BFD_ASSEMBLER) */ #endif /* ! defined (obj_handle_link_once) */ demand_empty_rest_of_line (); @@ -2082,11 +2077,9 @@ bss_alloc (symbolS *symbolP, addressT size, int align) { bss_seg = subseg_new (".sbss", 1); seg_info (bss_seg)->bss = 1; -#ifdef BFD_ASSEMBLER if (!bfd_set_section_flags (stdoutput, bss_seg, SEC_ALLOC)) as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ())); -#endif } } #endif @@ -2222,7 +2215,7 @@ s_lsym (int ignore ATTRIBUTE_UNUSED) if (name == p) { as_bad (_("expected symbol name")); - discard_rest_of_line (); + ignore_rest_of_line (); return; } @@ -2238,7 +2231,7 @@ s_lsym (int ignore ATTRIBUTE_UNUSED) } input_line_pointer++; - expression (&exp); + expression_and_evaluate (&exp); if (exp.X_op != O_constant && exp.X_op != O_register) @@ -2251,15 +2244,7 @@ s_lsym (int ignore ATTRIBUTE_UNUSED) *p = 0; symbolP = symbol_find_or_make (name); - /* FIXME-SOON I pulled a (&& symbolP->sy_other == 0 && - symbolP->sy_desc == 0) out of this test because coff doesn't have - those fields, and I can't see when they'd ever be tripped. I - don't think I understand why they were here so I may have - introduced a bug. As recently as 1.37 didn't have this test - anyway. xoxorich. */ - - if (S_GET_SEGMENT (symbolP) == undefined_section - && S_GET_VALUE (symbolP) == 0) + if (S_GET_SEGMENT (symbolP) == undefined_section) { /* The name might be an undefined .global symbol; be sure to keep the "external" bit. */ @@ -2284,8 +2269,7 @@ s_lsym (int ignore ATTRIBUTE_UNUSED) static int get_line_sb (sb *line) { - char quote1, quote2, inquote; - unsigned char c; + char *eol; if (input_line_pointer[-1] == '\n') bump_line_counters (); @@ -2297,45 +2281,16 @@ get_line_sb (sb *line) return 0; } - /* If app.c sets any other characters to LEX_IS_STRINGQUOTE, this - code needs to be changed. */ - if (!flag_m68k_mri) - quote1 = '"'; - else - quote1 = '\0'; - - quote2 = '\0'; - if (flag_m68k_mri) - quote2 = '\''; -#ifdef LEX_IS_STRINGQUOTE - quote2 = '\''; -#endif - - inquote = '\0'; - - while ((c = * input_line_pointer ++) != 0 - && (!is_end_of_line[c] - || (inquote != '\0' && c != '\n'))) - { - if (inquote == c) - inquote = '\0'; - else if (inquote == '\0') - { - if (c == quote1) - inquote = quote1; - else if (c == quote2) - inquote = quote2; - } - - sb_add_char (line, c); - } + eol = find_end_of_line (input_line_pointer, flag_m68k_mri); + sb_add_buffer (line, input_line_pointer, eol - input_line_pointer); + input_line_pointer = eol; /* Don't skip multiple end-of-line characters, because that breaks support for the IA-64 stop bit (;;) which looks like two consecutive end-of-line characters but isn't. Instead just skip one end of line character and return the character skipped so that the caller can re-insert it if necessary. */ - return c; + return *input_line_pointer++; } /* Define a macro. This is an interface to macro.c. */ @@ -2343,24 +2298,30 @@ get_line_sb (sb *line) void s_macro (int ignore ATTRIBUTE_UNUSED) { - char *file; + char *file, *eol; unsigned int line; sb s; - sb label; const char *err; const char *name; as_where (&file, &line); sb_new (&s); - while (!is_end_of_line[(unsigned char) *input_line_pointer]) - sb_add_char (&s, *input_line_pointer++); + eol = find_end_of_line (input_line_pointer, 0); + sb_add_buffer (&s, input_line_pointer, eol - input_line_pointer); + input_line_pointer = eol; - sb_new (&label); if (line_label != NULL) - sb_add_string (&label, S_GET_NAME (line_label)); + { + sb label; - err = define_macro (0, &s, &label, get_line_sb, file, line, &name); + sb_new (&label); + sb_add_string (&label, S_GET_NAME (line_label)); + err = define_macro (0, &s, &label, get_line_sb, file, line, &name); + sb_kill (&label); + } + else + err = define_macro (0, &s, NULL, get_line_sb, file, line, &name); if (err != NULL) as_bad_where (file, line, err, name); else @@ -2523,8 +2484,7 @@ s_org (int ignore ATTRIBUTE_UNUSED) called by the obj-format routine which handles section changing when in MRI mode. It will create a new section, and return it. It will set *TYPE to the section type: one of 'C' (code), 'D' (data), - 'M' (mixed), or 'R' (romable). If BFD_ASSEMBLER is defined, the - flags will be set in the section. */ + 'M' (mixed), or 'R' (romable). The flags will be set in the section. */ void s_mri_sect (char *type ATTRIBUTE_UNUSED) @@ -2578,7 +2538,6 @@ s_mri_sect (char *type ATTRIBUTE_UNUSED) as_bad (_("unrecognized section type")); ++input_line_pointer; -#ifdef BFD_ASSEMBLER { flagword flags; @@ -2597,7 +2556,6 @@ s_mri_sect (char *type ATTRIBUTE_UNUSED) bfd_errmsg (bfd_get_error ())); } } -#endif } /* Ignore the HP type. */ @@ -2798,7 +2756,7 @@ end_repeat (int extra) } static void -assign_symbol (char *name, int no_reassign) +assign_symbol (char *name, int mode) { symbolS *symbolP; @@ -2839,18 +2797,34 @@ assign_symbol (char *name, int no_reassign) #endif } - /* Permit register names to be redefined. */ - if (no_reassign - && S_IS_DEFINED (symbolP) - && S_GET_SEGMENT (symbolP) != reg_section) - as_bad (_("symbol `%s' is already defined"), name); + if (S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP)) + { + /* Permit register names to be redefined. */ + if ((mode != 0 || !S_IS_VOLATILE (symbolP)) + && S_GET_SEGMENT (symbolP) != reg_section) + { + as_bad (_("symbol `%s' is already defined"), name); + symbolP = symbol_clone (symbolP, 0); + } + /* If the symbol is volatile, copy the symbol and replace the + original with the copy, so that previous uses of the symbol will + retain the value of the symbol at the point of use. */ + else if (S_IS_VOLATILE (symbolP)) + symbolP = symbol_clone (symbolP, 1); + } + + if (mode == 0) + S_SET_VOLATILE (symbolP); + else if (mode < 0) + S_SET_FORWARD_REF (symbolP); pseudo_set (symbolP); } -/* Handle the .equ, .equiv and .set directives. If EQUIV is 1, then - this is .equiv, and it is an error if the symbol is already - defined. */ +/* Handle the .equ, .equiv, .eqv, and .set directives. If EQUIV is 1, + then this is .equiv, and it is an error if the symbol is already + defined. If EQUIV is -1, the symbol additionally is a forward + reference. */ void s_set (int equiv) @@ -2870,7 +2844,7 @@ s_set (int equiv) if (name == end_name) { as_bad (_("expected symbol name")); - discard_rest_of_line (); + ignore_rest_of_line (); return; } @@ -2972,6 +2946,7 @@ s_space (int mult) || val.X_add_number > 0xff || (mult != 0 && mult != 1 && val.X_add_number != 0)) { + resolve_expression (&exp); if (exp.X_op != O_constant) as_bad (_("unsupported variable size or fill value")); else @@ -2987,6 +2962,9 @@ s_space (int mult) } else { + if (now_seg == absolute_section || mri_common_symbol != NULL) + resolve_expression (&exp); + if (exp.X_op == O_constant) { long repeat; @@ -3173,6 +3151,137 @@ s_text (int ignore ATTRIBUTE_UNUSED) const_flag &= ~IN_DEFAULT_SECTION; #endif } + +/* .weakref x, y sets x as an alias to y that, as long as y is not + referenced directly, will cause y to become a weak symbol. */ +void +s_weakref (int ignore ATTRIBUTE_UNUSED) +{ + char *name; + char delim; + char *end_name; + symbolS *symbolP; + symbolS *symbolP2; + expressionS exp; + + name = input_line_pointer; + delim = get_symbol_end (); + end_name = input_line_pointer; + + if (name == end_name) + { + as_bad (_("expected symbol name")); + *end_name = delim; + ignore_rest_of_line (); + return; + } + + symbolP = symbol_find_or_make (name); + + if (S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP)) + { + if (!S_IS_VOLATILE (symbolP)) + { + as_bad (_("symbol `%s' is already defined"), name); + *end_name = delim; + ignore_rest_of_line (); + return; + } + symbolP = symbol_clone (symbolP, 1); + S_CLEAR_VOLATILE (symbolP); + } + + *end_name = delim; + + SKIP_WHITESPACE (); + + if (*input_line_pointer != ',') + { + *end_name = 0; + as_bad (_("expected comma after \"%s\""), name); + *end_name = delim; + ignore_rest_of_line (); + return; + } + + input_line_pointer++; + + SKIP_WHITESPACE (); + + name = input_line_pointer; + delim = get_symbol_end (); + end_name = input_line_pointer; + + if (name == end_name) + { + as_bad (_("expected symbol name")); + ignore_rest_of_line (); + return; + } + + if ((symbolP2 = symbol_find_noref (name, 1)) == NULL + && (symbolP2 = md_undefined_symbol (name)) == NULL) + { + symbolP2 = symbol_find_or_make (name); + S_SET_WEAKREFD (symbolP2); + } + else + { + symbolS *symp = symbolP2; + + while (S_IS_WEAKREFR (symp) && symp != symbolP) + { + expressionS *expP = symbol_get_value_expression (symp); + + assert (expP->X_op == O_symbol + && expP->X_add_number == 0); + symp = expP->X_add_symbol; + } + if (symp == symbolP) + { + char *loop; + + loop = concat (S_GET_NAME (symbolP), + " => ", S_GET_NAME (symbolP2), NULL); + + symp = symbolP2; + while (symp != symbolP) + { + char *old_loop = loop; + symp = symbol_get_value_expression (symp)->X_add_symbol; + loop = concat (loop, " => ", S_GET_NAME (symp), NULL); + free (old_loop); + } + + as_bad (_("%s: would close weakref loop: %s"), + S_GET_NAME (symbolP), loop); + + free (loop); + + *end_name = delim; + ignore_rest_of_line (); + return; + } + + /* Short-circuiting instead of just checking here might speed + things up a tiny little bit, but loop error messages would + miss intermediate links. */ + /* symbolP2 = symp; */ + } + + *end_name = delim; + + memset (&exp, 0, sizeof (exp)); + exp.X_op = O_symbol; + exp.X_add_symbol = symbolP2; + + S_SET_SEGMENT (symbolP, undefined_section); + symbol_set_value_expression (symbolP, &exp); + symbol_set_frag (symbolP, &zero_address_frag); + S_SET_WEAKREFR (symbolP); + + demand_empty_rest_of_line (); +} /* Verify that we are at the end of a line. If not, issue an error and @@ -3215,19 +3324,6 @@ ignore_rest_of_line (void) know (is_end_of_line[(unsigned char) input_line_pointer[-1]]); } -void -discard_rest_of_line (void) -{ - while (input_line_pointer < buffer_limit - && !is_end_of_line[(unsigned char) *input_line_pointer]) - input_line_pointer++; - - input_line_pointer++; - - /* Return pointing just after end-of-line. */ - know (is_end_of_line[(unsigned char) input_line_pointer[-1]]); -} - /* Sets frag for given symbol to zero_address_frag, except when the symbol frag is already set to a dummy listing frag. */ @@ -3250,13 +3346,13 @@ pseudo_set (symbolS *symbolP) { expressionS exp; segT seg; -#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER) - int ext; -#endif /* OBJ_AOUT or OBJ_BOUT */ know (symbolP); /* NULL pointer is logic error. */ - (void) expression (&exp); + if (!S_IS_FORWARD_REF (symbolP)) + (void) expression (&exp); + else + (void) deferred_expression (&exp); if (exp.X_op == O_illegal) as_bad (_("illegal expression")); @@ -3270,6 +3366,7 @@ pseudo_set (symbolS *symbolP) as_bad (_("floating point number invalid")); } else if (exp.X_op == O_subtract + && !S_IS_FORWARD_REF (symbolP) && SEG_NORMAL (S_GET_SEGMENT (exp.X_add_symbol)) && (symbol_get_frag (exp.X_add_symbol) == symbol_get_frag (exp.X_op_symbol))) @@ -3284,9 +3381,6 @@ pseudo_set (symbolS *symbolP) as_bad ("attempt to set value of section symbol"); return; } -#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER) - ext = S_IS_EXTERNAL (symbolP); -#endif /* OBJ_AOUT or OBJ_BOUT */ switch (exp.X_op) { @@ -3319,7 +3413,7 @@ pseudo_set (symbolS *symbolP) *symbol_X_add_number (symbolP) += exp.X_add_number; break; } - else if (seg != undefined_section) + else if (!S_IS_FORWARD_REF (symbolP) && seg != undefined_section) { symbolS *s = exp.X_add_symbol; @@ -3333,23 +3427,18 @@ pseudo_set (symbolS *symbolP) copy_symbol_attributes (symbolP, s); break; } - /* Fall thru */ + S_SET_SEGMENT (symbolP, undefined_section); + symbol_set_value_expression (symbolP, &exp); + set_zero_frag (symbolP); + break; default: - /* The value is some complex expression. - Set segment and frag back to that of a newly created symbol. */ - S_SET_SEGMENT (symbolP, undefined_section); + /* The value is some complex expression. */ + S_SET_SEGMENT (symbolP, expr_section); symbol_set_value_expression (symbolP, &exp); set_zero_frag (symbolP); break; } - -#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER) - if (ext) - S_SET_EXTERNAL (symbolP); - else - S_CLEAR_EXTERNAL (symbolP); -#endif /* OBJ_AOUT or OBJ_BOUT */ } /* cons() @@ -3769,16 +3858,8 @@ emit_expr (expressionS *exp, unsigned int nbytes) { memset (p, 0, nbytes); - /* Now we need to generate a fixS to record the symbol value. - This is easy for BFD. For other targets it can be more - complex. For very complex cases (currently, the HPPA and - NS32K), you can define TC_CONS_FIX_NEW to do whatever you - want. For simpler cases, you can define TC_CONS_RELOC to be - the name of the reloc code that should be stored in the fixS. - If neither is defined, the code uses NO_RELOC if it is - defined, and otherwise uses 0. */ + /* Now we need to generate a fixS to record the symbol value. */ -#ifdef BFD_ASSEMBLER #ifdef TC_CONS_FIX_NEW TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp); #else @@ -3808,24 +3889,6 @@ emit_expr (expressionS *exp, unsigned int nbytes) 0, r); } #endif -#else -#ifdef TC_CONS_FIX_NEW - TC_CONS_FIX_NEW (frag_now, p - frag_now->fr_literal, nbytes, exp); -#else - /* Figure out which reloc number to use. Use TC_CONS_RELOC if - it is defined, otherwise use NO_RELOC if it is defined, - otherwise use 0. */ -#ifndef TC_CONS_RELOC -#ifdef NO_RELOC -#define TC_CONS_RELOC NO_RELOC -#else -#define TC_CONS_RELOC 0 -#endif -#endif - fix_new_exp (frag_now, p - frag_now->fr_literal, (int) nbytes, exp, 0, - TC_CONS_RELOC); -#endif /* TC_CONS_FIX_NEW */ -#endif /* BFD_ASSEMBLER */ } } @@ -4943,6 +5006,8 @@ equals (char *sym_name, int reassign) input_line_pointer++; if (*input_line_pointer == '=') input_line_pointer++; + if (reassign < 0 && *input_line_pointer == '=') + input_line_pointer++; while (*input_line_pointer == ' ' || *input_line_pointer == '\t') input_line_pointer++; @@ -4950,7 +5015,7 @@ equals (char *sym_name, int reassign) if (flag_mri) stop = mri_comment_field (&stopc); - assign_symbol (sym_name, !reassign); + assign_symbol (sym_name, reassign >= 0 ? !reassign : reassign); if (flag_mri) { @@ -5256,10 +5321,7 @@ do_s_func (int end_p, const char *default_prefix) asprintf (&label, "%s%s", default_prefix, name); else { - char leading_char = 0; -#ifdef BFD_ASSEMBLER - leading_char = bfd_get_symbol_leading_char (stdoutput); -#endif + char leading_char = bfd_get_symbol_leading_char (stdoutput); /* Missing entry point, use function's name with the leading char prepended. */ if (leading_char) @@ -5291,11 +5353,7 @@ do_s_func (int end_p, const char *default_prefix) void s_ignore (int arg ATTRIBUTE_UNUSED) { - while (!is_end_of_line[(unsigned char) *input_line_pointer]) - { - ++input_line_pointer; - } - ++input_line_pointer; + ignore_rest_of_line (); } void @@ -5333,3 +5391,51 @@ input_scrub_insert_file (char *path) input_scrub_include_file (path, input_line_pointer); buffer_limit = input_scrub_next_buffer (&input_line_pointer); } + +/* Find the end of a line, considering quotation and escaping of quotes. */ + +#if !defined(TC_SINGLE_QUOTE_STRINGS) && defined(SINGLE_QUOTE_STRINGS) +# define TC_SINGLE_QUOTE_STRINGS 1 +#endif + +static char * +_find_end_of_line (char *s, int mri_string, int insn ATTRIBUTE_UNUSED) +{ + char inquote = '\0'; + int inescape = 0; + + while (!is_end_of_line[(unsigned char) *s] + || (inquote && !ISCNTRL (*s)) + || (inquote == '\'' && flag_mri) +#ifdef TC_EOL_IN_INSN + || (insn && TC_EOL_IN_INSN (s)) +#endif + ) + { + if (mri_string && *s == '\'') + inquote ^= *s; + else if (inescape) + inescape = 0; + else if (*s == '\\') + inescape = 1; + else if (!inquote + ? *s == '"' +#ifdef TC_SINGLE_QUOTE_STRINGS + || (TC_SINGLE_QUOTE_STRINGS && *s == '\'') +#endif + : *s == inquote) + inquote ^= *s; + ++s; + } + if (inquote) + as_warn (_("missing closing `%c'"), inquote); + if (inescape) + as_warn (_("stray `\\'")); + return s; +} + +char * +find_end_of_line (char *s, int mri_string) +{ + return _find_end_of_line (s, mri_string, 0); +}