1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2019, Joyent, Inc.
14 */
15
16 /*
17 * To perform a merge of two CTF containers, we first diff the two containers
18 * types. For every type that's in the src container, but not in the dst
19 * container, we note it and add it to dst container. If there are any objects
20 * or functions associated with src, we go through and update the types that
21 * they refer to such that they all refer to types in the dst container.
22 *
23 * The bulk of the logic for the merge, after we've run the diff, occurs in
24 * ctf_merge_common().
25 *
26 * In terms of exported APIs, we don't really export a simple merge two
27 * containers, as the general way this is used, in something like ctfmerge(1),
28 * is to add all the containers and then let us figure out the best way to merge
29 * it.
30 */
31
32 #include <libctf_impl.h>
33 #include <sys/debug.h>
323 ctf_id_t cme_id;
324 } ctf_merge_enum_t;
325
326 static int
327 ctf_merge_add_enumerator(const char *name, int value, void *arg)
328 {
329 ctf_merge_enum_t *cmep = arg;
330
331 return (ctf_add_enumerator(cmep->cme_fp, cmep->cme_id, name, value) ==
332 CTF_ERR);
333 }
334
335 static int
336 ctf_merge_add_enum(ctf_merge_types_t *cmp, ctf_id_t id)
337 {
338 int flags;
339 const ctf_type_t *tp;
340 const char *name;
341 ctf_id_t enumid;
342 ctf_merge_enum_t cme;
343
344 tp = LCTF_INDEX_TO_TYPEPTR(cmp->cm_src, id);
345 name = ctf_strraw(cmp->cm_src, tp->ctt_name);
346 if (CTF_INFO_ISROOT(tp->ctt_info) != 0)
347 flags = CTF_ADD_ROOT;
348 else
349 flags = CTF_ADD_NONROOT;
350
351 enumid = ctf_add_enum(cmp->cm_out, flags, name);
352 if (enumid == CTF_ERR)
353 return (enumid);
354
355 cme.cme_fp = cmp->cm_out;
356 cme.cme_id = enumid;
357 if (ctf_enum_iter(cmp->cm_src, id, ctf_merge_add_enumerator,
358 &cme) != 0)
359 return (CTF_ERR);
360
361 VERIFY(cmp->cm_tmap[id].cmt_map == 0);
362 cmp->cm_tmap[id].cmt_map = enumid;
363 return (0);
364 }
365
366 static int
367 ctf_merge_add_func(ctf_merge_types_t *cmp, ctf_id_t id)
368 {
369 int ret, flags, i;
370 const ctf_type_t *tp;
371 ctf_funcinfo_t ctc;
|
1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2020 Joyent, Inc.
14 */
15
16 /*
17 * To perform a merge of two CTF containers, we first diff the two containers
18 * types. For every type that's in the src container, but not in the dst
19 * container, we note it and add it to dst container. If there are any objects
20 * or functions associated with src, we go through and update the types that
21 * they refer to such that they all refer to types in the dst container.
22 *
23 * The bulk of the logic for the merge, after we've run the diff, occurs in
24 * ctf_merge_common().
25 *
26 * In terms of exported APIs, we don't really export a simple merge two
27 * containers, as the general way this is used, in something like ctfmerge(1),
28 * is to add all the containers and then let us figure out the best way to merge
29 * it.
30 */
31
32 #include <libctf_impl.h>
33 #include <sys/debug.h>
323 ctf_id_t cme_id;
324 } ctf_merge_enum_t;
325
326 static int
327 ctf_merge_add_enumerator(const char *name, int value, void *arg)
328 {
329 ctf_merge_enum_t *cmep = arg;
330
331 return (ctf_add_enumerator(cmep->cme_fp, cmep->cme_id, name, value) ==
332 CTF_ERR);
333 }
334
335 static int
336 ctf_merge_add_enum(ctf_merge_types_t *cmp, ctf_id_t id)
337 {
338 int flags;
339 const ctf_type_t *tp;
340 const char *name;
341 ctf_id_t enumid;
342 ctf_merge_enum_t cme;
343 size_t size;
344
345 tp = LCTF_INDEX_TO_TYPEPTR(cmp->cm_src, id);
346 if (CTF_INFO_ISROOT(tp->ctt_info) != 0)
347 flags = CTF_ADD_ROOT;
348 else
349 flags = CTF_ADD_NONROOT;
350
351 name = ctf_strraw(cmp->cm_src, tp->ctt_name);
352 size = ctf_get_ctt_size(cmp->cm_src, tp, NULL, NULL);
353
354 enumid = ctf_add_enum(cmp->cm_out, flags, name, size);
355 if (enumid == CTF_ERR)
356 return (enumid);
357
358 cme.cme_fp = cmp->cm_out;
359 cme.cme_id = enumid;
360 if (ctf_enum_iter(cmp->cm_src, id, ctf_merge_add_enumerator,
361 &cme) != 0)
362 return (CTF_ERR);
363
364 VERIFY(cmp->cm_tmap[id].cmt_map == 0);
365 cmp->cm_tmap[id].cmt_map = enumid;
366 return (0);
367 }
368
369 static int
370 ctf_merge_add_func(ctf_merge_types_t *cmp, ctf_id_t id)
371 {
372 int ret, flags, i;
373 const ctf_type_t *tp;
374 ctf_funcinfo_t ctc;
|