Print this page
12259 CTF shouldn't assume enum size


   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 
  23 /*
  24  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  25  * Use is subject to license terms.
  26  */
  27 /*
  28  * Copyright (c) 2019, Joyent, Inc.
  29  */
  30 
  31 #include <sys/sysmacros.h>
  32 #include <sys/param.h>
  33 #include <sys/mman.h>
  34 #include <ctf_impl.h>
  35 #include <sys/debug.h>
  36 
  37 /*
  38  * This static string is used as the template for initially populating a
  39  * dynamic container's string table.  We always store \0 in the first byte,
  40  * and we use the generic string "PARENT" to mark this container's parent
  41  * if one is associated with the container using ctf_import().
  42  */
  43 static const char _CTF_STRTAB_TEMPLATE[] = "\0PARENT";
  44 
  45 /*
  46  * To create an empty CTF container, we just declare a zeroed header and call
  47  * ctf_bufopen() on it.  If ctf_bufopen succeeds, we mark the new container r/w
  48  * and initialize the dynamic members.  We set dtstrlen to 1 to reserve the


1229         }
1230 
1231         if (dtd == NULL) {
1232                 type = ctf_add_generic(fp, flag, name, &dtd);
1233                 if (type == CTF_ERR)
1234                         return (CTF_ERR); /* errno is set for us */
1235         }
1236 
1237         VERIFY(type != CTF_ERR);
1238         dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_UNION, flag, 0);
1239         dtd->dtd_data.ctt_size = 0;
1240 
1241         /*
1242          * Always dirty in case we modified a forward.
1243          */
1244         fp->ctf_flags |= LCTF_DIRTY;
1245 
1246         return (type);
1247 }
1248 




1249 ctf_id_t
1250 ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name)
1251 {
1252         ctf_hash_t *hp = &fp->ctf_enums;
1253         ctf_helem_t *hep = NULL;
1254         ctf_dtdef_t *dtd = NULL;
1255         ctf_id_t type = CTF_ERR;
1256 
1257         if (name != NULL)
1258                 hep = ctf_hash_lookup(hp, fp, name, strlen(name));
1259 
1260         if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD) {
1261                 type = hep->h_type;
1262                 dtd = ctf_dtd_lookup(fp, type);
1263                 if (CTF_INFO_KIND(dtd->dtd_data.ctt_info) != CTF_K_FORWARD)
1264                         dtd = NULL;
1265         }
1266 
1267         if (dtd == NULL) {
1268                 type = ctf_add_generic(fp, flag, name, &dtd);
1269                 if (type == CTF_ERR)
1270                         return (CTF_ERR); /* errno is set for us */
1271         }
1272 
1273         VERIFY(type != CTF_ERR);
1274         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 
1277         /*
1278          * Always dirty in case we modified a forward.
1279          */
1280         fp->ctf_flags |= LCTF_DIRTY;
1281 
1282         return (type);
1283 }
1284 
1285 ctf_id_t
1286 ctf_add_forward(ctf_file_t *fp, uint_t flag, const char *name, uint_t kind)
1287 {
1288         ctf_hash_t *hp;
1289         ctf_helem_t *hep;
1290         ctf_dtdef_t *dtd;
1291         ctf_id_t type;
1292 
1293         switch (kind) {
1294         case CTF_K_STRUCT:
1295                 hp = &fp->ctf_structs;


1911 
1912                 if (errs)
1913                         return (CTF_ERR); /* errno is set for us */
1914 
1915                 /*
1916                  * Now that we know that we can't fail, we go through and bump
1917                  * all the reference counts on the member types.
1918                  */
1919                 for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
1920                     dmd != NULL; dmd = ctf_list_next(dmd))
1921                         ctf_ref_inc(dst_fp, dmd->dmd_type);
1922                 break;
1923         }
1924 
1925         case CTF_K_ENUM:
1926                 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) {
1927                         if (ctf_enum_iter(src_fp, src_type, enumcmp, &dst) ||
1928                             ctf_enum_iter(dst_fp, dst_type, enumcmp, &src))
1929                                 return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1930                 } else {
1931                         dst_type = ctf_add_enum(dst_fp, flag, name);

1932                         if ((dst.ctb_type = dst_type) == CTF_ERR ||
1933                             ctf_enum_iter(src_fp, src_type, enumadd, &dst))
1934                                 return (CTF_ERR); /* errno is set for us */
1935                 }
1936                 break;
1937 
1938         case CTF_K_FORWARD:
1939                 if (dst_type == CTF_ERR) {
1940                         dst_type = ctf_add_forward(dst_fp,
1941                             flag, name, CTF_K_STRUCT); /* assume STRUCT */
1942                 }
1943                 break;
1944 
1945         case CTF_K_TYPEDEF:
1946                 src_type = ctf_type_reference(src_fp, src_type);
1947                 src_type = ctf_add_type(dst_fp, src_fp, src_type);
1948 
1949                 if (src_type == CTF_ERR)
1950                         return (CTF_ERR); /* errno is set for us */
1951 




   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 
  23 /*
  24  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  25  * Use is subject to license terms.
  26  */
  27 /*
  28  * Copyright 2020 Joyent, Inc.
  29  */
  30 
  31 #include <sys/sysmacros.h>
  32 #include <sys/param.h>
  33 #include <sys/mman.h>
  34 #include <ctf_impl.h>
  35 #include <sys/debug.h>
  36 
  37 /*
  38  * This static string is used as the template for initially populating a
  39  * dynamic container's string table.  We always store \0 in the first byte,
  40  * and we use the generic string "PARENT" to mark this container's parent
  41  * if one is associated with the container using ctf_import().
  42  */
  43 static const char _CTF_STRTAB_TEMPLATE[] = "\0PARENT";
  44 
  45 /*
  46  * To create an empty CTF container, we just declare a zeroed header and call
  47  * ctf_bufopen() on it.  If ctf_bufopen succeeds, we mark the new container r/w
  48  * and initialize the dynamic members.  We set dtstrlen to 1 to reserve the


1229         }
1230 
1231         if (dtd == NULL) {
1232                 type = ctf_add_generic(fp, flag, name, &dtd);
1233                 if (type == CTF_ERR)
1234                         return (CTF_ERR); /* errno is set for us */
1235         }
1236 
1237         VERIFY(type != CTF_ERR);
1238         dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_UNION, flag, 0);
1239         dtd->dtd_data.ctt_size = 0;
1240 
1241         /*
1242          * Always dirty in case we modified a forward.
1243          */
1244         fp->ctf_flags |= LCTF_DIRTY;
1245 
1246         return (type);
1247 }
1248 
1249 /*
1250  * If size is 0, we use the standard integer size. This is almost always the
1251  * case, except for packed enums.
1252  */
1253 ctf_id_t
1254 ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name, size_t size)
1255 {
1256         ctf_hash_t *hp = &fp->ctf_enums;
1257         ctf_helem_t *hep = NULL;
1258         ctf_dtdef_t *dtd = NULL;
1259         ctf_id_t type = CTF_ERR;
1260 
1261         if (name != NULL)
1262                 hep = ctf_hash_lookup(hp, fp, name, strlen(name));
1263 
1264         if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD) {
1265                 type = hep->h_type;
1266                 dtd = ctf_dtd_lookup(fp, type);
1267                 if (CTF_INFO_KIND(dtd->dtd_data.ctt_info) != CTF_K_FORWARD)
1268                         dtd = NULL;
1269         }
1270 
1271         if (dtd == NULL) {
1272                 type = ctf_add_generic(fp, flag, name, &dtd);
1273                 if (type == CTF_ERR)
1274                         return (CTF_ERR); /* errno is set for us */
1275         }
1276 
1277         VERIFY(type != CTF_ERR);
1278         dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, flag, 0);
1279 
1280         if (size == 0) {
1281                 dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
1282         } else {
1283                 if (size > CTF_MAX_SIZE) {
1284                         dtd->dtd_data.ctt_size = CTF_LSIZE_SENT;
1285                         dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
1286                         dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
1287                 } else
1288                         dtd->dtd_data.ctt_size = size;
1289         }
1290 
1291         /*
1292          * Always dirty in case we modified a forward.
1293          */
1294         fp->ctf_flags |= LCTF_DIRTY;
1295 
1296         return (type);
1297 }
1298 
1299 ctf_id_t
1300 ctf_add_forward(ctf_file_t *fp, uint_t flag, const char *name, uint_t kind)
1301 {
1302         ctf_hash_t *hp;
1303         ctf_helem_t *hep;
1304         ctf_dtdef_t *dtd;
1305         ctf_id_t type;
1306 
1307         switch (kind) {
1308         case CTF_K_STRUCT:
1309                 hp = &fp->ctf_structs;


1925 
1926                 if (errs)
1927                         return (CTF_ERR); /* errno is set for us */
1928 
1929                 /*
1930                  * Now that we know that we can't fail, we go through and bump
1931                  * all the reference counts on the member types.
1932                  */
1933                 for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
1934                     dmd != NULL; dmd = ctf_list_next(dmd))
1935                         ctf_ref_inc(dst_fp, dmd->dmd_type);
1936                 break;
1937         }
1938 
1939         case CTF_K_ENUM:
1940                 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) {
1941                         if (ctf_enum_iter(src_fp, src_type, enumcmp, &dst) ||
1942                             ctf_enum_iter(dst_fp, dst_type, enumcmp, &src))
1943                                 return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1944                 } else {
1945                         size_t size = ctf_type_size(src_fp, src_type);
1946                         dst_type = ctf_add_enum(dst_fp, flag, name, size);
1947                         if ((dst.ctb_type = dst_type) == CTF_ERR ||
1948                             ctf_enum_iter(src_fp, src_type, enumadd, &dst))
1949                                 return (CTF_ERR); /* errno is set for us */
1950                 }
1951                 break;
1952 
1953         case CTF_K_FORWARD:
1954                 if (dst_type == CTF_ERR) {
1955                         dst_type = ctf_add_forward(dst_fp,
1956                             flag, name, CTF_K_STRUCT); /* assume STRUCT */
1957                 }
1958                 break;
1959 
1960         case CTF_K_TYPEDEF:
1961                 src_type = ctf_type_reference(src_fp, src_type);
1962                 src_type = ctf_add_type(dst_fp, src_fp, src_type);
1963 
1964                 if (src_type == CTF_ERR)
1965                         return (CTF_ERR); /* errno is set for us */
1966