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 }
|