Print this page
5595 libzpool won't build with a studio primary


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #pragma ident   "%Z%%M% %I%     %E% SMI"
  27 
  28 /*
  29  * Given several files containing CTF data, merge and uniquify that data into
  30  * a single CTF section in an output file.
  31  *
  32  * Merges can proceed independently.  As such, we perform the merges in parallel
  33  * using a worker thread model.  A given glob of CTF data (either all of the CTF
  34  * data from a single input file, or the result of one or more merges) can only
  35  * be involved in a single merge at any given time, so the process decreases in
  36  * parallelism, especially towards the end, as more and more files are
  37  * consolidated, finally resulting in a single merge of two large CTF graphs.
  38  * Unfortunately, the last merge is also the slowest, as the two graphs being
  39  * merged are each the product of merges of half of the input files.
  40  *
  41  * The algorithm consists of two phases, described in detail below.  The first
  42  * phase entails the merging of CTF data in groups of eight.  The second phase
  43  * takes the results of Phase I, and merges them two at a time.  This disparity
  44  * is due to an observation that the merge time increases at least quadratically
  45  * with the size of the CTF data being merged.  As such, merges of CTF graphs
  46  * newly read from input files are much faster than merges of CTF graphs that
  47  * are themselves the results of prior merges.


 585 }
 586 
 587 static void
 588 terminate_cleanup(void)
 589 {
 590         int dounlink = getenv("CTFMERGE_TERMINATE_NO_UNLINK") ? 0 : 1;
 591 
 592         if (tmpname != NULL && dounlink)
 593                 unlink(tmpname);
 594 
 595         if (outfile == NULL)
 596                 return;
 597 
 598         if (dounlink) {
 599                 fprintf(stderr, "Removing %s\n", outfile);
 600                 unlink(outfile);
 601         }
 602 }
 603 
 604 static void
 605 copy_ctf_data(char *srcfile, char *destfile, int keep_stabs)
 606 {
 607         tdata_t *srctd;
 608 
 609         if (read_ctf(&srcfile, 1, NULL, read_ctf_save_cb, &srctd, 1) == 0)
 610                 terminate("No CTF data found in source file %s\n", srcfile);
 611 
 612         tmpname = mktmpname(destfile, ".ctf");
 613         write_ctf(srctd, destfile, tmpname, CTF_COMPRESS | keep_stabs);
 614         if (rename(tmpname, destfile) != 0) {
 615                 terminate("Couldn't rename temp file %s to %s", tmpname,
 616                     destfile);
 617         }
 618         free(tmpname);
 619         tdata_free(srctd);
 620 }
 621 
 622 static void
 623 wq_init(workqueue_t *wq, int nfiles)
 624 {
 625         int throttle, nslots, i;
 626 
 627         if (getenv("CTFMERGE_MAX_SLOTS"))
 628                 nslots = atoi(getenv("CTFMERGE_MAX_SLOTS"));
 629         else
 630                 nslots = MERGE_PHASE1_MAX_SLOTS;
 631 
 632         if (getenv("CTFMERGE_PHASE1_BATCH_SIZE"))
 633                 wq->wq_maxbatchsz = atoi(getenv("CTFMERGE_PHASE1_BATCH_SIZE"));


 724 
 725 /*
 726  * Core work queue structure; passed to worker threads on thread creation
 727  * as the main point of coordination.  Allocate as a static structure; we
 728  * could have put this into a local variable in main, but passing a pointer
 729  * into your stack to another thread is fragile at best and leads to some
 730  * hard-to-debug failure modes.
 731  */
 732 static workqueue_t wq;
 733 
 734 int
 735 main(int argc, char **argv)
 736 {
 737         tdata_t *mstrtd, *savetd;
 738         char *uniqfile = NULL, *uniqlabel = NULL;
 739         char *withfile = NULL;
 740         char *label = NULL;
 741         char **ifiles, **tifiles;
 742         int verbose = 0, docopy = 0;
 743         int write_fuzzy_match = 0;
 744         int keep_stabs = 0;
 745         int require_ctf = 0;
 746         int nifiles, nielems;
 747         int c, i, idx, tidx, err;
 748 
 749         progname = basename(argv[0]);
 750 
 751         if (getenv("CTFMERGE_DEBUG_LEVEL"))
 752                 debug_level = atoi(getenv("CTFMERGE_DEBUG_LEVEL"));
 753 
 754         err = 0;
 755         while ((c = getopt(argc, argv, ":cd:D:fgl:L:o:tvw:s")) != EOF) {
 756                 switch (c) {
 757                 case 'c':
 758                         docopy = 1;
 759                         break;
 760                 case 'd':
 761                         /* Uniquify against `uniqfile' */
 762                         uniqfile = optarg;
 763                         break;
 764                 case 'D':
 765                         /* Uniquify against label `uniqlabel' in `uniqfile' */
 766                         uniqlabel = optarg;
 767                         break;
 768                 case 'f':
 769                         write_fuzzy_match = CTF_FUZZY_MATCH;
 770                         break;
 771                 case 'g':
 772                         keep_stabs = CTF_KEEP_STABS;
 773                         break;
 774                 case 'l':
 775                         /* Label merged types with `label' */
 776                         label = optarg;
 777                         break;
 778                 case 'L':
 779                         /* Label merged types with getenv(`label`) */
 780                         if ((label = getenv(optarg)) == NULL)
 781                                 label = CTF_DEFAULT_LABEL;
 782                         break;
 783                 case 'o':
 784                         /* Place merged types in CTF section in `outfile' */
 785                         outfile = optarg;
 786                         break;
 787                 case 't':
 788                         /* Insist *all* object files built from C have CTF */
 789                         require_ctf = 1;
 790                         break;
 791                 case 'v':
 792                         /* More debugging information */
 793                         verbose = 1;


 816                         err++;
 817         } else {
 818                 if (uniqfile != NULL && withfile != NULL)
 819                         err++;
 820 
 821                 if (uniqlabel != NULL && uniqfile == NULL)
 822                         err++;
 823 
 824                 if (outfile == NULL || label == NULL)
 825                         err++;
 826 
 827                 if (argc - optind == 0)
 828                         err++;
 829         }
 830 
 831         if (err) {
 832                 usage();
 833                 exit(2);
 834         }
 835 
 836         if (getenv("STRIPSTABS_KEEP_STABS") != NULL)
 837                 keep_stabs = CTF_KEEP_STABS;
 838 
 839         if (uniqfile && access(uniqfile, R_OK) != 0) {
 840                 warning("Uniquification file %s couldn't be opened and "
 841                     "will be ignored.\n", uniqfile);
 842                 uniqfile = NULL;
 843         }
 844         if (withfile && access(withfile, R_OK) != 0) {
 845                 warning("With file %s couldn't be opened and will be "
 846                     "ignored.\n", withfile);
 847                 withfile = NULL;
 848         }
 849         if (outfile && access(outfile, R_OK|W_OK) != 0)
 850                 terminate("Cannot open output file %s for r/w", outfile);
 851 
 852         /*
 853          * This is ugly, but we don't want to have to have a separate tool
 854          * (yet) just for copying an ELF section with our specific requirements,
 855          * so we shoe-horn a copier into ctfmerge.
 856          */
 857         if (docopy) {
 858                 copy_ctf_data(argv[optind], argv[optind + 1], keep_stabs);
 859 
 860                 exit(0);
 861         }
 862 
 863         set_terminate_cleanup(terminate_cleanup);
 864 
 865         /* Sort the input files and strip out duplicates */
 866         nifiles = argc - optind;
 867         ifiles = xmalloc(sizeof (char *) * nifiles);
 868         tifiles = xmalloc(sizeof (char *) * nifiles);
 869 
 870         for (i = 0; i < nifiles; i++)
 871                 tifiles[i] = argv[optind + i];
 872         qsort(tifiles, nifiles, sizeof (char *), (int (*)())strcompare);
 873 
 874         ifiles[0] = tifiles[0];
 875         for (idx = 0, tidx = 1; tidx < nifiles; tidx++) {
 876                 if (strcmp(ifiles[idx], tifiles[tidx]) != 0)
 877                         ifiles[++idx] = tifiles[tidx];
 878         }


 982                         savetd->td_parlabel = xstrdup(parle->le_name);
 983 
 984                         strncpy(uniqname, reffile, sizeof (uniqname));
 985                         uniqname[MAXPATHLEN - 1] = '\0';
 986                         savetd->td_parname = xstrdup(basename(uniqname));
 987                 }
 988 
 989         } else {
 990                 /*
 991                  * No post processing.  Write the merged tree as-is into the
 992                  * output file.
 993                  */
 994                 tdata_label_free(mstrtd);
 995                 tdata_label_add(mstrtd, label, CTF_LABEL_LASTIDX);
 996 
 997                 savetd = mstrtd;
 998         }
 999 
1000         tmpname = mktmpname(outfile, ".ctf");
1001         write_ctf(savetd, outfile, tmpname,
1002             CTF_COMPRESS | write_fuzzy_match | dynsym | keep_stabs);
1003         if (rename(tmpname, outfile) != 0)
1004                 terminate("Couldn't rename output temp file %s", tmpname);
1005         free(tmpname);
1006 
1007         return (0);
1008 }


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 


  26 /*
  27  * Given several files containing CTF data, merge and uniquify that data into
  28  * a single CTF section in an output file.
  29  *
  30  * Merges can proceed independently.  As such, we perform the merges in parallel
  31  * using a worker thread model.  A given glob of CTF data (either all of the CTF
  32  * data from a single input file, or the result of one or more merges) can only
  33  * be involved in a single merge at any given time, so the process decreases in
  34  * parallelism, especially towards the end, as more and more files are
  35  * consolidated, finally resulting in a single merge of two large CTF graphs.
  36  * Unfortunately, the last merge is also the slowest, as the two graphs being
  37  * merged are each the product of merges of half of the input files.
  38  *
  39  * The algorithm consists of two phases, described in detail below.  The first
  40  * phase entails the merging of CTF data in groups of eight.  The second phase
  41  * takes the results of Phase I, and merges them two at a time.  This disparity
  42  * is due to an observation that the merge time increases at least quadratically
  43  * with the size of the CTF data being merged.  As such, merges of CTF graphs
  44  * newly read from input files are much faster than merges of CTF graphs that
  45  * are themselves the results of prior merges.


 583 }
 584 
 585 static void
 586 terminate_cleanup(void)
 587 {
 588         int dounlink = getenv("CTFMERGE_TERMINATE_NO_UNLINK") ? 0 : 1;
 589 
 590         if (tmpname != NULL && dounlink)
 591                 unlink(tmpname);
 592 
 593         if (outfile == NULL)
 594                 return;
 595 
 596         if (dounlink) {
 597                 fprintf(stderr, "Removing %s\n", outfile);
 598                 unlink(outfile);
 599         }
 600 }
 601 
 602 static void
 603 copy_ctf_data(char *srcfile, char *destfile)
 604 {
 605         tdata_t *srctd;
 606 
 607         if (read_ctf(&srcfile, 1, NULL, read_ctf_save_cb, &srctd, 1) == 0)
 608                 terminate("No CTF data found in source file %s\n", srcfile);
 609 
 610         tmpname = mktmpname(destfile, ".ctf");
 611         write_ctf(srctd, destfile, tmpname, CTF_COMPRESS);
 612         if (rename(tmpname, destfile) != 0) {
 613                 terminate("Couldn't rename temp file %s to %s", tmpname,
 614                     destfile);
 615         }
 616         free(tmpname);
 617         tdata_free(srctd);
 618 }
 619 
 620 static void
 621 wq_init(workqueue_t *wq, int nfiles)
 622 {
 623         int throttle, nslots, i;
 624 
 625         if (getenv("CTFMERGE_MAX_SLOTS"))
 626                 nslots = atoi(getenv("CTFMERGE_MAX_SLOTS"));
 627         else
 628                 nslots = MERGE_PHASE1_MAX_SLOTS;
 629 
 630         if (getenv("CTFMERGE_PHASE1_BATCH_SIZE"))
 631                 wq->wq_maxbatchsz = atoi(getenv("CTFMERGE_PHASE1_BATCH_SIZE"));


 722 
 723 /*
 724  * Core work queue structure; passed to worker threads on thread creation
 725  * as the main point of coordination.  Allocate as a static structure; we
 726  * could have put this into a local variable in main, but passing a pointer
 727  * into your stack to another thread is fragile at best and leads to some
 728  * hard-to-debug failure modes.
 729  */
 730 static workqueue_t wq;
 731 
 732 int
 733 main(int argc, char **argv)
 734 {
 735         tdata_t *mstrtd, *savetd;
 736         char *uniqfile = NULL, *uniqlabel = NULL;
 737         char *withfile = NULL;
 738         char *label = NULL;
 739         char **ifiles, **tifiles;
 740         int verbose = 0, docopy = 0;
 741         int write_fuzzy_match = 0;

 742         int require_ctf = 0;
 743         int nifiles, nielems;
 744         int c, i, idx, tidx, err;
 745 
 746         progname = basename(argv[0]);
 747 
 748         if (getenv("CTFMERGE_DEBUG_LEVEL"))
 749                 debug_level = atoi(getenv("CTFMERGE_DEBUG_LEVEL"));
 750 
 751         err = 0;
 752         while ((c = getopt(argc, argv, ":cd:D:fl:L:o:tvw:s")) != EOF) {
 753                 switch (c) {
 754                 case 'c':
 755                         docopy = 1;
 756                         break;
 757                 case 'd':
 758                         /* Uniquify against `uniqfile' */
 759                         uniqfile = optarg;
 760                         break;
 761                 case 'D':
 762                         /* Uniquify against label `uniqlabel' in `uniqfile' */
 763                         uniqlabel = optarg;
 764                         break;
 765                 case 'f':
 766                         write_fuzzy_match = CTF_FUZZY_MATCH;
 767                         break;



 768                 case 'l':
 769                         /* Label merged types with `label' */
 770                         label = optarg;
 771                         break;
 772                 case 'L':
 773                         /* Label merged types with getenv(`label`) */
 774                         if ((label = getenv(optarg)) == NULL)
 775                                 label = CTF_DEFAULT_LABEL;
 776                         break;
 777                 case 'o':
 778                         /* Place merged types in CTF section in `outfile' */
 779                         outfile = optarg;
 780                         break;
 781                 case 't':
 782                         /* Insist *all* object files built from C have CTF */
 783                         require_ctf = 1;
 784                         break;
 785                 case 'v':
 786                         /* More debugging information */
 787                         verbose = 1;


 810                         err++;
 811         } else {
 812                 if (uniqfile != NULL && withfile != NULL)
 813                         err++;
 814 
 815                 if (uniqlabel != NULL && uniqfile == NULL)
 816                         err++;
 817 
 818                 if (outfile == NULL || label == NULL)
 819                         err++;
 820 
 821                 if (argc - optind == 0)
 822                         err++;
 823         }
 824 
 825         if (err) {
 826                 usage();
 827                 exit(2);
 828         }
 829 



 830         if (uniqfile && access(uniqfile, R_OK) != 0) {
 831                 warning("Uniquification file %s couldn't be opened and "
 832                     "will be ignored.\n", uniqfile);
 833                 uniqfile = NULL;
 834         }
 835         if (withfile && access(withfile, R_OK) != 0) {
 836                 warning("With file %s couldn't be opened and will be "
 837                     "ignored.\n", withfile);
 838                 withfile = NULL;
 839         }
 840         if (outfile && access(outfile, R_OK|W_OK) != 0)
 841                 terminate("Cannot open output file %s for r/w", outfile);
 842 
 843         /*
 844          * This is ugly, but we don't want to have to have a separate tool
 845          * (yet) just for copying an ELF section with our specific requirements,
 846          * so we shoe-horn a copier into ctfmerge.
 847          */
 848         if (docopy) {
 849                 copy_ctf_data(argv[optind], argv[optind + 1]);
 850 
 851                 exit(0);
 852         }
 853 
 854         set_terminate_cleanup(terminate_cleanup);
 855 
 856         /* Sort the input files and strip out duplicates */
 857         nifiles = argc - optind;
 858         ifiles = xmalloc(sizeof (char *) * nifiles);
 859         tifiles = xmalloc(sizeof (char *) * nifiles);
 860 
 861         for (i = 0; i < nifiles; i++)
 862                 tifiles[i] = argv[optind + i];
 863         qsort(tifiles, nifiles, sizeof (char *), (int (*)())strcompare);
 864 
 865         ifiles[0] = tifiles[0];
 866         for (idx = 0, tidx = 1; tidx < nifiles; tidx++) {
 867                 if (strcmp(ifiles[idx], tifiles[tidx]) != 0)
 868                         ifiles[++idx] = tifiles[tidx];
 869         }


 973                         savetd->td_parlabel = xstrdup(parle->le_name);
 974 
 975                         strncpy(uniqname, reffile, sizeof (uniqname));
 976                         uniqname[MAXPATHLEN - 1] = '\0';
 977                         savetd->td_parname = xstrdup(basename(uniqname));
 978                 }
 979 
 980         } else {
 981                 /*
 982                  * No post processing.  Write the merged tree as-is into the
 983                  * output file.
 984                  */
 985                 tdata_label_free(mstrtd);
 986                 tdata_label_add(mstrtd, label, CTF_LABEL_LASTIDX);
 987 
 988                 savetd = mstrtd;
 989         }
 990 
 991         tmpname = mktmpname(outfile, ".ctf");
 992         write_ctf(savetd, outfile, tmpname,
 993             CTF_COMPRESS | write_fuzzy_match | dynsym);
 994         if (rename(tmpname, outfile) != 0)
 995                 terminate("Couldn't rename output temp file %s", tmpname);
 996         free(tmpname);
 997 
 998         return (0);
 999 }