Print this page
12259 CTF shouldn't assume enum size


  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright 2012 Jason King.  All rights reserved.
  27  * Use is subject to license terms.
  28  */
  29 
  30 /*
  31  * Copyright 2019, Joyent, Inc.
  32  */
  33 
  34 /*
  35  * CTF DWARF conversion theory.
  36  *
  37  * DWARF data contains a series of compilation units. Each compilation unit
  38  * generally refers to an object file or what once was, in the case of linked
  39  * binaries and shared objects. Each compilation unit has a series of what DWARF
  40  * calls a DIE (Debugging Information Entry). The set of entries that we care
  41  * about have type information stored in a series of attributes. Each DIE also
  42  * has a tag that identifies the kind of attributes that it has.
  43  *
  44  * A given DIE may itself have children. For example, a DIE that represents a
  45  * structure has children which represent members. Whenever we encounter a DIE
  46  * that has children or other values or types associated with it, we recursively
  47  * process those children first so that way we can then refer to the generated
  48  * CTF type id while processing its parent. This reduces the amount of unknowns
  49  * and fixups that we need. It also ensures that we don't accidentally add types
  50  * that an overzealous compiler might add to the DWARF data but aren't used by
  51  * anything in the system.


1196                             ctf_errmsg(ctf_errno(cup->cu_ctfp)));
1197                         ctf_free(name, namesz + 1);
1198                         ctf_free(cdb, sizeof (ctf_dwbitf_t));
1199                         return (ECTF_CONVBKERR);
1200                 }
1201                 ctf_free(name, namesz + 1);
1202                 ctf_list_append(&cup->cu_bitfields, cdb);
1203         }
1204 
1205         *idp = cdb->cdb_id;
1206 
1207         return (0);
1208 }
1209 
1210 static int
1211 ctf_dwarf_fixup_sou(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t base, boolean_t add)
1212 {
1213         int ret, kind;
1214         Dwarf_Die child, memb;
1215         Dwarf_Unsigned size;
1216         ulong_t nsz;
1217 
1218         kind = ctf_type_kind(cup->cu_ctfp, base);
1219         VERIFY(kind != CTF_ERR);
1220         VERIFY(kind == CTF_K_STRUCT || kind == CTF_K_UNION);
1221 
1222         /*
1223          * Members are in children. However, gcc also allows empty ones.
1224          */
1225         if ((ret = ctf_dwarf_child(cup, die, &child)) != 0)
1226                 return (ret);
1227         if (child == NULL)
1228                 return (0);
1229 
1230         memb = child;
1231         while (memb != NULL) {
1232                 Dwarf_Die sib, tdie;
1233                 Dwarf_Half tag;
1234                 ctf_id_t mid;
1235                 char *mname;
1236                 ulong_t memboff = 0;


1289 
1290                 if (mname != NULL)
1291                         ctf_free(mname, strlen(mname) + 1);
1292 
1293 next:
1294                 if ((ret = ctf_dwarf_sib(cup, memb, &sib)) != 0)
1295                         return (ret);
1296                 memb = sib;
1297         }
1298 
1299         /*
1300          * If we're not adding members, then we don't know the final size of the
1301          * structure, so end here.
1302          */
1303         if (add == B_FALSE)
1304                 return (0);
1305 
1306         /* Finally set the size of the structure to the actual byte size */
1307         if ((ret = ctf_dwarf_unsigned(cup, die, DW_AT_byte_size, &size)) != 0)
1308                 return (ret);
1309         nsz = size;
1310         if ((ctf_set_size(cup->cu_ctfp, base, nsz)) == CTF_ERR) {
1311                 int e = ctf_errno(cup->cu_ctfp);
1312                 (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
1313                     "failed to set type size for %d to 0x%x: %s", base,
1314                     (uint32_t)size, ctf_errmsg(e));
1315                 return (ECTF_CONVBKERR);
1316         }
1317 
1318         return (0);
1319 }
1320 
1321 static int
1322 ctf_dwarf_create_sou(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp,
1323     int kind, int isroot)
1324 {
1325         int ret;
1326         char *name;
1327         ctf_id_t base;
1328         Dwarf_Die child;
1329         Dwarf_Bool decl;
1330 


1597                 if (ret != 0) {
1598                         ret = (ctf_errno(cup->cu_ctfp));
1599                 } else {
1600                         *idp = id;
1601                 }
1602 
1603                 ctf_free(name, namelen);
1604                 return (ret);
1605         }
1606 
1607         if ((*idp = ctf_add_reftype(cup->cu_ctfp, isroot, name, id, kind)) ==
1608             CTF_ERR) {
1609                 ctf_free(name, namelen);
1610                 return (ctf_errno(cup->cu_ctfp));
1611         }
1612 
1613         ctf_free(name, namelen);
1614         return (ctf_dwmap_add(cup, *idp, die, B_FALSE));
1615 }
1616 







1617 static int
1618 ctf_dwarf_create_enum(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot)
1619 {



1620         int ret;
1621         ctf_id_t id;


















1622         Dwarf_Die child;

1623         char *name;

1624 
1625         if ((ret = ctf_dwarf_string(cup, die, DW_AT_name, &name)) != 0 &&
1626             ret != ENOENT)
1627                 return (ret);
1628         if (ret == ENOENT)
1629                 name = NULL;
1630         id = ctf_add_enum(cup->cu_ctfp, isroot, name);



1631         ctf_dprintf("added enum %s (%d)\n", name, id);
1632         if (name != NULL)
1633                 ctf_free(name, strlen(name) + 1);
1634         if (id == CTF_ERR)
1635                 return (ctf_errno(cup->cu_ctfp));
1636         *idp = id;
1637         if ((ret = ctf_dwmap_add(cup, id, die, B_FALSE)) != 0)
1638                 return (ret);
1639 
1640         if ((ret = ctf_dwarf_child(cup, die, &child)) != 0) {
1641                 if (ret == ENOENT)
1642                         ret = 0;
1643                 return (ret);
1644         }
1645 
1646         while (child != NULL) {
1647                 Dwarf_Half tag;
1648                 Dwarf_Signed sval;
1649                 Dwarf_Unsigned uval;
1650                 Dwarf_Die arg = child;




  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*
  26  * Copyright 2012 Jason King.  All rights reserved.
  27  * Use is subject to license terms.
  28  */
  29 
  30 /*
  31  * Copyright 2020 Joyent, Inc.
  32  */
  33 
  34 /*
  35  * CTF DWARF conversion theory.
  36  *
  37  * DWARF data contains a series of compilation units. Each compilation unit
  38  * generally refers to an object file or what once was, in the case of linked
  39  * binaries and shared objects. Each compilation unit has a series of what DWARF
  40  * calls a DIE (Debugging Information Entry). The set of entries that we care
  41  * about have type information stored in a series of attributes. Each DIE also
  42  * has a tag that identifies the kind of attributes that it has.
  43  *
  44  * A given DIE may itself have children. For example, a DIE that represents a
  45  * structure has children which represent members. Whenever we encounter a DIE
  46  * that has children or other values or types associated with it, we recursively
  47  * process those children first so that way we can then refer to the generated
  48  * CTF type id while processing its parent. This reduces the amount of unknowns
  49  * and fixups that we need. It also ensures that we don't accidentally add types
  50  * that an overzealous compiler might add to the DWARF data but aren't used by
  51  * anything in the system.


1196                             ctf_errmsg(ctf_errno(cup->cu_ctfp)));
1197                         ctf_free(name, namesz + 1);
1198                         ctf_free(cdb, sizeof (ctf_dwbitf_t));
1199                         return (ECTF_CONVBKERR);
1200                 }
1201                 ctf_free(name, namesz + 1);
1202                 ctf_list_append(&cup->cu_bitfields, cdb);
1203         }
1204 
1205         *idp = cdb->cdb_id;
1206 
1207         return (0);
1208 }
1209 
1210 static int
1211 ctf_dwarf_fixup_sou(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t base, boolean_t add)
1212 {
1213         int ret, kind;
1214         Dwarf_Die child, memb;
1215         Dwarf_Unsigned size;

1216 
1217         kind = ctf_type_kind(cup->cu_ctfp, base);
1218         VERIFY(kind != CTF_ERR);
1219         VERIFY(kind == CTF_K_STRUCT || kind == CTF_K_UNION);
1220 
1221         /*
1222          * Members are in children. However, gcc also allows empty ones.
1223          */
1224         if ((ret = ctf_dwarf_child(cup, die, &child)) != 0)
1225                 return (ret);
1226         if (child == NULL)
1227                 return (0);
1228 
1229         memb = child;
1230         while (memb != NULL) {
1231                 Dwarf_Die sib, tdie;
1232                 Dwarf_Half tag;
1233                 ctf_id_t mid;
1234                 char *mname;
1235                 ulong_t memboff = 0;


1288 
1289                 if (mname != NULL)
1290                         ctf_free(mname, strlen(mname) + 1);
1291 
1292 next:
1293                 if ((ret = ctf_dwarf_sib(cup, memb, &sib)) != 0)
1294                         return (ret);
1295                 memb = sib;
1296         }
1297 
1298         /*
1299          * If we're not adding members, then we don't know the final size of the
1300          * structure, so end here.
1301          */
1302         if (add == B_FALSE)
1303                 return (0);
1304 
1305         /* Finally set the size of the structure to the actual byte size */
1306         if ((ret = ctf_dwarf_unsigned(cup, die, DW_AT_byte_size, &size)) != 0)
1307                 return (ret);
1308         if ((ctf_set_size(cup->cu_ctfp, base, size)) == CTF_ERR) {

1309                 int e = ctf_errno(cup->cu_ctfp);
1310                 (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
1311                     "failed to set type size for %d to 0x%x: %s", base,
1312                     (uint32_t)size, ctf_errmsg(e));
1313                 return (ECTF_CONVBKERR);
1314         }
1315 
1316         return (0);
1317 }
1318 
1319 static int
1320 ctf_dwarf_create_sou(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp,
1321     int kind, int isroot)
1322 {
1323         int ret;
1324         char *name;
1325         ctf_id_t base;
1326         Dwarf_Die child;
1327         Dwarf_Bool decl;
1328 


1595                 if (ret != 0) {
1596                         ret = (ctf_errno(cup->cu_ctfp));
1597                 } else {
1598                         *idp = id;
1599                 }
1600 
1601                 ctf_free(name, namelen);
1602                 return (ret);
1603         }
1604 
1605         if ((*idp = ctf_add_reftype(cup->cu_ctfp, isroot, name, id, kind)) ==
1606             CTF_ERR) {
1607                 ctf_free(name, namelen);
1608                 return (ctf_errno(cup->cu_ctfp));
1609         }
1610 
1611         ctf_free(name, namelen);
1612         return (ctf_dwmap_add(cup, *idp, die, B_FALSE));
1613 }
1614 
1615 /*
1616  * Get the size of the type of a particular die. Note that this is a simple
1617  * version that doesn't attempt to traverse further than expecting a single
1618  * sized type reference (so no qualifiers etc.). Nor does it attempt to do as
1619  * much as ctf_type_size() - which we cannot use here as that doesn't look up
1620  * dynamic types, and we don't yet want to do a ctf_update().
1621  */
1622 static int
1623 ctf_dwarf_get_type_size(ctf_cu_t *cup, Dwarf_Die die, size_t *sizep)
1624 {
1625         const ctf_type_t *t;
1626         Dwarf_Die tdie;
1627         ctf_id_t tid;
1628         int ret;
1629 
1630         if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_type, &tdie)) != 0)
1631                 return (ret);
1632 
1633         if ((ret = ctf_dwarf_convert_type(cup, tdie, &tid,
1634             CTF_ADD_NONROOT)) != 0)
1635                 return (ret);
1636 
1637         if ((t = ctf_dyn_lookup_by_id(cup->cu_ctfp, tid)) == NULL)
1638                 return (ENOENT);
1639 
1640         *sizep = ctf_get_ctt_size(cup->cu_ctfp, t, NULL, NULL);
1641         return (0);
1642 }
1643 
1644 static int
1645 ctf_dwarf_create_enum(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot)
1646 {
1647         size_t size = 0;
1648         Dwarf_Die child;
1649         ctf_id_t id;
1650         char *name;
1651         int ret;
1652 
1653         if ((ret = ctf_dwarf_string(cup, die, DW_AT_name, &name)) != 0 &&
1654             ret != ENOENT)
1655                 return (ret);
1656         if (ret == ENOENT)
1657                 name = NULL;
1658 
1659         (void) ctf_dwarf_get_type_size(cup, die, &size);
1660 
1661         id = ctf_add_enum(cup->cu_ctfp, isroot, name, size);
1662         ctf_dprintf("added enum %s (%d)\n", name, id);
1663         if (name != NULL)
1664                 ctf_free(name, strlen(name) + 1);
1665         if (id == CTF_ERR)
1666                 return (ctf_errno(cup->cu_ctfp));
1667         *idp = id;
1668         if ((ret = ctf_dwmap_add(cup, id, die, B_FALSE)) != 0)
1669                 return (ret);
1670 
1671         if ((ret = ctf_dwarf_child(cup, die, &child)) != 0) {
1672                 if (ret == ENOENT)
1673                         ret = 0;
1674                 return (ret);
1675         }
1676 
1677         while (child != NULL) {
1678                 Dwarf_Half tag;
1679                 Dwarf_Signed sval;
1680                 Dwarf_Unsigned uval;
1681                 Dwarf_Die arg = child;