diff options
Diffstat (limited to 'usr/src/lib/libctf/common')
-rw-r--r-- | usr/src/lib/libctf/common/ctf_convert.c | 136 | ||||
-rw-r--r-- | usr/src/lib/libctf/common/ctf_dwarf.c | 260 | ||||
-rw-r--r-- | usr/src/lib/libctf/common/libctf.h | 17 | ||||
-rw-r--r-- | usr/src/lib/libctf/common/libctf_impl.h | 10 | ||||
-rw-r--r-- | usr/src/lib/libctf/common/mapfile-vers | 3 |
5 files changed, 249 insertions, 177 deletions
diff --git a/usr/src/lib/libctf/common/ctf_convert.c b/usr/src/lib/libctf/common/ctf_convert.c index 7190e66718..9441aa6ed7 100644 --- a/usr/src/lib/libctf/common/ctf_convert.c +++ b/usr/src/lib/libctf/common/ctf_convert.c @@ -21,6 +21,7 @@ */ #include <libctf_impl.h> +#include <assert.h> #include <gelf.h> ctf_convert_f ctf_converters[] = { @@ -29,76 +30,73 @@ ctf_convert_f ctf_converters[] = { #define NCONVERTS (sizeof (ctf_converters) / sizeof (ctf_convert_f)) -typedef enum ctf_convert_source { - CTFCONV_SOURCE_NONE = 0x0, - CTFCONV_SOURCE_UNKNOWN = 0x01, - CTFCONV_SOURCE_C = 0x02, - CTFCONV_SOURCE_S = 0x04 -} ctf_convert_source_t; - -static void -ctf_convert_ftypes(Elf *elf, ctf_convert_source_t *types) +ctf_hsc_ret_t +ctf_has_c_source(Elf *elf, char *errmsg, size_t errlen) { - int i; - Elf_Scn *scn = NULL, *strscn; - *types = CTFCONV_SOURCE_NONE; - GElf_Shdr shdr; + ctf_hsc_ret_t ret = CHR_NO_C_SOURCE; + Elf_Scn *scn, *strscn; Elf_Data *data, *strdata; + GElf_Shdr shdr; + ulong_t i; + scn = NULL; while ((scn = elf_nextscn(elf, scn)) != NULL) { - - if (gelf_getshdr(scn, &shdr) == NULL) - return; + if (gelf_getshdr(scn, &shdr) == NULL) { + (void) snprintf(errmsg, errlen, + "failed to get section header: %s", + elf_errmsg(elf_errno())); + return (CHR_ERROR); + } if (shdr.sh_type == SHT_SYMTAB) break; } if (scn == NULL) - return; + return (CHR_NO_C_SOURCE); - if ((strscn = elf_getscn(elf, shdr.sh_link)) == NULL) - return; + if ((strscn = elf_getscn(elf, shdr.sh_link)) == NULL) { + (void) snprintf(errmsg, errlen, "failed to get str section: %s", + elf_errmsg(elf_errno())); + return (CHR_ERROR); + } - if ((data = elf_getdata(scn, NULL)) == NULL) - return; + if ((data = elf_getdata(scn, NULL)) == NULL) { + (void) snprintf(errmsg, errlen, "failed to read section: %s", + elf_errmsg(elf_errno())); + return (CHR_ERROR); + } - if ((strdata = elf_getdata(strscn, NULL)) == NULL) - return; + if ((strdata = elf_getdata(strscn, NULL)) == NULL) { + (void) snprintf(errmsg, errlen, + "failed to read string table: %s", elf_errmsg(elf_errno())); + return (CHR_ERROR); + } for (i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) { GElf_Sym sym; const char *file; size_t len; - if (gelf_getsym(data, i, &sym) == NULL) - return; + if (gelf_getsym(data, i, &sym) == NULL) { + (void) snprintf(errmsg, errlen, + "failed to read sym %lu: %s", + i, elf_errmsg(elf_errno())); + return (CHR_ERROR); + } if (GELF_ST_TYPE(sym.st_info) != STT_FILE) continue; file = (const char *)((uintptr_t)strdata->d_buf + sym.st_name); len = strlen(file); - if (len < 2 || file[len - 2] != '.') { - *types |= CTFCONV_SOURCE_UNKNOWN; - continue; - } - - switch (file[len - 1]) { - case 'c': - *types |= CTFCONV_SOURCE_C; - break; - case 'h': - /* We traditionally ignore header files... */ - break; - case 's': - *types |= CTFCONV_SOURCE_S; - break; - default: - *types |= CTFCONV_SOURCE_UNKNOWN; + if (len >= 2 && strncmp(".c", &file[len - 2], 2) == 0) { + ret = CHR_HAS_C_SOURCE; break; } } + + return (ret); } ctf_file_t * @@ -107,8 +105,6 @@ ctf_elfconvert(int fd, Elf *elf, const char *label, uint_t nthrs, uint_t flags, { int err, i; ctf_file_t *fp = NULL; - boolean_t notsup = B_TRUE; - ctf_convert_source_t type; if (errp == NULL) errp = &err; @@ -118,7 +114,7 @@ ctf_elfconvert(int fd, Elf *elf, const char *label, uint_t nthrs, uint_t flags, return (NULL); } - if (flags & ~CTF_CONVERT_F_IGNNONC) { + if (flags & ~CTF_ALLOW_MISSING_DEBUG) { *errp = EINVAL; return (NULL); } @@ -128,47 +124,35 @@ ctf_elfconvert(int fd, Elf *elf, const char *label, uint_t nthrs, uint_t flags, return (NULL); } - ctf_convert_ftypes(elf, &type); - ctf_dprintf("got types: %d\n", type); - if (flags & CTF_CONVERT_F_IGNNONC) { - if (type == CTFCONV_SOURCE_NONE || - (type & CTFCONV_SOURCE_UNKNOWN)) { - *errp = ECTF_CONVNOCSRC; - return (NULL); - } + switch (ctf_has_c_source(elf, errbuf, errlen)) { + case CHR_ERROR: + *errp = ECTF_ELF; + return (NULL); + + case CHR_NO_C_SOURCE: + *errp = ECTF_CONVNOCSRC; + return (NULL); + + default: + break; } for (i = 0; i < NCONVERTS; i++) { - ctf_conv_status_t cs; - fp = NULL; - cs = ctf_converters[i](fd, elf, nthrs, errp, &fp, errbuf, - errlen); - if (cs == CTF_CONV_SUCCESS) { - notsup = B_FALSE; - break; - } - if (cs == CTF_CONV_ERROR) { - fp = NULL; - notsup = B_FALSE; + err = ctf_converters[i](fd, elf, nthrs, flags, + &fp, errbuf, errlen); + + if (err != ECTF_CONVNODEBUG) break; - } } - if (notsup == B_TRUE) { - if ((flags & CTF_CONVERT_F_IGNNONC) != 0 && - (type & CTFCONV_SOURCE_C) == 0) { - *errp = ECTF_CONVNOCSRC; - return (NULL); - } - *errp = ECTF_NOCONVBKEND; + if (err != 0) { + assert(fp == NULL); + *errp = err; return (NULL); } - /* - * Succsesful conversion. - */ - if (fp != NULL && label != NULL) { + if (label != NULL) { if (ctf_add_label(fp, label, fp->ctf_typemax, 0) == CTF_ERR) { *errp = ctf_errno(fp); ctf_close(fp); diff --git a/usr/src/lib/libctf/common/ctf_dwarf.c b/usr/src/lib/libctf/common/ctf_dwarf.c index 7cd02db43c..aa55127d26 100644 --- a/usr/src/lib/libctf/common/ctf_dwarf.c +++ b/usr/src/lib/libctf/common/ctf_dwarf.c @@ -883,7 +883,7 @@ ctf_dwarf_dwarf_base(ctf_cu_t *cup, Dwarf_Die die, int *kindp, break; default: (void) snprintf(cup->cu_errbuf, cup->cu_errlen, - "encountered unkown DWARF encoding: %d", type); + "encountered unknown DWARF encoding: %d", type); return (ECTF_CONVBKERR); } @@ -1778,6 +1778,7 @@ ctf_dwarf_convert_type(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, break; default: ctf_dprintf("ignoring tag type %x\n", tag); + *idp = CTF_ERR; ret = 0; break; } @@ -2677,7 +2678,8 @@ ctf_dwarf_free_die(ctf_cu_t *cup) } ctf_dprintf("Trying to clean up dwarf_t: %p\n", cup->cu_dwarf); - (void) dwarf_finish(cup->cu_dwarf, &derr); + if (cup->cu_dwarf != NULL) + (void) dwarf_finish(cup->cu_dwarf, &derr); cup->cu_dwarf = NULL; ctf_close(cup->cu_ctfp); @@ -2727,13 +2729,6 @@ ctf_dwarf_count_dies(Dwarf_Debug dw, Dwarf_Error *derr, int *ndies, *ndies = *ndies + 1; } - if (*ndies == 0) { - (void) snprintf(errbuf, errlen, - "file does not contain valid DWARF data: %s\n", - dwarf_errmsg(*derr)); - return (ECTF_CONVBKERR); - } - return (0); } @@ -2769,10 +2764,9 @@ ctf_dwarf_init_die(int fd, Elf *elf, ctf_cu_t *cup, int ndie, char *errbuf, cup->cu_elf = elf; cup->cu_maxoff = nexthdr - 1; cup->cu_ctfp = ctf_fdcreate(fd, &ret); - if (cup->cu_ctfp == NULL) { - ctf_free(cup, sizeof (ctf_cu_t)); + if (cup->cu_ctfp == NULL) return (ret); - } + avl_create(&cup->cu_map, ctf_dwmap_comp, sizeof (ctf_dwmap_t), offsetof(ctf_dwmap_t, cdm_avl)); cup->cu_errbuf = errbuf; @@ -2782,46 +2776,32 @@ ctf_dwarf_init_die(int fd, Elf *elf, ctf_cu_t *cup, int ndie, char *errbuf, bzero(&cup->cu_bitfields, sizeof (ctf_list_t)); if ((ret = ctf_dwarf_die_elfenc(elf, cup, errbuf, - errlen)) != 0) { - avl_destroy(&cup->cu_map); - ctf_free(cup, sizeof (ctf_cu_t)); + errlen)) != 0) return (ret); - } - if ((ret = ctf_dwarf_sib(cup, NULL, &cu)) != 0) { - avl_destroy(&cup->cu_map); - ctf_free(cup, sizeof (ctf_cu_t)); + if ((ret = ctf_dwarf_sib(cup, NULL, &cu)) != 0) return (ret); - } + if (cu == NULL) { (void) snprintf(errbuf, errlen, - "file does not contain DWARF data\n"); - avl_destroy(&cup->cu_map); - ctf_free(cup, sizeof (ctf_cu_t)); - return (ECTF_CONVBKERR); + "file does not contain DWARF data"); + return (ECTF_CONVNODEBUG); } - if ((ret = ctf_dwarf_child(cup, cu, &child)) != 0) { - avl_destroy(&cup->cu_map); - ctf_free(cup, sizeof (ctf_cu_t)); + if ((ret = ctf_dwarf_child(cup, cu, &child)) != 0) return (ret); - } + if (child == NULL) { (void) snprintf(errbuf, errlen, - "file does not contain DWARF data\n"); - avl_destroy(&cup->cu_map); - ctf_free(cup, sizeof (ctf_cu_t)); - return (ECTF_CONVBKERR); + "file does not contain DWARF data"); + return (ECTF_CONVNODEBUG); } cup->cu_cuoff = offset; cup->cu_cu = child; - if ((cup->cu_cmh = ctf_merge_init(fd, &ret)) == NULL) { - avl_destroy(&cup->cu_map); - ctf_free(cup, sizeof (ctf_cu_t)); + if ((cup->cu_cmh = ctf_merge_init(fd, &ret)) == NULL) return (ret); - } if (ctf_dwarf_string(cup, cu, DW_AT_name, &name) == 0) { size_t len = strlen(name) + 1; @@ -2835,41 +2815,143 @@ ctf_dwarf_init_die(int fd, Elf *elf, ctf_cu_t *cup, int ndie, char *errbuf, return (0); } +/* + * This is our only recourse to identify a C source file that is missing debug + * info: it will be mentioned as an STT_FILE, but not have a compile unit entry. + * (A traditional ctfmerge works on individual files, so can identify missing + * DWARF more directly, via ctf_has_c_source() on the .o file.) + * + * As we operate on basenames, this can of course miss some cases, but it's + * better than not checking at all. + * + * We explicitly whitelist some CRT components. Failing that, there's always + * the -m option. + */ +static boolean_t +c_source_has_debug(const char *file, ctf_cu_t *cus, size_t nr_cus) +{ + const char *basename = strrchr(file, '/'); + + if (basename == NULL) + basename = file; + else + basename++; + + if (strcmp(basename, "common-crt.c") == 0 || + strcmp(basename, "gmon.c") == 0 || + strcmp(basename, "dlink_init.c") == 0 || + strcmp(basename, "dlink_common.c") == 0 || + strncmp(basename, "crt", strlen("crt")) == 0 || + strncmp(basename, "values-", strlen("values-")) == 0) + return (B_TRUE); -ctf_conv_status_t -ctf_dwarf_convert(int fd, Elf *elf, uint_t nthrs, int *errp, ctf_file_t **fpp, + for (size_t i = 0; i < nr_cus; i++) { + if (strcmp(basename, cus[i].cu_name) == 0) + return (B_TRUE); + } + + return (B_FALSE); +} + +static int +ctf_dwarf_check_missing(ctf_cu_t *cus, size_t nr_cus, Elf *elf, char *errmsg, size_t errlen) { + Elf_Scn *scn, *strscn; + Elf_Data *data, *strdata; + GElf_Shdr shdr; + ulong_t i; + + scn = NULL; + while ((scn = elf_nextscn(elf, scn)) != NULL) { + if (gelf_getshdr(scn, &shdr) == NULL) { + (void) snprintf(errmsg, errlen, + "failed to get section header: %s\n", + elf_errmsg(elf_errno())); + return (EINVAL); + } + + if (shdr.sh_type == SHT_SYMTAB) + break; + } + + if (scn == NULL) + return (0); + + if ((strscn = elf_getscn(elf, shdr.sh_link)) == NULL) { + (void) snprintf(errmsg, errlen, + "failed to get str section: %s\n", + elf_errmsg(elf_errno())); + return (EINVAL); + } + + if ((data = elf_getdata(scn, NULL)) == NULL) { + (void) snprintf(errmsg, errlen, "failed to read section: %s\n", + elf_errmsg(elf_errno())); + return (EINVAL); + } + + if ((strdata = elf_getdata(strscn, NULL)) == NULL) { + (void) snprintf(errmsg, errlen, + "failed to read string table: %s\n", + elf_errmsg(elf_errno())); + return (EINVAL); + } + + for (i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) { + GElf_Sym sym; + const char *file; + size_t len; + + if (gelf_getsym(data, i, &sym) == NULL) { + (void) snprintf(errmsg, errlen, + "failed to read sym %lu: %s\n", + i, elf_errmsg(elf_errno())); + return (EINVAL); + } + + if (GELF_ST_TYPE(sym.st_info) != STT_FILE) + continue; + + file = (const char *)((uintptr_t)strdata->d_buf + sym.st_name); + len = strlen(file); + if (len < 2 || strncmp(".c", &file[len - 2], 2) != 0) + continue; + + if (!c_source_has_debug(file, cus, nr_cus)) { + (void) snprintf(errmsg, errlen, + "file %s is missing debug info\n", file); + return (ECTF_CONVNODEBUG); + } + } + + return (0); +} + +int +ctf_dwarf_convert(int fd, Elf *elf, uint_t nthrs, uint_t flags, + ctf_file_t **fpp, char *errbuf, size_t errlen) +{ int err, ret, ndies, i; Dwarf_Debug dw; Dwarf_Error derr; ctf_cu_t *cdies = NULL, *cup; workq_t *wqp = NULL; - if (errp == NULL) - errp = &err; - *errp = 0; *fpp = NULL; ret = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, &dw, &derr); if (ret != DW_DLV_OK) { - /* - * We may want to expect DWARF data here and fail conversion if - * it's missing. In this case, if we actually have some amount - * of DWARF, but no section, for now, just go ahead and create - * an empty CTF file. - */ if (ret == DW_DLV_NO_ENTRY || dwarf_errno(derr) == DW_DLE_DEBUG_INFO_NULL) { - *fpp = ctf_create(errp); - return (*fpp != NULL ? CTF_CONV_SUCCESS : - CTF_CONV_ERROR); + (void) snprintf(errbuf, errlen, + "file does not contain DWARF data\n"); + return (ECTF_CONVNODEBUG); } - (void) snprintf(errmsg, errlen, - "failed to initialize DWARF: %s\n", - dwarf_errmsg(derr)); - *errp = ECTF_CONVBKERR; - return (CTF_CONV_ERROR); + + (void) snprintf(errbuf, errlen, + "dwarf_elf_init() failed: %s\n", dwarf_errmsg(derr)); + return (ECTF_CONVBKERR); } /* @@ -2880,42 +2962,47 @@ ctf_dwarf_convert(int fd, Elf *elf, uint_t nthrs, int *errp, ctf_file_t **fpp, * only a single Dwarf_Debug as well. */ ndies = 0; - ret = ctf_dwarf_count_dies(dw, &derr, &ndies, errmsg, errlen); - if (ret != 0) { - *errp = ret; - goto out; + err = ctf_dwarf_count_dies(dw, &derr, &ndies, errbuf, errlen); + + ctf_dprintf("found %d DWARF CUs\n", ndies); + + if (ndies == 0) { + (void) snprintf(errbuf, errlen, + "file does not contain DWARF data\n"); + return (ECTF_CONVNODEBUG); } (void) dwarf_finish(dw, &derr); cdies = ctf_alloc(sizeof (ctf_cu_t) * ndies); if (cdies == NULL) { - *errp = ENOMEM; - return (CTF_CONV_ERROR); + return (ENOMEM); } + bzero(cdies, sizeof (ctf_cu_t) * ndies); + for (i = 0; i < ndies; i++) { cup = &cdies[i]; ret = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, &cup->cu_dwarf, &derr); if (ret != 0) { ctf_free(cdies, sizeof (ctf_cu_t) * ndies); - (void) snprintf(errmsg, errlen, + (void) snprintf(errbuf, errlen, "failed to initialize DWARF: %s\n", dwarf_errmsg(derr)); - *errp = ECTF_CONVBKERR; - return (CTF_CONV_ERROR); + return (ECTF_CONVBKERR); } - ret = ctf_dwarf_init_die(fd, elf, &cdies[i], i, errmsg, errlen); - if (ret != 0) { - *errp = ret; + err = ctf_dwarf_init_die(fd, elf, cup, i, errbuf, errlen); + if (err != 0) goto out; - } cup->cu_doweaks = ndies > 1 ? B_FALSE : B_TRUE; } - ctf_dprintf("found %d DWARF CUs\n", ndies); + if (!(flags & CTF_ALLOW_MISSING_DEBUG) && + (err = ctf_dwarf_check_missing(cdies, ndies, + elf, errbuf, errlen)) != 0) + goto out; /* * If we only have one compilation unit, there's no reason to use @@ -2926,7 +3013,7 @@ ctf_dwarf_convert(int fd, Elf *elf, uint_t nthrs, int *errp, ctf_file_t **fpp, nthrs = 1; if (workq_init(&wqp, nthrs) == -1) { - *errp = errno; + err = errno; goto out; } @@ -2935,18 +3022,18 @@ ctf_dwarf_convert(int fd, Elf *elf, uint_t nthrs, int *errp, ctf_file_t **fpp, ctf_dprintf("adding cu %s: %p, %x %x\n", cup->cu_name, cup->cu_cu, cup->cu_cuoff, cup->cu_maxoff); if (workq_add(wqp, cup) == -1) { - *errp = errno; + err = errno; goto out; } } - ret = workq_work(wqp, ctf_dwarf_convert_one, NULL, errp); + ret = workq_work(wqp, ctf_dwarf_convert_one, NULL, &err); if (ret == WORKQ_ERROR) { - *errp = errno; + err = errno; goto out; } else if (ret == WORKQ_UERROR) { ctf_dprintf("internal convert failed: %s\n", - ctf_errmsg(*errp)); + ctf_errmsg(err)); goto out; } @@ -2954,44 +3041,37 @@ ctf_dwarf_convert(int fd, Elf *elf, uint_t nthrs, int *errp, ctf_file_t **fpp, if (ndies != 1) { ctf_merge_t *cmp; - cmp = ctf_merge_init(fd, &ret); - if (cmp == NULL) { - *errp = ret; + cmp = ctf_merge_init(fd, &err); + if (cmp == NULL) goto out; - } ctf_dprintf("setting threads\n"); - if ((ret = ctf_merge_set_nthreads(cmp, nthrs)) != 0) { + if ((err = ctf_merge_set_nthreads(cmp, nthrs)) != 0) { ctf_merge_fini(cmp); - *errp = ret; goto out; } for (i = 0; i < ndies; i++) { cup = &cdies[i]; - ctf_dprintf("adding cu %s (%p)\n", cup->cu_name, - cup->cu_ctfp); - if ((ret = ctf_merge_add(cmp, cup->cu_ctfp)) != 0) { + if ((err = ctf_merge_add(cmp, cup->cu_ctfp)) != 0) { ctf_merge_fini(cmp); - *errp = ret; goto out; } } ctf_dprintf("performing merge\n"); - ret = ctf_merge_merge(cmp, fpp); - if (ret != 0) { + err = ctf_merge_merge(cmp, fpp); + if (err != 0) { ctf_dprintf("failed merge!\n"); *fpp = NULL; ctf_merge_fini(cmp); - *errp = ret; goto out; } ctf_merge_fini(cmp); - *errp = 0; + err = 0; ctf_dprintf("successfully converted!\n"); } else { - *errp = 0; + err = 0; *fpp = cdies->cu_ctfp; cdies->cu_ctfp = NULL; ctf_dprintf("successfully converted!\n"); @@ -3000,5 +3080,5 @@ ctf_dwarf_convert(int fd, Elf *elf, uint_t nthrs, int *errp, ctf_file_t **fpp, out: workq_fini(wqp); ctf_dwarf_free_dies(cdies, ndies); - return (*fpp != NULL ? CTF_CONV_SUCCESS : CTF_CONV_ERROR); + return (err); } diff --git a/usr/src/lib/libctf/common/libctf.h b/usr/src/lib/libctf/common/libctf.h index a5c5027048..78b0a7a786 100644 --- a/usr/src/lib/libctf/common/libctf.h +++ b/usr/src/lib/libctf/common/libctf.h @@ -24,7 +24,7 @@ * Use is subject to license terms. */ /* - * Copyright (c) 2015, Joyent, Inc. + * Copyright (c) 2019, Joyent, Inc. */ /* @@ -75,12 +75,25 @@ extern int ctf_diff_functions(ctf_diff_t *, ctf_diff_func_f, void *); extern int ctf_diff_objects(ctf_diff_t *, ctf_diff_obj_f, void *); extern void ctf_diff_fini(ctf_diff_t *); -#define CTF_CONVERT_F_IGNNONC 0x01 +/* + * Normally, we return a failure if we find a C-derived compilation unit that + * lacks DWARF or CTF (as required). This flag over-rides this check. + */ +#define CTF_ALLOW_MISSING_DEBUG 0x01 + extern ctf_file_t *ctf_elfconvert(int, Elf *, const char *, uint_t, uint_t, int *, char *, size_t); extern ctf_file_t *ctf_fdconvert(int, const char *, uint_t, uint_t, int *, char *, size_t); +typedef enum ctf_hsc_ret { + CHR_ERROR = -1, + CHR_NO_C_SOURCE = 0, + CHR_HAS_C_SOURCE = 1 +} ctf_hsc_ret_t; + +extern ctf_hsc_ret_t ctf_has_c_source(Elf *, char *, size_t); + typedef struct ctf_merge_handle ctf_merge_t; extern ctf_merge_t *ctf_merge_init(int, int *); extern int ctf_merge_add(ctf_merge_t *, ctf_file_t *); diff --git a/usr/src/lib/libctf/common/libctf_impl.h b/usr/src/lib/libctf/common/libctf_impl.h index be091ef199..5c88b9454d 100644 --- a/usr/src/lib/libctf/common/libctf_impl.h +++ b/usr/src/lib/libctf/common/libctf_impl.h @@ -29,15 +29,9 @@ extern "C" { #endif -typedef enum ctf_conv_status { - CTF_CONV_SUCCESS = 0, - CTF_CONV_ERROR = 1, - CTF_CONV_NOTSUP = 2 -} ctf_conv_status_t; - -typedef ctf_conv_status_t (*ctf_convert_f)(int, Elf *, uint_t, int *, +typedef int (*ctf_convert_f)(int, Elf *, uint_t, uint_t, ctf_file_t **, char *, size_t); -extern ctf_conv_status_t ctf_dwarf_convert(int, Elf *, uint_t, int *, +extern int ctf_dwarf_convert(int, Elf *, uint_t, uint_t, ctf_file_t **, char *, size_t); /* diff --git a/usr/src/lib/libctf/common/mapfile-vers b/usr/src/lib/libctf/common/mapfile-vers index 243f072a3d..9281bbfff5 100644 --- a/usr/src/lib/libctf/common/mapfile-vers +++ b/usr/src/lib/libctf/common/mapfile-vers @@ -23,7 +23,7 @@ # # -# Copyright 2018 Joyent, Inc. +# Copyright 2019 Joyent, Inc. # # @@ -87,6 +87,7 @@ SYMBOL_VERSION SUNWprivate_1.2 { ctf_func_args_by_id; ctf_func_info_by_id; ctf_function_iter; + ctf_has_c_source; ctf_kind_name; ctf_label_info; ctf_label_iter; |