diff options
author | Robert Mustacchi <rm@fingolfin.org> | 2020-01-11 10:14:11 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@fingolfin.org> | 2020-02-13 05:12:47 +0000 |
commit | 3df9f0641f28754051d5e82c6457527cf4af1258 (patch) | |
tree | 2004e72ac7bda03ce0df401c40c8e051d1c47f76 /usr/src/lib/libctf/common/ctf_dwarf.c | |
parent | 6d9e11ccb59a5d4ea2127e1791163333c4337a08 (diff) | |
download | illumos-joyent-3df9f0641f28754051d5e82c6457527cf4af1258.tar.gz |
12227 libctf incorrectly handles clang anonymous unions
Reviewed by: John Levon <john.levon@joyent.com>
Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src/lib/libctf/common/ctf_dwarf.c')
-rw-r--r-- | usr/src/lib/libctf/common/ctf_dwarf.c | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/usr/src/lib/libctf/common/ctf_dwarf.c b/usr/src/lib/libctf/common/ctf_dwarf.c index 1aa0f2e5e1..529195d296 100644 --- a/usr/src/lib/libctf/common/ctf_dwarf.c +++ b/usr/src/lib/libctf/common/ctf_dwarf.c @@ -1238,7 +1238,7 @@ ctf_dwarf_fixup_sou(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t base, boolean_t add) return (ret); if (tag != DW_TAG_member) - continue; + goto next; if ((ret = ctf_dwarf_refdie(cup, memb, DW_AT_type, &tdie)) != 0) return (ret); @@ -1373,12 +1373,39 @@ ctf_dwarf_create_sou(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, return (ret); /* - * Members are in children. However, gcc also allows empty ones. + * The children of a structure or union are generally members. However, + * some compilers actually insert structs and unions there and not as a + * top-level die. Therefore, to make sure we honor our pass 1 contract + * of having all the base types, but not members, we need to walk this + * for instances of a DW_TAG_union_type. */ if ((ret = ctf_dwarf_child(cup, die, &child)) != 0) return (ret); - if (child == NULL) - return (0); + + while (child != NULL) { + Dwarf_Half tag; + Dwarf_Die sib; + + if ((ret = ctf_dwarf_tag(cup, child, &tag)) != 0) + return (ret); + + switch (tag) { + case DW_TAG_union_type: + case DW_TAG_structure_type: + ret = ctf_dwarf_convert_type(cup, child, NULL, + CTF_ADD_NONROOT); + if (ret != 0) { + return (ret); + } + break; + default: + break; + } + + if ((ret = ctf_dwarf_sib(cup, child, &sib)) != 0) + return (ret); + child = sib; + } return (0); } |