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,15 +861,23 @@
}
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,
+ /*
+ * 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,13 +1649,39 @@
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 */
+ /* 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)