* 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:
parent
b17e0267c9
commit
f6a91cc0f7
4 changed files with 188 additions and 101 deletions
|
@ -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
|
||||
|
|
48
gas/app.c
48
gas/app.c
|
@ -29,7 +29,6 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue