diff options
Diffstat (limited to 'usr/src/lib/libctf/common')
-rw-r--r-- | usr/src/lib/libctf/common/ctf_dwarf.c | 80 | ||||
-rw-r--r-- | usr/src/lib/libctf/common/mapfile-vers | 5 |
2 files changed, 63 insertions, 22 deletions
diff --git a/usr/src/lib/libctf/common/ctf_dwarf.c b/usr/src/lib/libctf/common/ctf_dwarf.c index 13a049d243..f490c8f351 100644 --- a/usr/src/lib/libctf/common/ctf_dwarf.c +++ b/usr/src/lib/libctf/common/ctf_dwarf.c @@ -469,7 +469,7 @@ ctf_dwarf_refdie(ctf_die_t *cdp, Dwarf_Die die, Dwarf_Half name, Dwarf_Off off; Dwarf_Error derr; - if ((ret = ctf_dwarf_ref(cdp, die, DW_AT_type, &off)) != 0) + if ((ret = ctf_dwarf_ref(cdp, die, name, &off)) != 0) return (ret); off += cdp->cd_cuoff; @@ -630,6 +630,17 @@ ctf_dwarf_offset(ctf_die_t *cdp, Dwarf_Die die, Dwarf_Off *offsetp) return (ECTF_CONVBKERR); } +/* simpler variant for debugging output */ +static Dwarf_Off +ctf_die_offset(Dwarf_Die die) +{ + Dwarf_Off off = -1; + Dwarf_Error derr; + + (void) dwarf_dieoffset(die, &off, &derr); + return (off); +} + static int ctf_dwarf_tag(ctf_die_t *cdp, Dwarf_Die die, Dwarf_Half *tagp) { @@ -1547,7 +1558,6 @@ ctf_dwarf_create_enum(ctf_die_t *cdp, Dwarf_Die die, ctf_id_t *idp, int isroot) if ((ret = ctf_dwmap_add(cdp, id, die, B_FALSE)) != 0) return (ret); - if ((ret = ctf_dwarf_child(cdp, die, &child)) != 0) { if (ret == ENOENT) ret = 0; @@ -1574,27 +1584,35 @@ ctf_dwarf_create_enum(ctf_die_t *cdp, Dwarf_Die die, ctf_id_t *idp, int isroot) continue; } - if ((ret = ctf_dwarf_signed(cdp, arg, DW_AT_const_value, - &sval)) == 0) { - eval = sval; - } else if (ret != ENOENT) { + /* + * DWARF v4 section 5.7 tells us we'll always have names. + */ + if ((ret = ctf_dwarf_string(cdp, arg, DW_AT_name, &name)) != 0) return (ret); - } else if ((ret = ctf_dwarf_unsigned(cdp, arg, - DW_AT_const_value, &uval)) == 0) { + + /* + * We have to be careful here: newer GCCs generate DWARF where + * an unsigned value will happily pass ctf_dwarf_signed(). + * Since negative values will fail ctf_dwarf_unsigned(), we try + * that first to make sure we get the right value. + */ + if ((ret = ctf_dwarf_unsigned(cdp, arg, DW_AT_const_value, + &uval)) == 0) { eval = (int)uval; - } else { + } else if ((ret = ctf_dwarf_signed(cdp, arg, DW_AT_const_value, + &sval)) == 0) { + eval = sval; + } + + if (ret != 0) { + if (ret != ENOENT) + return (ret); + (void) snprintf(cdp->cd_errbuf, cdp->cd_errlen, - "encountered enumration without constant value\n"); + "encountered enumeration without constant value\n"); return (ECTF_CONVBKERR); } - /* - * DWARF v4 section 5.7 tells us we'll always have names. - */ - if ((ret = ctf_dwarf_string(cdp, arg, DW_AT_name, - &name)) != 0) - return (ret); - ret = ctf_add_enumerator(cdp->cd_ctfp, id, name, eval); if (ret == CTF_ERR) { (void) snprintf(cdp->cd_errbuf, cdp->cd_errlen, @@ -1995,11 +2013,31 @@ ctf_dwarf_convert_variable(ctf_die_t *cdp, Dwarf_Die die) ctf_id_t id; ctf_dwvar_t *cdv; - if ((ret = ctf_dwarf_boolean(cdp, die, DW_AT_declaration, &b)) != 0) { - if (ret != ENOENT) + /* Skip "Non-Defining Declarations" */ + if ((ret = ctf_dwarf_boolean(cdp, die, DW_AT_declaration, &b)) == 0) { + if (b != 0) + return (0); + } else if (ret != ENOENT) { + return (ret); + } + + /* + * 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 ((ret = ctf_dwarf_refdie(cdp, die, DW_AT_specification, + &tdie)) == 0) { + Dwarf_Off offset; + if ((ret = ctf_dwarf_offset(cdp, tdie, &offset)) != 0) return (ret); - } else if (b != 0) { - return (0); + ctf_dprintf("die 0x%llx DW_AT_specification -> die 0x%llx\n", + ctf_die_offset(die), ctf_die_offset(tdie)); + die = tdie; + } else if (ret != ENOENT) { + return (ret); } if ((ret = ctf_dwarf_string(cdp, die, DW_AT_name, &name)) != 0 && diff --git a/usr/src/lib/libctf/common/mapfile-vers b/usr/src/lib/libctf/common/mapfile-vers index cfd2952bbe..f64eb407df 100644 --- a/usr/src/lib/libctf/common/mapfile-vers +++ b/usr/src/lib/libctf/common/mapfile-vers @@ -23,7 +23,7 @@ # # -# Copyright (c) 2015, Joyent, Inc. All rights reserved. +# Copyright 2018 Joyent, Inc. # # @@ -91,6 +91,7 @@ SYMBOL_VERSION SUNWprivate_1.2 { ctf_label_info; ctf_label_iter; ctf_label_topmost; + ctf_max_id; ctf_member_info; ctf_merge_add; ctf_merge_dedup; @@ -100,6 +101,7 @@ SYMBOL_VERSION SUNWprivate_1.2 { ctf_merge_merge; ctf_merge_set_nthreads; ctf_merge_uniquify; + ctf_nr_syms; ctf_object_iter; ctf_parent_file; ctf_parent_label; @@ -111,6 +113,7 @@ SYMBOL_VERSION SUNWprivate_1.2 { ctf_symbol_name; ctf_type_align; ctf_type_cmp; + ctf_type_cname; ctf_type_compat; ctf_type_pointer; ctf_update; |