/* ieee.c -- Read and write IEEE-695 debugging information.
- Copyright (C) 1996 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1998, 1999, 2000 Free Software Foundation, Inc.
This file is part of GNU Binutils.
#include "libiberty.h"
#include "debug.h"
#include "budbg.h"
+#include "filenames.h"
/* This structure holds an entry on the block stack. */
const char *filename;
/* The index of the function type, for a BB4 or BB6 block. */
unsigned int fnindx;
+ /* True if this function is being skipped. */
+ boolean skip;
};
/* This structure is the block stack. */
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;
};
struct ieee_info *info;
{
ieee_error (info, (const bfd_byte *) NULL,
- "unexpected end of debugging information");
+ _("unexpected end of debugging information"));
}
/* Save a string in memory. */
return true;
}
- ieee_error (info, *pp - 1, "invalid number");
+ ieee_error (info, *pp - 1, _("invalid number"));
return false;
}
*ppresent = false;
return true;
}
- ieee_error (info, *pp - 1, "invalid string length");
+ ieee_error (info, *pp - 1, _("invalid string length"));
return false;
}
{
if (esp - expr_stack >= EXPR_STACK_SIZE)
{
- ieee_error (info, start, "expression stack overflow");
+ ieee_error (info, start, _("expression stack overflow"));
return false;
}
*esp++ = val;
switch (c)
{
default:
- ieee_error (info, start, "unsupported IEEE expression operator");
+ ieee_error (info, start, _("unsupported IEEE expression operator"));
break;
case ieee_variable_R_enum:
break;
if (s == NULL)
{
- ieee_error (info, start, "unknown section");
+ ieee_error (info, start, _("unknown section"));
return false;
}
if (esp - expr_stack >= EXPR_STACK_SIZE)
{
- ieee_error (info, start, "expression stack overflow");
+ ieee_error (info, start, _("expression stack overflow"));
return false;
}
if (esp - expr_stack < 2)
{
- ieee_error (info, start, "expression stack underflow");
+ ieee_error (info, start, _("expression stack underflow"));
return false;
}
if (esp - 1 != expr_stack)
{
- ieee_error (info, expr_start, "expression stack mismatch");
+ ieee_error (info, expr_start, _("expression stack mismatch"));
return false;
}
switch ((enum builtin_types) indx)
{
default:
- ieee_error (info, p, "unknown builtin type");
+ ieee_error (info, p, _("unknown builtin type"));
return NULL;
case builtin_unknown:
break;
case builtin_bcd_float:
- ieee_error (info, p, "BCD float type not supported");
- return false;
+ ieee_error (info, p, _("BCD float type not supported"));
+ return DEBUG_TYPE_NULL;
}
if (name != NULL)
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.global_vars = NULL;
info.types.alloc = 0;
info.types.types = NULL;
+ info.global_types = NULL;
info.tags = NULL;
for (i = 0; i < BUILTIN_TYPE_COUNT; i++)
info.types.builtins[i] = DEBUG_TYPE_NULL;
if (c <= ieee_number_repeat_end_enum)
{
- ieee_error (&info, record_start, "unexpected number");
+ ieee_error (&info, record_start, _("unexpected number"));
return false;
}
switch (c)
{
default:
- ieee_error (&info, record_start, "unexpected record type");
+ ieee_error (&info, record_start, _("unexpected record type"));
return false;
case ieee_bb_record_enum:
if (info.blockstack.bsp != info.blockstack.stack)
{
ieee_error (&info, (const bfd_byte *) NULL,
- "blocks left on stack at end");
+ _("blocks left on stack at end"));
return false;
}
bfd_vma size;
const char *name;
unsigned long namlen;
- char *namcopy;
+ char *namcopy = NULL;
unsigned int fnindx;
+ boolean skip;
block_start = *pp;
return false;
fnindx = (unsigned int) -1;
+ skip = false;
switch (b)
{
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:
empty, but we don't check. */
if (! debug_set_filename (info->dhandle, "*global*"))
return false;
+ info->saw_filename = true;
break;
case 3:
}
else
{
- debug_type return_type;
-
- if (typindx < 256)
- {
- return_type = ieee_builtin_type (info, block_start, typindx);
- if (return_type == NULL)
- return false;
- }
+ /* The MRI C++ compiler will output a fake function named
+ __XRYCPP to hold C++ debugging information. We skip
+ that function. This is not crucial, but it makes
+ converting from IEEE to other debug formats work
+ better. */
+ if (strncmp (name, "__XRYCPP", namlen) == 0)
+ skip = true;
else
{
- typindx -= 256;
- if (! ieee_alloc_type (info, typindx, true))
+ debug_type return_type;
+
+ if (typindx < 256)
+ {
+ return_type = ieee_builtin_type (info, block_start,
+ typindx);
+ if (return_type == NULL)
+ return false;
+ }
+ else
+ {
+ typindx -= 256;
+ if (! ieee_alloc_type (info, typindx, true))
+ return false;
+ fnindx = typindx;
+ return_type = info->types.types[typindx].type;
+ if (debug_get_type_kind (info->dhandle, return_type)
+ == DEBUG_KIND_FUNCTION)
+ return_type = debug_get_return_type (info->dhandle,
+ return_type);
+ }
+
+ namcopy = savestring (name, namlen);
+ if (namcopy == NULL)
+ return false;
+ if (! debug_record_function (info->dhandle, namcopy,
+ return_type, false, offset))
return false;
- fnindx = typindx;
- return_type = info->types.types[typindx].type;
- if (debug_get_type_kind (info->dhandle, return_type)
- == DEBUG_KIND_FUNCTION)
- return_type = debug_get_return_type (info->dhandle,
- return_type);
}
-
- namcopy = savestring (name, namlen);
- if (namcopy == NULL)
- return false;
- if (! debug_record_function (info->dhandle, namcopy, return_type,
- false, offset))
- return false;
}
}
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;
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))
break;
default:
- ieee_error (info, block_start, "unknown BB type");
+ ieee_error (info, block_start, _("unknown BB type"));
return false;
}
if (info->blockstack.bsp >= info->blockstack.stack + BLOCKSTACK_SIZE)
{
- ieee_error (info, (const bfd_byte *) NULL, "stack overflow");
+ ieee_error (info, (const bfd_byte *) NULL, _("stack overflow"));
return false;
}
if (b == 5)
info->blockstack.bsp->filename = namcopy;
info->blockstack.bsp->fnindx = fnindx;
+ info->blockstack.bsp->skip = skip;
++info->blockstack.bsp;
return true;
if (info->blockstack.bsp <= info->blockstack.stack)
{
- ieee_error (info, *pp, "stack underflow");
+ ieee_error (info, *pp, _("stack underflow"));
return false;
}
--info->blockstack.bsp;
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))
return false;
- if (! debug_end_function (info->dhandle, offset))
- return false;
+ if (! info->blockstack.bsp->skip)
+ {
+ if (! debug_end_function (info->dhandle, offset + 1))
+ return false;
+ }
break;
case 0x86:
function. */
if (! ieee_read_expression (info, pp, &offset))
return false;
- if (! debug_end_block (info->dhandle, offset))
+ if (! debug_end_block (info->dhandle, offset + 1))
return false;
break;
if (varindx < 32)
{
- ieee_error (info, nn_start, "illegal variable index");
+ ieee_error (info, nn_start, _("illegal variable index"));
return false;
}
varindx -= 32;
if (typeindx < 256)
{
- ieee_error (info, ty_start, "illegal type index");
+ ieee_error (info, ty_start, _("illegal type index"));
return false;
}
if (**pp != 0xce)
{
- ieee_error (info, *pp, "unknown TY code");
+ ieee_error (info, *pp, _("unknown TY code"));
return false;
}
++*pp;
if (varindx < 32)
{
- ieee_error (info, ty_var_start, "illegal variable index");
+ ieee_error (info, ty_var_start, _("illegal variable index"));
return false;
}
varindx -= 32;
if (varindx >= info->vars.alloc || info->vars.vars[varindx].name == NULL)
{
- ieee_error (info, ty_var_start, "undefined variable in TY");
+ ieee_error (info, ty_var_start, _("undefined variable in TY"));
return false;
}
switch (tc)
{
default:
- ieee_error (info, ty_code_start, "unknown TY code");
+ ieee_error (info, ty_code_start, _("unknown TY code"));
return false;
case '!':
}
break;
+ case 'V':
+ /* Void. This is not documented, but the MRI compiler emits it. */
+ type = debug_make_void_type (dhandle);
+ break;
+
case 'Z':
/* Array with 0 lower bound. */
{
case 'f':
/* Pascal file name. FIXME. */
- ieee_error (info, ty_code_start, "Pascal file name not supported");
+ ieee_error (info, ty_code_start, _("Pascal file name not supported"));
return false;
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;
switch (kind)
{
default:
- ieee_error (info, ty_start, "unsupported qualifer");
+ ieee_error (info, ty_start, _("unsupported qualifer"));
return false;
case 1:
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;
}
else if (varindx < 32)
{
- ieee_error (info, atn_start, "illegal variable index");
+ /* The MRI compiler reportedly sometimes emits variable lifetime
+ information for a register. We just ignore it. */
+ if (atn_code == 9)
+ return ieee_read_number (info, pp, &v);
+
+ ieee_error (info, atn_start, _("illegal variable index"));
return false;
}
else
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;
switch (atn_code)
{
default:
- ieee_error (info, atn_code_start, "unknown ATN type");
+ ieee_error (info, atn_code_start, _("unknown ATN type"));
return false;
case 1:
return true;
case 10:
- /* Locked register. */
+ /* Locked register. The spec says that there are two required
+ fields, but at least on occasion the MRI compiler only emits
+ one. */
if (! ieee_read_number (info, pp, &v)
- || ! ieee_read_number (info, pp, &v2))
+ || ! ieee_read_optional_number (info, pp, &v2, &present))
return false;
/* I think this means a variable that is both in a register and
case 11:
/* Reserved for FORTRAN common. */
- ieee_error (info, atn_code_start, "unsupported ATN11");
+ ieee_error (info, atn_code_start, _("unsupported ATN11"));
/* Return true to keep going. */
return true;
/* We have no way to record this information. FIXME. */
- ieee_error (info, atn_code_start, "unsupported ATN12");
+ ieee_error (info, atn_code_start, _("unsupported ATN12"));
/* Return true to keep going. */
return true;
if (present)
{
ieee_error (info, atn_code_start,
- "unexpected string in C++ misc");
+ _("unexpected string in C++ misc"));
return false;
}
return ieee_read_cxx_misc (info, pp, v2);
switch ((ieee_record_enum_type) **pp)
{
default:
- ieee_error (info, *pp, "bad misc record");
+ ieee_error (info, *pp, _("bad misc record"));
return false;
case ieee_at_record_enum:
switch (category)
{
default:
- ieee_error (info, start, "unrecognized C++ misc record");
+ ieee_error (info, start, _("unrecognized C++ misc record"));
return false;
case 'T':
break;
if (it == NULL)
{
- ieee_error (info, start, "undefined C++ object");
+ ieee_error (info, start, _("undefined C++ object"));
return false;
}
switch (id)
{
default:
- ieee_error (info, spec_start, "unrecognized C++ object spec");
+ ieee_error (info, spec_start, _("unrecognized C++ object spec"));
return false;
case 'b':
if ((fieldlen == 0) == (cinline == 0))
{
- ieee_error (info, start, "unsupported C++ object type");
+ ieee_error (info, start, _("unsupported C++ object type"));
return false;
}
free (basecopy);
if (basetype == DEBUG_TYPE_NULL)
{
- ieee_error (info, start, "C++ base class not defined");
+ ieee_error (info, start, _("C++ base class not defined"));
return false;
}
if (structfields == NULL)
{
- ieee_error (info, start, "C++ object has no fields");
+ ieee_error (info, start, _("C++ object has no fields"));
return false;
}
if (*pf == DEBUG_FIELD_NULL)
{
ieee_error (info, start,
- "C++ base class not found in container");
+ _("C++ base class not found in container"));
return false;
}
char *fieldcopy;
boolean staticp;
debug_type ftype;
- const debug_field *pf;
+ const debug_field *pf = NULL;
enum debug_visibility visibility;
debug_field field;
if (structfields == NULL)
{
- ieee_error (info, start, "C++ object has no fields");
+ ieee_error (info, start, _("C++ object has no fields"));
return false;
}
if (*pf == DEBUG_FIELD_NULL)
{
ieee_error (info, start,
- "C++ data member not found in container");
+ _("C++ data member not found in container"));
return false;
}
switch (flags & CXXFLAGS_VISIBILITY)
{
default:
- ieee_error (info, start, "unknown C++ visibility");
+ ieee_error (info, start, _("unknown C++ visibility"));
return false;
case CXXFLAGS_VISIBILITY_PUBLIC:
bitsize = debug_get_field_bitsize (dhandle, *pf);
if (bitpos == (bfd_vma) -1 || bitsize == (bfd_vma) -1)
{
- ieee_error (info, start, "bad C++ field bit pos or size");
+ ieee_error (info, start, _("bad C++ field bit pos or size"));
return false;
}
field = debug_make_field (dhandle, fieldcopy, ftype, bitpos,
!= DEBUG_KIND_FUNCTION)
{
ieee_error (info, start,
- "bad type for C++ method function");
+ _("bad type for C++ method function"));
return false;
}
if (return_type == DEBUG_TYPE_NULL || arg_types == NULL)
{
ieee_error (info, start,
- "no type information for C++ method function");
+ _("no type information for C++ method function"));
return false;
}
switch (flags & CXXFLAGS_VISIBILITY)
{
default:
- ieee_error (info, start, "unknown C++ visibility");
+ ieee_error (info, start, _("unknown C++ visibility"));
return false;
case CXXFLAGS_VISIBILITY_PUBLIC:
{
if (id == 'v')
{
- ieee_error (info, start, "C++ static virtual method");
+ ieee_error (info, start, _("C++ static virtual method"));
return false;
}
mv = debug_make_static_method_variant (dhandle, mangledcopy,
else
{
ieee_error (info, start,
- "unrecognized C++ object overhead spec");
+ _("unrecognized C++ object overhead spec"));
return false;
}
}
free (basecopy);
if (vptrbase == DEBUG_TYPE_NULL)
{
- ieee_error (info, start, "undefined C++ vtable");
+ ieee_error (info, start, _("undefined C++ vtable"));
return false;
}
}
if (info->blockstack.bsp <= info->blockstack.stack
|| info->blockstack.bsp[-1].fnindx == (unsigned int) -1)
{
- ieee_error (info, start, "C++ default values not in a function");
+ ieee_error (info, start, _("C++ default values not in a function"));
return false;
}
break;
default:
- ieee_error (info, start, "unrecognized C++ default type");
+ ieee_error (info, start, _("unrecognized C++ default type"));
return false;
}
|| (debug_get_type_kind (dhandle, arg_slots[indx])
!= DEBUG_KIND_POINTER))
{
- ieee_error (info, start, "reference parameter is not a pointer");
+ ieee_error (info, start, _("reference parameter is not a pointer"));
return false;
}
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;
-
- pv = info->vars.vars + i;
+ struct ieee_vars *vars;
+ int i;
+ struct ieee_var *pv = NULL;
- if (pv->pslot == NULL
- || pv->namlen != namlen
- || strncmp (pv->name, name, namlen) != 0)
- continue;
+ if (pass == 0)
+ vars = &info->vars;
+ else
+ {
+ vars = info->global_vars;
+ if (vars == NULL)
+ break;
+ }
- found = false;
- switch (flags)
+ for (i = (int) vars->alloc - 1; i >= 0; i--)
{
- default:
- ieee_error (info, start,
- "unrecognized C++ reference type");
- return false;
+ boolean found;
- case 0:
- /* Global variable or function. */
- if (pv->kind == IEEE_GLOBAL
- || pv->kind == IEEE_EXTERNAL
- || pv->kind == IEEE_FUNCTION)
- found = true;
- break;
+ pv = vars->vars + i;
- case 1:
- /* Global static variable or function. */
- if (pv->kind == IEEE_STATIC
- || pv->kind == IEEE_FUNCTION)
- found = true;
- break;
+ if (pv->pslot == NULL
+ || pv->namlen != namlen
+ || strncmp (pv->name, name, namlen) != 0)
+ continue;
- case 2:
- /* Local variable. */
- if (pv->kind == IEEE_LOCAL)
- found = true;
- break;
+ 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 (found)
- break;
+ if (i >= 0)
+ {
+ pslot = pv->pslot;
+ break;
+ }
}
-
- if (i >= 0)
- pslot = pv->pslot;
}
else
{
if (pslot == NULL)
{
- ieee_error (info, start, "C++ reference not found");
+ ieee_error (info, start, _("C++ reference not found"));
return false;
}
to *pslot, which we can now update to be a reference type. */
if (debug_get_type_kind (info->dhandle, *pslot) != DEBUG_KIND_POINTER)
{
- ieee_error (info, start, "C++ reference is not pointer");
+ ieee_error (info, start, _("C++ reference is not pointer"));
return false;
}
c = (ieee_record_enum_type) **pp;
if (c != ieee_e2_first_byte_enum)
{
- ieee_error (info, start, "missing required ASN");
+ ieee_error (info, start, _("missing required ASN"));
return false;
}
++*pp;
c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp);
if (c != ieee_asn_record_enum)
{
- ieee_error (info, start, "missing required ASN");
+ ieee_error (info, start, _("missing required ASN"));
return false;
}
++*pp;
c = (ieee_record_enum_type) **pp;
if (c != ieee_at_record_enum)
{
- ieee_error (info, start, "missing required ATN65");
+ ieee_error (info, start, _("missing required ATN65"));
return false;
}
++*pp;
c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp);
if (c != ieee_atn_record_enum)
{
- ieee_error (info, start, "missing required ATN65");
+ ieee_error (info, start, _("missing required ATN65"));
return false;
}
++*pp;
if (type_indx != 0 || atn_code != 65)
{
- ieee_error (info, start, "bad ATN65 record");
+ ieee_error (info, start, _("bad ATN65 record"));
return false;
}
struct ieee_defined_enum *next;
/* Type index. */
unsigned int indx;
+ /* Whether this enum has been defined. */
+ boolean defined;
/* Tag. */
const char *tag;
/* Names. */
struct ieee_modified_type *modified;
/* Number of entries allocated in modified. */
unsigned int modified_alloc;
+ /* 4 byte complex type. */
+ unsigned int complex_float_index;
+ /* 8 byte complex type. */
+ unsigned int complex_double_index;
/* The depth of block nesting. This is 0 outside a function, and 1
just after start_function is called. */
unsigned int block_depth;
/*ARGSUSED*/
static boolean
ieee_init_buffer (info, buflist)
- struct ieee_handle *info;
+ struct ieee_handle *info ATTRIBUTE_UNUSED;
struct ieee_buflist *buflist;
{
buflist->head = NULL;
/*ARGSUSED*/
static boolean
ieee_append_buffer (info, mainbuf, newbuf)
- struct ieee_handle *info;
+ struct ieee_handle *info ATTRIBUTE_UNUSED;
struct ieee_buflist *mainbuf;
struct ieee_buflist *newbuf;
{
if (c > (unsigned int) (ieee_number_repeat_end_enum
- ieee_number_repeat_start_enum))
{
- fprintf (stderr, "IEEE numeric overflow: 0x");
+ fprintf (stderr, _("IEEE numeric overflow: 0x"));
fprintf_vma (stderr, v);
fprintf (stderr, "\n");
return false;
}
else
{
- fprintf (stderr, "IEEE string length overflow: %u\n", len);
+ fprintf (stderr, _("IEEE string length overflow: %u\n"), len);
return false;
}
/* Prepend the global typedef information to the other data. */
if (! ieee_buffer_emptyp (&info.global_types))
{
+ /* The HP debugger seems to have a bug in which it ignores the
+ last entry in the global types, so we add a dummy entry. */
if (! ieee_change_buffer (&info, &info.global_types)
+ || ! ieee_write_byte (&info, (int) ieee_nn_record)
+ || ! ieee_write_number (&info, info.name_indx)
+ || ! ieee_write_id (&info, "")
+ || ! ieee_write_byte (&info, (int) ieee_ty_record_enum)
+ || ! ieee_write_number (&info, info.type_indx)
+ || ! ieee_write_byte (&info, 0xce)
+ || ! ieee_write_number (&info, info.name_indx)
+ || ! ieee_write_number (&info, 'P')
+ || ! ieee_write_number (&info, (int) builtin_void + 32)
|| ! ieee_write_byte (&info, (int) ieee_be_record_enum))
return false;
{
struct ieee_handle *info = (struct ieee_handle *) p;
const char *modname;
+ const char *backslash;
char *c, *s;
unsigned int nindx;
info->filename = filename;
modname = strrchr (filename, '/');
+ /* We could have a mixed forward/back slash case. */
+ backslash = strrchr (filename, '\\');
+ if (modname == NULL || (backslash != NULL && backslash > modname))
+ modname = backslash;
+
if (modname != NULL)
++modname;
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ else if (filename[0] && filename[1] == ':')
+ modname = filename + 2;
+#endif
else
- {
- modname = strrchr (filename, '\\');
- if (modname != NULL)
- ++modname;
- else
- modname = filename;
- }
+ modname = filename;
+
c = xstrdup (modname);
s = strrchr (c, '.');
if (s != NULL)
/* Coalesce ranges if it seems reasonable. */
while (r->next != NULL
- && high + 64 >= r->next->low
+ && high + 0x1000 >= r->next->low
&& (r->next->high
<= (bfd_get_section_vma (info->abfd, s)
+ bfd_section_size (info->abfd, s))))
static void
ieee_add_bb11_blocks (abfd, sec, data)
- bfd *abfd;
+ bfd *abfd ATTRIBUTE_UNUSED;
asection *sec;
PTR data;
{
return;
}
- if (low < r->low)
+ if (low < r->low
+ && r->low - low > 0x100)
{
if (! ieee_add_bb11 (info, sec, low, r->low))
{
}
else
{
- const char *filename, *modname;
+ const char *filename, *modname, *backslash;
char *c, *s;
/* Start the enclosing BB10 block. */
filename = bfd_get_filename (info->abfd);
modname = strrchr (filename, '/');
+ backslash = strrchr (filename, '\\');
+ if (modname == NULL || (backslash != NULL && backslash > modname))
+ modname = backslash;
+
if (modname != NULL)
++modname;
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ else if (filename[0] && filename[1] == ':')
+ modname = filename + 2;
+#endif
else
- {
- modname = strrchr (filename, '\\');
- if (modname != NULL)
- ++modname;
- else
- modname = filename;
- }
+ modname = filename;
+
c = xstrdup (modname);
s = strrchr (c, '.');
if (s != NULL)
/*ARGSUSED*/
static boolean
ieee_start_source (p, filename)
- PTR p;
- const char *filename;
+ PTR p ATTRIBUTE_UNUSED;
+ const char *filename ATTRIBUTE_UNUSED;
{
return true;
}
{
struct ieee_handle *info = (struct ieee_handle *) p;
- return ieee_push_type (info, 0, 0, false, false);
+ return ieee_push_type (info, (int) builtin_unknown, 0, false, false);
}
/* Make a void type. */
{
struct ieee_handle *info = (struct ieee_handle *) p;
- return ieee_push_type (info, 1, 0, false, false);
+ return ieee_push_type (info, (int) builtin_void, 0, false, false);
}
/* Make an integer type. */
indx = (int) builtin_signed_long_long;
break;
default:
- fprintf (stderr, "IEEE unsupported integer type size %u\n", size);
+ fprintf (stderr, _("IEEE unsupported integer type size %u\n"), size);
return false;
}
indx = (int) builtin_long_long_double;
break;
default:
- fprintf (stderr, "IEEE unsupported float type size %u\n", size);
+ fprintf (stderr, _("IEEE unsupported float type size %u\n"), size);
return false;
}
switch (size)
{
case 4:
+ if (info->complex_float_index != 0)
+ return ieee_push_type (info, info->complex_float_index, size * 2,
+ false, false);
code = 'c';
break;
+ case 12:
+ case 16:
+ /* These cases can be output by gcc -gstabs. Outputting the
+ wrong type is better than crashing. */
case 8:
+ if (info->complex_double_index != 0)
+ return ieee_push_type (info, info->complex_double_index, size * 2,
+ false, false);
code = 'd';
break;
default:
- fprintf (stderr, "IEEE unsupported complex type size %u\n", size);
+ fprintf (stderr, _("IEEE unsupported complex type size %u\n"), size);
return false;
}
/* FIXME: I don't know what the string is for. */
- return (ieee_define_type (info, size, false, false)
- && ieee_write_number (info, code)
- && ieee_write_id (info, ""));
+ if (! ieee_define_type (info, size * 2, false, false)
+ || ! ieee_write_number (info, code)
+ || ! ieee_write_id (info, ""))
+ return false;
+
+ if (size == 4)
+ info->complex_float_index = info->type_stack->type.indx;
+ else
+ info->complex_double_index = info->type_stack->type.indx;
+
+ return true;
}
/* Make a boolean type. IEEE doesn't support these, so we just make
struct ieee_handle *info = (struct ieee_handle *) p;
struct ieee_defined_enum *e;
boolean localp, simple;
- int i;
+ unsigned int indx;
+ int i = 0;
localp = false;
+ indx = (unsigned int) -1;
for (e = info->enums; e != NULL; e = e->next)
{
if (tag == NULL)
continue;
}
+ if (! e->defined)
+ {
+ /* This enum tag has been seen but not defined. */
+ indx = e->indx;
+ break;
+ }
+
if (names != NULL && e->names != NULL)
{
for (i = 0; names[i] != NULL && e->names[i] != NULL; i++)
}
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);
}
}
- if (! ieee_define_named_type (info, tag, (unsigned int) -1, 0,
- true, localp, (struct ieee_buflist *) NULL)
+ if (! ieee_define_named_type (info, tag, indx, 0, true, localp,
+ (struct ieee_buflist *) NULL)
|| ! ieee_write_number (info, simple ? 'E' : 'N'))
return false;
if (simple)
if (! localp)
{
- e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
- memset (e, 0, sizeof *e);
+ if (indx == (unsigned int) -1)
+ {
+ e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
+ memset (e, 0, sizeof *e);
+ e->indx = info->type_stack->type.indx;
+ e->tag = tag;
+
+ e->next = info->enums;
+ info->enums = e;
+ }
- e->indx = info->type_stack->type.indx;
- e->tag = tag;
e->names = names;
e->vals = vals;
-
- e->next = info->enums;
- info->enums = e;
+ e->defined = true;
}
return true;
PTR p;
bfd_signed_vma low;
bfd_signed_vma high;
- boolean stringp;
+ boolean stringp ATTRIBUTE_UNUSED;
{
struct ieee_handle *info = (struct ieee_handle *) p;
unsigned int eleindx;
boolean localp;
+ unsigned int size;
struct ieee_modified_type *m = NULL;
struct ieee_modified_array_type *a;
/* IEEE does not store the range, so we just ignore it. */
ieee_pop_unused_type (info);
localp = info->type_stack->type.localp;
+ size = info->type_stack->type.size;
eleindx = ieee_pop_type (info);
+ /* If we don't know the range, treat the size as exactly one
+ element. */
+ if (low < high)
+ size *= (high - low) + 1;
+
if (! localp)
{
m = ieee_get_modified_info (info, eleindx);
for (a = m->arrays; a != NULL; a = a->next)
{
if (a->low == low && a->high == high)
- return ieee_push_type (info, a->indx, 0, false, false);
+ return ieee_push_type (info, a->indx, size, false, false);
}
}
- if (! ieee_define_type (info, 0, false, localp)
+ if (! ieee_define_type (info, size, false, localp)
|| ! ieee_write_number (info, low == 0 ? 'Z' : 'C')
|| ! ieee_write_number (info, eleindx))
return false;
static boolean
ieee_set_type (p, bitstringp)
PTR p;
- boolean bitstringp;
+ boolean bitstringp ATTRIBUTE_UNUSED;
{
struct ieee_handle *info = (struct ieee_handle *) p;
boolean localp;
for (e = info->enums; e != NULL; e = e->next)
if (e->tag != NULL && strcmp (e->tag, name) == 0)
return ieee_push_type (info, e->indx, 0, true, false);
- abort ();
+
+ e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
+ memset (e, 0, sizeof *e);
+
+ e->indx = info->type_indx;
+ ++info->type_indx;
+ e->tag = name;
+ e->defined = false;
+
+ e->next = info->enums;
+ info->enums = e;
+
+ return ieee_push_type (info, e->indx, 0, true, false);
}
localp = false;
static boolean
ieee_tag (p, name)
PTR p;
- const char *name;
+ const char *name ATTRIBUTE_UNUSED;
{
struct ieee_handle *info = (struct ieee_handle *) p;
static boolean
ieee_int_constant (p, name, val)
- PTR p;
- const char *name;
- bfd_vma val;
+ PTR p ATTRIBUTE_UNUSED;
+ const char *name ATTRIBUTE_UNUSED;
+ bfd_vma val ATTRIBUTE_UNUSED;
{
/* FIXME. */
return true;
static boolean
ieee_float_constant (p, name, val)
- PTR p;
- const char *name;
- double val;
+ PTR p ATTRIBUTE_UNUSED;
+ const char *name ATTRIBUTE_UNUSED;
+ double val ATTRIBUTE_UNUSED;
{
/* FIXME. */
return true;
static boolean
ieee_typed_constant (p, name, val)
PTR p;
- const char *name;
- bfd_vma val;
+ const char *name ATTRIBUTE_UNUSED;
+ bfd_vma val ATTRIBUTE_UNUSED;
{
struct ieee_handle *info = (struct ieee_handle *) p;
return false;
if (strcmp (info->filename, info->pending_lineno_filename) == 0)
{
- /* We need a new NN record, and we aren't output to
+ /* We need a new NN record, and we aren't about to
output one. */
info->lineno_name_indx = info->name_indx;
++info->name_indx;