* 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.
This commit is contained in:
Ian Lance Taylor 1993-03-18 00:52:37 +00:00
parent b17e0267c9
commit f6a91cc0f7
4 changed files with 188 additions and 101 deletions

View file

@ -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) Mon Mar 15 12:17:28 1993 Ian Lance Taylor (ian@cygnus.com)
* write.c (write_contents): Compute the relocs before writing out * write.c (write_contents): Compute the relocs before writing out

View file

@ -29,7 +29,6 @@
#include <stdio.h> #include <stdio.h>
#include "as.h" /* For BAD_CASE() only */ #include "as.h" /* For BAD_CASE() only */
#include "read.h"
#if (__STDC__ != 1) && !defined(const) #if (__STDC__ != 1) && !defined(const)
#define const /* Nothing */ #define const /* Nothing */
@ -250,10 +249,18 @@ do_scrub_next_char (get, unget)
6: putting out \ escape in a "d string. 6: putting out \ escape in a "d string.
7: After putting out a .app-file, put out string. 7: After putting out a .app-file, put out string.
8: After putting out a .app-file string, flush until newline. 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 -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 -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; register int ch, ch2 = 0;
switch (state) switch (state)
@ -399,7 +406,7 @@ do_scrub_next_char (get, unget)
return ch; return ch;
} }
/* OK, we are somewhere in states 0 through 4 */ /* OK, we are somewhere in states 0 through 4 or 9 */
/* flushchar: */ /* flushchar: */
ch = (*get) (); ch = (*get) ();
@ -447,7 +454,8 @@ recycle:
case 1: case 1:
BAD_CASE (state); /* We can't get here */ BAD_CASE (state); /* We can't get here */
case 2: case 2:
state++; case 9:
state = 3;
(*unget) (ch); (*unget) (ch);
return ' '; /* Sp after opco */ return ' '; /* Sp after opco */
case 3: case 3:
@ -561,18 +569,22 @@ recycle:
goto de_fault; goto de_fault;
/* FIXME-someday: The two character comment stuff was badly /* FIXME-someday: The two character comment stuff was badly
thought out. On i386, we want '/' as line comment start thought out. On i386, we want '/' as line comment start AND
AND we want C style comments. hence this hack. The we want C style comments. hence this hack. The whole
whole lexical process should be reworked. xoxorich. */ lexical process should be reworked. xoxorich. */
if (ch == '/' && (ch2 = (*get) ()) == '*') if (ch == '/')
{ {
state = -2; ch2 = (*get) ();
return (do_scrub_next_char (get, unget)); if (ch2 == '*')
} {
else state = -2;
{ return (do_scrub_next_char (get, unget));
(*unget) (ch2); }
else
{
(*unget) (ch2);
}
} /* bad hack */ } /* bad hack */
do do
@ -609,6 +621,10 @@ recycle:
state = 0; state = 0;
return '\n'; return '\n';
case LEX_IS_SYMBOL_COMPONENT:
if (state == 3)
state = 9;
/* Fall through. */
default: default:
de_fault: de_fault:
/* Some relatively `normal' character. */ /* Some relatively `normal' character. */
@ -622,6 +638,12 @@ recycle:
state = 2; /* Ditto */ state = 2; /* Ditto */
return ch; return ch;
} }
else if (state == 9)
{
if (lex[ch] != LEX_IS_SYMBOL_COMPONENT)
state = 3;
return ch;
}
else else
{ {
return ch; /* Opcode or operands already */ return ch; /* Opcode or operands already */

View file

@ -831,6 +831,7 @@ typedef struct scope {
information we generate. The gas symbol will be NULL if this is information we generate. The gas symbol will be NULL if this is
only a debugging symbol. */ only a debugging symbol. */
typedef struct localsym { typedef struct localsym {
const char *name; /* symbol name */
symbolS *as_sym; /* symbol as seen by gas */ symbolS *as_sym; /* symbol as seen by gas */
struct efdr *file_ptr; /* file pointer */ struct efdr *file_ptr; /* file pointer */
struct ecoff_proc *proc_ptr; /* proc pointer */ struct ecoff_proc *proc_ptr; /* proc pointer */
@ -1393,7 +1394,8 @@ static alloc_info_t alloc_counts[ (int)alloc_type_last ];
/* Various statics. */ /* Various statics. */
static efdr_t *cur_file_ptr = (efdr_t *) 0; /* current file desc. header */ 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 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 #ifdef ECOFF_DEBUG
static int debug = 0; /* trace functions */ static int debug = 0; /* trace functions */
#endif #endif
@ -1561,6 +1563,11 @@ obj_read_begin_hook ()
tag_hash = hash_new (); tag_hash = hash_new ();
if (tag_hash == (struct hash_control *) NULL) if (tag_hash == (struct hash_control *) NULL)
as_fatal ("Can't create hash table"); 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. */ /* 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++ ]; 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; psym->as_sym = sym_value;
if (sym_value != (symbolS *) NULL) if (sym_value != (symbolS *) NULL)
sym_value->ecoff_symbol = 1; sym_value->ecoff_symbol = 1;
@ -2194,7 +2205,7 @@ add_procedure (func)
new_proc_ptr->pdr.iline = -1; new_proc_ptr->pdr.iline = -1;
/* Push the start of the function. */ /* 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), symbol_find_or_make (func),
(symint_t) 0, (symint_t) 0); (symint_t) 0, (symint_t) 0);
@ -2428,7 +2439,10 @@ obj_ecoff_begin (ignore)
*input_line_pointer = name_end; *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 /* Parse .bend directives which have a label as the first argument
@ -2440,7 +2454,7 @@ obj_ecoff_bend (ignore)
{ {
char *name; char *name;
char name_end; char name_end;
symbolS *begin; symbolS *endsym;
if (cur_file_ptr == (efdr_t *) NULL) if (cur_file_ptr == (efdr_t *) NULL)
{ {
@ -2460,21 +2474,21 @@ obj_ecoff_bend (ignore)
name_end = get_symbol_end (); name_end = get_symbol_end ();
/* The value is the distance between the .bend directive and the /* The value is the distance between the .bend directive and the
corresponding symbol. We create a fake symbol to hold the corresponding symbol. We fill in the offset when we write out
current location, and put in the offset when we write out the the symbol. */
symbol. */ endsym = symbol_find (name);
begin = symbol_find (name); if (endsym == (symbolS *) NULL)
if (begin == (symbolS *) NULL)
as_warn (".bend directive names unknown symbol"); as_warn (".bend directive names unknown symbol");
else else
(void) add_ecoff_symbol (name, st_End, sc_Text, (void) add_ecoff_symbol ((const char *) NULL, st_End, sc_Text, endsym,
symbol_new ("L0\001", now_seg,
frag_now_fix (), frag_now),
(symint_t) 0, (symint_t) 0); (symint_t) 0, (symint_t) 0);
*input_line_pointer = name_end; *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 /* COFF debugging information is provided as a series of directives
@ -2601,15 +2615,8 @@ obj_ecoff_scl (ignore)
val = get_absolute_expression (); val = get_absolute_expression ();
/* If the symbol is a static or external, we have already gotten the coff_symbol_type = map_coff_sym_type[val];
appropriate type and class, so make sure we don't override those coff_storage_class = map_coff_storage[val];
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];
}
demand_empty_rest_of_line (); demand_empty_rest_of_line ();
} }
@ -2674,6 +2681,7 @@ obj_ecoff_type (ignore)
{ {
long val; long val;
tq_t *tq_ptr; tq_t *tq_ptr;
tq_t *tq_shft;
if (coff_sym_name == (char *) NULL) if (coff_sym_name == (char *) NULL)
{ {
@ -2687,27 +2695,31 @@ obj_ecoff_type (ignore)
coff_type.orig_type = BTYPE (val); coff_type.orig_type = BTYPE (val);
coff_type.basic_type = map_coff_types[coff_type.orig_type]; 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) 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"); as_warn ("Too derived values in .type argument");
break; break;
} }
if (ISPTR (val)) if (ISPTR (val))
*tq_ptr++ = tq_Ptr; *--tq_ptr = tq_Ptr;
else if (ISFCN (val)) else if (ISFCN (val))
*tq_ptr++ = tq_Proc; *--tq_ptr = tq_Proc;
else if (ISARY (val)) else if (ISARY (val))
*tq_ptr++ = tq_Array; *--tq_ptr = tq_Array;
else else
as_fatal ("Unrecognized .type argument"); as_fatal ("Unrecognized .type argument");
val = DECREF (val); 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 /* 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 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 MIPS knows what reason, we must strip off the function type
at this point. */ at this point. */
coff_is_function = 1; 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 (); demand_empty_rest_of_line ();
} }
@ -2796,6 +2811,7 @@ static void
obj_ecoff_endef (ignore) obj_ecoff_endef (ignore)
int ignore; int ignore;
{ {
char *name;
symint_t indx; symint_t indx;
localsym_t *sym; localsym_t *sym;
@ -2807,6 +2823,19 @@ obj_ecoff_endef (ignore)
return; 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; coff_type.extra_sizes = coff_tag != (char *) NULL;
if (coff_type.num_dims > 0) if (coff_type.num_dims > 0)
{ {
@ -2863,7 +2892,7 @@ obj_ecoff_endef (ignore)
{ {
if (coff_tag == (char *) NULL) if (coff_tag == (char *) NULL)
{ {
as_warn ("No tag specified for %s", coff_sym_name); as_warn ("No tag specified for %s", name);
return; return;
} }
@ -2908,8 +2937,8 @@ obj_ecoff_endef (ignore)
name which is always ".eos". This needs to be done last, so name which is always ".eos". This needs to be done last, so
that any error reporting above gives the correct name. */ that any error reporting above gives the correct name. */
case st_End: case st_End:
free (coff_sym_name); free (name);
coff_sym_name = (char *) NULL; name = (char *) NULL;
coff_value = 0; coff_value = 0;
coff_inside_enumeration = 0; coff_inside_enumeration = 0;
break; break;
@ -2927,7 +2956,7 @@ obj_ecoff_endef (ignore)
} }
/* Add the symbol. */ /* Add the symbol. */
sym = add_ecoff_symbol (coff_sym_name, sym = add_ecoff_symbol (name,
coff_symbol_type, coff_symbol_type,
coff_storage_class, coff_storage_class,
coff_sym_value, coff_sym_value,
@ -2938,7 +2967,7 @@ obj_ecoff_endef (ignore)
if (coff_symbol_type == st_Block) if (coff_symbol_type == st_Block)
{ {
/* Create or update the tag information. */ /* Create or update the tag information. */
tag_t *tag_ptr = get_tag (coff_sym_name, tag_t *tag_ptr = get_tag (name,
sym, sym,
coff_type.basic_type); coff_type.basic_type);
forward_t **pf; forward_t **pf;
@ -2998,7 +3027,7 @@ obj_ecoff_end (ignore)
if (ent == (symbolS *) NULL) if (ent == (symbolS *) NULL)
as_warn (".end directive names unknown symbol"); as_warn (".end directive names unknown symbol");
else 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, symbol_new ("L0\001", now_seg,
frag_now_fix (), frag_now), frag_now_fix (), frag_now),
(symint_t) 0, (symint_t) 0); (symint_t) 0, (symint_t) 0);
@ -3189,18 +3218,10 @@ obj_ecoff_loc (ignore)
return; return;
} }
/* FIXME: .loc directives look like ``.loc 1 4'' where the first /* Skip the file number. */
number is the file index and the second number is the line SKIP_WHITESPACE ();
number. Unfortunately, do_scrub_next_char removes the space, get_absolute_expression ();
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_WHITESPACE (); SKIP_WHITESPACE ();
input_line_pointer += 1 + (cur_file_ptr->file_index + 1) / 10;
list = allocate_lineno_list (); list = allocate_lineno_list ();
@ -3599,7 +3620,7 @@ ecoff_build_lineno (buf, bufend, offset, linecntptr)
} }
else if (delta <= -7) else if (delta <= -7)
{ {
*bufptr++ = 0x0f + (9 << 4); *bufptr++ = 0x0f + (-7 << 4);
delta += 7; delta += 7;
} }
else else
@ -3745,6 +3766,7 @@ ecoff_build_symbols (buf,
for (; sym_ptr < sym_end; sym_ptr++) for (; sym_ptr < sym_end; sym_ptr++)
{ {
int local; int local;
symbolS *as_sym;
forward_t *f; forward_t *f;
know (sym_ptr->file_ptr == fil_ptr); know (sym_ptr->file_ptr == fil_ptr);
@ -3757,26 +3779,65 @@ ecoff_build_symbols (buf,
both if the local provides additional debugging both if the local provides additional debugging
information for the external). */ information for the external). */
local = 1; 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 /* This is just an external symbol if it is
outside a procedure and it has a type. */ outside a procedure and it has a type.
if ((S_IS_EXTERNAL (sym_ptr->as_sym) FIXME: g++ will generate symbols which have
|| ! S_IS_DEFINED (sym_ptr->as_sym)) 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->proc_ptr == (proc_t *) NULL
&& sym_ptr->ecoff_sym.st != (int) st_Nil) && sym_ptr->ecoff_sym.st != (int) st_Nil)
local = 0; local = 0;
/* If an st_end symbol has an associated gas /* If an st_end symbol has an associated gas
symbol, then it is a fake created for a .bend symbol, then it is a local label created for
or .end directive. */ a .bend or .end directive. */
if (local && sym_ptr->ecoff_sym.st != st_End) if (local && sym_ptr->ecoff_sym.st != st_End)
sym_ptr->ecoff_sym.iss = sym_ptr->ecoff_sym.iss =
add_string (&fil_ptr->strings, add_string (&fil_ptr->strings,
fil_ptr->str_hash, fil_ptr->str_hash,
S_GET_NAME (sym_ptr->as_sym), sym_ptr->name,
(shash_t **) NULL); (shash_t **) NULL);
} }
@ -3817,12 +3878,13 @@ ecoff_build_symbols (buf,
/* The value of the symbol marking the end of a /* The value of the symbol marking the end of a
procedure or block is the size of the procedure or block is the size of the
procedure or block. */ 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); know (begin_ptr->as_sym != (symbolS *) NULL);
sym_ptr->ecoff_sym.value = sym_ptr->ecoff_sym.value =
(S_GET_VALUE (sym_ptr->as_sym) (S_GET_VALUE (as_sym)
- S_GET_VALUE (begin_ptr->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 this is an external symbol, swap it out. */
if (sym_ptr->as_sym != (symbolS *) NULL if (as_sym != (symbolS *) NULL
&& (S_IS_EXTERNAL (sym_ptr->as_sym) && (S_IS_EXTERNAL (as_sym)
|| ! S_IS_DEFINED (sym_ptr->as_sym))) || ! S_IS_DEFINED (as_sym)))
{ {
EXTR ext; EXTR ext;
@ -3866,7 +3928,7 @@ ecoff_build_symbols (buf,
ext.ifd = fil_ptr->file_index; ext.ifd = fil_ptr->file_index;
ext.asym.iss = add_string (ext_strings, ext.asym.iss = add_string (ext_strings,
ext_str_hash, ext_str_hash,
S_GET_NAME (sym_ptr->as_sym), S_GET_NAME (as_sym),
(shash_t **) NULL); (shash_t **) NULL);
if (*extbufend - (char *) ext_out if (*extbufend - (char *) ext_out
< sizeof (struct ext_ext)) < sizeof (struct ext_ext))
@ -3875,7 +3937,7 @@ ecoff_build_symbols (buf,
(char *) ext_out, (char *) ext_out,
sizeof (struct ext_ext))); sizeof (struct ext_ext)));
ecoff_swap_ext_out (stdoutput, &ext, ext_out); 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; ++ext_out;
++iext; ++iext;
} }
@ -4245,6 +4307,8 @@ ecoff_frob_symbol (sym)
void void
ecoff_frob_file () ecoff_frob_file ()
{ {
tag_t *ptag;
tag_t *ptag_next;
efdr_t *fil_ptr; efdr_t *fil_ptr;
efdr_t *hold_file_ptr; efdr_t *hold_file_ptr;
proc_t * hold_proc_ptr; proc_t * hold_proc_ptr;
@ -4261,6 +4325,21 @@ ecoff_frob_file ()
struct hash_control *ext_str_hash; struct hash_control *ext_str_hash;
char *set; 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 /* 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 here for the last file, so we may as well do it for all of the
files. */ files. */
@ -4283,35 +4362,12 @@ ecoff_frob_file ()
cur_proc_ptr = (proc_t *) NULL; cur_proc_ptr = (proc_t *) NULL;
for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym)) for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym))
{ {
st_t st;
sc_t sc;
if (sym->ecoff_symbol if (sym->ecoff_symbol
|| sym->ecoff_file == (efdr_t *) NULL) || sym->ecoff_file == (efdr_t *) NULL)
continue; 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; 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); S_GET_VALUE (sym), indexNil);
} }
cur_proc_ptr = hold_proc_ptr; cur_proc_ptr = hold_proc_ptr;

View file

@ -1096,7 +1096,7 @@ macro (ip)
case M_LWR_AB: case M_LWR_AB:
s = "lwr"; s = "lwr";
ld: ld:
if (breg == treg) { if (breg == treg || treg == 0) {
tempreg = AT; tempreg = AT;
used_at = 1; used_at = 1;
} else { } else {