Print this page
10816 ctf_dwarf_convert_type() relies on un-initialized id
10817 ctfconvert -i option is mis-handled
10818 Improve ctfconvert error messages
10819 ctfconvert should handle empty dies
10820 ctfconvert -i never converts
10821 bad free in ctf_dwarf_init_die
10815 shouldn't build gcore.c as part of kmdb
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>


 866                 break;
 867         case DW_ATE_signed_char:
 868                 *kindp = CTF_K_INTEGER;
 869                 enc->cte_format = CTF_INT_SIGNED | CTF_INT_CHAR;
 870                 break;
 871         case DW_ATE_boolean:
 872                 *kindp = CTF_K_INTEGER;
 873                 enc->cte_format = CTF_INT_SIGNED | CTF_INT_BOOL;
 874                 break;
 875         case DW_ATE_float:
 876         case DW_ATE_complex_float:
 877         case DW_ATE_imaginary_float:
 878         case DW_ATE_SUN_imaginary_float:
 879         case DW_ATE_SUN_interval_float:
 880                 *kindp = CTF_K_FLOAT;
 881                 if ((ret = ctf_dwarf_float_base(cup, type, enc)) != 0)
 882                         return (ret);
 883                 break;
 884         default:
 885                 (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 886                     "encountered unkown DWARF encoding: %d", type);
 887                 return (ECTF_CONVBKERR);
 888         }
 889 
 890         return (0);
 891 }
 892 
 893 /*
 894  * Different compilers (at least GCC and Studio) use different names for types.
 895  * This parses the types and attempts to unify them. If this fails, we just fall
 896  * back to using the DWARF itself.
 897  */
 898 static int
 899 ctf_dwarf_parse_base(const char *name, int *kindp, ctf_encoding_t *enc,
 900     char **newnamep)
 901 {
 902         char buf[256];
 903         char *base, *c, *last;
 904         int nlong = 0, nshort = 0, nchar = 0, nint = 0;
 905         int sign = 1;
 906 


1761                 ret = ctf_dwarf_create_sou(cup, die, idp, CTF_K_UNION,
1762                     isroot);
1763                 break;
1764         case DW_TAG_const_type:
1765                 ctf_dprintf("const\n");
1766                 ret = ctf_dwarf_create_reference(cup, die, idp, CTF_K_CONST,
1767                     isroot);
1768                 break;
1769         case DW_TAG_volatile_type:
1770                 ctf_dprintf("volatile\n");
1771                 ret = ctf_dwarf_create_reference(cup, die, idp, CTF_K_VOLATILE,
1772                     isroot);
1773                 break;
1774         case DW_TAG_restrict_type:
1775                 ctf_dprintf("restrict\n");
1776                 ret = ctf_dwarf_create_reference(cup, die, idp, CTF_K_RESTRICT,
1777                     isroot);
1778                 break;
1779         default:
1780                 ctf_dprintf("ignoring tag type %x\n", tag);

1781                 ret = 0;
1782                 break;
1783         }
1784         ctf_dprintf("ctf_dwarf_convert_type tag specific handler returned %d\n",
1785             ret);
1786 
1787         return (ret);
1788 }
1789 
1790 static int
1791 ctf_dwarf_walk_lexical(ctf_cu_t *cup, Dwarf_Die die)
1792 {
1793         int ret;
1794         Dwarf_Die child;
1795 
1796         if ((ret = ctf_dwarf_child(cup, die, &child)) != 0)
1797                 return (ret);
1798 
1799         if (child == NULL)
1800                 return (0);


2660                         ctf_free(cdf->cdf_argv,
2661                             sizeof (ctf_id_t) * cdf->cdf_fip.ctc_argc);
2662                 }
2663                 ctf_free(cdf, sizeof (ctf_dwfunc_t));
2664         }
2665 
2666         ctf_dprintf("Trying to free variables\n");
2667         for (cdv = ctf_list_next(&cup->cu_vars); cdv != NULL; cdv = ndv) {
2668                 ndv = ctf_list_next(cdv);
2669                 ctf_free(cdv->cdv_name, strlen(cdv->cdv_name) + 1);
2670                 ctf_free(cdv, sizeof (ctf_dwvar_t));
2671         }
2672 
2673         ctf_dprintf("Trying to free bitfields\n");
2674         for (cdb = ctf_list_next(&cup->cu_bitfields); cdb != NULL; cdb = ndb) {
2675                 ndb = ctf_list_next(cdb);
2676                 ctf_free(cdb, sizeof (ctf_dwbitf_t));
2677         }
2678 
2679         ctf_dprintf("Trying to clean up dwarf_t: %p\n", cup->cu_dwarf);

2680         (void) dwarf_finish(cup->cu_dwarf, &derr);
2681         cup->cu_dwarf = NULL;
2682         ctf_close(cup->cu_ctfp);
2683 
2684         cookie = NULL;
2685         while ((map = avl_destroy_nodes(&cup->cu_map, &cookie)) != NULL) {
2686                 ctf_free(map, sizeof (ctf_dwmap_t));
2687         }
2688         avl_destroy(&cup->cu_map);
2689         cup->cu_errbuf = NULL;
2690 }
2691 
2692 static void
2693 ctf_dwarf_free_dies(ctf_cu_t *cdies, int ndies)
2694 {
2695         int i;
2696 
2697         ctf_dprintf("Beginning to free dies\n");
2698         for (i = 0; i < ndies; i++) {
2699                 ctf_dwarf_free_die(&cdies[i]);


2710         Dwarf_Half vers;
2711         Dwarf_Unsigned nexthdr;
2712 
2713         while ((ret = dwarf_next_cu_header(dw, NULL, &vers, NULL, NULL,
2714             &nexthdr, derr)) != DW_DLV_NO_ENTRY) {
2715                 if (ret != DW_DLV_OK) {
2716                         (void) snprintf(errbuf, errlen,
2717                             "file does not contain valid DWARF data: %s\n",
2718                             dwarf_errmsg(*derr));
2719                         return (ECTF_CONVBKERR);
2720                 }
2721 
2722                 if (vers != DWARF_VERSION_TWO) {
2723                         (void) snprintf(errbuf, errlen,
2724                             "unsupported DWARF version: %d\n", vers);
2725                         return (ECTF_CONVBKERR);
2726                 }
2727                 *ndies = *ndies + 1;
2728         }
2729 
2730         if (*ndies == 0) {
2731                 (void) snprintf(errbuf, errlen,
2732                     "file does not contain valid DWARF data: %s\n",
2733                     dwarf_errmsg(*derr));
2734                 return (ECTF_CONVBKERR);
2735         }
2736 
2737         return (0);
2738 }
2739 
2740 static int
2741 ctf_dwarf_init_die(int fd, Elf *elf, ctf_cu_t *cup, int ndie, char *errbuf,
2742     size_t errlen)
2743 {
2744         int ret;
2745         Dwarf_Unsigned hdrlen, abboff, nexthdr;
2746         Dwarf_Half addrsz;
2747         Dwarf_Unsigned offset = 0;
2748         Dwarf_Error derr;
2749 
2750         while ((ret = dwarf_next_cu_header(cup->cu_dwarf, &hdrlen, NULL,
2751             &abboff, &addrsz, &nexthdr, &derr)) != DW_DLV_NO_ENTRY) {
2752                 char *name;
2753                 Dwarf_Die cu, child;
2754 
2755                 /* Based on the counting above, we should be good to go */
2756                 VERIFY(ret == DW_DLV_OK);
2757                 if (ndie > 0) {
2758                         ndie--;
2759                         offset = nexthdr;
2760                         continue;
2761                 }
2762 
2763                 /*
2764                  * Compilers are apparently inconsistent. Some emit no DWARF for
2765                  * empty files and others emit empty compilation unit.
2766                  */
2767                 cup->cu_voidtid = CTF_ERR;
2768                 cup->cu_longtid = CTF_ERR;
2769                 cup->cu_elf = elf;
2770                 cup->cu_maxoff = nexthdr - 1;
2771                 cup->cu_ctfp = ctf_fdcreate(fd, &ret);
2772                 if (cup->cu_ctfp == NULL) {
2773                         ctf_free(cup, sizeof (ctf_cu_t));
2774                         return (ret);
2775                 }
2776                 avl_create(&cup->cu_map, ctf_dwmap_comp, sizeof (ctf_dwmap_t),
2777                     offsetof(ctf_dwmap_t, cdm_avl));
2778                 cup->cu_errbuf = errbuf;
2779                 cup->cu_errlen = errlen;
2780                 bzero(&cup->cu_vars, sizeof (ctf_list_t));
2781                 bzero(&cup->cu_funcs, sizeof (ctf_list_t));
2782                 bzero(&cup->cu_bitfields, sizeof (ctf_list_t));
2783 
2784                 if ((ret = ctf_dwarf_die_elfenc(elf, cup, errbuf,
2785                     errlen)) != 0) {
2786                         avl_destroy(&cup->cu_map);
2787                         ctf_free(cup, sizeof (ctf_cu_t));
2788                         return (ret);
2789                 }
2790 
2791                 if ((ret = ctf_dwarf_sib(cup, NULL, &cu)) != 0) {
2792                         avl_destroy(&cup->cu_map);
2793                         ctf_free(cup, sizeof (ctf_cu_t));
2794                         return (ret);
2795                 }
2796                 if (cu == NULL) {
2797                         (void) snprintf(errbuf, errlen,
2798                             "file does not contain DWARF data\n");
2799                         avl_destroy(&cup->cu_map);
2800                         ctf_free(cup, sizeof (ctf_cu_t));
2801                         return (ECTF_CONVBKERR);
2802                 }
2803 
2804                 if ((ret = ctf_dwarf_child(cup, cu, &child)) != 0) {
2805                         avl_destroy(&cup->cu_map);
2806                         ctf_free(cup, sizeof (ctf_cu_t));
2807                         return (ret);
2808                 }
2809                 if (child == NULL) {
2810                         (void) snprintf(errbuf, errlen,
2811                             "file does not contain DWARF data\n");
2812                         avl_destroy(&cup->cu_map);
2813                         ctf_free(cup, sizeof (ctf_cu_t));
2814                         return (ECTF_CONVBKERR);
2815                 }
2816 
2817                 cup->cu_cuoff = offset;
2818                 cup->cu_cu = child;
2819 
2820                 if ((cup->cu_cmh = ctf_merge_init(fd, &ret)) == NULL) {
2821                         avl_destroy(&cup->cu_map);
2822                         ctf_free(cup, sizeof (ctf_cu_t));
2823                         return (ret);
2824                 }
2825 
2826                 if (ctf_dwarf_string(cup, cu, DW_AT_name, &name) == 0) {
2827                         size_t len = strlen(name) + 1;
2828                         char *b = basename(name);
2829                         cup->cu_name = strdup(b);
2830                         ctf_free(name, len);
2831                 }
2832                 break;
2833         }
2834 
2835         return (0);
2836 }
2837 
















2838 
2839 ctf_conv_status_t
2840 ctf_dwarf_convert(int fd, Elf *elf, uint_t nthrs, int *errp, ctf_file_t **fpp,





















2841     char *errmsg, size_t errlen)
2842 {











































































2843         int err, ret, ndies, i;
2844         Dwarf_Debug dw;
2845         Dwarf_Error derr;
2846         ctf_cu_t *cdies = NULL, *cup;
2847         workq_t *wqp = NULL;
2848 
2849         if (errp == NULL)
2850                 errp = &err;
2851         *errp = 0;
2852         *fpp = NULL;
2853 
2854         ret = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, &dw, &derr);
2855         if (ret != DW_DLV_OK) {
2856                 /*
2857                  * We may want to expect DWARF data here and fail conversion if
2858                  * it's missing. In this case, if we actually have some amount
2859                  * of DWARF, but no section, for now, just go ahead and create
2860                  * an empty CTF file.
2861                  */
2862                 if (ret == DW_DLV_NO_ENTRY ||
2863                     dwarf_errno(derr) == DW_DLE_DEBUG_INFO_NULL) {
2864                         *fpp = ctf_create(errp);
2865                         return (*fpp != NULL ? CTF_CONV_SUCCESS :
2866                             CTF_CONV_ERROR);
2867                 }
2868                 (void) snprintf(errmsg, errlen,
2869                     "failed to initialize DWARF: %s\n",
2870                     dwarf_errmsg(derr));
2871                 *errp = ECTF_CONVBKERR;
2872                 return (CTF_CONV_ERROR);
2873         }
2874 
2875         /*
2876          * Iterate over all of the compilation units and create a ctf_cu_t for
2877          * each of them.  This is used to determine if we have zero, one, or
2878          * multiple dies to convert. If we have zero, that's an error. If
2879          * there's only one die, that's the simple case.  No merge needed and
2880          * only a single Dwarf_Debug as well.
2881          */
2882         ndies = 0;
2883         ret = ctf_dwarf_count_dies(dw, &derr, &ndies, errmsg, errlen);
2884         if (ret != 0) {
2885                 *errp = ret;
2886                 goto out;




2887         }
2888 
2889         (void) dwarf_finish(dw, &derr);
2890         cdies = ctf_alloc(sizeof (ctf_cu_t) * ndies);
2891         if (cdies == NULL) {
2892                 *errp = ENOMEM;
2893                 return (CTF_CONV_ERROR);
2894         }
2895 


2896         for (i = 0; i < ndies; i++) {
2897                 cup = &cdies[i];
2898                 ret = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL,
2899                     &cup->cu_dwarf, &derr);
2900                 if (ret != 0) {
2901                         ctf_free(cdies, sizeof (ctf_cu_t) * ndies);
2902                         (void) snprintf(errmsg, errlen,
2903                             "failed to initialize DWARF: %s\n",
2904                             dwarf_errmsg(derr));
2905                         *errp = ECTF_CONVBKERR;
2906                         return (CTF_CONV_ERROR);
2907                 }
2908 
2909                 ret = ctf_dwarf_init_die(fd, elf, &cdies[i], i, errmsg, errlen);
2910                 if (ret != 0) {
2911                         *errp = ret;
2912                         goto out;
2913                 }
2914 
2915                 cup->cu_doweaks = ndies > 1 ? B_FALSE : B_TRUE;
2916         }
2917 
2918         ctf_dprintf("found %d DWARF CUs\n", ndies);



2919 
2920         /*
2921          * If we only have one compilation unit, there's no reason to use
2922          * multiple threads, even if the user requested them. After all, they
2923          * just gave us an upper bound.
2924          */
2925         if (ndies == 1)
2926                 nthrs = 1;
2927 
2928         if (workq_init(&wqp, nthrs) == -1) {
2929                 *errp = errno;
2930                 goto out;
2931         }
2932 
2933         for (i = 0; i < ndies; i++) {
2934                 cup = &cdies[i];
2935                 ctf_dprintf("adding cu %s: %p, %x %x\n", cup->cu_name,
2936                     cup->cu_cu, cup->cu_cuoff, cup->cu_maxoff);
2937                 if (workq_add(wqp, cup) == -1) {
2938                         *errp = errno;
2939                         goto out;
2940                 }
2941         }
2942 
2943         ret = workq_work(wqp, ctf_dwarf_convert_one, NULL, errp);
2944         if (ret == WORKQ_ERROR) {
2945                 *errp = errno;
2946                 goto out;
2947         } else if (ret == WORKQ_UERROR) {
2948                 ctf_dprintf("internal convert failed: %s\n",
2949                     ctf_errmsg(*errp));
2950                 goto out;
2951         }
2952 
2953         ctf_dprintf("Determining next phase: have %d CUs\n", ndies);
2954         if (ndies != 1) {
2955                 ctf_merge_t *cmp;
2956 
2957                 cmp = ctf_merge_init(fd, &ret);
2958                 if (cmp == NULL) {
2959                         *errp = ret;
2960                         goto out;
2961                 }
2962 
2963                 ctf_dprintf("setting threads\n");
2964                 if ((ret = ctf_merge_set_nthreads(cmp, nthrs)) != 0) {
2965                         ctf_merge_fini(cmp);
2966                         *errp = ret;
2967                         goto out;
2968                 }
2969 
2970                 for (i = 0; i < ndies; i++) {
2971                         cup = &cdies[i];
2972                         ctf_dprintf("adding cu %s (%p)\n", cup->cu_name,
2973                             cup->cu_ctfp);
2974                         if ((ret = ctf_merge_add(cmp, cup->cu_ctfp)) != 0) {
2975                                 ctf_merge_fini(cmp);
2976                                 *errp = ret;
2977                                 goto out;
2978                         }
2979                 }
2980 
2981                 ctf_dprintf("performing merge\n");
2982                 ret = ctf_merge_merge(cmp, fpp);
2983                 if (ret != 0) {
2984                         ctf_dprintf("failed merge!\n");
2985                         *fpp = NULL;
2986                         ctf_merge_fini(cmp);
2987                         *errp = ret;
2988                         goto out;
2989                 }
2990                 ctf_merge_fini(cmp);
2991                 *errp = 0;
2992                 ctf_dprintf("successfully converted!\n");
2993         } else {
2994                 *errp = 0;
2995                 *fpp = cdies->cu_ctfp;
2996                 cdies->cu_ctfp = NULL;
2997                 ctf_dprintf("successfully converted!\n");
2998         }
2999 
3000 out:
3001         workq_fini(wqp);
3002         ctf_dwarf_free_dies(cdies, ndies);
3003         return (*fpp != NULL ? CTF_CONV_SUCCESS : CTF_CONV_ERROR);
3004 }


 866                 break;
 867         case DW_ATE_signed_char:
 868                 *kindp = CTF_K_INTEGER;
 869                 enc->cte_format = CTF_INT_SIGNED | CTF_INT_CHAR;
 870                 break;
 871         case DW_ATE_boolean:
 872                 *kindp = CTF_K_INTEGER;
 873                 enc->cte_format = CTF_INT_SIGNED | CTF_INT_BOOL;
 874                 break;
 875         case DW_ATE_float:
 876         case DW_ATE_complex_float:
 877         case DW_ATE_imaginary_float:
 878         case DW_ATE_SUN_imaginary_float:
 879         case DW_ATE_SUN_interval_float:
 880                 *kindp = CTF_K_FLOAT;
 881                 if ((ret = ctf_dwarf_float_base(cup, type, enc)) != 0)
 882                         return (ret);
 883                 break;
 884         default:
 885                 (void) snprintf(cup->cu_errbuf, cup->cu_errlen,
 886                     "encountered unknown DWARF encoding: %d", type);
 887                 return (ECTF_CONVBKERR);
 888         }
 889 
 890         return (0);
 891 }
 892 
 893 /*
 894  * Different compilers (at least GCC and Studio) use different names for types.
 895  * This parses the types and attempts to unify them. If this fails, we just fall
 896  * back to using the DWARF itself.
 897  */
 898 static int
 899 ctf_dwarf_parse_base(const char *name, int *kindp, ctf_encoding_t *enc,
 900     char **newnamep)
 901 {
 902         char buf[256];
 903         char *base, *c, *last;
 904         int nlong = 0, nshort = 0, nchar = 0, nint = 0;
 905         int sign = 1;
 906 


1761                 ret = ctf_dwarf_create_sou(cup, die, idp, CTF_K_UNION,
1762                     isroot);
1763                 break;
1764         case DW_TAG_const_type:
1765                 ctf_dprintf("const\n");
1766                 ret = ctf_dwarf_create_reference(cup, die, idp, CTF_K_CONST,
1767                     isroot);
1768                 break;
1769         case DW_TAG_volatile_type:
1770                 ctf_dprintf("volatile\n");
1771                 ret = ctf_dwarf_create_reference(cup, die, idp, CTF_K_VOLATILE,
1772                     isroot);
1773                 break;
1774         case DW_TAG_restrict_type:
1775                 ctf_dprintf("restrict\n");
1776                 ret = ctf_dwarf_create_reference(cup, die, idp, CTF_K_RESTRICT,
1777                     isroot);
1778                 break;
1779         default:
1780                 ctf_dprintf("ignoring tag type %x\n", tag);
1781                 *idp = CTF_ERR;
1782                 ret = 0;
1783                 break;
1784         }
1785         ctf_dprintf("ctf_dwarf_convert_type tag specific handler returned %d\n",
1786             ret);
1787 
1788         return (ret);
1789 }
1790 
1791 static int
1792 ctf_dwarf_walk_lexical(ctf_cu_t *cup, Dwarf_Die die)
1793 {
1794         int ret;
1795         Dwarf_Die child;
1796 
1797         if ((ret = ctf_dwarf_child(cup, die, &child)) != 0)
1798                 return (ret);
1799 
1800         if (child == NULL)
1801                 return (0);


2661                         ctf_free(cdf->cdf_argv,
2662                             sizeof (ctf_id_t) * cdf->cdf_fip.ctc_argc);
2663                 }
2664                 ctf_free(cdf, sizeof (ctf_dwfunc_t));
2665         }
2666 
2667         ctf_dprintf("Trying to free variables\n");
2668         for (cdv = ctf_list_next(&cup->cu_vars); cdv != NULL; cdv = ndv) {
2669                 ndv = ctf_list_next(cdv);
2670                 ctf_free(cdv->cdv_name, strlen(cdv->cdv_name) + 1);
2671                 ctf_free(cdv, sizeof (ctf_dwvar_t));
2672         }
2673 
2674         ctf_dprintf("Trying to free bitfields\n");
2675         for (cdb = ctf_list_next(&cup->cu_bitfields); cdb != NULL; cdb = ndb) {
2676                 ndb = ctf_list_next(cdb);
2677                 ctf_free(cdb, sizeof (ctf_dwbitf_t));
2678         }
2679 
2680         ctf_dprintf("Trying to clean up dwarf_t: %p\n", cup->cu_dwarf);
2681         if (cup->cu_dwarf != NULL)
2682                 (void) dwarf_finish(cup->cu_dwarf, &derr);
2683         cup->cu_dwarf = NULL;
2684         ctf_close(cup->cu_ctfp);
2685 
2686         cookie = NULL;
2687         while ((map = avl_destroy_nodes(&cup->cu_map, &cookie)) != NULL) {
2688                 ctf_free(map, sizeof (ctf_dwmap_t));
2689         }
2690         avl_destroy(&cup->cu_map);
2691         cup->cu_errbuf = NULL;
2692 }
2693 
2694 static void
2695 ctf_dwarf_free_dies(ctf_cu_t *cdies, int ndies)
2696 {
2697         int i;
2698 
2699         ctf_dprintf("Beginning to free dies\n");
2700         for (i = 0; i < ndies; i++) {
2701                 ctf_dwarf_free_die(&cdies[i]);


2712         Dwarf_Half vers;
2713         Dwarf_Unsigned nexthdr;
2714 
2715         while ((ret = dwarf_next_cu_header(dw, NULL, &vers, NULL, NULL,
2716             &nexthdr, derr)) != DW_DLV_NO_ENTRY) {
2717                 if (ret != DW_DLV_OK) {
2718                         (void) snprintf(errbuf, errlen,
2719                             "file does not contain valid DWARF data: %s\n",
2720                             dwarf_errmsg(*derr));
2721                         return (ECTF_CONVBKERR);
2722                 }
2723 
2724                 if (vers != DWARF_VERSION_TWO) {
2725                         (void) snprintf(errbuf, errlen,
2726                             "unsupported DWARF version: %d\n", vers);
2727                         return (ECTF_CONVBKERR);
2728                 }
2729                 *ndies = *ndies + 1;
2730         }
2731 







2732         return (0);
2733 }
2734 
2735 static int
2736 ctf_dwarf_init_die(int fd, Elf *elf, ctf_cu_t *cup, int ndie, char *errbuf,
2737     size_t errlen)
2738 {
2739         int ret;
2740         Dwarf_Unsigned hdrlen, abboff, nexthdr;
2741         Dwarf_Half addrsz;
2742         Dwarf_Unsigned offset = 0;
2743         Dwarf_Error derr;
2744 
2745         while ((ret = dwarf_next_cu_header(cup->cu_dwarf, &hdrlen, NULL,
2746             &abboff, &addrsz, &nexthdr, &derr)) != DW_DLV_NO_ENTRY) {
2747                 char *name;
2748                 Dwarf_Die cu, child;
2749 
2750                 /* Based on the counting above, we should be good to go */
2751                 VERIFY(ret == DW_DLV_OK);
2752                 if (ndie > 0) {
2753                         ndie--;
2754                         offset = nexthdr;
2755                         continue;
2756                 }
2757 
2758                 /*
2759                  * Compilers are apparently inconsistent. Some emit no DWARF for
2760                  * empty files and others emit empty compilation unit.
2761                  */
2762                 cup->cu_voidtid = CTF_ERR;
2763                 cup->cu_longtid = CTF_ERR;
2764                 cup->cu_elf = elf;
2765                 cup->cu_maxoff = nexthdr - 1;
2766                 cup->cu_ctfp = ctf_fdcreate(fd, &ret);
2767                 if (cup->cu_ctfp == NULL)

2768                         return (ret);
2769 
2770                 avl_create(&cup->cu_map, ctf_dwmap_comp, sizeof (ctf_dwmap_t),
2771                     offsetof(ctf_dwmap_t, cdm_avl));
2772                 cup->cu_errbuf = errbuf;
2773                 cup->cu_errlen = errlen;
2774                 bzero(&cup->cu_vars, sizeof (ctf_list_t));
2775                 bzero(&cup->cu_funcs, sizeof (ctf_list_t));
2776                 bzero(&cup->cu_bitfields, sizeof (ctf_list_t));
2777 
2778                 if ((ret = ctf_dwarf_die_elfenc(elf, cup, errbuf,
2779                     errlen)) != 0)


2780                         return (ret);

2781 
2782                 if ((ret = ctf_dwarf_sib(cup, NULL, &cu)) != 0)


2783                         return (ret);
2784 
2785                 if (cu == NULL) {
2786                         (void) snprintf(errbuf, errlen,
2787                             "file does not contain DWARF data");
2788                         return (ECTF_CONVNODEBUG);


2789                 }
2790 
2791                 if ((ret = ctf_dwarf_child(cup, cu, &child)) != 0)


2792                         return (ret);
2793 
2794                 if (child == NULL) {
2795                         (void) snprintf(errbuf, errlen,
2796                             "file does not contain DWARF data");
2797                         return (ECTF_CONVNODEBUG);


2798                 }
2799 
2800                 cup->cu_cuoff = offset;
2801                 cup->cu_cu = child;
2802 
2803                 if ((cup->cu_cmh = ctf_merge_init(fd, &ret)) == NULL)


2804                         return (ret);

2805 
2806                 if (ctf_dwarf_string(cup, cu, DW_AT_name, &name) == 0) {
2807                         size_t len = strlen(name) + 1;
2808                         char *b = basename(name);
2809                         cup->cu_name = strdup(b);
2810                         ctf_free(name, len);
2811                 }
2812                 break;
2813         }
2814 
2815         return (0);
2816 }
2817 
2818 /*
2819  * This is our only recourse to identify a C source file that is missing debug
2820  * info: it will be mentioned as an STT_FILE, but not have a compile unit entry.
2821  * (A traditional ctfmerge works on individual files, so can identify missing
2822  * DWARF more directly, via ctf_has_c_source() on the .o file.)
2823  *
2824  * As we operate on basenames, this can of course miss some cases, but it's
2825  * better than not checking at all.
2826  *
2827  * We explicitly whitelist some CRT components.  Failing that, there's always
2828  * the -m option.
2829  */
2830 static boolean_t
2831 c_source_has_debug(const char *file, ctf_cu_t *cus, size_t nr_cus)
2832 {
2833         const char *basename = strrchr(file, '/');
2834 
2835         if (basename == NULL)
2836                 basename = file;
2837         else
2838                 basename++;
2839 
2840         if (strcmp(basename, "common-crt.c") == 0 ||
2841             strcmp(basename, "gmon.c") == 0 ||
2842             strcmp(basename, "dlink_init.c") == 0 ||
2843             strcmp(basename, "dlink_common.c") == 0 ||
2844             strncmp(basename, "crt", strlen("crt")) == 0 ||
2845             strncmp(basename, "values-", strlen("values-")) == 0)
2846                 return (B_TRUE);
2847 
2848         for (size_t i = 0; i < nr_cus; i++) {
2849                 if (strcmp(basename, cus[i].cu_name) == 0)
2850                         return (B_TRUE);
2851         }
2852 
2853         return (B_FALSE);
2854 }
2855 
2856 static int
2857 ctf_dwarf_check_missing(ctf_cu_t *cus, size_t nr_cus, Elf *elf,
2858     char *errmsg, size_t errlen)
2859 {
2860         Elf_Scn *scn, *strscn;
2861         Elf_Data *data, *strdata;
2862         GElf_Shdr shdr;
2863         ulong_t i;
2864 
2865         scn = NULL;
2866         while ((scn = elf_nextscn(elf, scn)) != NULL) {
2867                 if (gelf_getshdr(scn, &shdr) == NULL) {
2868                         (void) snprintf(errmsg, errlen,
2869                             "failed to get section header: %s\n",
2870                             elf_errmsg(elf_errno()));
2871                         return (EINVAL);
2872                 }
2873 
2874                 if (shdr.sh_type == SHT_SYMTAB)
2875                         break;
2876         }
2877 
2878         if (scn == NULL)
2879                 return (0);
2880 
2881         if ((strscn = elf_getscn(elf, shdr.sh_link)) == NULL) {
2882                 (void) snprintf(errmsg, errlen,
2883                     "failed to get str section: %s\n",
2884                     elf_errmsg(elf_errno()));
2885                 return (EINVAL);
2886         }
2887 
2888         if ((data = elf_getdata(scn, NULL)) == NULL) {
2889                 (void) snprintf(errmsg, errlen, "failed to read section: %s\n",
2890                     elf_errmsg(elf_errno()));
2891                 return (EINVAL);
2892         }
2893 
2894         if ((strdata = elf_getdata(strscn, NULL)) == NULL) {
2895                 (void) snprintf(errmsg, errlen,
2896                     "failed to read string table: %s\n",
2897                     elf_errmsg(elf_errno()));
2898                 return (EINVAL);
2899         }
2900 
2901         for (i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) {
2902                 GElf_Sym sym;
2903                 const char *file;
2904                 size_t len;
2905 
2906                 if (gelf_getsym(data, i, &sym) == NULL) {
2907                         (void) snprintf(errmsg, errlen,
2908                             "failed to read sym %lu: %s\n",
2909                             i, elf_errmsg(elf_errno()));
2910                         return (EINVAL);
2911                 }
2912 
2913                 if (GELF_ST_TYPE(sym.st_info) != STT_FILE)
2914                         continue;
2915 
2916                 file = (const char *)((uintptr_t)strdata->d_buf + sym.st_name);
2917                 len = strlen(file);
2918                 if (len < 2 || strncmp(".c", &file[len - 2], 2) != 0)
2919                         continue;
2920 
2921                 if (!c_source_has_debug(file, cus, nr_cus)) {
2922                         (void) snprintf(errmsg, errlen,
2923                             "file %s is missing debug info\n", file);
2924                         return (ECTF_CONVNODEBUG);
2925                 }
2926         }
2927 
2928         return (0);
2929 }
2930 
2931 int
2932 ctf_dwarf_convert(int fd, Elf *elf, uint_t nthrs, uint_t flags,
2933     ctf_file_t **fpp, char *errbuf, size_t errlen)
2934 {
2935         int err, ret, ndies, i;
2936         Dwarf_Debug dw;
2937         Dwarf_Error derr;
2938         ctf_cu_t *cdies = NULL, *cup;
2939         workq_t *wqp = NULL;
2940 



2941         *fpp = NULL;
2942 
2943         ret = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, &dw, &derr);
2944         if (ret != DW_DLV_OK) {






2945                 if (ret == DW_DLV_NO_ENTRY ||
2946                     dwarf_errno(derr) == DW_DLE_DEBUG_INFO_NULL) {
2947                         (void) snprintf(errbuf, errlen,
2948                             "file does not contain DWARF data\n");
2949                         return (ECTF_CONVNODEBUG);
2950                 }
2951 
2952                 (void) snprintf(errbuf, errlen,
2953                     "dwarf_elf_init() failed: %s\n", dwarf_errmsg(derr));
2954                 return (ECTF_CONVBKERR);

2955         }
2956 
2957         /*
2958          * Iterate over all of the compilation units and create a ctf_cu_t for
2959          * each of them.  This is used to determine if we have zero, one, or
2960          * multiple dies to convert. If we have zero, that's an error. If
2961          * there's only one die, that's the simple case.  No merge needed and
2962          * only a single Dwarf_Debug as well.
2963          */
2964         ndies = 0;
2965         err = ctf_dwarf_count_dies(dw, &derr, &ndies, errbuf, errlen);
2966 
2967         ctf_dprintf("found %d DWARF CUs\n", ndies);
2968 
2969         if (ndies == 0) {
2970                 (void) snprintf(errbuf, errlen,
2971                     "file does not contain DWARF data\n");
2972                 return (ECTF_CONVNODEBUG);
2973         }
2974 
2975         (void) dwarf_finish(dw, &derr);
2976         cdies = ctf_alloc(sizeof (ctf_cu_t) * ndies);
2977         if (cdies == NULL) {
2978                 return (ENOMEM);

2979         }
2980 
2981         bzero(cdies, sizeof (ctf_cu_t) * ndies);
2982 
2983         for (i = 0; i < ndies; i++) {
2984                 cup = &cdies[i];
2985                 ret = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL,
2986                     &cup->cu_dwarf, &derr);
2987                 if (ret != 0) {
2988                         ctf_free(cdies, sizeof (ctf_cu_t) * ndies);
2989                         (void) snprintf(errbuf, errlen,
2990                             "failed to initialize DWARF: %s\n",
2991                             dwarf_errmsg(derr));
2992                         return (ECTF_CONVBKERR);

2993                 }
2994 
2995                 err = ctf_dwarf_init_die(fd, elf, cup, i, errbuf, errlen);
2996                 if (err != 0)

2997                         goto out;

2998 
2999                 cup->cu_doweaks = ndies > 1 ? B_FALSE : B_TRUE;
3000         }
3001 
3002         if (!(flags & CTF_ALLOW_MISSING_DEBUG) &&
3003             (err = ctf_dwarf_check_missing(cdies, ndies,
3004             elf, errbuf, errlen)) != 0)
3005                 goto out;
3006 
3007         /*
3008          * If we only have one compilation unit, there's no reason to use
3009          * multiple threads, even if the user requested them. After all, they
3010          * just gave us an upper bound.
3011          */
3012         if (ndies == 1)
3013                 nthrs = 1;
3014 
3015         if (workq_init(&wqp, nthrs) == -1) {
3016                 err = errno;
3017                 goto out;
3018         }
3019 
3020         for (i = 0; i < ndies; i++) {
3021                 cup = &cdies[i];
3022                 ctf_dprintf("adding cu %s: %p, %x %x\n", cup->cu_name,
3023                     cup->cu_cu, cup->cu_cuoff, cup->cu_maxoff);
3024                 if (workq_add(wqp, cup) == -1) {
3025                         err = errno;
3026                         goto out;
3027                 }
3028         }
3029 
3030         ret = workq_work(wqp, ctf_dwarf_convert_one, NULL, &err);
3031         if (ret == WORKQ_ERROR) {
3032                 err = errno;
3033                 goto out;
3034         } else if (ret == WORKQ_UERROR) {
3035                 ctf_dprintf("internal convert failed: %s\n",
3036                     ctf_errmsg(err));
3037                 goto out;
3038         }
3039 
3040         ctf_dprintf("Determining next phase: have %d CUs\n", ndies);
3041         if (ndies != 1) {
3042                 ctf_merge_t *cmp;
3043 
3044                 cmp = ctf_merge_init(fd, &err);
3045                 if (cmp == NULL)

3046                         goto out;

3047 
3048                 ctf_dprintf("setting threads\n");
3049                 if ((err = ctf_merge_set_nthreads(cmp, nthrs)) != 0) {
3050                         ctf_merge_fini(cmp);

3051                         goto out;
3052                 }
3053 
3054                 for (i = 0; i < ndies; i++) {
3055                         cup = &cdies[i];
3056                         if ((err = ctf_merge_add(cmp, cup->cu_ctfp)) != 0) {


3057                                 ctf_merge_fini(cmp);

3058                                 goto out;
3059                         }
3060                 }
3061 
3062                 ctf_dprintf("performing merge\n");
3063                 err = ctf_merge_merge(cmp, fpp);
3064                 if (err != 0) {
3065                         ctf_dprintf("failed merge!\n");
3066                         *fpp = NULL;
3067                         ctf_merge_fini(cmp);

3068                         goto out;
3069                 }
3070                 ctf_merge_fini(cmp);
3071                 err = 0;
3072                 ctf_dprintf("successfully converted!\n");
3073         } else {
3074                 err = 0;
3075                 *fpp = cdies->cu_ctfp;
3076                 cdies->cu_ctfp = NULL;
3077                 ctf_dprintf("successfully converted!\n");
3078         }
3079 
3080 out:
3081         workq_fini(wqp);
3082         ctf_dwarf_free_dies(cdies, ndies);
3083         return (err);
3084 }