X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Fieee.c;h=ad5ddc7d65cb3aed0b6adcd83e4d2703fb3b7ae6;hb=279a96ca3981d4b8c2396c26a0bbba6a02226dde;hp=642006b27297fe683494ec5ca5a2ffc46ec12627;hpb=fe1dc0a65609c03742ad506f9185778415e021f7;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/ieee.c b/binutils/ieee.c index 642006b272..ad5ddc7d65 100644 --- a/binutils/ieee.c +++ b/binutils/ieee.c @@ -1,5 +1,5 @@ /* ieee.c -- Read and write IEEE-695 debugging information. - Copyright (C) 1996 Free Software Foundation, Inc. + Copyright 1996, 1998, 2000, 2001 Free Software Foundation, Inc. Written by Ian Lance Taylor . This file is part of GNU Binutils. @@ -30,6 +30,7 @@ #include "libiberty.h" #include "debug.h" #include "budbg.h" +#include "filenames.h" /* This structure holds an entry on the block stack. */ @@ -41,6 +42,8 @@ struct ieee_block 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. */ @@ -152,10 +155,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; }; @@ -305,7 +314,7 @@ ieee_eof (info) 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. */ @@ -400,8 +409,8 @@ ieee_read_optional_number (info, pp, pv, ppresent) return true; } - ieee_error (info, *pp - 1, "invalid number"); - return false; + ieee_error (info, *pp - 1, _("invalid number")); + return false; } /* Read a required string from an IEEE file. */ @@ -459,7 +468,7 @@ ieee_read_optional_id (info, pp, pname, pnamlen, ppresent) *ppresent = false; return true; } - ieee_error (info, *pp - 1, "invalid string length"); + ieee_error (info, *pp - 1, _("invalid string length")); return false; } @@ -516,7 +525,7 @@ ieee_read_expression (info, pp, pv) { 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; @@ -536,7 +545,7 @@ ieee_read_expression (info, pp, pv) 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: @@ -551,13 +560,13 @@ ieee_read_expression (info, pp, pv) 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; } @@ -572,7 +581,7 @@ ieee_read_expression (info, pp, pv) if (esp - expr_stack < 2) { - ieee_error (info, start, "expression stack underflow"); + ieee_error (info, start, _("expression stack underflow")); return false; } @@ -586,7 +595,7 @@ ieee_read_expression (info, pp, pv) if (esp - 1 != expr_stack) { - ieee_error (info, expr_start, "expression stack mismatch"); + ieee_error (info, expr_start, _("expression stack mismatch")); return false; } @@ -625,7 +634,7 @@ ieee_builtin_type (info, p, indx) 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: @@ -770,8 +779,8 @@ ieee_builtin_type (info, p, indx) 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) @@ -889,10 +898,13 @@ 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.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; @@ -913,14 +925,14 @@ parse_ieee (dhandle, abfd, bytes, len) 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: @@ -953,7 +965,7 @@ parse_ieee (dhandle, abfd, bytes, len) 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; } @@ -972,8 +984,9 @@ parse_ieee_bb (info, pp) bfd_vma size; const char *name; unsigned long namlen; - char *namcopy; + char *namcopy = NULL; unsigned int fnindx; + boolean skip; block_start = *pp; @@ -985,6 +998,7 @@ parse_ieee_bb (info, pp) return false; fnindx = (unsigned int) -1; + skip = false; switch (b) { @@ -995,6 +1009,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: @@ -1002,6 +1039,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: @@ -1098,40 +1136,51 @@ parse_ieee_bb (info, pp) } 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; @@ -1139,6 +1188,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)) @@ -1171,7 +1230,7 @@ parse_ieee_bb (info, pp) break; default: - ieee_error (info, block_start, "unknown BB type"); + ieee_error (info, block_start, _("unknown BB type")); return false; } @@ -1180,7 +1239,7 @@ parse_ieee_bb (info, pp) 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; } @@ -1188,6 +1247,7 @@ parse_ieee_bb (info, pp) if (b == 5) info->blockstack.bsp->filename = namcopy; info->blockstack.bsp->fnindx = fnindx; + info->blockstack.bsp->skip = skip; ++info->blockstack.bsp; return true; @@ -1204,19 +1264,53 @@ parse_ieee_be (info, pp) 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: @@ -1224,7 +1318,7 @@ parse_ieee_be (info, pp) 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; @@ -1284,7 +1378,7 @@ parse_ieee_nn (info, pp) if (varindx < 32) { - ieee_error (info, nn_start, "illegal variable index"); + ieee_error (info, nn_start, _("illegal variable index")); return false; } varindx -= 32; @@ -1334,7 +1428,7 @@ parse_ieee_ty (info, pp) if (typeindx < 256) { - ieee_error (info, ty_start, "illegal type index"); + ieee_error (info, ty_start, _("illegal type index")); return false; } @@ -1344,7 +1438,7 @@ parse_ieee_ty (info, pp) if (**pp != 0xce) { - ieee_error (info, *pp, "unknown TY code"); + ieee_error (info, *pp, _("unknown TY code")); return false; } ++*pp; @@ -1356,14 +1450,14 @@ parse_ieee_ty (info, 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; } @@ -1381,7 +1475,7 @@ parse_ieee_ty (info, pp) switch (tc) { default: - ieee_error (info, ty_code_start, "unknown TY code"); + ieee_error (info, ty_code_start, _("unknown TY code")); return false; case '!': @@ -1734,6 +1828,11 @@ parse_ieee_ty (info, pp) } 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. */ { @@ -1769,22 +1868,37 @@ parse_ieee_ty (info, pp) 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; @@ -1802,7 +1916,7 @@ parse_ieee_ty (info, pp) switch (kind) { default: - ieee_error (info, ty_start, "unsupported qualifer"); + ieee_error (info, ty_start, _("unsupported qualifer")); return false; case 1: @@ -1935,8 +2049,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; @@ -2031,7 +2144,12 @@ parse_ieee_atn (info, pp) } 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 @@ -2040,8 +2158,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; @@ -2082,7 +2230,7 @@ parse_ieee_atn (info, pp) 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: @@ -2185,9 +2333,11 @@ parse_ieee_atn (info, pp) 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 @@ -2202,7 +2352,7 @@ parse_ieee_atn (info, pp) 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; @@ -2229,7 +2379,7 @@ parse_ieee_atn (info, pp) /* 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; @@ -2289,7 +2439,7 @@ parse_ieee_atn (info, pp) 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); @@ -2302,7 +2452,7 @@ parse_ieee_atn (info, pp) 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: @@ -2345,7 +2495,7 @@ ieee_read_cxx_misc (info, pp, count) switch (category) { default: - ieee_error (info, start, "unrecognized C++ misc record"); + ieee_error (info, start, _("unrecognized C++ misc record")); return false; case 'T': @@ -2462,7 +2612,7 @@ ieee_read_cxx_class (info, pp, count) break; if (it == NULL) { - ieee_error (info, start, "undefined C++ object"); + ieee_error (info, start, _("undefined C++ object")); return false; } @@ -2496,7 +2646,7 @@ ieee_read_cxx_class (info, pp, count) 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': @@ -2532,7 +2682,7 @@ ieee_read_cxx_class (info, pp, count) if ((fieldlen == 0) == (cinline == 0)) { - ieee_error (info, start, "unsupported C++ object type"); + ieee_error (info, start, _("unsupported C++ object type")); return false; } @@ -2542,7 +2692,7 @@ ieee_read_cxx_class (info, pp, count) 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; } @@ -2554,7 +2704,7 @@ ieee_read_cxx_class (info, pp, count) if (structfields == NULL) { - ieee_error (info, start, "C++ object has no fields"); + ieee_error (info, start, _("C++ object has no fields")); return false; } @@ -2573,7 +2723,7 @@ ieee_read_cxx_class (info, pp, count) 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; } @@ -2617,7 +2767,7 @@ ieee_read_cxx_class (info, pp, count) char *fieldcopy; boolean staticp; debug_type ftype; - const debug_field *pf; + const debug_field *pf = NULL; enum debug_visibility visibility; debug_field field; @@ -2659,7 +2809,7 @@ ieee_read_cxx_class (info, pp, count) if (structfields == NULL) { - ieee_error (info, start, "C++ object has no fields"); + ieee_error (info, start, _("C++ object has no fields")); return false; } @@ -2680,7 +2830,7 @@ ieee_read_cxx_class (info, pp, count) 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; } @@ -2721,7 +2871,7 @@ ieee_read_cxx_class (info, pp, count) 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: @@ -2755,7 +2905,7 @@ ieee_read_cxx_class (info, pp, count) 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, @@ -2847,7 +2997,7 @@ ieee_read_cxx_class (info, pp, count) != DEBUG_KIND_FUNCTION) { ieee_error (info, start, - "bad type for C++ method function"); + _("bad type for C++ method function")); return false; } @@ -2857,7 +3007,7 @@ ieee_read_cxx_class (info, pp, count) 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; } @@ -2871,7 +3021,7 @@ ieee_read_cxx_class (info, pp, count) 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: @@ -2896,7 +3046,7 @@ ieee_read_cxx_class (info, pp, count) { 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, @@ -2991,7 +3141,7 @@ ieee_read_cxx_class (info, pp, count) else { ieee_error (info, start, - "unrecognized C++ object overhead spec"); + _("unrecognized C++ object overhead spec")); return false; } } @@ -3030,7 +3180,7 @@ ieee_read_cxx_class (info, pp, count) free (basecopy); if (vptrbase == DEBUG_TYPE_NULL) { - ieee_error (info, start, "undefined C++ vtable"); + ieee_error (info, start, _("undefined C++ vtable")); return false; } } @@ -3101,7 +3251,7 @@ ieee_read_cxx_defaults (info, pp, count) 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; } @@ -3141,7 +3291,7 @@ ieee_read_cxx_defaults (info, pp, count) break; default: - ieee_error (info, start, "unrecognized C++ default type"); + ieee_error (info, start, _("unrecognized C++ default type")); return false; } @@ -3172,7 +3322,7 @@ ieee_read_cxx_defaults (info, pp, count) || (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; } @@ -3219,60 +3369,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; + 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 { @@ -3320,7 +3489,7 @@ ieee_read_reference (info, pp) if (pslot == NULL) { - ieee_error (info, start, "C++ reference not found"); + ieee_error (info, start, _("C++ reference not found")); return false; } @@ -3328,7 +3497,7 @@ ieee_read_reference (info, pp) 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; } @@ -3357,7 +3526,7 @@ ieee_require_asn (info, pp, pv) 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; @@ -3365,7 +3534,7 @@ ieee_require_asn (info, pp, pv) 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; @@ -3395,7 +3564,7 @@ ieee_require_atn65 (info, pp, pname, pnamlen) 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; @@ -3403,7 +3572,7 @@ ieee_require_atn65 (info, pp, pname, pnamlen) 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; @@ -3417,7 +3586,7 @@ ieee_require_atn65 (info, pp, pname, pnamlen) if (type_indx != 0 || atn_code != 65) { - ieee_error (info, start, "bad ATN65 record"); + ieee_error (info, start, _("bad ATN65 record")); return false; } @@ -3432,6 +3601,25 @@ ieee_regno_to_genreg (abfd, r) bfd *abfd; int r; { + switch (bfd_get_arch (abfd)) + { + case bfd_arch_m68k: + /* For some reasons stabs adds 2 to the floating point register + numbers. */ + if (r >= 16) + r += 2; + break; + + case bfd_arch_i960: + /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and + 32 to 35 for fp0 to fp3. */ + --r; + break; + + default: + break; + } + return r; } @@ -3442,6 +3630,25 @@ ieee_genreg_to_regno (abfd, r) bfd *abfd; int r; { + switch (bfd_get_arch (abfd)) + { + case bfd_arch_m68k: + /* For some reason stabs add 2 to the floating point register + numbers. */ + if (r >= 18) + r -= 2; + break; + + case bfd_arch_i960: + /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and + 32 to 35 for fp0 to fp3. */ + ++r; + break; + + default: + break; + } + return r; } @@ -3592,6 +3799,8 @@ struct ieee_defined_enum struct ieee_defined_enum *next; /* Type index. */ unsigned int indx; + /* Whether this enum has been defined. */ + boolean defined; /* Tag. */ const char *tag; /* Names. */ @@ -3703,6 +3912,10 @@ struct ieee_handle 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; @@ -3892,7 +4105,7 @@ static const struct debug_write_fns ieee_fns = /*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; @@ -3933,7 +4146,7 @@ ieee_change_buffer (info, buflist) /*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; { @@ -4020,7 +4233,7 @@ ieee_write_number (info, v) 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; @@ -4066,7 +4279,7 @@ ieee_write_id (info, s) } else { - fprintf (stderr, "IEEE string length overflow: %u\n", len); + fprintf (stderr, _("IEEE string length overflow: %u\n"), len); return false; } @@ -4281,7 +4494,7 @@ ieee_start_range (info, low) r->next = info->pending_ranges; info->pending_ranges = r; return true; -} +} /* Finish a range started by ieee_start_range. */ @@ -4527,7 +4740,18 @@ write_ieee_debugging_info (abfd, dhandle) /* 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; @@ -4642,6 +4866,14 @@ ieee_write_undefined_tag (h, p) return false; } } + else + { + if (! ieee_change_buffer (info, &info->global_types)) + { + info->error = true; + return false; + } + } name_indx = info->name_indx; ++info->name_indx; @@ -4695,6 +4927,9 @@ ieee_start_compilation_unit (p, filename) { struct ieee_handle *info = (struct ieee_handle *) p; const char *modname; +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + const char *backslash; +#endif char *c, *s; unsigned int nindx; @@ -4706,16 +4941,22 @@ ieee_start_compilation_unit (p, filename) info->filename = filename; modname = strrchr (filename, '/'); +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + /* We could have a mixed forward/back slash case. */ + backslash = strrchr (filename, '\\'); + if (modname == NULL || (backslash != NULL && backslash > modname)) + modname = backslash; +#endif + 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) @@ -4861,7 +5102,7 @@ ieee_finish_compilation_unit (info) /* 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)))) @@ -4904,7 +5145,7 @@ ieee_finish_compilation_unit (info) static void ieee_add_bb11_blocks (abfd, sec, data) - bfd *abfd; + bfd *abfd ATTRIBUTE_UNUSED; asection *sec; PTR data; { @@ -4930,7 +5171,8 @@ ieee_add_bb11_blocks (abfd, sec, data) return; } - if (low < r->low) + if (low < r->low + && r->low - low > 0x100) { if (! ieee_add_bb11 (info, sec, low, r->low)) { @@ -4963,21 +5205,29 @@ ieee_add_bb11 (info, sec, low, high) else { const char *filename, *modname; +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + const char *backslash; +#endif char *c, *s; /* Start the enclosing BB10 block. */ filename = bfd_get_filename (info->abfd); modname = strrchr (filename, '/'); +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + backslash = strrchr (filename, '\\'); + if (modname == NULL || (backslash != NULL && backslash > modname)) + modname = backslash; +#endif + 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) @@ -5026,8 +5276,8 @@ ieee_add_bb11 (info, sec, low, high) /*ARGSUSED*/ static boolean ieee_start_source (p, filename) - PTR p; - const char *filename; + PTR p ATTRIBUTE_UNUSED; + const char *filename ATTRIBUTE_UNUSED; { return true; } @@ -5040,7 +5290,7 @@ ieee_empty_type (p) { 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. */ @@ -5051,7 +5301,7 @@ ieee_void_type (p) { 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. */ @@ -5080,7 +5330,7 @@ ieee_int_type (p, size, unsignedp) 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; } @@ -5116,7 +5366,7 @@ ieee_float_type (p, size) 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; } @@ -5136,20 +5386,38 @@ ieee_complex_type (p, size) 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 @@ -5175,9 +5443,11 @@ ieee_enum_type (p, tag, names, vals) 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) @@ -5193,6 +5463,13 @@ ieee_enum_type (p, tag, names, vals) 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++) @@ -5205,7 +5482,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); @@ -5237,8 +5517,8 @@ ieee_enum_type (p, tag, names, vals) } } - 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) @@ -5264,16 +5544,20 @@ ieee_enum_type (p, tag, names, vals) 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; @@ -5459,19 +5743,26 @@ ieee_array_type (p, low, high, stringp) 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); @@ -5481,11 +5772,11 @@ ieee_array_type (p, low, high, stringp) 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; @@ -5519,7 +5810,7 @@ ieee_array_type (p, low, high, stringp) 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; @@ -5556,7 +5847,7 @@ ieee_offset_type (p) which seems pretty important. I'm going to punt this for now. */ return ieee_int_type (p, 4, true); -} +} /* Make a method type. */ @@ -6417,6 +6708,30 @@ ieee_tag_type (p, name, id, kind) struct ieee_name_type_hash_entry *h; struct ieee_name_type *nt; + if (kind == DEBUG_KIND_ENUM) + { + struct ieee_defined_enum *e; + + if (name == NULL) + abort (); + 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); + + 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; copy = false; @@ -6715,7 +7030,7 @@ ieee_typdef (p, name) static boolean ieee_tag (p, name) PTR p; - const char *name; + const char *name ATTRIBUTE_UNUSED; { struct ieee_handle *info = (struct ieee_handle *) p; @@ -6729,9 +7044,9 @@ ieee_tag (p, name) 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; @@ -6741,9 +7056,9 @@ ieee_int_constant (p, name, val) 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; @@ -6754,8 +7069,8 @@ ieee_float_constant (p, name, val) 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; @@ -7006,7 +7321,7 @@ ieee_function_parameter (p, name, kind, val) return false; ++info->fnargcount; - return true; + return true; } /* Output pending function parameters. */ @@ -7265,7 +7580,7 @@ ieee_lineno (p, filename, lineno, addr) 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;