* 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)
|
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
|
||||||
|
|
48
gas/app.c
48
gas/app.c
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue