When copying types from one CTF container to another, ensure that we

always copy intrinsic data types before copying bitfields which are
based on those types. This ensures the type ordering in the destination
CTF container matches the assumption made elsewhere in the CTF code
that instrinsic data types will always appear before bitfields based on
those types.

This resolves the following error message some users have seen after
r366908:
    "/usr/lib/dtrace/ipfw.d", line 121: failed to copy type of 'ip6p':
    Conflicting type is already defined

Reviewed by:	markj
Sponsored by:	Netflix
Differential Revision:	https://reviews.freebsd.org/D27213
This commit is contained in:
Jonathan T. Looney 2020-11-17 14:07:27 +00:00
parent 2f40fc6ff3
commit 3cbb4cc200
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=367763

View File

@ -1258,7 +1258,7 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
uint_t kind, flag, vlen;
ctf_bundle_t src, dst;
ctf_encoding_t src_en, dst_en;
ctf_encoding_t src_en, main_en, dst_en;
ctf_arinfo_t src_ar, dst_ar;
ctf_dtdef_t *dtd;
@ -1373,6 +1373,27 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
if (ctf_type_encoding(src_fp, src_type, &src_en) != 0)
return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
/*
* This could be a bitfield, and the CTF library assumes
* intrinsics will appear before bitfields. Therefore,
* try to copy over the intrinsic prior to copying the
* bitfield.
*/
if (dst_type == CTF_ERR && name[0] != '\0' &&
(hep = ctf_hash_lookup(&src_fp->ctf_names, src_fp, name,
strlen(name))) != NULL &&
src_type != (ctf_id_t)hep->h_type) {
if (ctf_type_encoding(src_fp, (ctf_id_t)hep->h_type,
&main_en) != 0) {
return (ctf_set_errno(dst_fp,
ctf_errno(src_fp)));
}
if (bcmp(&src_en, &main_en, sizeof (ctf_encoding_t)) &&
ctf_add_type(dst_fp, src_fp,
(ctf_id_t)hep->h_type) == CTF_ERR)
return (CTF_ERR); /* errno is set for us */
}
if (dst_type != CTF_ERR) {
if (ctf_type_encoding(dst_fp, dst_type, &dst_en) != 0)
return (CTF_ERR); /* errno is set for us */