Print this page
rm code review
12259 CTF shouldn't assume enum size

Split Close
Expand all
Collapse all
          --- old/usr/src/common/ctf/ctf_create.c
          +++ new/usr/src/common/ctf/ctf_create.c
↓ open down ↓ 17 lines elided ↑ open up ↑
  18   18   * information: Portions Copyright [yyyy] [name of copyright owner]
  19   19   *
  20   20   * CDDL HEADER END
  21   21   */
  22   22  
  23   23  /*
  24   24   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  25   25   * Use is subject to license terms.
  26   26   */
  27   27  /*
  28      - * Copyright (c) 2019, Joyent, Inc.
       28 + * Copyright 2020 Joyent, Inc.
  29   29   */
  30   30  
  31   31  #include <sys/sysmacros.h>
  32   32  #include <sys/param.h>
  33   33  #include <sys/mman.h>
  34   34  #include <ctf_impl.h>
  35   35  #include <sys/debug.h>
  36   36  
  37   37  /*
       38 + * SSIZE_MAX is not available in the kernel, so we define it here rather than
       39 + * accidentally inject into headers where it's not wanted.
       40 + */
       41 +#ifndef SSIZE_MAX
       42 +#define SSIZE_MAX (LONG_MAX)
       43 +#endif
       44 +
       45 +/*
  38   46   * This static string is used as the template for initially populating a
  39   47   * dynamic container's string table.  We always store \0 in the first byte,
  40   48   * and we use the generic string "PARENT" to mark this container's parent
  41   49   * if one is associated with the container using ctf_import().
  42   50   */
  43   51  static const char _CTF_STRTAB_TEMPLATE[] = "\0PARENT";
  44   52  
  45   53  /*
  46   54   * To create an empty CTF container, we just declare a zeroed header and call
  47   55   * ctf_bufopen() on it.  If ctf_bufopen succeeds, we mark the new container r/w
↓ open down ↓ 1191 lines elided ↑ open up ↑
1239 1247          dtd->dtd_data.ctt_size = 0;
1240 1248  
1241 1249          /*
1242 1250           * Always dirty in case we modified a forward.
1243 1251           */
1244 1252          fp->ctf_flags |= LCTF_DIRTY;
1245 1253  
1246 1254          return (type);
1247 1255  }
1248 1256  
     1257 +/*
     1258 + * If size is 0, we use the standard integer size. This is almost always the
     1259 + * case, except for packed enums.
     1260 + */
1249 1261  ctf_id_t
1250      -ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name)
     1262 +ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name, size_t size)
1251 1263  {
1252 1264          ctf_hash_t *hp = &fp->ctf_enums;
1253 1265          ctf_helem_t *hep = NULL;
1254 1266          ctf_dtdef_t *dtd = NULL;
1255 1267          ctf_id_t type = CTF_ERR;
1256 1268  
     1269 +        /* Check we could return something valid in ctf_type_size. */
     1270 +        if (size > SSIZE_MAX)
     1271 +                return (ctf_set_errno(fp, EINVAL));
     1272 +
1257 1273          if (name != NULL)
1258 1274                  hep = ctf_hash_lookup(hp, fp, name, strlen(name));
1259 1275  
1260 1276          if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD) {
1261 1277                  type = hep->h_type;
1262 1278                  dtd = ctf_dtd_lookup(fp, type);
1263 1279                  if (CTF_INFO_KIND(dtd->dtd_data.ctt_info) != CTF_K_FORWARD)
1264 1280                          dtd = NULL;
1265 1281          }
1266 1282  
1267 1283          if (dtd == NULL) {
1268 1284                  type = ctf_add_generic(fp, flag, name, &dtd);
1269 1285                  if (type == CTF_ERR)
1270 1286                          return (CTF_ERR); /* errno is set for us */
1271 1287          }
1272 1288  
1273 1289          VERIFY(type != CTF_ERR);
1274 1290          dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, flag, 0);
1275      -        dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
1276 1291  
     1292 +        ctf_set_ctt_size(&dtd->dtd_data, size == 0 ?
     1293 +            fp->ctf_dmodel->ctd_int : size);
     1294 +
1277 1295          /*
1278 1296           * Always dirty in case we modified a forward.
1279 1297           */
1280 1298          fp->ctf_flags |= LCTF_DIRTY;
1281 1299  
1282 1300          return (type);
1283 1301  }
1284 1302  
1285 1303  ctf_id_t
1286 1304  ctf_add_forward(ctf_file_t *fp, uint_t flag, const char *name, uint_t kind)
↓ open down ↓ 257 lines elided ↑ open up ↑
1544 1562                  } else {
1545 1563                          dmd->dmd_offset = offset;
1546 1564                          ssize = (offset + mbitsz) / NBBY;
1547 1565                  }
1548 1566          } else {
1549 1567                  dmd->dmd_offset = 0;
1550 1568                  ssize = ctf_get_ctt_size(fp, &dtd->dtd_data, NULL, NULL);
1551 1569                  ssize = MAX(ssize, msize);
1552 1570          }
1553 1571  
1554      -        if (ssize > CTF_MAX_SIZE) {
1555      -                dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1556      -                dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(ssize);
1557      -                dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(ssize);
1558      -        } else
1559      -                dtd->dtd_data.ctt_size = (ushort_t)ssize;
     1572 +        ctf_set_ctt_size(&dtd->dtd_data, ssize);
1560 1573  
1561 1574          dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1);
1562 1575          ctf_list_append(&dtd->dtd_u.dtu_members, dmd);
1563 1576  
1564 1577          if (s != NULL)
1565 1578                  fp->ctf_dtstrlen += strlen(s) + 1;
1566 1579  
1567 1580          ctf_ref_inc(fp, type);
1568 1581          fp->ctf_flags |= LCTF_DIRTY;
1569 1582          return (0);
↓ open down ↓ 116 lines elided ↑ open up ↑
1686 1699          const ctf_type_t *tp;
1687 1700          const char *name;
1688 1701          uint_t kind, flag, vlen;
1689 1702  
1690 1703          ctf_bundle_t src, dst;
1691 1704          ctf_encoding_t src_en, dst_en;
1692 1705          ctf_arinfo_t src_ar, dst_ar;
1693 1706  
1694 1707          ctf_dtdef_t *dtd;
1695 1708          ctf_funcinfo_t ctc;
1696      -        ssize_t size;
1697 1709  
1698 1710          ctf_hash_t *hp;
1699 1711          ctf_helem_t *hep;
1700 1712  
1701 1713          if (dst_fp == src_fp)
1702 1714                  return (src_type);
1703 1715  
1704 1716          if (!(dst_fp->ctf_flags & LCTF_RDWR))
1705 1717                  return (ctf_set_errno(dst_fp, ECTF_RDONLY));
1706 1718  
↓ open down ↓ 174 lines elided ↑ open up ↑
1881 1893                  dst_type = ctf_add_generic(dst_fp, flag, name, &dtd);
1882 1894                  if (dst_type == CTF_ERR)
1883 1895                          return (CTF_ERR); /* errno is set for us */
1884 1896  
1885 1897                  dst.ctb_type = dst_type;
1886 1898                  dst.ctb_dtd = dtd;
1887 1899  
1888 1900                  if (ctf_member_iter(src_fp, src_type, membadd, &dst) != 0)
1889 1901                          errs++; /* increment errs and fail at bottom of case */
1890 1902  
1891      -                if ((size = ctf_type_size(src_fp, src_type)) > CTF_MAX_SIZE) {
1892      -                        dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1893      -                        dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
1894      -                        dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
1895      -                } else
1896      -                        dtd->dtd_data.ctt_size = (ushort_t)size;
     1903 +                ctf_set_ctt_size(&dtd->dtd_data,
     1904 +                    ctf_type_size(src_fp, src_type));
1897 1905  
1898 1906                  dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, vlen);
1899 1907  
1900 1908                  /*
1901 1909                   * Make a final pass through the members changing each dmd_type
1902 1910                   * (a src_fp type) to an equivalent type in dst_fp.  We pass
1903 1911                   * through all members, leaving any that fail set to CTF_ERR.
1904 1912                   */
1905 1913                  for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
1906 1914                      dmd != NULL; dmd = ctf_list_next(dmd)) {
↓ open down ↓ 14 lines elided ↑ open up ↑
1921 1929                          ctf_ref_inc(dst_fp, dmd->dmd_type);
1922 1930                  break;
1923 1931          }
1924 1932  
1925 1933          case CTF_K_ENUM:
1926 1934                  if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) {
1927 1935                          if (ctf_enum_iter(src_fp, src_type, enumcmp, &dst) ||
1928 1936                              ctf_enum_iter(dst_fp, dst_type, enumcmp, &src))
1929 1937                                  return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1930 1938                  } else {
1931      -                        dst_type = ctf_add_enum(dst_fp, flag, name);
     1939 +                        ssize_t size = ctf_type_size(src_fp, src_type);
     1940 +
     1941 +                        if (size == CTF_ERR)
     1942 +                                return (CTF_ERR); /* errno is set for us */
     1943 +
     1944 +                        dst_type = ctf_add_enum(dst_fp, flag, name, size);
1932 1945                          if ((dst.ctb_type = dst_type) == CTF_ERR ||
1933 1946                              ctf_enum_iter(src_fp, src_type, enumadd, &dst))
1934 1947                                  return (CTF_ERR); /* errno is set for us */
1935 1948                  }
1936 1949                  break;
1937 1950  
1938 1951          case CTF_K_FORWARD:
1939 1952                  if (dst_type == CTF_ERR) {
1940 1953                          dst_type = ctf_add_forward(dst_fp,
1941 1954                              flag, name, CTF_K_STRUCT); /* assume STRUCT */
↓ open down ↓ 216 lines elided ↑ open up ↑
2158 2171  
2159 2172          if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
2160 2173                  return (ctf_set_errno(fp, ECTF_NOTSOU));
2161 2174  
2162 2175          if ((oldsz = dtd->dtd_data.ctt_size) == CTF_LSIZE_SENT)
2163 2176                  oldsz = CTF_TYPE_LSIZE(&dtd->dtd_data);
2164 2177  
2165 2178          if (newsz < oldsz)
2166 2179                  return (ctf_set_errno(fp, EINVAL));
2167 2180  
2168      -        if (newsz > CTF_MAX_SIZE) {
2169      -                dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
2170      -                dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(newsz);
2171      -                dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(newsz);
2172      -        } else {
2173      -                dtd->dtd_data.ctt_size = (ushort_t)newsz;
2174      -        }
     2181 +        ctf_set_ctt_size(&dtd->dtd_data, newsz);
2175 2182  
2176 2183          fp->ctf_flags |= LCTF_DIRTY;
2177 2184          return (0);
2178 2185  }
2179 2186  
2180 2187  int
2181 2188  ctf_set_root(ctf_file_t *fp, ctf_id_t id, const boolean_t vis)
2182 2189  {
2183 2190          ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, id);
2184 2191          uint_t kind, vlen;
↓ open down ↓ 13 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX