X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fread.c;h=2ea5e2b61210642d4e132f40acfb9154ce57074d;hb=5bd987222faa869dc0524071f9694c41688d1ece;hp=0716a5fb2d4ac2c6febeacec62f5ca9c53e7f0dd;hpb=d341ae3fefdd4fbd7a02a81ab6d7bb06f68e2517;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/read.c b/gas/read.c index 0716a5fb2d..2ea5e2b612 100644 --- a/gas/read.c +++ b/gas/read.c @@ -1,6 +1,6 @@ /* read.c - read a source file - - Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 96, 97, 1998 - Free Software Foundation, Inc. + Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 2000 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -53,6 +53,21 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #define TC_START_LABEL(x,y) (x==':') #endif +/* Set by the object-format or the target. */ +#ifndef TC_IMPLICIT_LCOMM_ALIGNMENT +#define TC_IMPLICIT_LCOMM_ALIGNMENT(SIZE, P2VAR) \ + do { \ + if ((SIZE) >= 8) \ + (P2VAR) = 3; \ + else if ((SIZE) >= 4) \ + (P2VAR) = 2; \ + else if ((SIZE) >= 2) \ + (P2VAR) = 1; \ + else \ + (P2VAR) = 0; \ + } while (0) +#endif + /* The NOP_OPCODE is for the alignment fill value. * fill it a nop instruction so that the disassembler does not choke * on it @@ -89,6 +104,12 @@ die horribly; #define LEX_QM 0 #endif +#ifndef LEX_HASH +/* The IA-64 assembler uses # as a suffix designating a symbol. We include + it in the symbol and strip it out in tc_canonicalize_symbol_name. */ +#define LEX_HASH 0 +#endif + #ifndef LEX_DOLLAR /* The a29k assembler does not permits labels to start with $. */ #define LEX_DOLLAR 3 @@ -104,19 +125,20 @@ char lex_type[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */ - 0, 0, 0, 0, LEX_DOLLAR, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */ + 0, 0, 0, LEX_HASH, LEX_DOLLAR, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, LEX_QM, /* 0123456789:;<=>? */ LEX_AT, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, 0, 3, /* PQRSTUVWXYZ[\]^_ */ 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, LEX_TILDE, 0, /* pqrstuvwxyz{|}~. */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; @@ -124,33 +146,33 @@ char lex_type[256] = * In: a character. * Out: 1 if this character ends a line. */ -#define _ (0) +#define Z_ (0) char is_end_of_line[256] = { #ifdef CR_EOL - 99, _, _, _, _, _, _, _, _, _, 99, _, _, 99, _, _, /* @abcdefghijklmno */ + 99, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, 99, Z_, Z_, 99, Z_, Z_, /* @abcdefghijklmno */ #else - 99, _, _, _, _, _, _, _, _, _, 99, _, _, _, _, _, /* @abcdefghijklmno */ + 99, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, 99, Z_, Z_, Z_, Z_, Z_, /* @abcdefghijklmno */ #endif - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ + Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ #ifdef TC_HPPA - _,99, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* _!"#$%&'()*+,-./ */ - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0123456789:;<=>? */ + Z_,99, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* _!"#$%&'()*+,-./ */ + Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* 0123456789:;<=>? */ #else - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ - _, _, _, _, _, _, _, _, _, _, _, 99, _, _, _, _, /* 0123456789:;<=>? */ + Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ + Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, 99, Z_, Z_, Z_, Z_, /* 0123456789:;<=>? */ #endif - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ - _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */ + Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ + Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ + Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ + Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ + Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ + Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ + Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ + Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ + Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, Z_, /* */ }; -#undef _ +#undef Z_ /* Functions private to this file. */ @@ -207,16 +229,25 @@ static int dwarf_file_string; #endif static void cons_worker PARAMS ((int, int)); -static int scrub_from_string PARAMS ((char **)); +static int scrub_from_string PARAMS ((char *, int)); static void do_align PARAMS ((int, char *, int, int)); static void s_align PARAMS ((int, int)); +static void s_lcomm_internal PARAMS ((int, int)); static int hex_float PARAMS ((int, char *)); +static inline int sizeof_sleb128 PARAMS ((offsetT)); +static inline int sizeof_uleb128 PARAMS ((valueT)); +static inline int output_sleb128 PARAMS ((char *, offsetT)); +static inline int output_uleb128 PARAMS ((char *, valueT)); +static inline int output_big_sleb128 PARAMS ((char *, LITTLENUM_TYPE *, int)); +static inline int output_big_uleb128 PARAMS ((char *, LITTLENUM_TYPE *, int)); +static int output_big_leb128 PARAMS ((char *, LITTLENUM_TYPE *, int, int)); static void do_org PARAMS ((segT, expressionS *, int)); char *demand_copy_string PARAMS ((int *lenP)); static segT get_segmented_expression PARAMS ((expressionS *expP)); static segT get_known_segmented_expression PARAMS ((expressionS * expP)); static void pobegin PARAMS ((void)); static int get_line_sb PARAMS ((sb *)); +static void generate_file_debug PARAMS ((void)); void @@ -292,8 +323,10 @@ static const pseudo_typeS potable[] = {"eject", listing_eject, 0}, /* Formfeed listing */ {"else", s_else, 0}, {"elsec", s_else, 0}, + {"elseif", s_elseif, (int) O_ne}, {"end", s_end, 0}, {"endc", s_endif, 0}, + {"endfunc", s_func, 1}, {"endif", s_endif, 0}, /* endef */ {"equ", s_set, 0}, @@ -309,6 +342,7 @@ static const pseudo_typeS potable[] = {"fill", s_fill, 0}, {"float", float_cons, 'f'}, {"format", s_ignore, 0}, + {"func", s_func, 0}, {"global", s_globl, 0}, {"globl", s_globl, 0}, {"hword", cons, 2}, @@ -403,7 +437,7 @@ static const pseudo_typeS potable[] = {"xstabs", s_xstab, 's'}, {"word", cons, 2}, {"zero", s_space, 0}, - {NULL} /* end sentinel */ + {NULL, NULL, 0} /* end sentinel */ }; static int pop_override_ok = 0; @@ -419,7 +453,7 @@ pop_insert (table) { errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop); if (errtxt && (!pop_override_ok || strcmp (errtxt, "exists"))) - as_fatal ("error constructing %s pseudo-op table: %s", pop_table_name, + as_fatal (_("error constructing %s pseudo-op table: %s"), pop_table_name, errtxt); } } @@ -468,15 +502,18 @@ static char *scrub_string; static char *scrub_string_end; static int -scrub_from_string (from) - char **from; +scrub_from_string (buf, buflen) + char *buf; + int buflen; { - int size; - - *from = scrub_string; - size = scrub_string_end - scrub_string; - scrub_string = scrub_string_end; - return size; + int copy; + + copy = scrub_string_end - scrub_string; + if (copy > buflen) + copy = buflen; + memcpy (buf, scrub_string, copy); + scrub_string += copy; + return copy; } /* read_a_source_file() @@ -499,6 +536,11 @@ read_a_source_file (name) listing_newline (NULL); register_dependency (name); + /* Generate debugging information before we've read anything in to denote + this file as the "main" source file and not a subordinate one + (e.g. N_SO vs N_SOL in stabs). */ + generate_file_debug (); + while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0) { /* We have another line to parse. */ know (buffer_limit[-1] == '\n'); /* Must have a sentinel. */ @@ -525,11 +567,7 @@ read_a_source_file (name) line_label = NULL; - if (flag_m68k_mri -#ifdef LABELS_WITHOUT_COLONS - || 1 -#endif - ) + if (LABELS_WITHOUT_COLONS || flag_m68k_mri) { /* Text at the start of a line must be a label, we run down and stick a colon in. */ @@ -574,7 +612,12 @@ read_a_source_file (name) /* In MRI mode, we need to handle the MACRO pseudo-op specially: we don't want to put the symbol in the symbol table. */ - if (! mri_line_macro) + if (! mri_line_macro +#ifdef TC_START_LABEL_WITHOUT_COLON + && TC_START_LABEL_WITHOUT_COLON(c, + input_line_pointer) +#endif + ) line_label = colon (line_start); else line_label = symbol_create (line_start, @@ -712,18 +755,14 @@ read_a_source_file (name) char *s2 = s; while (*s2) { - if (isupper (*s2)) + if (isupper ((unsigned char) *s2)) *s2 = tolower (*s2); s2++; } } #endif - if (flag_m68k_mri -#ifdef NO_PSEUDO_DOT - || 1 -#endif - ) + if (NO_PSEUDO_DOT || flag_m68k_mri) { /* The MRI assembler and the m88k use pseudo-ops without a period. */ @@ -771,7 +810,7 @@ read_a_source_file (name) mri_pending_align = 0; if (line_label != NULL) { - line_label->sy_frag = frag_now; + symbol_set_frag (line_label, frag_now); S_SET_VALUE (line_label, frag_now_fix ()); } } @@ -779,7 +818,7 @@ read_a_source_file (name) /* Print the error msg now, while we still can */ if (pop == NULL) { - as_bad ("Unknown pseudo-op: `%s'", s); + as_bad (_("Unknown pseudo-op: `%s'"), s); *input_line_pointer = c; s_ignore (0); continue; @@ -806,6 +845,9 @@ read_a_source_file (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. */ @@ -819,52 +861,41 @@ read_a_source_file (name) { 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++; } c = *input_line_pointer; *input_line_pointer = '\0'; - if (debug_type == DEBUG_STABS) - stabs_generate_asm_lineno (); - -#ifdef OBJ_GENERATE_ASM_LINENO -#ifdef ECOFF_DEBUGGING - /* ECOFF assemblers automatically generate - debugging information. FIXME: This should - probably be handled elsewhere. */ - if (debug_type == DEBUG_NONE) - { - if (ecoff_no_current_file ()) - debug_type = DEBUG_ECOFF; - } - - if (debug_type == DEBUG_ECOFF) - { - unsigned int lineno; - char *s; - - as_where (&s, &lineno); - OBJ_GENERATE_ASM_LINENO (s, lineno); - } -#endif -#endif + generate_lineno_debug (); if (macro_defined) { sb out; const char *err; + macro_entry *macro; - if (check_macro (s, &out, '\0', &err)) + if (check_macro (s, &out, '\0', &err, ¯o)) { if (err != NULL) - as_bad (err); + as_bad ("%s", err); *input_line_pointer++ = c; input_scrub_include_sb (&out, - input_line_pointer); + input_line_pointer, 1); sb_kill (&out); buffer_limit = input_scrub_next_buffer (&input_line_pointer); +#ifdef md_macro_info + md_macro_info (macro); +#endif continue; } } @@ -875,7 +906,7 @@ read_a_source_file (name) mri_pending_align = 0; if (line_label != NULL) { - line_label->sy_frag = frag_now; + symbol_set_frag (line_label, frag_now); S_SET_VALUE (line_label, frag_now_fix ()); } } @@ -897,7 +928,7 @@ read_a_source_file (name) continue; if ((LOCAL_LABELS_DOLLAR || LOCAL_LABELS_FB) - && isdigit (c)) + && isdigit ((unsigned char) c)) { /* local label ("4:") */ char *backup = input_line_pointer; @@ -906,7 +937,7 @@ read_a_source_file (name) temp = c - '0'; - while (isdigit (*input_line_pointer)) + while (isdigit ((unsigned char) *input_line_pointer)) { temp = (temp * 10) + *input_line_pointer - '0'; ++input_line_pointer; @@ -920,7 +951,7 @@ read_a_source_file (name) if (dollar_label_defined (temp)) { - as_fatal ("label \"%d$\" redefined", temp); + as_fatal (_("label \"%d$\" redefined"), temp); } define_dollar_label (temp); @@ -1135,9 +1166,9 @@ mri_comment_end (stop, stopc) void s_abort (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { - as_fatal (".abort detected. Abandoning ship."); + as_fatal (_(".abort detected. Abandoning ship.")); } /* Guts of .align directive. N is the power of two to which to align. @@ -1161,21 +1192,7 @@ do_align (n, fill, len, max) if (fill == NULL) { - int maybe_text; - -#ifdef BFD_ASSEMBLER - if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0) - maybe_text = 1; - else - maybe_text = 0; -#else - if (now_seg != data_section && now_seg != bss_section) - maybe_text = 1; - else - maybe_text = 0; -#endif - - if (maybe_text) + if (subseg_text_p (now_seg)) default_fill = NOP_OPCODE; else default_fill = 0; @@ -1196,7 +1213,7 @@ do_align (n, fill, len, max) just_record_alignment: #endif - record_alignment (now_seg, n); + record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER); } /* Handle the .align pseudo-op. A positive ARG is a default alignment @@ -1242,7 +1259,7 @@ s_align (arg, bytes_p) for (i = 0; (align & 1) == 0; align >>= 1, ++i) ; if (align != 1) - as_bad ("Alignment not a power of 2"); + as_bad (_("Alignment not a power of 2")); align = i; } } @@ -1250,7 +1267,7 @@ s_align (arg, bytes_p) if (align > 15) { align = 15; - as_bad ("Alignment too large: %u assumed", align); + as_bad (_("Alignment too large: %u assumed"), align); } if (*input_line_pointer != ',') @@ -1282,7 +1299,7 @@ s_align (arg, bytes_p) if (! fill_p) { if (arg < 0) - as_warn ("expected fill pattern missing"); + as_warn (_("expected fill pattern missing")); do_align (align, (char *) NULL, 0, max); } else @@ -1304,17 +1321,17 @@ s_align (arg, bytes_p) { char ab[16]; - if (fill_len > sizeof ab) + if ((size_t) fill_len > sizeof ab) abort (); md_number_to_chars (ab, fill, fill_len); do_align (align, ab, fill_len, max); } } + demand_empty_rest_of_line (); + if (flag_mri) mri_comment_end (stop, stopc); - - demand_empty_rest_of_line (); } /* Handle the .align pseudo-op on machines where ".align 4" means @@ -1339,7 +1356,7 @@ s_align_ptwo (arg) void s_comm (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { register char *name; register char c; @@ -1360,19 +1377,19 @@ s_comm (ignore) SKIP_WHITESPACE (); if (*input_line_pointer != ',') { - as_bad ("Expected comma after symbol-name: rest of line ignored."); + as_bad (_("Expected comma after symbol-name: rest of line ignored.")); + ignore_rest_of_line (); if (flag_mri) mri_comment_end (stop, stopc); - ignore_rest_of_line (); return; } input_line_pointer++; /* skip ',' */ if ((temp = get_absolute_expression ()) < 0) { - as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp); + as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp); + ignore_rest_of_line (); if (flag_mri) mri_comment_end (stop, stopc); - ignore_rest_of_line (); return; } *p = 0; @@ -1380,17 +1397,17 @@ s_comm (ignore) *p = c; if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP)) { - as_bad ("Ignoring attempt to re-define symbol `%s'.", + as_bad (_("Ignoring attempt to re-define symbol `%s'."), S_GET_NAME (symbolP)); + ignore_rest_of_line (); if (flag_mri) mri_comment_end (stop, stopc); - ignore_rest_of_line (); return; } if (S_GET_VALUE (symbolP)) { if (S_GET_VALUE (symbolP) != (valueT) temp) - as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.", + as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."), S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), (long) temp); @@ -1409,10 +1426,10 @@ s_comm (ignore) #endif /* not OBJ_VMS */ know (symbolP->sy_frag == &zero_address_frag); + demand_empty_rest_of_line (); + if (flag_mri) mri_comment_end (stop, stopc); - - demand_empty_rest_of_line (); } /* s_comm() */ /* The MRI COMMON pseudo-op. We handle this by creating a common @@ -1421,7 +1438,7 @@ s_comm (ignore) void s_mri_common (small) - int small; + int small ATTRIBUTE_UNUSED; { char *name; char c; @@ -1479,9 +1496,9 @@ s_mri_common (small) if (S_IS_DEFINED (sym) && ! S_IS_COMMON (sym)) { - as_bad ("attempt to re-define symbol `%s'", S_GET_NAME (sym)); - mri_comment_end (stop, stopc); + as_bad (_("attempt to re-define symbol `%s'"), S_GET_NAME (sym)); ignore_rest_of_line (); + mri_comment_end (stop, stopc); return; } @@ -1495,10 +1512,12 @@ s_mri_common (small) if (line_label != NULL) { - line_label->sy_value.X_op = O_symbol; - line_label->sy_value.X_add_symbol = sym; - line_label->sy_value.X_add_number = S_GET_VALUE (sym); - line_label->sy_frag = &zero_address_frag; + expressionS exp; + exp.X_op = O_symbol; + exp.X_add_symbol = sym; + exp.X_add_number = 0; + symbol_set_value_expression (line_label, &exp); + symbol_set_frag (line_label, &zero_address_frag); S_SET_SEGMENT (line_label, expr_section); } @@ -1511,14 +1530,14 @@ s_mri_common (small) if (*input_line_pointer == ',') input_line_pointer += 2; - mri_comment_end (stop, stopc); - demand_empty_rest_of_line (); + + mri_comment_end (stop, stopc); } void s_data (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { segT section; register int temp; @@ -1592,7 +1611,7 @@ s_app_file (appfile) void s_app_line (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { int l; @@ -1601,7 +1620,7 @@ s_app_line (ignore) if (l < 0) /* Some of the back ends can't deal with non-positive line numbers. Besides, it's silly. */ - as_warn ("Line numbers must be positive; line number %d rejected.", l+1); + as_warn (_("Line numbers must be positive; line number %d rejected."), l+1); else { new_logical_line ((char *) NULL, l); @@ -1618,7 +1637,7 @@ s_app_line (ignore) void s_end (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { if (flag_mri) { @@ -1628,7 +1647,7 @@ s_end (ignore) if (! is_end_of_line[(unsigned char) *input_line_pointer] && *input_line_pointer != '*' && *input_line_pointer != '!') - as_warn ("start address not supported"); + as_warn (_("start address not supported")); } } @@ -1636,9 +1655,9 @@ s_end (ignore) void s_err (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { - as_bad (".err encountered"); + as_bad (_(".err encountered")); demand_empty_rest_of_line (); } @@ -1646,7 +1665,7 @@ s_err (ignore) void s_fail (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { offsetT temp; char *stop = NULL; @@ -1657,75 +1676,105 @@ s_fail (ignore) temp = get_absolute_expression (); if (temp >= 500) - as_warn (".fail %ld encountered", (long) temp); + as_warn (_(".fail %ld encountered"), (long) temp); else - as_bad (".fail %ld encountered", (long) temp); + as_bad (_(".fail %ld encountered"), (long) temp); + + demand_empty_rest_of_line (); if (flag_mri) mri_comment_end (stop, stopc); - - demand_empty_rest_of_line (); } void s_fill (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { - long temp_repeat = 0; - long temp_size = 1; - register long temp_fill = 0; + expressionS rep_exp; + long size = 1; + register long fill = 0; char *p; #ifdef md_flush_pending_output md_flush_pending_output (); #endif - temp_repeat = get_absolute_expression (); + get_known_segmented_expression (&rep_exp); if (*input_line_pointer == ',') { input_line_pointer++; - temp_size = get_absolute_expression (); + size = get_absolute_expression (); if (*input_line_pointer == ',') { input_line_pointer++; - temp_fill = get_absolute_expression (); + fill = get_absolute_expression (); } } + /* This is to be compatible with BSD 4.2 AS, not for any rational reason. */ #define BSD_FILL_SIZE_CROCK_8 (8) - if (temp_size > BSD_FILL_SIZE_CROCK_8) + if (size > BSD_FILL_SIZE_CROCK_8) { - as_warn (".fill size clamped to %d.", BSD_FILL_SIZE_CROCK_8); - temp_size = BSD_FILL_SIZE_CROCK_8; + as_warn (_(".fill size clamped to %d."), BSD_FILL_SIZE_CROCK_8); + size = BSD_FILL_SIZE_CROCK_8; } - if (temp_size < 0) + if (size < 0) { - as_warn ("Size negative: .fill ignored."); - temp_size = 0; + as_warn (_("Size negative: .fill ignored.")); + size = 0; } - else if (temp_repeat <= 0) + else if (rep_exp.X_op == O_constant && rep_exp.X_add_number <= 0) { - if (temp_repeat < 0) - as_warn ("Repeat < 0, .fill ignored"); - temp_size = 0; + if (rep_exp.X_add_number < 0) + as_warn (_("Repeat < 0, .fill ignored")); + size = 0; } - if (temp_size && !need_pass_2) + if (size && !need_pass_2) { - p = frag_var (rs_fill, (int) temp_size, (int) temp_size, - (relax_substateT) 0, (symbolS *) 0, (offsetT) temp_repeat, - (char *) 0); - memset (p, 0, (unsigned int) temp_size); + if (rep_exp.X_op == O_constant) + { + p = frag_var (rs_fill, (int) size, (int) size, + (relax_substateT) 0, (symbolS *) 0, + (offsetT) rep_exp.X_add_number, + (char *) 0); + } + else + { + /* We don't have a constant repeat count, so we can't use + rs_fill. We can get the same results out of rs_space, + but its argument is in bytes, so we must multiply the + repeat count by size. */ + + symbolS *rep_sym; + rep_sym = make_expr_symbol (&rep_exp); + if (size != 1) + { + expressionS size_exp; + size_exp.X_op = O_constant; + size_exp.X_add_number = size; + + rep_exp.X_op = O_multiply; + rep_exp.X_add_symbol = rep_sym; + rep_exp.X_op_symbol = make_expr_symbol (&size_exp); + rep_exp.X_add_number = 0; + rep_sym = make_expr_symbol (&rep_exp); + } + + p = frag_var (rs_space, (int) size, (int) size, + (relax_substateT) 0, rep_sym, (offsetT) 0, (char *) 0); + } + memset (p, 0, (unsigned int) size); /* The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX * flavoured AS. The following bizzare behaviour is to be * compatible with above. I guess they tried to take up to 8 * bytes from a 4-byte expression and they forgot to sign * extend. Un*x Sux. */ #define BSD_FILL_SIZE_CROCK_4 (4) - md_number_to_chars (p, (valueT) temp_fill, - (temp_size > BSD_FILL_SIZE_CROCK_4 + md_number_to_chars (p, (valueT) fill, + (size > BSD_FILL_SIZE_CROCK_4 ? BSD_FILL_SIZE_CROCK_4 - : (int) temp_size)); + : (int) size)); /* Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes) * but emits no error message because it seems a legal thing to do. * It is a degenerate case of .fill but could be emitted by a compiler. @@ -1736,7 +1785,7 @@ s_fill (ignore) void s_globl (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { char *name; int c; @@ -1752,9 +1801,11 @@ s_globl (ignore) name = input_line_pointer; c = get_symbol_end (); symbolP = symbol_find_or_make (name); + S_SET_EXTERNAL (symbolP); + *input_line_pointer = c; SKIP_WHITESPACE (); - S_SET_EXTERNAL (symbolP); + c = *input_line_pointer; if (c == ',') { input_line_pointer++; @@ -1765,10 +1816,10 @@ s_globl (ignore) } while (c == ','); + demand_empty_rest_of_line (); + if (flag_mri) mri_comment_end (stop, stopc); - - demand_empty_rest_of_line (); } /* Handle the MRI IRP and IRPC pseudo-ops. */ @@ -1797,7 +1848,7 @@ s_irp (irpc) sb_kill (&s); - input_scrub_include_sb (&out, input_line_pointer); + input_scrub_include_sb (&out, input_line_pointer, 1); sb_kill (&out); buffer_limit = input_scrub_next_buffer (&input_line_pointer); } @@ -1809,7 +1860,7 @@ s_irp (irpc) void s_linkonce (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { enum linkonce_type type; @@ -1833,7 +1884,7 @@ s_linkonce (ignore) else if (strcasecmp (s, "same_contents") == 0) type = LINKONCE_SAME_CONTENTS; else - as_warn ("unrecognized .linkonce type `%s'", s); + as_warn (_("unrecognized .linkonce type `%s'"), s); *input_line_pointer = c; } @@ -1846,7 +1897,7 @@ s_linkonce (ignore) flagword flags; if ((bfd_applicable_section_flags (stdoutput) & SEC_LINK_ONCE) == 0) - as_warn (".linkonce is not supported for this object file format"); + as_warn (_(".linkonce is not supported for this object file format")); flags = bfd_get_section_flags (stdoutput, now_seg); flags |= SEC_LINK_ONCE; @@ -1868,11 +1919,11 @@ s_linkonce (ignore) break; } if (! bfd_set_section_flags (stdoutput, now_seg, flags)) - as_bad ("bfd_set_section_flags: %s", + 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"); + as_warn (_(".linkonce is not supported for this object file format")); #endif /* ! defined (BFD_ASSEMBLER) */ #endif /* ! defined (obj_handle_link_once) */ @@ -1915,13 +1966,13 @@ s_lcomm_internal (needs_align, bytes_p) if (*input_line_pointer == '\n') { - as_bad ("Missing size expression"); + as_bad (_("Missing size expression")); return; } if ((temp = get_absolute_expression ()) < 0) { - as_warn ("BSS length (%d.) <0! Ignored.", temp); + as_warn (_("BSS length (%d.) <0! Ignored."), temp); ignore_rest_of_line (); return; } @@ -1937,30 +1988,20 @@ s_lcomm_internal (needs_align, bytes_p) 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", + as_warn (_("error setting flags for \".sbss\": %s"), bfd_errmsg (bfd_get_error ())); #endif } } #endif + if (!needs_align) { - /* FIXME. This needs to be machine independent. */ - if (temp >= 8) - align = 3; - else if (temp >= 4) - align = 2; - else if (temp >= 2) - align = 1; - else - align = 0; - -#ifdef OBJ_EVAX - /* FIXME: This needs to be done in a more general fashion. */ - align = 3; -#endif + TC_IMPLICIT_LCOMM_ALIGNMENT (temp, align); - record_alignment(bss_seg, align); + /* Still zero unless TC_IMPLICIT_LCOMM_ALIGNMENT set it. */ + if (align) + record_alignment(bss_seg, align); } if (needs_align) @@ -1969,7 +2010,7 @@ s_lcomm_internal (needs_align, bytes_p) SKIP_WHITESPACE (); if (*input_line_pointer != ',') { - as_bad ("Expected comma after size"); + as_bad (_("Expected comma after size")); ignore_rest_of_line (); return; } @@ -1977,7 +2018,7 @@ s_lcomm_internal (needs_align, bytes_p) SKIP_WHITESPACE (); if (*input_line_pointer == '\n') { - as_bad ("Missing alignment"); + as_bad (_("Missing alignment")); return; } align = get_absolute_expression (); @@ -1991,19 +2032,19 @@ s_lcomm_internal (needs_align, bytes_p) for (i = 0; (align & 1) == 0; align >>= 1, ++i) ; if (align != 1) - as_bad ("Alignment not a power of 2"); + as_bad (_("Alignment not a power of 2")); align = i; } } if (align > max_alignment) { align = max_alignment; - as_warn ("Alignment too large: %d. assumed.", align); + as_warn (_("Alignment too large: %d. assumed."), align); } else if (align < 0) { align = 0; - as_warn ("Alignment negative. 0 assumed."); + as_warn (_("Alignment negative. 0 assumed.")); } record_alignment (bss_seg, align); } /* if needs align */ @@ -2025,12 +2066,17 @@ s_lcomm_internal (needs_align, bytes_p) *p = c; if ( -#if defined(OBJ_AOUT) | defined(OBJ_BOUT) - S_GET_OTHER (symbolP) == 0 && - S_GET_DESC (symbolP) == 0 && -#endif /* OBJ_AOUT or OBJ_BOUT */ - (S_GET_SEGMENT (symbolP) == bss_seg - || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0))) +#if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT) \ + || defined (OBJ_BOUT) || defined (OBJ_MAYBE_BOUT)) +#ifdef BFD_ASSEMBLER + (OUTPUT_FLAVOR != bfd_target_aout_flavour + || (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0)) && +#else + (S_GET_OTHER (symbolP) == 0 && S_GET_DESC (symbolP) == 0) && +#endif +#endif + (S_GET_SEGMENT (symbolP) == bss_seg + || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0))) { char *pfrag; @@ -2040,9 +2086,9 @@ s_lcomm_internal (needs_align, bytes_p) frag_align (align, 0, 0); /* detach from old frag */ if (S_GET_SEGMENT (symbolP) == bss_seg) - symbolP->sy_frag->fr_symbol = NULL; + symbol_get_frag (symbolP)->fr_symbol = NULL; - symbolP->sy_frag = frag_now; + symbol_set_frag (symbolP, frag_now); pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP, (offsetT) temp, (char *) 0); *pfrag = 0; @@ -2064,7 +2110,7 @@ s_lcomm_internal (needs_align, bytes_p) #endif } else - as_bad ("Ignoring attempt to re-define symbol `%s'.", + as_bad (_("Ignoring attempt to re-define symbol `%s'."), S_GET_NAME (symbolP)); subseg_set (current_seg, current_subseg); @@ -2087,7 +2133,7 @@ void s_lcomm_bytes (needs_align) void s_lsym (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { register char *name; register char c; @@ -2104,7 +2150,7 @@ s_lsym (ignore) if (*input_line_pointer != ',') { *p = 0; - as_bad ("Expected comma after name \"%s\"", name); + as_bad (_("Expected comma after name \"%s\""), name); *p = c; ignore_rest_of_line (); return; @@ -2114,7 +2160,7 @@ s_lsym (ignore) if (exp.X_op != O_constant && exp.X_op != O_register) { - as_bad ("bad expression"); + as_bad (_("bad expression")); ignore_rest_of_line (); return; } @@ -2141,7 +2187,7 @@ s_lsym (ignore) } else { - as_bad ("Symbol %s already defined", name); + as_bad (_("Symbol %s already defined"), name); } *p = c; demand_empty_rest_of_line (); @@ -2209,7 +2255,7 @@ get_line_sb (line) void s_macro (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { char *file; unsigned int line; @@ -2237,19 +2283,15 @@ s_macro (ignore) { S_SET_SEGMENT (line_label, undefined_section); S_SET_VALUE (line_label, 0); - line_label->sy_frag = &zero_address_frag; + symbol_set_frag (line_label, &zero_address_frag); } - if (((flag_m68k_mri -#ifdef NO_PSEUDO_DOT - || 1 -#endif - ) + if (((NO_PSEUDO_DOT || flag_m68k_mri) && hash_find (po_hash, name) != NULL) || (! flag_m68k_mri && *name == '.' && hash_find (po_hash, name + 1) != NULL)) - as_warn ("attempt to redefine pseudo-op `%s' ignored", + as_warn (_("attempt to redefine pseudo-op `%s' ignored"), name); } @@ -2261,7 +2303,7 @@ s_macro (ignore) void s_mexit (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { cond_exit_macro (macro_nest); buffer_limit = input_scrub_next_buffer (&input_line_pointer); @@ -2271,7 +2313,7 @@ s_mexit (ignore) void s_mri (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { int on, old_flag; @@ -2283,13 +2325,21 @@ s_mri (ignore) #ifdef TC_M68K flag_m68k_mri = 1; #endif + macro_mri_mode (1); } else { flag_mri = 0; +#ifdef TC_M68K flag_m68k_mri = 0; +#endif + macro_mri_mode (0); } + /* Operator precedence changes in m68k MRI mode, so we need to + update the operator rankings. */ + expr_set_precedence (); + #ifdef MRI_MODE_CHANGE if (on != old_flag) MRI_MODE_CHANGE (on); @@ -2307,16 +2357,16 @@ do_org (segment, exp, fill) int fill; { if (segment != now_seg && segment != absolute_section) - as_bad ("invalid segment \"%s\"; segment \"%s\" assumed", + as_bad (_("invalid segment \"%s\"; segment \"%s\" assumed"), segment_name (segment), segment_name (now_seg)); if (now_seg == absolute_section) { if (fill != 0) - as_warn ("ignoring fill value in absolute section"); + as_warn (_("ignoring fill value in absolute section")); if (exp->X_op != O_constant) { - as_bad ("only constant offsets supported in absolute section"); + as_bad (_("only constant offsets supported in absolute section")); exp->X_add_number = 0; } abs_section_offset = exp->X_add_number; @@ -2326,25 +2376,29 @@ do_org (segment, exp, fill) char *p; p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp->X_add_symbol, - exp->X_add_number, (char *) NULL); + exp->X_add_number * OCTETS_PER_BYTE, (char *) NULL); *p = fill; } } void s_org (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { register segT segment; expressionS exp; register long temp_fill; +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + /* The m68k MRI assembler has a different meaning for .org. It means to create an absolute section at a given address. We can't support that--use a linker script instead. */ if (flag_m68k_mri) { - as_bad ("MRI style ORG pseudo-op not supported"); + as_bad (_("MRI style ORG pseudo-op not supported")); ignore_rest_of_line (); return; } @@ -2385,7 +2439,7 @@ s_org (ignore) void s_mri_sect (type) - char *type; + char *type ATTRIBUTE_UNUSED; { #ifdef TC_M68K @@ -2432,7 +2486,7 @@ s_mri_sect (type) if (c == 'C' || c == 'D' || c == 'M' || c == 'R') *type = c; else - as_bad ("unrecognized section type"); + as_bad (_("unrecognized section type")); ++input_line_pointer; #ifdef BFD_ASSEMBLER @@ -2449,7 +2503,7 @@ s_mri_sect (type) if (flags != SEC_NO_FLAGS) { if (! bfd_set_section_flags (stdoutput, seg, flags)) - as_warn ("error setting flags for \"%s\": %s", + as_warn (_("error setting flags for \"%s\": %s"), bfd_section_name (stdoutput, seg), bfd_errmsg (bfd_get_error ())); } @@ -2500,7 +2554,7 @@ s_mri_sect (type) else if (strcasecmp (sectype, "romdata") == 0) *type = 'R'; else - as_warn ("unrecognized section type `%s'", sectype); + as_warn (_("unrecognized section type `%s'"), sectype); *input_line_pointer = c; } @@ -2514,7 +2568,7 @@ s_mri_sect (type) c = get_symbol_end (); if (strcasecmp (seccmd, "absolute") == 0) { - as_bad ("absolute sections are not supported"); + as_bad (_("absolute sections are not supported")); *input_line_pointer = c; ignore_rest_of_line (); return; @@ -2529,7 +2583,7 @@ s_mri_sect (type) } else { - as_warn ("unrecognized section command `%s'", seccmd); + as_warn (_("unrecognized section command `%s'"), seccmd); *input_line_pointer = c; } } @@ -2539,7 +2593,8 @@ s_mri_sect (type) #else /* ! TC_I960 */ /* The MRI assembler seems to use different forms of .sect for different targets. */ - abort (); + as_bad ("MRI mode not supported for this target"); + ignore_rest_of_line (); #endif /* ! TC_I960 */ #endif /* ! TC_M68K */ } @@ -2548,7 +2603,7 @@ s_mri_sect (type) void s_print (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { char *s; int len; @@ -2562,7 +2617,7 @@ s_print (ignore) void s_purgem (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { if (is_it_end_of_statement ()) { @@ -2592,18 +2647,31 @@ s_purgem (ignore) void s_rept (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { int count; - sb one; - sb many; count = get_absolute_expression (); + do_repeat(count, "REPT", "ENDR"); +} + +/* This function provides a generic repeat block implementation. It allows + different directives to be used as the start/end keys. */ + +void +do_repeat (count, start, end) + int count; + const char *start; + const char *end; +{ + sb one; + sb many; + sb_new (&one); - if (! buffer_and_nest ("REPT", "ENDR", &one, get_line_sb)) + if (! buffer_and_nest (start, end, &one, get_line_sb)) { - as_bad ("rept without endr"); + as_bad (_("%s without %s"), start, end); return; } @@ -2613,11 +2681,28 @@ s_rept (ignore) sb_kill (&one); - input_scrub_include_sb (&many, input_line_pointer); + input_scrub_include_sb (&many, input_line_pointer, 1); sb_kill (&many); buffer_limit = input_scrub_next_buffer (&input_line_pointer); } +/* Skip to end of current repeat loop; EXTRA indicates how many additional + input buffers to skip. Assumes that conditionals preceding the loop end + are properly nested. + + This function makes it easier to implement a premature "break" out of the + loop. The EXTRA arg accounts for other buffers we might have inserted, + such as line substitutions. */ + +void +end_repeat (extra) + int extra; +{ + cond_exit_macro (macro_nest); + while (extra-- >= 0) + buffer_limit = input_scrub_next_buffer (&input_line_pointer); +} + /* 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. */ @@ -2645,7 +2730,7 @@ s_set (equiv) if (*input_line_pointer != ',') { *end_name = 0; - as_bad ("Expected comma after name \"%s\"", name); + as_bad (_("Expected comma after name \"%s\""), name); *end_name = delim; ignore_rest_of_line (); return; @@ -2672,7 +2757,24 @@ s_set (equiv) if ((symbolP = symbol_find (name)) == NULL && (symbolP = md_undefined_symbol (name)) == NULL) { - symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag); +#ifndef NO_LISTING + /* When doing symbol listings, play games with dummy fragments living + outside the normal fragment chain to record the file and line info + for this symbol. */ + if (listing & LISTING_SYMBOLS) + { + extern struct list_info_struct *listing_tail; + fragS *dummy_frag = (fragS *) xmalloc (sizeof(fragS)); + memset (dummy_frag, 0, sizeof(fragS)); + dummy_frag->fr_type = rs_fill; + dummy_frag->line = listing_tail; + symbolP = symbol_new (name, undefined_section, 0, dummy_frag); + dummy_frag->fr_symbol = symbolP; + } + else +#endif + symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag); + #ifdef OBJ_COFF /* "set" symbols are local unless otherwise specified. */ SF_SET_LOCAL (symbolP); @@ -2687,7 +2789,7 @@ s_set (equiv) if (equiv && S_IS_DEFINED (symbolP) && S_GET_SEGMENT (symbolP) != reg_section) - as_bad ("symbol `%s' already defined", S_GET_NAME (symbolP)); + as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP)); pseudo_set (symbolP); demand_empty_rest_of_line (); @@ -2731,9 +2833,12 @@ s_space (mult) S_SET_VALUE (mri_common_symbol, val + 1); if (line_label != NULL) { - know (line_label->sy_value.X_op == O_symbol); - know (line_label->sy_value.X_add_symbol == mri_common_symbol); - line_label->sy_value.X_add_number += 1; + expressionS *symexp; + + symexp = symbol_get_value_expression (line_label); + know (symexp->X_op == O_symbol); + know (symexp->X_add_symbol == mri_common_symbol); + symexp->X_add_number += 1; } } } @@ -2742,7 +2847,7 @@ s_space (mult) do_align (1, (char *) NULL, 0, 0); if (line_label != NULL) { - line_label->sy_frag = frag_now; + symbol_set_frag (line_label, frag_now); S_SET_VALUE (line_label, frag_now_fix ()); } } @@ -2770,7 +2875,7 @@ s_space (mult) || (mult != 0 && mult != 1 && val.X_add_number != 0)) { if (exp.X_op != O_constant) - as_bad ("Unsupported variable size or fill value"); + as_bad (_("Unsupported variable size or fill value")); else { offsetT i; @@ -2794,9 +2899,10 @@ s_space (mult) bytes = repeat; if (repeat <= 0) { - if (! flag_mri || repeat < 0) - as_warn (".space repeat count is %s, ignored", - repeat ? "negative" : "zero"); + if (! flag_mri) + as_warn (_(".space repeat count is zero, ignored")); + else if (repeat < 0) + as_warn (_(".space repeat count is negative, ignored")); goto getout; } @@ -2825,12 +2931,12 @@ s_space (mult) { if (now_seg == absolute_section) { - as_bad ("space allocation too complex in absolute section"); + as_bad (_("space allocation too complex in absolute section")); subseg_set (text_section, 0); } if (mri_common_symbol != NULL) { - as_bad ("space allocation too complex in common section"); + as_bad (_("space allocation too complex in common section")); mri_common_symbol = NULL; } if (!need_pass_2) @@ -2850,10 +2956,10 @@ s_space (mult) if (flag_mri && (bytes & 1) != 0) mri_pending_align = 1; + demand_empty_rest_of_line (); + if (flag_mri) mri_comment_end (stop, stopc); - - demand_empty_rest_of_line (); } /* This is like s_space, but the value is a floating point number with @@ -2878,10 +2984,10 @@ s_float_space (float_type) SKIP_WHITESPACE (); if (*input_line_pointer != ',') { - as_bad ("missing value"); + as_bad (_("missing value")); + ignore_rest_of_line (); if (flag_mri) mri_comment_end (stop, stopc); - ignore_rest_of_line (); return; } @@ -2891,7 +2997,8 @@ s_float_space (float_type) /* Skip any 0{letter} that may be present. Don't even check if the * letter is legal. */ - if (input_line_pointer[0] == '0' && isalpha (input_line_pointer[1])) + if (input_line_pointer[0] == '0' + && isalpha ((unsigned char) input_line_pointer[1])) input_line_pointer += 2; /* Accept :xxxx, where the x's are hex digits, for a floating point @@ -2901,9 +3008,9 @@ s_float_space (float_type) flen = hex_float (float_type, temp); if (flen < 0) { + ignore_rest_of_line (); if (flag_mri) mri_comment_end (stop, stopc); - ignore_rest_of_line (); return; } } @@ -2916,10 +3023,10 @@ s_float_space (float_type) know (flen > 0); if (err) { - as_bad ("Bad floating literal: %s", err); + as_bad (_("Bad floating literal: %s"), err); + ignore_rest_of_line (); if (flag_mri) mri_comment_end (stop, stopc); - ignore_rest_of_line (); return; } } @@ -2932,17 +3039,17 @@ s_float_space (float_type) memcpy (p, temp, (unsigned int) flen); } + demand_empty_rest_of_line (); + if (flag_mri) mri_comment_end (stop, stopc); - - demand_empty_rest_of_line (); } /* Handle the .struct pseudo-op, as found in MIPS assemblers. */ void s_struct (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { char *stop = NULL; char stopc; @@ -2951,14 +3058,14 @@ s_struct (ignore) stop = mri_comment_field (&stopc); abs_section_offset = get_absolute_expression (); subseg_set (absolute_section, 0); + demand_empty_rest_of_line (); if (flag_mri) mri_comment_end (stop, stopc); - demand_empty_rest_of_line (); } void s_text (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { register int temp; @@ -2991,11 +3098,11 @@ ignore_rest_of_line () /* For suspect lines: gives warning. */ { if (!is_end_of_line[(unsigned char) *input_line_pointer]) { - if (isprint (*input_line_pointer)) - as_bad ("Rest of line ignored. First ignored character is `%c'.", + if (isprint ((unsigned char) *input_line_pointer)) + as_bad (_("Rest of line ignored. First ignored character is `%c'."), *input_line_pointer); else - as_bad ("Rest of line ignored. First ignored character valued 0x%x.", + as_bad (_("Rest of line ignored. First ignored character valued 0x%x."), *input_line_pointer); while (input_line_pointer < buffer_limit && !is_end_of_line[(unsigned char) *input_line_pointer]) @@ -3007,6 +3114,18 @@ ignore_rest_of_line () /* For suspect lines: gives warning. */ know (is_end_of_line[(unsigned char) input_line_pointer[-1]]); } +void +discard_rest_of_line () +{ + 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]]); +} + /* * pseudo_set() * @@ -3034,17 +3153,22 @@ pseudo_set (symbolP) (void) expression (&exp); if (exp.X_op == O_illegal) - as_bad ("illegal expression; zero assumed"); + as_bad (_("illegal expression; zero assumed")); else if (exp.X_op == O_absent) - as_bad ("missing expression; zero assumed"); + as_bad (_("missing expression; zero assumed")); else if (exp.X_op == O_big) - as_bad ("%s number invalid; zero assumed", - exp.X_add_number > 0 ? "bignum" : "floating point"); + { + if (exp.X_add_number > 0) + as_bad (_("bignum invalid; zero assumed")); + else + as_bad (_("floating point number invalid; zero assumed")); + } else if (exp.X_op == O_subtract && (S_GET_SEGMENT (exp.X_add_symbol) == S_GET_SEGMENT (exp.X_op_symbol)) && SEG_NORMAL (S_GET_SEGMENT (exp.X_add_symbol)) - && exp.X_add_symbol->sy_frag == exp.X_op_symbol->sy_frag) + && (symbol_get_frag (exp.X_add_symbol) + == symbol_get_frag (exp.X_op_symbol))) { exp.X_op = O_constant; exp.X_add_number = (S_GET_VALUE (exp.X_add_symbol) @@ -3067,19 +3191,22 @@ pseudo_set (symbolP) S_CLEAR_EXTERNAL (symbolP); #endif /* OBJ_AOUT or OBJ_BOUT */ S_SET_VALUE (symbolP, (valueT) exp.X_add_number); - symbolP->sy_frag = &zero_address_frag; + if (exp.X_op != O_constant) + symbol_set_frag (symbolP, &zero_address_frag); break; case O_register: S_SET_SEGMENT (symbolP, reg_section); S_SET_VALUE (symbolP, (valueT) exp.X_add_number); - symbolP->sy_frag = &zero_address_frag; + symbol_set_frag (symbolP, &zero_address_frag); break; case O_symbol: if (S_GET_SEGMENT (exp.X_add_symbol) == undefined_section || exp.X_add_number != 0) - symbolP->sy_value = exp; + symbol_set_value_expression (symbolP, &exp); + else if (symbol_section_p (symbolP)) + as_bad ("invalid attempt to set value of section symbol"); else { symbolS *s = exp.X_add_symbol; @@ -3093,7 +3220,7 @@ pseudo_set (symbolP) #endif /* OBJ_AOUT or OBJ_BOUT */ S_SET_VALUE (symbolP, exp.X_add_number + S_GET_VALUE (s)); - symbolP->sy_frag = s->sy_frag; + symbol_set_frag (symbolP, symbol_get_frag (s)); copy_symbol_attributes (symbolP, s); } break; @@ -3101,7 +3228,7 @@ pseudo_set (symbolP) default: /* The value is some complex expression. FIXME: Should we set the segment to anything? */ - symbolP->sy_value = exp; + symbol_set_value_expression (symbolP, &exp); break; } } @@ -3131,8 +3258,10 @@ pseudo_set (symbolP) are defined, which is the normal case, then only simple expressions are permitted. */ +#ifdef TC_M68K static void parse_mri_cons PARAMS ((expressionS *exp, unsigned int nbytes)); +#endif #ifndef TC_PARSE_CONS_EXPRESSION #ifdef BITFIELD_CONS_EXPRESSIONS @@ -3174,9 +3303,9 @@ cons_worker (nbytes, rva) if (is_it_end_of_statement ()) { + demand_empty_rest_of_line (); if (flag_mri) mri_comment_end (stop, stopc); - demand_empty_rest_of_line (); return; } @@ -3187,9 +3316,11 @@ cons_worker (nbytes, rva) c = 0; do { +#ifdef TC_M68K if (flag_m68k_mri) parse_mri_cons (&exp, (unsigned int) nbytes); else +#endif TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes); if (rva) @@ -3197,7 +3328,7 @@ cons_worker (nbytes, rva) if (exp.X_op == O_symbol) exp.X_op = O_symbol_rva; else - as_fatal ("rva without symbol"); + as_fatal (_("rva without symbol")); } emit_expr (&exp, (unsigned int) nbytes); ++c; @@ -3212,10 +3343,10 @@ cons_worker (nbytes, rva) input_line_pointer--; /* Put terminator back into stream. */ + demand_empty_rest_of_line (); + if (flag_mri) mri_comment_end (stop, stopc); - - demand_empty_rest_of_line (); } @@ -3233,7 +3364,6 @@ s_rva (size) cons_worker (size, 1); } - /* Put the contents of expression EXP into the object file using NBYTES bytes. If need_pass_2 is 1, this does nothing. */ @@ -3314,13 +3444,16 @@ emit_expr (exp, nbytes) #endif #endif + if (check_eh_frame (exp, &nbytes)) + return; + op = exp->X_op; /* Allow `.word 0' in the absolute section. */ if (now_seg == absolute_section) { if (op != O_constant || exp->X_add_number != 0) - as_bad ("attempt to store value in absolute section"); + as_bad (_("attempt to store value in absolute section")); abs_section_offset += nbytes; return; } @@ -3328,13 +3461,13 @@ emit_expr (exp, nbytes) /* Handle a negative bignum. */ if (op == O_uminus && exp->X_add_number == 0 - && exp->X_add_symbol->sy_value.X_op == O_big - && exp->X_add_symbol->sy_value.X_add_number > 0) + && symbol_get_value_expression (exp->X_add_symbol)->X_op == O_big + && symbol_get_value_expression (exp->X_add_symbol)->X_add_number > 0) { int i; unsigned long carry; - exp = &exp->X_add_symbol->sy_value; + exp = symbol_get_value_expression (exp->X_add_symbol); /* Negate the bignum: one's complement each digit and add 1. */ carry = 1; @@ -3358,19 +3491,19 @@ emit_expr (exp, nbytes) if (op == O_absent || op == O_illegal) { - as_warn ("zero assumed for missing expression"); + as_warn (_("zero assumed for missing expression")); exp->X_add_number = 0; op = O_constant; } else if (op == O_big && exp->X_add_number <= 0) { - as_bad ("floating point number invalid; zero assumed"); + as_bad (_("floating point number invalid; zero assumed")); exp->X_add_number = 0; op = O_constant; } else if (op == O_register) { - as_warn ("register value used as expression"); + as_warn (_("register value used as expression")); op = O_constant; } @@ -3386,6 +3519,8 @@ emit_expr (exp, nbytes) x = (struct broken_word *) xmalloc (sizeof (struct broken_word)); x->next_broken_word = broken_words; broken_words = x; + x->seg = now_seg; + x->subseg = now_subseg; x->frag = frag_now; x->word_goes_here = p; x->dispfrag = 0; @@ -3458,7 +3593,7 @@ emit_expr (exp, nbytes) && ((get & mask) != mask || (get & hibit) == 0)) { /* Leading bits contain both 0s & 1s. */ - as_warn ("Value 0x%lx truncated to 0x%lx.", + as_warn (_("Value 0x%lx truncated to 0x%lx."), (unsigned long) get, (unsigned long) use); } /* put bytes in right order. */ @@ -3466,7 +3601,7 @@ emit_expr (exp, nbytes) } else if (op == O_big) { - int size; + unsigned int size; LITTLENUM_TYPE *nums; know (nbytes % CHARS_PER_LITTLENUM == 0); @@ -3474,7 +3609,7 @@ emit_expr (exp, nbytes) size = exp->X_add_number * CHARS_PER_LITTLENUM; if (nbytes < size) { - as_warn ("Bignum truncated to %d bytes", nbytes); + as_warn (_("Bignum truncated to %d bytes"), nbytes); size = nbytes; } @@ -3551,7 +3686,7 @@ emit_expr (exp, nbytes) r = BFD_RELOC_64; break; default: - as_bad ("unsupported BFD relocation size %u", nbytes); + as_bad (_("unsupported BFD relocation size %u"), nbytes); r = BFD_RELOC_32; break; } @@ -3640,7 +3775,7 @@ parse_bitfield_cons (exp, nbytes) if (exp->X_op == O_absent) { - as_warn ("using a bit field width of zero"); + as_warn (_("using a bit field width of zero")); exp->X_add_number = 0; exp->X_op = O_constant; } /* implied zero width bitfield */ @@ -3648,7 +3783,7 @@ parse_bitfield_cons (exp, nbytes) if (exp->X_op != O_constant) { *input_line_pointer = '\0'; - as_bad ("field width \"%s\" too complex for a bitfield", hold); + as_bad (_("field width \"%s\" too complex for a bitfield"), hold); *input_line_pointer = ':'; demand_empty_rest_of_line (); return; @@ -3656,7 +3791,7 @@ parse_bitfield_cons (exp, nbytes) if ((width = exp->X_add_number) > (BITS_PER_CHAR * nbytes)) { - as_warn ("field width %lu too big to fit in %d bytes: truncated to %d bits", + as_warn (_("field width %lu too big to fit in %d bytes: truncated to %d bits"), width, nbytes, (BITS_PER_CHAR * nbytes)); width = BITS_PER_CHAR * nbytes; } /* too big */ @@ -3677,7 +3812,7 @@ parse_bitfield_cons (exp, nbytes) char cache = *input_line_pointer; *input_line_pointer = '\0'; - as_bad ("field value \"%s\" too complex for a bitfield", hold); + as_bad (_("field value \"%s\" too complex for a bitfield"), hold); *input_line_pointer = cache; demand_empty_rest_of_line (); return; @@ -3707,6 +3842,7 @@ parse_bitfield_cons (exp, nbytes) /* Handle an MRI style string expression. */ +#ifdef TC_M68K static void parse_mri_cons (exp, nbytes) expressionS *exp; @@ -3719,7 +3855,7 @@ parse_mri_cons (exp, nbytes) TC_PARSE_CONS_EXPRESSION (exp, nbytes); else { - int scan = 0; + unsigned int scan; unsigned int result = 0; /* An MRI style string. Cut into as many bytes as will fit into @@ -3729,7 +3865,7 @@ parse_mri_cons (exp, nbytes) ++input_line_pointer; else if (*input_line_pointer == 'E') { - as_bad ("EBCDIC constants are not supported"); + as_bad (_("EBCDIC constants are not supported")); ++input_line_pointer; } @@ -3769,6 +3905,7 @@ parse_mri_cons (exp, nbytes) input_line_pointer++; } } +#endif /* TC_M68K */ #ifdef REPEAT_CONS_EXPRESSIONS @@ -3799,7 +3936,7 @@ parse_repeat_cons (exp, nbytes) if (count.X_op != O_constant || count.X_add_number <= 0) { - as_warn ("Unresolvable or nonpositive repeat count; using 1"); + as_warn (_("Unresolvable or nonpositive repeat count; using 1")); return; } @@ -3850,7 +3987,7 @@ hex_float (float_type, bytes) break; default: - as_bad ("Unknown floating type type '%c'", float_type); + as_bad (_("Unknown floating type type '%c'"), float_type); return -1; } @@ -3872,7 +4009,7 @@ hex_float (float_type, bytes) if (i >= length) { - as_warn ("Floating point constant too large"); + as_warn (_("Floating point constant too large")); return -1; } d = hex_value (*input_line_pointer) << 4; @@ -3952,7 +4089,8 @@ float_cons (float_type) * has no use for such information. Lusers beware: you get * diagnostics if your input is ill-conditioned. */ - if (input_line_pointer[0] == '0' && isalpha (input_line_pointer[1])) + if (input_line_pointer[0] == '0' + && isalpha ((unsigned char) input_line_pointer[1])) input_line_pointer += 2; /* Accept :xxxx, where the x's are hex digits, for a floating @@ -3974,7 +4112,7 @@ float_cons (float_type) know (length > 0); if (err) { - as_bad ("Bad floating literal: %s", err); + as_bad (_("Bad floating literal: %s"), err); ignore_rest_of_line (); return; } @@ -3996,7 +4134,7 @@ float_cons (float_type) if (count_exp.X_op != O_constant || count_exp.X_add_number <= 0) { - as_warn ("unresolvable or nonpositive repeat count; using 1"); + as_warn (_("unresolvable or nonpositive repeat count; using 1")); } else count = count_exp.X_add_number; @@ -4059,7 +4197,7 @@ sizeof_uleb128 (value) return size; } -inline int +int sizeof_leb128 (value, sign) valueT value; int sign; @@ -4123,7 +4261,7 @@ output_uleb128 (p, value) return p - orig; } -inline int +int output_leb128 (p, value, sign) char *p; valueT value; @@ -4139,14 +4277,14 @@ output_leb128 (p, value, sign) we don't output for NULL values of P. It isn't really as critical as for "normal" values that this be streamlined. */ -static int +static inline int output_big_sleb128 (p, bignum, size) char *p; LITTLENUM_TYPE *bignum; int size; { char *orig = p; - valueT val; + valueT val = 0; int loaded = 0; unsigned byte; @@ -4185,14 +4323,14 @@ output_big_sleb128 (p, bignum, size) return p - orig; } -static int +static inline int output_big_uleb128 (p, bignum, size) char *p; LITTLENUM_TYPE *bignum; int size; { char *orig = p; - valueT val; + valueT val = 0; int loaded = 0; unsigned byte; @@ -4227,7 +4365,7 @@ output_big_uleb128 (p, bignum, size) return p - orig; } -static inline int +static int output_big_leb128 (p, bignum, size, sign) char *p; LITTLENUM_TYPE *bignum; @@ -4251,19 +4389,19 @@ emit_leb128_expr(exp, sign) if (op == O_absent || op == O_illegal) { - as_warn ("zero assumed for missing expression"); + as_warn (_("zero assumed for missing expression")); exp->X_add_number = 0; op = O_constant; } else if (op == O_big && exp->X_add_number <= 0) { - as_bad ("floating point number invalid; zero assumed"); + as_bad (_("floating point number invalid; zero assumed")); exp->X_add_number = 0; op = O_constant; } else if (op == O_register) { - as_warn ("register value used as expression"); + as_warn (_("register value used as expression")); op = O_constant; } @@ -4320,7 +4458,7 @@ s_leb128 (sign) /* * stringer() * - * We read 0 or more ',' seperated, double-quoted strings. + * We read 0 or more ',' separated, double-quoted strings. * * Caller should have checked need_pass_2 is FALSE because we don't check it. */ @@ -4340,7 +4478,7 @@ stringer (append_zero) /* Worker to do .ascii etc statements. */ /* * The following awkward logic is to parse ZERO or more strings, - * comma seperated. Recall a string expression includes spaces + * comma separated. Recall a string expression includes spaces * before the opening '\"' and spaces after the closing '\"'. * We fake a leading ',' if there is (supposed to be) * a 1st, expression. We keep demanding expressions for each @@ -4400,7 +4538,7 @@ stringer (append_zero) /* Worker to do .ascii etc statements. */ FRAG_APPEND_1_CHAR (c); if (*input_line_pointer != '>') { - as_bad ("Expected "); + as_bad (_("Expected ")); } input_line_pointer++; break; @@ -4433,7 +4571,7 @@ next_char_of_string () break; case '\n': - as_warn ("Unterminated string: Newline inserted."); + as_warn (_("Unterminated string: Newline inserted.")); bump_line_counters (); break; @@ -4516,7 +4654,7 @@ next_char_of_string () case '\n': /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */ - as_warn ("Unterminated string: Newline inserted."); + as_warn (_("Unterminated string: Newline inserted.")); c = '\n'; bump_line_counters (); break; @@ -4524,7 +4662,7 @@ next_char_of_string () default: #ifdef ONLY_STANDARD_ESCAPES - as_bad ("Bad escaped character in string, '?' assumed"); + as_bad (_("Bad escaped character in string, '?' assumed")); c = '?'; #endif /* ONLY_STANDARD_ESCAPES */ @@ -4550,7 +4688,7 @@ get_segmented_expression (expP) || expP->X_op == O_absent || expP->X_op == O_big) { - as_bad ("expected address expression; zero assumed"); + as_bad (_("expected address expression; zero assumed")); expP->X_op = O_constant; expP->X_add_number = 0; retval = absolute_section; @@ -4570,10 +4708,10 @@ get_known_segmented_expression (expP) expression. */ if (expP->X_add_symbol != NULL && S_GET_SEGMENT (expP->X_add_symbol) != expr_section) - as_warn ("symbol \"%s\" undefined; zero assumed", + as_warn (_("symbol \"%s\" undefined; zero assumed"), S_GET_NAME (expP->X_add_symbol)); else - as_warn ("some symbol undefined; zero assumed"); + as_warn (_("some symbol undefined; zero assumed")); retval = absolute_section; expP->X_op = O_constant; expP->X_add_number = 0; @@ -4591,7 +4729,7 @@ get_absolute_expression () if (exp.X_op != O_constant) { if (exp.X_op != O_absent) - as_bad ("bad or irreducible absolute expression; zero assumed"); + as_bad (_("bad or irreducible absolute expression; zero assumed")); exp.X_add_number = 0; } return exp.X_add_number; @@ -4629,7 +4767,7 @@ demand_copy_C_string (len_pointer) s = 0; len = 1; *len_pointer = 0; - as_bad ("This string may not contain \'\\0\'"); + as_bad (_("This string may not contain \'\\0\'")); } } } @@ -4668,7 +4806,7 @@ demand_copy_string (lenP) } else { - as_warn ("Missing string"); + as_warn (_("Missing string")); retval = NULL; ignore_rest_of_line (); } @@ -4698,7 +4836,7 @@ equals (sym_name, reassign) int reassign; { register symbolS *symbolP; /* symbol we are working with */ - char *stop; + char *stop = NULL; char stopc; input_line_pointer++; @@ -4728,12 +4866,15 @@ equals (sym_name, reassign) if (! reassign && S_IS_DEFINED (symbolP) && S_GET_SEGMENT (symbolP) != reg_section) - as_bad ("symbol `%s' already defined", S_GET_NAME (symbolP)); + as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP)); pseudo_set (symbolP); } if (flag_mri) - mri_comment_end (stop, stopc); + { + ignore_rest_of_line (); /* check garbage after the expression */ + mri_comment_end (stop, stopc); + } } /* equals() */ /* .include -- include a file at this point. */ @@ -4741,9 +4882,8 @@ equals (sym_name, reassign) /* ARGSUSED */ void s_include (arg) - int arg; + int arg ATTRIBUTE_UNUSED; { - char *newbuf; char *filename; int i; FILE *try; @@ -4794,8 +4934,7 @@ s_include (arg) gotit: /* malloc Storage leak when file is found on path. FIXME-SOMEDAY. */ register_dependency (path); - newbuf = input_scrub_include_file (path, input_line_pointer); - buffer_limit = input_scrub_next_buffer (&input_line_pointer); + input_scrub_insert_file (path); } /* s_include() */ void @@ -4823,10 +4962,147 @@ add_include_dir (path) if (i > include_dir_maxlen) include_dir_maxlen = i; } /* add_include_dir() */ + +/* Output debugging information to denote the source file. */ + +static void +generate_file_debug () +{ + if (debug_type == DEBUG_STABS) + stabs_generate_asm_file (); +} + +/* Output line number debugging information for the current source line. */ + +void +generate_lineno_debug () +{ +#ifdef ECOFF_DEBUGGING + /* ECOFF assemblers automatically generate debugging information. + FIXME: This should probably be handled elsewhere. */ + if (debug_type == DEBUG_UNSPECIFIED) + { + if (ECOFF_DEBUGGING && ecoff_no_current_file ()) + debug_type = DEBUG_ECOFF; + else + debug_type = DEBUG_NONE; + } +#endif + + switch (debug_type) + { + case DEBUG_UNSPECIFIED: + case DEBUG_NONE: + break; + case DEBUG_STABS: + stabs_generate_asm_lineno (); + break; + case DEBUG_ECOFF: + ecoff_generate_asm_lineno (); + break; + case DEBUG_DWARF: + case DEBUG_DWARF2: + /* FIXME. */ + break; + } +} + +/* Output debugging information to mark a function entry point or end point. + END_P is zero for .func, and non-zero for .endfunc. */ + +void +s_func (end_p) + int end_p; +{ + do_s_func (end_p, NULL); +} + +/* Subroutine of s_func so targets can choose a different default prefix. + If DEFAULT_PREFIX is NULL, use the target's "leading char". */ + +void +do_s_func (end_p, default_prefix) + int end_p; + const char *default_prefix; +{ + /* Record the current function so that we can issue an error message for + misplaced .func,.endfunc, and also so that .endfunc needs no + arguments. */ + static char *current_name; + static char *current_label; + + if (end_p) + { + if (current_name == NULL) + { + as_bad (_("missing .func")); + ignore_rest_of_line (); + return; + } + if (debug_type == DEBUG_STABS) + stabs_generate_asm_endfunc (current_name, current_label); + + current_name = current_label = NULL; + } + else /* ! end_p */ + { + char *name,*label; + char delim1,delim2; + + if (current_name != NULL) + { + as_bad (_(".endfunc missing for previous .func")); + ignore_rest_of_line (); + return; + } + + name = input_line_pointer; + delim1 = get_symbol_end (); + name = xstrdup (name); + *input_line_pointer = delim1; + SKIP_WHITESPACE (); + if (*input_line_pointer != ',') + { + if (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 + /* Missing entry point, use function's name with the leading + char prepended. */ + if (leading_char) + asprintf (&label, "%c%s", leading_char, name); + else + label = name; + } + } + else + { + ++input_line_pointer; + SKIP_WHITESPACE (); + label = input_line_pointer; + delim2 = get_symbol_end (); + label = xstrdup (label); + *input_line_pointer = delim2; + } + + if (debug_type == DEBUG_STABS) + stabs_generate_asm_func (name, label); + + current_name = name; + current_label = label; + } + + demand_empty_rest_of_line (); +} + void s_ignore (arg) - int arg; + int arg ATTRIBUTE_UNUSED; { while (!is_end_of_line[(unsigned char) *input_line_pointer]) { @@ -4843,4 +5119,36 @@ read_print_statistics (file) hash_print_statistics (file, "pseudo-op table", po_hash); } +/* Inserts the given line into the input stream. + + This call avoids macro/conditionals nesting checking, since the contents of + the line are assumed to replace the contents of a line already scanned. + + An appropriate use of this function would be substition of input lines when + called by md_start_line_hook(). The given line is assumed to already be + properly scrubbed. */ + +void +input_scrub_insert_line (line) + const char *line; +{ + sb newline; + sb_new (&newline); + sb_add_string (&newline, line); + input_scrub_include_sb (&newline, input_line_pointer, 0); + sb_kill (&newline); + buffer_limit = input_scrub_next_buffer (&input_line_pointer); +} + +/* Insert a file into the input stream; the path must resolve to an actual + file; no include path searching or dependency registering is performed. */ + +void +input_scrub_insert_file (path) + char *path; +{ + input_scrub_include_file (path, input_line_pointer); + buffer_limit = input_scrub_next_buffer (&input_line_pointer); +} + /* end of read.c */