mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-13 12:23:33 +08:00
* ieee.c (struct ieee_info): Add global_types field.
(parse_ieee_bb): When starting a BB1, initialize the types field to the global_types field. (parse_ieee_be): When ending a BB2, copy the types field to the global_types field.
This commit is contained in:
parent
9859bc3192
commit
0dcbbb6029
@ -1,3 +1,11 @@
|
||||
Mon Sep 16 15:30:54 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* ieee.c (struct ieee_info): Add global_types field.
|
||||
(parse_ieee_bb): When starting a BB1, initialize the types field
|
||||
to the global_types field.
|
||||
(parse_ieee_be): When ending a BB2, copy the types field to the
|
||||
global_types field.
|
||||
|
||||
Fri Sep 13 17:32:21 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* objcopy.c (change_leading_char): New static variable.
|
||||
|
256
binutils/ieee.c
256
binutils/ieee.c
@ -154,10 +154,16 @@ struct ieee_info
|
||||
const bfd_byte *pend;
|
||||
/* The block stack. */
|
||||
struct ieee_blockstack blockstack;
|
||||
/* Whether we have seen a BB1 or BB2. */
|
||||
boolean saw_filename;
|
||||
/* The variables. */
|
||||
struct ieee_vars vars;
|
||||
/* The global variables, after a global typedef block. */
|
||||
struct ieee_vars *global_vars;
|
||||
/* The types. */
|
||||
struct ieee_types types;
|
||||
/* The global types, after a global typedef block. */
|
||||
struct ieee_types *global_types;
|
||||
/* The list of tagged structs. */
|
||||
struct ieee_tag *tags;
|
||||
};
|
||||
@ -891,6 +897,7 @@ parse_ieee (dhandle, abfd, bytes, len)
|
||||
info.bytes = bytes;
|
||||
info.pend = bytes + len;
|
||||
info.blockstack.bsp = info.blockstack.stack;
|
||||
info.saw_filename = false;
|
||||
info.vars.alloc = 0;
|
||||
info.vars.vars = NULL;
|
||||
info.types.alloc = 0;
|
||||
@ -999,6 +1006,29 @@ parse_ieee_bb (info, pp)
|
||||
return false;
|
||||
if (! debug_set_filename (info->dhandle, namcopy))
|
||||
return false;
|
||||
info->saw_filename = true;
|
||||
|
||||
/* Discard any variables or types we may have seen before. */
|
||||
if (info->vars.vars != NULL)
|
||||
free (info->vars.vars);
|
||||
info->vars.vars = NULL;
|
||||
info->vars.alloc = 0;
|
||||
if (info->types.types != NULL)
|
||||
free (info->types.types);
|
||||
info->types.types = NULL;
|
||||
info->types.alloc = 0;
|
||||
|
||||
/* Initialize the types to the global types. */
|
||||
if (info->global_types != NULL)
|
||||
{
|
||||
info->types.alloc = info->global_types->alloc;
|
||||
info->types.types = ((struct ieee_type *)
|
||||
xmalloc (info->types.alloc
|
||||
* sizeof (*info->types.types)));
|
||||
memcpy (info->types.types, info->global_types->types,
|
||||
info->types.alloc * sizeof (*info->types.types));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
@ -1006,6 +1036,7 @@ parse_ieee_bb (info, pp)
|
||||
empty, but we don't check. */
|
||||
if (! debug_set_filename (info->dhandle, "*global*"))
|
||||
return false;
|
||||
info->saw_filename = true;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
@ -1145,8 +1176,8 @@ parse_ieee_bb (info, pp)
|
||||
break;
|
||||
|
||||
case 10:
|
||||
/* BB10: Assembler module scope. We completely ignore all this
|
||||
information. FIXME. */
|
||||
/* BB10: Assembler module scope. In the normal case, we
|
||||
completely ignore all this information. FIXME. */
|
||||
{
|
||||
const char *inam, *vstr;
|
||||
unsigned long inamlen, vstrlen;
|
||||
@ -1154,6 +1185,16 @@ parse_ieee_bb (info, pp)
|
||||
boolean present;
|
||||
unsigned int i;
|
||||
|
||||
if (! info->saw_filename)
|
||||
{
|
||||
namcopy = savestring (name, namlen);
|
||||
if (namcopy == NULL)
|
||||
return false;
|
||||
if (! debug_set_filename (info->dhandle, namcopy))
|
||||
return false;
|
||||
info->saw_filename = true;
|
||||
}
|
||||
|
||||
if (! ieee_read_id (info, pp, &inam, &inamlen)
|
||||
|| ! ieee_read_number (info, pp, &tool_type)
|
||||
|| ! ieee_read_optional_id (info, pp, &vstr, &vstrlen, &present))
|
||||
@ -1227,6 +1268,37 @@ parse_ieee_be (info, pp)
|
||||
|
||||
switch (info->blockstack.bsp->kind)
|
||||
{
|
||||
case 2:
|
||||
/* When we end the global typedefs block, we copy out the the
|
||||
contents of info->vars. This is because the variable indices
|
||||
may be reused in the local blocks. However, we need to
|
||||
preserve them so that we can locate a function returning a
|
||||
reference variable whose type is named in the global typedef
|
||||
block. */
|
||||
info->global_vars = ((struct ieee_vars *)
|
||||
xmalloc (sizeof *info->global_vars));
|
||||
info->global_vars->alloc = info->vars.alloc;
|
||||
info->global_vars->vars = ((struct ieee_var *)
|
||||
xmalloc (info->vars.alloc
|
||||
* sizeof (*info->vars.vars)));
|
||||
memcpy (info->global_vars->vars, info->vars.vars,
|
||||
info->vars.alloc * sizeof (*info->vars.vars));
|
||||
|
||||
/* We also copy out the non builtin parts of info->types, since
|
||||
the types are discarded when we start a new block. */
|
||||
info->global_types = ((struct ieee_types *)
|
||||
xmalloc (sizeof *info->global_types));
|
||||
info->global_types->alloc = info->types.alloc;
|
||||
info->global_types->types = ((struct ieee_type *)
|
||||
xmalloc (info->types.alloc
|
||||
* sizeof (*info->types.types)));
|
||||
memcpy (info->global_types->types, info->types.types,
|
||||
info->types.alloc * sizeof (*info->types.types));
|
||||
memset (info->global_types->builtins, 0,
|
||||
sizeof (info->global_types->builtins));
|
||||
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 6:
|
||||
if (! ieee_read_expression (info, pp, &offset))
|
||||
@ -1799,16 +1871,31 @@ parse_ieee_ty (info, pp)
|
||||
case 'g':
|
||||
/* Bitfield type. */
|
||||
{
|
||||
bfd_vma signedp, bitsize;
|
||||
bfd_vma signedp, bitsize, dummy;
|
||||
const bfd_byte *hold;
|
||||
boolean present;
|
||||
|
||||
if (! ieee_read_number (info, pp, &signedp)
|
||||
|| ! ieee_read_number (info, pp, &bitsize)
|
||||
|| ! ieee_read_type_index (info, pp, &type))
|
||||
|| ! ieee_read_number (info, pp, &bitsize))
|
||||
return false;
|
||||
|
||||
/* FIXME: This is just a guess. */
|
||||
if (! signedp)
|
||||
type = debug_make_int_type (dhandle, 4, true);
|
||||
/* I think the documentation says that there is a type index,
|
||||
but some actual files do not have one. */
|
||||
hold = *pp;
|
||||
if (! ieee_read_optional_number (info, pp, &dummy, &present))
|
||||
return false;
|
||||
if (! present)
|
||||
{
|
||||
/* FIXME: This is just a guess. */
|
||||
type = debug_make_int_type (dhandle, 4,
|
||||
signedp ? false : true);
|
||||
}
|
||||
else
|
||||
{
|
||||
*pp = hold;
|
||||
if (! ieee_read_type_index (info, pp, &type))
|
||||
return false;
|
||||
}
|
||||
type_bitsize = bitsize;
|
||||
}
|
||||
break;
|
||||
@ -1959,8 +2046,7 @@ parse_ieee_ty (info, pp)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Record the type in the table. If the corresponding NN record has
|
||||
a name, name it. FIXME: Is this always correct? */
|
||||
/* Record the type in the table. */
|
||||
|
||||
if (type == DEBUG_TYPE_NULL)
|
||||
return false;
|
||||
@ -2064,8 +2150,38 @@ parse_ieee_atn (info, pp)
|
||||
if (varindx >= info->vars.alloc
|
||||
|| info->vars.vars[varindx].name == NULL)
|
||||
{
|
||||
ieee_error (info, atn_start, "undefined variable in ATN");
|
||||
return false;
|
||||
/* The MRI compiler or linker sometimes omits the NN record
|
||||
for a pmisc record. */
|
||||
if (atn_code == 62)
|
||||
{
|
||||
if (varindx >= info->vars.alloc)
|
||||
{
|
||||
unsigned int alloc;
|
||||
|
||||
alloc = info->vars.alloc;
|
||||
if (alloc == 0)
|
||||
alloc = 4;
|
||||
while (varindx >= alloc)
|
||||
alloc *= 2;
|
||||
info->vars.vars = ((struct ieee_var *)
|
||||
xrealloc (info->vars.vars,
|
||||
(alloc
|
||||
* sizeof *info->vars.vars)));
|
||||
memset (info->vars.vars + info->vars.alloc, 0,
|
||||
((alloc - info->vars.alloc)
|
||||
* sizeof *info->vars.vars));
|
||||
info->vars.alloc = alloc;
|
||||
}
|
||||
|
||||
pvar = info->vars.vars + varindx;
|
||||
pvar->name = "";
|
||||
pvar->namlen = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ieee_error (info, atn_start, "undefined variable in ATN");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
pvar = info->vars.vars + varindx;
|
||||
@ -3245,60 +3361,79 @@ ieee_read_reference (info, pp)
|
||||
pslot = NULL;
|
||||
if (flags != 3)
|
||||
{
|
||||
int i;
|
||||
struct ieee_var *pv = NULL;
|
||||
int pass;
|
||||
|
||||
/* We search from the last variable indices to the first in
|
||||
hopes of finding local variables correctly. FIXME: This
|
||||
probably won't work in all cases. On the other hand, I don't
|
||||
know what will. */
|
||||
for (i = (int) info->vars.alloc - 1; i >= 0; i--)
|
||||
hopes of finding local variables correctly. We search the
|
||||
local variables on the first pass, and the global variables
|
||||
on the second. FIXME: This probably won't work in all cases.
|
||||
On the other hand, I don't know what will. */
|
||||
for (pass = 0; pass < 2; pass++)
|
||||
{
|
||||
boolean found;
|
||||
struct ieee_vars *vars;
|
||||
int i;
|
||||
struct ieee_var *pv = NULL;
|
||||
|
||||
pv = info->vars.vars + i;
|
||||
|
||||
if (pv->pslot == NULL
|
||||
|| pv->namlen != namlen
|
||||
|| strncmp (pv->name, name, namlen) != 0)
|
||||
continue;
|
||||
|
||||
found = false;
|
||||
switch (flags)
|
||||
if (pass == 0)
|
||||
vars = &info->vars;
|
||||
else
|
||||
{
|
||||
default:
|
||||
ieee_error (info, start,
|
||||
"unrecognized C++ reference type");
|
||||
return false;
|
||||
|
||||
case 0:
|
||||
/* Global variable or function. */
|
||||
if (pv->kind == IEEE_GLOBAL
|
||||
|| pv->kind == IEEE_EXTERNAL
|
||||
|| pv->kind == IEEE_FUNCTION)
|
||||
found = true;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* Global static variable or function. */
|
||||
if (pv->kind == IEEE_STATIC
|
||||
|| pv->kind == IEEE_FUNCTION)
|
||||
found = true;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* Local variable. */
|
||||
if (pv->kind == IEEE_LOCAL)
|
||||
found = true;
|
||||
break;
|
||||
vars = info->global_vars;
|
||||
if (vars == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
for (i = (int) vars->alloc - 1; i >= 0; i--)
|
||||
{
|
||||
boolean found;
|
||||
|
||||
if (i >= 0)
|
||||
pslot = pv->pslot;
|
||||
pv = vars->vars + i;
|
||||
|
||||
if (pv->pslot == NULL
|
||||
|| pv->namlen != namlen
|
||||
|| strncmp (pv->name, name, namlen) != 0)
|
||||
continue;
|
||||
|
||||
found = false;
|
||||
switch (flags)
|
||||
{
|
||||
default:
|
||||
ieee_error (info, start,
|
||||
"unrecognized C++ reference type");
|
||||
return false;
|
||||
|
||||
case 0:
|
||||
/* Global variable or function. */
|
||||
if (pv->kind == IEEE_GLOBAL
|
||||
|| pv->kind == IEEE_EXTERNAL
|
||||
|| pv->kind == IEEE_FUNCTION)
|
||||
found = true;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* Global static variable or function. */
|
||||
if (pv->kind == IEEE_STATIC
|
||||
|| pv->kind == IEEE_FUNCTION)
|
||||
found = true;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* Local variable. */
|
||||
if (pv->kind == IEEE_LOCAL)
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= 0)
|
||||
{
|
||||
pslot = pv->pslot;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -5299,7 +5434,10 @@ ieee_enum_type (p, tag, names, vals)
|
||||
}
|
||||
|
||||
if ((names == NULL && e->names == NULL)
|
||||
|| (names[i] == NULL && e->names[i] == NULL))
|
||||
|| (names != NULL
|
||||
&& e->names != NULL
|
||||
&& names[i] == NULL
|
||||
&& e->names[i] == NULL))
|
||||
{
|
||||
/* We've seen this enum before. */
|
||||
return ieee_push_type (info, e->indx, 0, true, false);
|
||||
|
Loading…
Reference in New Issue
Block a user