Print this page
libdtrace: attempt to resolve FORWARD types to concrete types
1730 DTrace should ignore type information from modules with cth_parlabel mismatches
Reviewed by: Keith Wesolowski <keith.wesolowski@joyent.com>
Reviewed by: Adam Leventhal <ahl@delphix.com>


 826 
 827         dmp->dm_ctfp = ctf_bufopen(&dmp->dm_ctdata,
 828             &dmp->dm_symtab, &dmp->dm_strtab, &dtp->dt_ctferr);
 829 
 830         if (dmp->dm_ctfp == NULL) {
 831                 (void) dt_set_errno(dtp, EDT_CTF);
 832                 return (NULL);
 833         }
 834 
 835         (void) ctf_setmodel(dmp->dm_ctfp, model);
 836         ctf_setspecific(dmp->dm_ctfp, dmp);
 837 
 838         if ((parent = ctf_parent_name(dmp->dm_ctfp)) != NULL) {
 839                 if ((pmp = dt_module_create(dtp, parent)) == NULL ||
 840                     (pfp = dt_module_getctf(dtp, pmp)) == NULL) {
 841                         if (pmp == NULL)
 842                                 (void) dt_set_errno(dtp, EDT_NOMEM);
 843                         goto err;
 844                 }
 845 











 846                 if (ctf_import(dmp->dm_ctfp, pfp) == CTF_ERR) {
 847                         dtp->dt_ctferr = ctf_errno(dmp->dm_ctfp);
 848                         (void) dt_set_errno(dtp, EDT_CTF);
 849                         goto err;
 850                 }
 851         }
 852 
 853         dt_dprintf("loaded CTF container for %s (%p)\n",
 854             dmp->dm_name, (void *)dmp->dm_ctfp);
 855 
 856         return (dmp->dm_ctfp);
 857 
 858 err:


 859         ctf_close(dmp->dm_ctfp);
 860         dmp->dm_ctfp = NULL;
 861         return (NULL);
 862 }
 863 
 864 /*ARGSUSED*/
 865 void
 866 dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp)
 867 {
 868         int i;
 869 
 870         ctf_close(dmp->dm_ctfp);
 871         dmp->dm_ctfp = NULL;
 872 
 873         if (dmp->dm_libctfp != NULL) {
 874                 for (i = 0; i < dmp->dm_nctflibs; i++) {
 875                         ctf_close(dmp->dm_libctfp[i]);
 876                         free(dmp->dm_libctfn[i]);
 877                 }
 878                 free(dmp->dm_libctfp);


1355                 if (dmp->dm_ops->do_symaddr(dmp, addr, symp, &id) == NULL)
1356                         return (dt_set_errno(dtp, EDT_NOSYMADDR));
1357         }
1358 
1359         if (sip != NULL) {
1360                 sip->dts_object = dmp->dm_name;
1361 
1362                 if (symp != NULL) {
1363                         sip->dts_name = (const char *)
1364                             dmp->dm_strtab.cts_data + symp->st_name;
1365                         sip->dts_id = id;
1366                 } else {
1367                         sip->dts_name = NULL;
1368                         sip->dts_id = 0;
1369                 }
1370         }
1371 
1372         return (0);
1373 }
1374 

































1375 int
1376 dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,
1377     dtrace_typeinfo_t *tip)
1378 {
1379         dtrace_typeinfo_t ti;
1380         dt_module_t *dmp;
1381         int found = 0;
1382         ctf_id_t id;
1383         uint_t n, i;
1384         int justone;
1385         ctf_file_t *fp;
1386         char *buf, *p, *q;
1387 
1388         uint_t mask = 0; /* mask of dt_module flags to match */
1389         uint_t bits = 0; /* flag bits that must be present */
1390 
1391         if (object != DTRACE_OBJ_EVERY &&
1392             object != DTRACE_OBJ_KMODS &&
1393             object != DTRACE_OBJ_UMODS) {
1394                 if ((dmp = dt_module_from_object(dtp, object)) == NULL)


1446                                         p = q;
1447                                 *p = '\0';
1448                                 fp = dt_module_getctflib(dtp, dmp, buf);
1449                                 if (fp == NULL || (id = ctf_lookup_by_name(fp,
1450                                     p + 1)) == CTF_ERR)
1451                                         id = CTF_ERR;
1452                                 free(buf);
1453                         } else {
1454                                 for (i = 0; i < dmp->dm_nctflibs; i++) {
1455                                         fp = dmp->dm_libctfp[i];
1456                                         id = ctf_lookup_by_name(fp, name);
1457                                         if (id != CTF_ERR)
1458                                                 break;
1459                                 }
1460                         }
1461                 }
1462                 if (id != CTF_ERR) {
1463                         tip->dtt_object = dmp->dm_name;
1464                         tip->dtt_ctfp = fp;
1465                         tip->dtt_type = id;
1466                         if (ctf_type_kind(fp, ctf_type_resolve(fp, id)) !=
1467                             CTF_K_FORWARD)
1468                                 return (0);
1469 
1470                         found++;
1471                 }
1472         }
1473 
1474         if (found == 0)
1475                 return (dt_set_errno(dtp, EDT_NOTYPE));
1476 
1477         return (0);
1478 }
1479 
1480 int
1481 dtrace_symbol_type(dtrace_hdl_t *dtp, const GElf_Sym *symp,
1482     const dtrace_syminfo_t *sip, dtrace_typeinfo_t *tip)
1483 {
1484         dt_module_t *dmp;
1485 
1486         tip->dtt_object = NULL;
1487         tip->dtt_ctfp = NULL;




 826 
 827         dmp->dm_ctfp = ctf_bufopen(&dmp->dm_ctdata,
 828             &dmp->dm_symtab, &dmp->dm_strtab, &dtp->dt_ctferr);
 829 
 830         if (dmp->dm_ctfp == NULL) {
 831                 (void) dt_set_errno(dtp, EDT_CTF);
 832                 return (NULL);
 833         }
 834 
 835         (void) ctf_setmodel(dmp->dm_ctfp, model);
 836         ctf_setspecific(dmp->dm_ctfp, dmp);
 837 
 838         if ((parent = ctf_parent_name(dmp->dm_ctfp)) != NULL) {
 839                 if ((pmp = dt_module_create(dtp, parent)) == NULL ||
 840                     (pfp = dt_module_getctf(dtp, pmp)) == NULL) {
 841                         if (pmp == NULL)
 842                                 (void) dt_set_errno(dtp, EDT_NOMEM);
 843                         goto err;
 844                 }
 845 
 846                 /*
 847                  * If the label we claim the parent must have is not actually
 848                  * present in the parent module, ignore the CTF entirely
 849                  * rather than acquiring possibly bad type references.
 850                  */
 851                 if (ctf_label_info(pfp, ctf_parent_label(dmp->dm_ctfp),
 852                     NULL) == CTF_ERR) {
 853                         (void) dt_set_errno(dtp, EDT_BADCTF);
 854                         goto err;
 855                 }
 856 
 857                 if (ctf_import(dmp->dm_ctfp, pfp) == CTF_ERR) {
 858                         dtp->dt_ctferr = ctf_errno(dmp->dm_ctfp);
 859                         (void) dt_set_errno(dtp, EDT_CTF);
 860                         goto err;
 861                 }
 862         }
 863 
 864         dt_dprintf("loaded CTF container for %s (%p)\n",
 865             dmp->dm_name, (void *)dmp->dm_ctfp);
 866 
 867         return (dmp->dm_ctfp);
 868 
 869 err:
 870         dt_dprintf("could not load CTF container for %s: %s\n",
 871             dmp->dm_name, dtrace_errmsg(dtp, dtrace_errno(dtp)));
 872         ctf_close(dmp->dm_ctfp);
 873         dmp->dm_ctfp = NULL;
 874         return (NULL);
 875 }
 876 
 877 /*ARGSUSED*/
 878 void
 879 dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp)
 880 {
 881         int i;
 882 
 883         ctf_close(dmp->dm_ctfp);
 884         dmp->dm_ctfp = NULL;
 885 
 886         if (dmp->dm_libctfp != NULL) {
 887                 for (i = 0; i < dmp->dm_nctflibs; i++) {
 888                         ctf_close(dmp->dm_libctfp[i]);
 889                         free(dmp->dm_libctfn[i]);
 890                 }
 891                 free(dmp->dm_libctfp);


1368                 if (dmp->dm_ops->do_symaddr(dmp, addr, symp, &id) == NULL)
1369                         return (dt_set_errno(dtp, EDT_NOSYMADDR));
1370         }
1371 
1372         if (sip != NULL) {
1373                 sip->dts_object = dmp->dm_name;
1374 
1375                 if (symp != NULL) {
1376                         sip->dts_name = (const char *)
1377                             dmp->dm_strtab.cts_data + symp->st_name;
1378                         sip->dts_id = id;
1379                 } else {
1380                         sip->dts_name = NULL;
1381                         sip->dts_id = 0;
1382                 }
1383         }
1384 
1385         return (0);
1386 }
1387 
1388 boolean_t
1389 dt_is_forward_decl(ctf_file_t *file, ctf_id_t type)
1390 {
1391         ctf_id_t kind = ctf_type_kind(file, type);
1392 
1393         while ((type = ctf_type_reference(file, type)) != CTF_ERR) {
1394                 type = ctf_type_resolve(file, type);
1395                 kind = ctf_type_kind(file, type);
1396         }
1397 
1398         return (kind == CTF_K_FORWARD);
1399 }
1400 
1401 void
1402 dt_resolve_forward_decl(ctf_file_t **ctfp, ctf_id_t *type)
1403 {
1404         char name[DT_TYPE_NAMELEN];
1405 
1406         while (dt_is_forward_decl(*ctfp, *type)) {
1407                 char *tag = ctf_type_name(*ctfp, *type, name, sizeof (name));
1408                 dtrace_typeinfo_t dtt;
1409 
1410                 if (tag != NULL && dt_type_lookup(tag, &dtt) == 0 &&
1411                     (dtt.dtt_ctfp != *ctfp) || dtt.dtt_type != *type) {
1412                         *ctfp = dtt.dtt_ctfp;
1413                         *type = dtt.dtt_type;
1414                 } else {
1415                         /* All we have is the forward definition */
1416                         break;
1417                 }
1418         }
1419 }
1420 
1421 int
1422 dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,
1423     dtrace_typeinfo_t *tip)
1424 {
1425         dtrace_typeinfo_t ti;
1426         dt_module_t *dmp;
1427         int found = 0;
1428         ctf_id_t id;
1429         uint_t n, i;
1430         int justone;
1431         ctf_file_t *fp;
1432         char *buf, *p, *q;
1433 
1434         uint_t mask = 0; /* mask of dt_module flags to match */
1435         uint_t bits = 0; /* flag bits that must be present */
1436 
1437         if (object != DTRACE_OBJ_EVERY &&
1438             object != DTRACE_OBJ_KMODS &&
1439             object != DTRACE_OBJ_UMODS) {
1440                 if ((dmp = dt_module_from_object(dtp, object)) == NULL)


1492                                         p = q;
1493                                 *p = '\0';
1494                                 fp = dt_module_getctflib(dtp, dmp, buf);
1495                                 if (fp == NULL || (id = ctf_lookup_by_name(fp,
1496                                     p + 1)) == CTF_ERR)
1497                                         id = CTF_ERR;
1498                                 free(buf);
1499                         } else {
1500                                 for (i = 0; i < dmp->dm_nctflibs; i++) {
1501                                         fp = dmp->dm_libctfp[i];
1502                                         id = ctf_lookup_by_name(fp, name);
1503                                         if (id != CTF_ERR)
1504                                                 break;
1505                                 }
1506                         }
1507                 }
1508                 if (id != CTF_ERR) {
1509                         tip->dtt_object = dmp->dm_name;
1510                         tip->dtt_ctfp = fp;
1511                         tip->dtt_type = id;
1512                         if (!dt_is_forward_decl(fp, ctf_type_resolve(fp, id)))

1513                                 return (0);
1514 
1515                         found++;
1516                 }
1517         }
1518 
1519         if (found == 0)
1520                 return (dt_set_errno(dtp, EDT_NOTYPE));
1521 
1522         return (0);
1523 }
1524 
1525 int
1526 dtrace_symbol_type(dtrace_hdl_t *dtp, const GElf_Sym *symp,
1527     const dtrace_syminfo_t *sip, dtrace_typeinfo_t *tip)
1528 {
1529         dt_module_t *dmp;
1530 
1531         tip->dtt_object = NULL;
1532         tip->dtt_ctfp = NULL;