From f6a91cc0f7695aef3575c3d3cca397667a9f1027 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 18 Mar 1993 00:52:37 +0000 Subject: [PATCH] * app.c (do_scrub_next_char): Added new state, 9, to avoid dropping a space immediately following an identifier. * expr.c, write.c: Rewrote assert expressions to not use multiple lines; I don't think that can be done portably. * config/tc-mips.c (macro): Use $AT if target register is zero in load instruction, which it can be for a floating point load. Also a bunch more changes to config/obj-ecoff.c, still in flux. --- gas/ChangeLog | 9 ++ gas/app.c | 48 ++++++--- gas/config/obj-ecoff.c | 230 +++++++++++++++++++++++++---------------- gas/config/tc-mips.c | 2 +- 4 files changed, 188 insertions(+), 101 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index bfc4e5426fe..209343906f6 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,12 @@ +Wed Mar 17 16:44:06 1993 Ian Lance Taylor (ian@cygnus.com) + + * app.c (do_scrub_next_char): Added new state, 9, to avoid + dropping a space immediately following an identifier. + * expr.c, write.c: Rewrote assert expressions to not use multiple + lines; I don't think that can be done portably. + * config/tc-mips.c (macro): Use $AT if target register is zero in + load instruction, which it can be for a floating point load. + Mon Mar 15 12:17:28 1993 Ian Lance Taylor (ian@cygnus.com) * write.c (write_contents): Compute the relocs before writing out diff --git a/gas/app.c b/gas/app.c index ce75973f45d..1983c3ca6a8 100644 --- a/gas/app.c +++ b/gas/app.c @@ -29,7 +29,6 @@ #include #include "as.h" /* For BAD_CASE() only */ -#include "read.h" #if (__STDC__ != 1) && !defined(const) #define const /* Nothing */ @@ -250,10 +249,18 @@ do_scrub_next_char (get, unget) 6: putting out \ escape in a "d string. 7: After putting out a .app-file, put out string. 8: After putting out a .app-file string, flush until newline. + 9: After seeing symbol char in state 3 (keep 1white after symchar) -1: output string in out_string and go to the state in old_state -2: flush text until a '*' '/' is seen, then go to state old_state */ + /* I added state 9 because the MIPS ECOFF assembler uses constructs + like ``.loc 1 20''. This was turning into ``.loc 120''. State 9 + ensures that a space is never dropped immediately following a + character which could appear in a identifier. It is still + dropped following a comma, so this has no effect for most + assemblers. I hope. Ian Taylor, ian@cygnus.com. */ + register int ch, ch2 = 0; switch (state) @@ -399,7 +406,7 @@ do_scrub_next_char (get, unget) return ch; } - /* OK, we are somewhere in states 0 through 4 */ + /* OK, we are somewhere in states 0 through 4 or 9 */ /* flushchar: */ ch = (*get) (); @@ -447,7 +454,8 @@ recycle: case 1: BAD_CASE (state); /* We can't get here */ case 2: - state++; + case 9: + state = 3; (*unget) (ch); return ' '; /* Sp after opco */ case 3: @@ -561,18 +569,22 @@ recycle: goto de_fault; /* FIXME-someday: The two character comment stuff was badly - thought out. On i386, we want '/' as line comment start - AND we want C style comments. hence this hack. The - whole lexical process should be reworked. xoxorich. */ + thought out. On i386, we want '/' as line comment start AND + we want C style comments. hence this hack. The whole + lexical process should be reworked. xoxorich. */ - if (ch == '/' && (ch2 = (*get) ()) == '*') + if (ch == '/') { - state = -2; - return (do_scrub_next_char (get, unget)); - } - else - { - (*unget) (ch2); + ch2 = (*get) (); + if (ch2 == '*') + { + state = -2; + return (do_scrub_next_char (get, unget)); + } + else + { + (*unget) (ch2); + } } /* bad hack */ do @@ -609,6 +621,10 @@ recycle: state = 0; return '\n'; + case LEX_IS_SYMBOL_COMPONENT: + if (state == 3) + state = 9; + /* Fall through. */ default: de_fault: /* Some relatively `normal' character. */ @@ -622,6 +638,12 @@ recycle: state = 2; /* Ditto */ return ch; } + else if (state == 9) + { + if (lex[ch] != LEX_IS_SYMBOL_COMPONENT) + state = 3; + return ch; + } else { return ch; /* Opcode or operands already */ diff --git a/gas/config/obj-ecoff.c b/gas/config/obj-ecoff.c index 1e29ab874c9..d0a9b044e93 100644 --- a/gas/config/obj-ecoff.c +++ b/gas/config/obj-ecoff.c @@ -831,6 +831,7 @@ typedef struct scope { information we generate. The gas symbol will be NULL if this is only a debugging symbol. */ typedef struct localsym { + const char *name; /* symbol name */ symbolS *as_sym; /* symbol as seen by gas */ struct efdr *file_ptr; /* file pointer */ struct ecoff_proc *proc_ptr; /* proc pointer */ @@ -1393,7 +1394,8 @@ static alloc_info_t alloc_counts[ (int)alloc_type_last ]; /* Various statics. */ static efdr_t *cur_file_ptr = (efdr_t *) 0; /* current file desc. header */ static proc_t *cur_proc_ptr = (proc_t *) 0; /* current procedure header */ -static thead_t *cur_tag_head = (thead_t *)0; /* current tag head */ +static thead_t *top_tag_head = (thead_t *) 0; /* top level tag head */ +static thead_t *cur_tag_head = (thead_t *) 0; /* current tag head */ #ifdef ECOFF_DEBUG static int debug = 0; /* trace functions */ #endif @@ -1561,6 +1563,11 @@ obj_read_begin_hook () tag_hash = hash_new (); if (tag_hash == (struct hash_control *) NULL) as_fatal ("Can't create hash table"); + top_tag_head = allocate_thead (); + top_tag_head->first_tag = (tag_t *) NULL; + top_tag_head->free = (thead_t *) NULL; + top_tag_head->prev = cur_tag_head; + cur_tag_head = top_tag_head; } /* This function is called when a symbol is created. */ @@ -1683,6 +1690,10 @@ add_ecoff_symbol (str, type, storage, sym_value, value, indx) psym = &vp->last->datum->sym[ vp->objects_last_page++ ]; + if (str == (const char *) NULL && sym_value != (symbolS *) NULL) + psym->name = S_GET_NAME (sym_value); + else + psym->name = str; psym->as_sym = sym_value; if (sym_value != (symbolS *) NULL) sym_value->ecoff_symbol = 1; @@ -2194,7 +2205,7 @@ add_procedure (func) new_proc_ptr->pdr.iline = -1; /* Push the start of the function. */ - new_proc_ptr->sym = add_ecoff_symbol (func, st_Proc, sc_Text, + new_proc_ptr->sym = add_ecoff_symbol ((const char *) NULL, st_Proc, sc_Text, symbol_find_or_make (func), (symint_t) 0, (symint_t) 0); @@ -2428,7 +2439,10 @@ obj_ecoff_begin (ignore) *input_line_pointer = name_end; - demand_empty_rest_of_line (); + /* The line number follows, but we don't use it. */ + while (! is_end_of_line[*input_line_pointer]) + input_line_pointer++; + input_line_pointer++; } /* Parse .bend directives which have a label as the first argument @@ -2440,7 +2454,7 @@ obj_ecoff_bend (ignore) { char *name; char name_end; - symbolS *begin; + symbolS *endsym; if (cur_file_ptr == (efdr_t *) NULL) { @@ -2460,21 +2474,21 @@ obj_ecoff_bend (ignore) name_end = get_symbol_end (); /* The value is the distance between the .bend directive and the - corresponding symbol. We create a fake symbol to hold the - current location, and put in the offset when we write out the - symbol. */ - begin = symbol_find (name); - if (begin == (symbolS *) NULL) + corresponding symbol. We fill in the offset when we write out + the symbol. */ + endsym = symbol_find (name); + if (endsym == (symbolS *) NULL) as_warn (".bend directive names unknown symbol"); else - (void) add_ecoff_symbol (name, st_End, sc_Text, - symbol_new ("L0\001", now_seg, - frag_now_fix (), frag_now), + (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text, endsym, (symint_t) 0, (symint_t) 0); *input_line_pointer = name_end; - demand_empty_rest_of_line (); + /* The line number follows, but we don't use it. */ + while (! is_end_of_line[*input_line_pointer]) + input_line_pointer++; + input_line_pointer++; } /* COFF debugging information is provided as a series of directives @@ -2601,15 +2615,8 @@ obj_ecoff_scl (ignore) val = get_absolute_expression (); - /* If the symbol is a static or external, we have already gotten the - appropriate type and class, so make sure we don't override those - values. This is needed because there are some type and classes - that are not in COFF, such as short data, etc. */ - if (coff_symbol_type == st_Nil) - { - coff_symbol_type = map_coff_sym_type[val]; - coff_storage_class = map_coff_storage[val]; - } + coff_symbol_type = map_coff_sym_type[val]; + coff_storage_class = map_coff_storage[val]; demand_empty_rest_of_line (); } @@ -2674,6 +2681,7 @@ obj_ecoff_type (ignore) { long val; tq_t *tq_ptr; + tq_t *tq_shft; if (coff_sym_name == (char *) NULL) { @@ -2687,27 +2695,31 @@ obj_ecoff_type (ignore) coff_type.orig_type = BTYPE (val); coff_type.basic_type = map_coff_types[coff_type.orig_type]; - tq_ptr = &coff_type.type_qualifiers[0]; + tq_ptr = &coff_type.type_qualifiers[N_TQ]; while (val &~ N_BTMASK) { - if (tq_ptr == &coff_type.type_qualifiers[N_TQ]) + if (tq_ptr == &coff_type.type_qualifiers[0]) { as_warn ("Too derived values in .type argument"); break; } if (ISPTR (val)) - *tq_ptr++ = tq_Ptr; + *--tq_ptr = tq_Ptr; else if (ISFCN (val)) - *tq_ptr++ = tq_Proc; + *--tq_ptr = tq_Proc; else if (ISARY (val)) - *tq_ptr++ = tq_Array; + *--tq_ptr = tq_Array; else as_fatal ("Unrecognized .type argument"); val = DECREF (val); } - if (tq_ptr != &coff_type.type_qualifiers[0] && tq_ptr[-1] == tq_Proc) + tq_shft = &coff_type.type_qualifiers[0]; + while (tq_ptr != &coff_type.type_qualifiers[N_TQ]) + *tq_shft++ = *tq_ptr++; + + if (tq_shft != &coff_type.type_qualifiers[0] && tq_shft[-1] == tq_Proc) { /* If this is a function, ignore it, so that we don't get two entries (one from the .ent, and one for the .def that @@ -2716,9 +2728,12 @@ obj_ecoff_type (ignore) MIPS knows what reason, we must strip off the function type at this point. */ coff_is_function = 1; - tq_ptr[-1] = tq_Nil; + tq_shft[-1] = tq_Nil; } + while (tq_shft != &coff_type.type_qualifiers[N_TQ]) + *tq_shft++ = tq_Nil; + demand_empty_rest_of_line (); } @@ -2796,6 +2811,7 @@ static void obj_ecoff_endef (ignore) int ignore; { + char *name; symint_t indx; localsym_t *sym; @@ -2807,6 +2823,19 @@ obj_ecoff_endef (ignore) return; } + name = coff_sym_name; + coff_sym_name = (char *) NULL; + + /* If the symbol is a static or external, we have already gotten the + appropriate type and class, so make sure we don't override those + values. This is needed because there are some type and classes + that are not in COFF, such as short data, etc. */ + if (coff_sym_value != (symbolS *) NULL) + { + coff_symbol_type = st_Nil; + coff_storage_class = sc_Nil; + } + coff_type.extra_sizes = coff_tag != (char *) NULL; if (coff_type.num_dims > 0) { @@ -2863,7 +2892,7 @@ obj_ecoff_endef (ignore) { if (coff_tag == (char *) NULL) { - as_warn ("No tag specified for %s", coff_sym_name); + as_warn ("No tag specified for %s", name); return; } @@ -2908,8 +2937,8 @@ obj_ecoff_endef (ignore) name which is always ".eos". This needs to be done last, so that any error reporting above gives the correct name. */ case st_End: - free (coff_sym_name); - coff_sym_name = (char *) NULL; + free (name); + name = (char *) NULL; coff_value = 0; coff_inside_enumeration = 0; break; @@ -2927,7 +2956,7 @@ obj_ecoff_endef (ignore) } /* Add the symbol. */ - sym = add_ecoff_symbol (coff_sym_name, + sym = add_ecoff_symbol (name, coff_symbol_type, coff_storage_class, coff_sym_value, @@ -2938,7 +2967,7 @@ obj_ecoff_endef (ignore) if (coff_symbol_type == st_Block) { /* Create or update the tag information. */ - tag_t *tag_ptr = get_tag (coff_sym_name, + tag_t *tag_ptr = get_tag (name, sym, coff_type.basic_type); forward_t **pf; @@ -2998,7 +3027,7 @@ obj_ecoff_end (ignore) if (ent == (symbolS *) NULL) as_warn (".end directive names unknown symbol"); else - (void) add_ecoff_symbol (name, st_End, sc_Text, + (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text, symbol_new ("L0\001", now_seg, frag_now_fix (), frag_now), (symint_t) 0, (symint_t) 0); @@ -3189,18 +3218,10 @@ obj_ecoff_loc (ignore) return; } - /* FIXME: .loc directives look like ``.loc 1 4'' where the first - number is the file index and the second number is the line - number. Unfortunately, do_scrub_next_char removes the space, - producing ``.loc 14''. Urrrk. I'm afraid I'll break something - if I change do_scrub_next_char, so instead we do this gross hack. - Note that file_index is one less than the value in the .loc, - because we adjusted it by one in the call to add_file. This - actually won't work in the unfortunate circumstance of the same - file appearing twice with different indices with different - numbers of digits, which is possible. */ + /* Skip the file number. */ + SKIP_WHITESPACE (); + get_absolute_expression (); SKIP_WHITESPACE (); - input_line_pointer += 1 + (cur_file_ptr->file_index + 1) / 10; list = allocate_lineno_list (); @@ -3599,7 +3620,7 @@ ecoff_build_lineno (buf, bufend, offset, linecntptr) } else if (delta <= -7) { - *bufptr++ = 0x0f + (9 << 4); + *bufptr++ = 0x0f + (-7 << 4); delta += 7; } else @@ -3745,6 +3766,7 @@ ecoff_build_symbols (buf, for (; sym_ptr < sym_end; sym_ptr++) { int local; + symbolS *as_sym; forward_t *f; know (sym_ptr->file_ptr == fil_ptr); @@ -3757,26 +3779,65 @@ ecoff_build_symbols (buf, both if the local provides additional debugging information for the external). */ local = 1; - if (sym_ptr->as_sym != (symbolS *) NULL) + as_sym = sym_ptr->as_sym; + if (as_sym != (symbolS *) NULL) { - sym_ptr->ecoff_sym.value = S_GET_VALUE (sym_ptr->as_sym); + sym_ptr->ecoff_sym.value = S_GET_VALUE (as_sym); + + /* Get the type and storage class based on where + the symbol actually wound up. */ + if (sym_ptr->ecoff_sym.st == st_Nil + && sym_ptr->ecoff_sym.sc == sc_Nil + && ! MIPS_IS_STAB (&sym_ptr->ecoff_sym)) + { + st_t st; + sc_t sc; + + if (S_IS_EXTERNAL (as_sym) + || ! S_IS_DEFINED (as_sym)) + st = st_Global; + else if (S_GET_SEGMENT (as_sym) == text_section) + st = st_Label; + else + st = st_Static; + + if (! S_IS_DEFINED (as_sym)) + sc = sc_Undefined; + else if (S_IS_COMMON (as_sym)) + sc = sc_Common; + else if (S_GET_SEGMENT (as_sym) == text_section) + sc = sc_Text; + else if (S_GET_SEGMENT (as_sym) == data_section) + sc = sc_Data; + else if (S_GET_SEGMENT (as_sym) == bss_section) + sc = sc_Bss; + else + abort (); + + sym_ptr->ecoff_sym.st = (int) st; + sym_ptr->ecoff_sym.sc = (int) sc; + } /* This is just an external symbol if it is - outside a procedure and it has a type. */ - if ((S_IS_EXTERNAL (sym_ptr->as_sym) - || ! S_IS_DEFINED (sym_ptr->as_sym)) + outside a procedure and it has a type. + FIXME: g++ will generate symbols which have + different names in the debugging information + than the actual symbol. Should we handle + them here? */ + if ((S_IS_EXTERNAL (as_sym) + || ! S_IS_DEFINED (as_sym)) && sym_ptr->proc_ptr == (proc_t *) NULL && sym_ptr->ecoff_sym.st != (int) st_Nil) local = 0; /* If an st_end symbol has an associated gas - symbol, then it is a fake created for a .bend - or .end directive. */ + symbol, then it is a local label created for + a .bend or .end directive. */ if (local && sym_ptr->ecoff_sym.st != st_End) sym_ptr->ecoff_sym.iss = add_string (&fil_ptr->strings, fil_ptr->str_hash, - S_GET_NAME (sym_ptr->as_sym), + sym_ptr->name, (shash_t **) NULL); } @@ -3817,12 +3878,13 @@ ecoff_build_symbols (buf, /* The value of the symbol marking the end of a procedure or block is the size of the procedure or block. */ - if (begin_type == st_Proc || begin_type == st_Block) + if ((begin_type == st_Proc || begin_type == st_Block) + && sym_ptr->ecoff_sym.sc != (int) sc_Info) { - know (sym_ptr->as_sym != (symbolS *) NULL); + know (as_sym != (symbolS *) NULL); know (begin_ptr->as_sym != (symbolS *) NULL); sym_ptr->ecoff_sym.value = - (S_GET_VALUE (sym_ptr->as_sym) + (S_GET_VALUE (as_sym) - S_GET_VALUE (begin_ptr->as_sym)); } } @@ -3855,9 +3917,9 @@ ecoff_build_symbols (buf, } /* If this is an external symbol, swap it out. */ - if (sym_ptr->as_sym != (symbolS *) NULL - && (S_IS_EXTERNAL (sym_ptr->as_sym) - || ! S_IS_DEFINED (sym_ptr->as_sym))) + if (as_sym != (symbolS *) NULL + && (S_IS_EXTERNAL (as_sym) + || ! S_IS_DEFINED (as_sym))) { EXTR ext; @@ -3866,7 +3928,7 @@ ecoff_build_symbols (buf, ext.ifd = fil_ptr->file_index; ext.asym.iss = add_string (ext_strings, ext_str_hash, - S_GET_NAME (sym_ptr->as_sym), + S_GET_NAME (as_sym), (shash_t **) NULL); if (*extbufend - (char *) ext_out < sizeof (struct ext_ext)) @@ -3875,7 +3937,7 @@ ecoff_build_symbols (buf, (char *) ext_out, sizeof (struct ext_ext))); ecoff_swap_ext_out (stdoutput, &ext, ext_out); - ecoff_set_sym_index (sym_ptr->as_sym->bsym, iext); + ecoff_set_sym_index (as_sym->bsym, iext); ++ext_out; ++iext; } @@ -4245,6 +4307,8 @@ ecoff_frob_symbol (sym) void ecoff_frob_file () { + tag_t *ptag; + tag_t *ptag_next; efdr_t *fil_ptr; efdr_t *hold_file_ptr; proc_t * hold_proc_ptr; @@ -4261,6 +4325,21 @@ ecoff_frob_file () struct hash_control *ext_str_hash; char *set; + /* Handle any top level tags. */ + for (ptag = top_tag_head->first_tag; + ptag != (tag_t *) NULL; + ptag = ptag_next) + { + if (ptag->forward_ref != (forward_t *) NULL) + add_unknown_tag (ptag); + + ptag_next = ptag->same_block; + ptag->hash_ptr->tag_ptr = ptag->same_name; + free_tag (ptag); + } + + free_thead (top_tag_head); + /* Output an ending symbol for all the files. We have to do this here for the last file, so we may as well do it for all of the files. */ @@ -4283,35 +4362,12 @@ ecoff_frob_file () cur_proc_ptr = (proc_t *) NULL; for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym)) { - st_t st; - sc_t sc; - if (sym->ecoff_symbol || sym->ecoff_file == (efdr_t *) NULL) continue; - if (S_IS_EXTERNAL (sym) || ! S_IS_DEFINED (sym)) - st = st_Global; - else if (S_GET_SEGMENT (sym) == text_section) - st = st_Label; - else - st = st_Static; - - if (! S_IS_DEFINED (sym)) - sc = sc_Undefined; - else if (S_IS_COMMON (sym)) - sc = sc_Common; - else if (S_GET_SEGMENT (sym) == text_section) - sc = sc_Text; - else if (S_GET_SEGMENT (sym) == data_section) - sc = sc_Data; - else if (S_GET_SEGMENT (sym) == bss_section) - sc = sc_Bss; - else - abort (); - cur_file_ptr = sym->ecoff_file; - add_ecoff_symbol (S_GET_NAME (sym), st, sc, sym, + add_ecoff_symbol ((const char *) NULL, st_Nil, sc_Nil, sym, S_GET_VALUE (sym), indexNil); } cur_proc_ptr = hold_proc_ptr; diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index f59dca2b000..6a88a5aa5e5 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -1096,7 +1096,7 @@ macro (ip) case M_LWR_AB: s = "lwr"; ld: - if (breg == treg) { + if (breg == treg || treg == 0) { tempreg = AT; used_at = 1; } else { -- 2.30.2