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>

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libdtrace/common/dt_module.c
          +++ new/usr/src/lib/libdtrace/common/dt_module.c
↓ open down ↓ 835 lines elided ↑ open up ↑
 836  836          ctf_setspecific(dmp->dm_ctfp, dmp);
 837  837  
 838  838          if ((parent = ctf_parent_name(dmp->dm_ctfp)) != NULL) {
 839  839                  if ((pmp = dt_module_create(dtp, parent)) == NULL ||
 840  840                      (pfp = dt_module_getctf(dtp, pmp)) == NULL) {
 841  841                          if (pmp == NULL)
 842  842                                  (void) dt_set_errno(dtp, EDT_NOMEM);
 843  843                          goto err;
 844  844                  }
 845  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 +
 846  857                  if (ctf_import(dmp->dm_ctfp, pfp) == CTF_ERR) {
 847  858                          dtp->dt_ctferr = ctf_errno(dmp->dm_ctfp);
 848  859                          (void) dt_set_errno(dtp, EDT_CTF);
 849  860                          goto err;
 850  861                  }
 851  862          }
 852  863  
 853  864          dt_dprintf("loaded CTF container for %s (%p)\n",
 854  865              dmp->dm_name, (void *)dmp->dm_ctfp);
 855  866  
 856  867          return (dmp->dm_ctfp);
 857  868  
 858  869  err:
      870 +        dt_dprintf("could not load CTF container for %s: %s\n",
      871 +            dmp->dm_name, dtrace_errmsg(dtp, dtrace_errno(dtp)));
 859  872          ctf_close(dmp->dm_ctfp);
 860  873          dmp->dm_ctfp = NULL;
 861  874          return (NULL);
 862  875  }
 863  876  
 864  877  /*ARGSUSED*/
 865  878  void
 866  879  dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp)
 867  880  {
 868  881          int i;
↓ open down ↓ 496 lines elided ↑ open up ↑
1365 1378                          sip->dts_id = id;
1366 1379                  } else {
1367 1380                          sip->dts_name = NULL;
1368 1381                          sip->dts_id = 0;
1369 1382                  }
1370 1383          }
1371 1384  
1372 1385          return (0);
1373 1386  }
1374 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 +
1375 1421  int
1376 1422  dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,
1377 1423      dtrace_typeinfo_t *tip)
1378 1424  {
1379 1425          dtrace_typeinfo_t ti;
1380 1426          dt_module_t *dmp;
1381 1427          int found = 0;
1382 1428          ctf_id_t id;
1383 1429          uint_t n, i;
1384 1430          int justone;
↓ open down ↓ 71 lines elided ↑ open up ↑
1456 1502                                          id = ctf_lookup_by_name(fp, name);
1457 1503                                          if (id != CTF_ERR)
1458 1504                                                  break;
1459 1505                                  }
1460 1506                          }
1461 1507                  }
1462 1508                  if (id != CTF_ERR) {
1463 1509                          tip->dtt_object = dmp->dm_name;
1464 1510                          tip->dtt_ctfp = fp;
1465 1511                          tip->dtt_type = id;
1466      -                        if (ctf_type_kind(fp, ctf_type_resolve(fp, id)) !=
1467      -                            CTF_K_FORWARD)
     1512 +                        if (!dt_is_forward_decl(fp, ctf_type_resolve(fp, id)))
1468 1513                                  return (0);
1469 1514  
1470 1515                          found++;
1471 1516                  }
1472 1517          }
1473 1518  
1474 1519          if (found == 0)
1475 1520                  return (dt_set_errno(dtp, EDT_NOTYPE));
1476 1521  
1477 1522          return (0);
↓ open down ↓ 103 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX