Print this page
10827 some symbols have the wrong CTF type
Reviewed by: Robert Mustacchi <rm@joyent.com>
   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 (c) 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>


 598 static int
 599 ctf_merge_fixup_type(ctf_merge_types_t *cmp, ctf_id_t id)
 600 {
 601         int kind, ret;
 602 
 603         kind = ctf_type_kind(cmp->cm_src, id);
 604         switch (kind) {
 605         case CTF_K_STRUCT:
 606         case CTF_K_UNION:
 607                 ret = ctf_merge_fixup_sou(cmp, id);
 608                 break;
 609         default:
 610                 VERIFY(0);
 611                 ret = CTF_ERR;
 612         }
 613 
 614         return (ret);
 615 }
 616 
 617 /*
 618  * Now that we've successfully merged everything, we're going to clean
 619  * up the merge type table. Traditionally if we had just two different
 620  * files that we were working between, the types would be fully
 621  * resolved. However, because we were comparing with ourself every step
 622  * of the way and not our reduced self, we need to go through and update
 623  * every mapped entry to what it now points to in the deduped file.













 624  */
 625 static void
 626 ctf_merge_fixup_dedup_map(ctf_merge_types_t *cmp)
 627 {
 628         int i;
 629 
 630         for (i = 1; i < cmp->cm_src->ctf_typemax + 1; i++) {
 631                 ctf_id_t tid;
 632 
 633                 /*
 634                  * Missing types always have their id updated to exactly what it
 635                  * should be.
 636                  */
 637                 if (cmp->cm_tmap[i].cmt_missing == B_TRUE) {
 638                         VERIFY(cmp->cm_tmap[i].cmt_map != 0);
 639                         continue;
 640                 }
 641 
 642                 tid = i;
 643                 while (cmp->cm_tmap[tid].cmt_missing == B_FALSE) {
 644                         VERIFY(cmp->cm_tmap[tid].cmt_map != 0);
 645                         tid = cmp->cm_tmap[tid].cmt_map;
 646                 }
 647                 VERIFY(cmp->cm_tmap[tid].cmt_map != 0);
 648                 cmp->cm_tmap[i].cmt_map = cmp->cm_tmap[tid].cmt_map;
 649         }
 650 }
 651 
 652 
 653 /*
 654  * We're going to do three passes over the containers.
 655  *
 656  * Pass 1 checks for forward references in the output container that we know


 684                         }
 685                 }
 686         }
 687 
 688         /* Pass 2 */
 689         for (i = 1; i <= cmp->cm_src->ctf_typemax; i++) {
 690                 if (cmp->cm_tmap[i].cmt_missing == B_TRUE) {
 691                         ret = ctf_merge_add_type(cmp, i);
 692                         if (ret != 0) {
 693                                 ctf_dprintf("Failed to merge type %d\n", i);
 694                                 return (ret);
 695                         }
 696                 }
 697         }
 698 
 699         ret = ctf_update(cmp->cm_out);
 700         if (ret != 0)
 701                 return (ret);
 702 
 703         if (cmp->cm_dedup == B_TRUE) {
 704                 ctf_merge_fixup_dedup_map(cmp);
 705         }
 706 
 707         ctf_dprintf("Beginning merge pass 3\n");
 708         /* Pass 3 */
 709         for (i = 1; i <= cmp->cm_src->ctf_typemax; i++) {
 710                 if (cmp->cm_tmap[i].cmt_fixup == B_TRUE) {
 711                         ret = ctf_merge_fixup_type(cmp, i);
 712                         if (ret != 0)
 713                                 return (ret);
 714                 }
 715         }
 716 
 717         if (cmp->cm_dedup == B_TRUE) {
 718                 ctf_merge_fixup_dedup_map(cmp);
 719         }
 720 
 721         return (0);
 722 }
 723 
 724 /*
 725  * Uniquification is slightly different from a stock merge. For starters, we
 726  * don't need to replace any forward references in the output. In this case
 727  * though, the types that already exist are in a parent container to the empty
 728  * output container.
 729  */
 730 static int
 731 ctf_merge_uniquify_types(ctf_merge_types_t *cmp)
 732 {
 733         int i, ret;
 734 
 735         for (i = 1; i <= cmp->cm_src->ctf_typemax; i++) {
 736                 if (cmp->cm_tmap[i].cmt_missing == B_FALSE)
 737                         continue;
 738                 ret = ctf_merge_add_type(cmp, i);
 739                 if (ret != 0)
 740                         return (ret);


   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>


 598 static int
 599 ctf_merge_fixup_type(ctf_merge_types_t *cmp, ctf_id_t id)
 600 {
 601         int kind, ret;
 602 
 603         kind = ctf_type_kind(cmp->cm_src, id);
 604         switch (kind) {
 605         case CTF_K_STRUCT:
 606         case CTF_K_UNION:
 607                 ret = ctf_merge_fixup_sou(cmp, id);
 608                 break;
 609         default:
 610                 VERIFY(0);
 611                 ret = CTF_ERR;
 612         }
 613 
 614         return (ret);
 615 }
 616 
 617 /*
 618  * Now that we've successfully merged everything, we're going to remap the type
 619  * table.
 620  *
 621  * Remember we have two containers: ->cm_src is what we're working from, and
 622  * ->cm_out is where we are building the de-duplicated CTF.
 623  *
 624  * The index of this table is always the type IDs in ->cm_src.
 625  *
 626  * When we built this table originally in ctf_diff_self(), if we found a novel
 627  * type, we marked it as .cmt_missing to indicate it needs adding to ->cm_out.
 628  * Otherwise, .cmt_map indicated the ->cm_src type ID that this type duplicates.
 629  *
 630  * Then, in ctf_merge_common(), we walked through and added all "cmt_missing"
 631  * types to ->cm_out with ctf_merge_add_type(). These routines update cmt_map
 632  * to be the *new* type ID in ->cm_out.  In this function, you can read
 633  * "cmt_missing" as meaning "added to ->cm_out, and cmt_map updated".
 634  *
 635  * So at this point, we need to mop up all types where .cmt_missing == B_FALSE,
 636  * making sure *their* .cmt_map values also point to the ->cm_out container.
 637  */
 638 static void
 639 ctf_merge_dedup_remap(ctf_merge_types_t *cmp)
 640 {
 641         int i;
 642 
 643         for (i = 1; i < cmp->cm_src->ctf_typemax + 1; i++) {
 644                 ctf_id_t tid;
 645 




 646                 if (cmp->cm_tmap[i].cmt_missing == B_TRUE) {
 647                         VERIFY(cmp->cm_tmap[i].cmt_map != 0);
 648                         continue;
 649                 }
 650 
 651                 tid = i;
 652                 while (cmp->cm_tmap[tid].cmt_missing == B_FALSE) {
 653                         VERIFY(cmp->cm_tmap[tid].cmt_map != 0);
 654                         tid = cmp->cm_tmap[tid].cmt_map;
 655                 }
 656                 VERIFY(cmp->cm_tmap[tid].cmt_map != 0);
 657                 cmp->cm_tmap[i].cmt_map = cmp->cm_tmap[tid].cmt_map;
 658         }
 659 }
 660 
 661 
 662 /*
 663  * We're going to do three passes over the containers.
 664  *
 665  * Pass 1 checks for forward references in the output container that we know


 693                         }
 694                 }
 695         }
 696 
 697         /* Pass 2 */
 698         for (i = 1; i <= cmp->cm_src->ctf_typemax; i++) {
 699                 if (cmp->cm_tmap[i].cmt_missing == B_TRUE) {
 700                         ret = ctf_merge_add_type(cmp, i);
 701                         if (ret != 0) {
 702                                 ctf_dprintf("Failed to merge type %d\n", i);
 703                                 return (ret);
 704                         }
 705                 }
 706         }
 707 
 708         ret = ctf_update(cmp->cm_out);
 709         if (ret != 0)
 710                 return (ret);
 711 
 712         if (cmp->cm_dedup == B_TRUE) {
 713                 ctf_merge_dedup_remap(cmp);
 714         }
 715 
 716         ctf_dprintf("Beginning merge pass 3\n");
 717         /* Pass 3 */
 718         for (i = 1; i <= cmp->cm_src->ctf_typemax; i++) {
 719                 if (cmp->cm_tmap[i].cmt_fixup == B_TRUE) {
 720                         ret = ctf_merge_fixup_type(cmp, i);
 721                         if (ret != 0)
 722                                 return (ret);
 723                 }
 724         }
 725 




 726         return (0);
 727 }
 728 
 729 /*
 730  * Uniquification is slightly different from a stock merge. For starters, we
 731  * don't need to replace any forward references in the output. In this case
 732  * though, the types that already exist are in a parent container to the empty
 733  * output container.
 734  */
 735 static int
 736 ctf_merge_uniquify_types(ctf_merge_types_t *cmp)
 737 {
 738         int i, ret;
 739 
 740         for (i = 1; i <= cmp->cm_src->ctf_typemax; i++) {
 741                 if (cmp->cm_tmap[i].cmt_missing == B_FALSE)
 742                         continue;
 743                 ret = ctf_merge_add_type(cmp, i);
 744                 if (ret != 0)
 745                         return (ret);