Print this page
9312 ctf: be less clever about skipping 'extern' variables declarations
9864 DWARF->CTF enum conversion needs to be careful of sign

*** 861,875 **** } el = xcalloc(sizeof (elist_t)); el->el_name = die_name(dw, mem); ! if (die_signed(dw, mem, DW_AT_const_value, &sval, 0)) { ! el->el_number = sval; ! } else if (die_unsigned(dw, mem, DW_AT_const_value, &uval, 0)) { el->el_number = uval; } else { terminate("die %llu: enum %llu: member without " "value\n", off, die_off(dw, mem)); } --- 861,883 ---- } el = xcalloc(sizeof (elist_t)); el->el_name = die_name(dw, mem); ! /* ! * We have to be careful here: newer GCCs generate DWARF ! * where an unsigned value will happily pass ! * die_signed(). Since negative values will fail ! * die_unsigned(), we try that first to make sure we get ! * the right value. ! */ ! if (die_unsigned(dw, mem, DW_AT_const_value, &uval, 0)) { el->el_number = uval; + } else if (die_signed(dw, mem, DW_AT_const_value, + &sval, 0)) { + el->el_number = sval; } else { terminate("die %llu: enum %llu: member without " "value\n", off, die_off(dw, mem)); }
*** 1641,1653 **** iidesc_t *ii; char *name; debug(3, "die %llu: creating object definition\n", off); ! if (die_isdecl(dw, die) || (name = die_name(dw, die)) == NULL) ! return; /* skip prototypes and nameless objects */ ii = xcalloc(sizeof (iidesc_t)); ii->ii_type = die_isglobal(dw, die) ? II_GVAR : II_SVAR; ii->ii_name = name; ii->ii_dtype = die_lookup_pass1(dw, die, DW_AT_type); if (ii->ii_type == II_SVAR) --- 1649,1687 ---- iidesc_t *ii; char *name; debug(3, "die %llu: creating object definition\n", off); ! /* Skip "Non-Defining Declarations" */ ! if (die_isdecl(dw, die)) ! return; + /* + * If we find a DIE of "Declarations Completing Non-Defining + * Declarations", we will use the referenced type's DIE. This isn't + * quite correct, e.g. DW_AT_decl_line will be the forward declaration + * not this site. It's sufficient for what we need, however: in + * particular, we should find DW_AT_external as needed there. + */ + if (die_attr(dw, die, DW_AT_specification, 0) != NULL) { + Dwarf_Die sdie; + Dwarf_Off soff; + + soff = die_attr_ref(dw, die, DW_AT_specification); + + if (dwarf_offdie(dw->dw_dw, soff, + &sdie, &dw->dw_err) != DW_DLV_OK) { + terminate("dwarf_offdie(%llu) failed: %s\n", + soff, dwarf_errmsg(dw->dw_err)); + } + + die = sdie; + } + + if ((name = die_name(dw, die)) == NULL) + return; + ii = xcalloc(sizeof (iidesc_t)); ii->ii_type = die_isglobal(dw, die) ? II_GVAR : II_SVAR; ii->ii_name = name; ii->ii_dtype = die_lookup_pass1(dw, die, DW_AT_type); if (ii->ii_type == II_SVAR)