diff options
| -rw-r--r-- | usr/src/cmd/ctfconvert/ctfconvert.c | 38 | ||||
| -rw-r--r-- | usr/src/lib/libctf/common/ctf_convert.c | 13 | ||||
| -rw-r--r-- | usr/src/lib/libctf/common/ctf_dwarf.c | 370 | ||||
| -rw-r--r-- | usr/src/lib/libctf/common/libctf.h | 4 | ||||
| -rw-r--r-- | usr/src/lib/libctf/common/libctf_impl.h | 4 |
5 files changed, 251 insertions, 178 deletions
diff --git a/usr/src/cmd/ctfconvert/ctfconvert.c b/usr/src/cmd/ctfconvert/ctfconvert.c index a4394c3ec8..dbcf688657 100644 --- a/usr/src/cmd/ctfconvert/ctfconvert.c +++ b/usr/src/cmd/ctfconvert/ctfconvert.c @@ -37,6 +37,7 @@ #define CTFCONVERT_FATAL 1 #define CTFCONVERT_USAGE 2 +#define CTFCONVERT_DEFAULT_BATCHSIZE 256 #define CTFCONVERT_DEFAULT_NTHREADS 4 #define CTFCONVERT_ALTEXEC "CTFCONVERT_ALTEXEC" @@ -70,15 +71,18 @@ ctfconvert_usage(const char *fmt, ...) } (void) fprintf(stderr, "Usage: %s [-is] [-j nthrs] [-l label | " - "-L labelenv] [-o outfile] input\n" + "-L labelenv] [-b batchsize] [-o outfile] input\n" "\n" "\t-i ignore files not built partially from C sources\n" - "\t-j use nthrs threads to perform the merge\n" + "\t-b batch process this many dies at a time (default %d)\n" + "\t-j use nthrs threads to perform the merge (default %d)\n" "\t-k keep around original input file on failure\n" "\t-o copy input to outfile and add CTF\n" "\t-l set output container's label to specified value\n" "\t-L set output container's label to value from environment\n", - ctfconvert_progname); + ctfconvert_progname, + CTFCONVERT_DEFAULT_BATCHSIZE, + CTFCONVERT_DEFAULT_NTHREADS); } /* @@ -249,13 +253,14 @@ main(int argc, char *argv[]) int c, ifd, err; boolean_t keep = B_FALSE; uint_t flags = 0; + uint_t bsize = CTFCONVERT_DEFAULT_BATCHSIZE; uint_t nthreads = CTFCONVERT_DEFAULT_NTHREADS; const char *outfile = NULL; const char *label = NULL; const char *infile = NULL; char *tmpfile; ctf_file_t *ofp; - long argj; + long argno; char *eptr; char buf[4096]; boolean_t optx = B_FALSE; @@ -264,7 +269,7 @@ main(int argc, char *argv[]) ctfconvert_altexec(argv); - while ((c = getopt(argc, argv, ":j:kl:L:o:iX")) != -1) { + while ((c = getopt(argc, argv, ":b:j:kl:L:o:iX")) != -1) { switch (c) { case 'k': keep = B_TRUE; @@ -275,16 +280,27 @@ main(int argc, char *argv[]) case 'L': label = getenv(optarg); break; + case 'b': + errno = 0; + argno = strtol(optarg, &eptr, 10); + if (errno != 0 || argno == LONG_MAX || + argno == LONG_MIN || argno <= 0 || + argno > UINT_MAX || *eptr != '\0') { + ctfconvert_fatal("invalid argument for -b: " + "%s\n", optarg); + } + bsize = (uint_t)argno; + break; case 'j': errno = 0; - argj = strtol(optarg, &eptr, 10); - if (errno != 0 || argj == LONG_MAX || - argj == LONG_MIN || argj <= 0 || - argj > UINT_MAX || *eptr != '\0') { + argno = strtol(optarg, &eptr, 10); + if (errno != 0 || argno == LONG_MAX || + argno == LONG_MIN || argno <= 0 || + argno > UINT_MAX || *eptr != '\0') { ctfconvert_fatal("invalid argument for -j: " "%s\n", optarg); } - nthreads = (uint_t)argj; + nthreads = (uint_t)argno; break; case 'o': outfile = optarg; @@ -331,7 +347,7 @@ main(int argc, char *argv[]) if (outfile != NULL && strcmp(infile, outfile) != 0) keep = B_TRUE; - ofp = ctf_fdconvert(ifd, label, nthreads, flags, &err, buf, + ofp = ctf_fdconvert(ifd, label, bsize, nthreads, flags, &err, buf, sizeof (buf)); if (ofp == NULL) { /* diff --git a/usr/src/lib/libctf/common/ctf_convert.c b/usr/src/lib/libctf/common/ctf_convert.c index 1a433d17db..042cdf9b72 100644 --- a/usr/src/lib/libctf/common/ctf_convert.c +++ b/usr/src/lib/libctf/common/ctf_convert.c @@ -102,8 +102,8 @@ ctf_convert_ftypes(Elf *elf, ctf_convert_source_t *types) } ctf_file_t * -ctf_elfconvert(int fd, Elf *elf, const char *label, uint_t nthrs, uint_t flags, - int *errp, char *errbuf, size_t errlen) +ctf_elfconvert(int fd, Elf *elf, const char *label, uint_t bsize, uint_t nthrs, + uint_t flags, int *errp, char *errbuf, size_t errlen) { int err, i; ctf_file_t *fp = NULL; @@ -142,7 +142,7 @@ ctf_elfconvert(int fd, Elf *elf, const char *label, uint_t nthrs, uint_t flags, ctf_conv_status_t cs; fp = NULL; - cs = ctf_converters[i](fd, elf, nthrs, errp, &fp, errbuf, + cs = ctf_converters[i](fd, elf, bsize, nthrs, errp, &fp, errbuf, errlen); if (cs == CTF_CONV_SUCCESS) { notsup = B_FALSE; @@ -187,8 +187,8 @@ ctf_elfconvert(int fd, Elf *elf, const char *label, uint_t nthrs, uint_t flags, } ctf_file_t * -ctf_fdconvert(int fd, const char *label, uint_t nthrs, uint_t flags, int *errp, - char *errbuf, size_t errlen) +ctf_fdconvert(int fd, const char *label, uint_t bsize, uint_t nthrs, + uint_t flags, int *errp, char *errbuf, size_t errlen) { int err; Elf *elf; @@ -203,7 +203,8 @@ ctf_fdconvert(int fd, const char *label, uint_t nthrs, uint_t flags, int *errp, return (NULL); } - fp = ctf_elfconvert(fd, elf, label, nthrs, flags, errp, errbuf, errlen); + fp = ctf_elfconvert(fd, elf, label, bsize, nthrs, flags, errp, errbuf, + errlen); (void) elf_end(elf); return (fp); diff --git a/usr/src/lib/libctf/common/ctf_dwarf.c b/usr/src/lib/libctf/common/ctf_dwarf.c index 811a55bc64..e75db3b883 100644 --- a/usr/src/lib/libctf/common/ctf_dwarf.c +++ b/usr/src/lib/libctf/common/ctf_dwarf.c @@ -252,6 +252,8 @@ typedef struct ctf_dwbitf { */ typedef struct ctf_die { Elf *cd_elf; /* shared libelf handle */ + int cd_fd; /* shared file descriptor */ + int cd_ndie; /* DIE index */ char *cd_name; /* basename of the DIE */ ctf_merge_t *cd_cmh; /* merge handle */ ctf_list_t cd_vars; /* List of variables */ @@ -2495,92 +2497,6 @@ ctf_dwarf_conv_weaks(ctf_die_t *cdp) return (ctf_dwarf_symtab_iter(cdp, ctf_dwarf_conv_weaks_cb, NULL)); } -/* ARGSUSED */ -static int -ctf_dwarf_convert_one(void *arg, void *unused) -{ - int ret; - ctf_file_t *dedup; - ctf_die_t *cdp = arg; - - ctf_dprintf("converting die: %s\n", cdp->cd_name); - ctf_dprintf("max offset: %x\n", cdp->cd_maxoff); - VERIFY(cdp != NULL); - - ret = ctf_dwarf_convert_die(cdp, cdp->cd_cu); - ctf_dprintf("ctf_dwarf_convert_die (%s) returned %d\n", cdp->cd_name, - ret); - if (ret != 0) { - return (ret); - } - if (ctf_update(cdp->cd_ctfp) != 0) { - return (ctf_dwarf_error(cdp, cdp->cd_ctfp, 0, - "failed to update output ctf container")); - } - - ret = ctf_dwarf_fixup_die(cdp, B_FALSE); - ctf_dprintf("ctf_dwarf_fixup_die (%s) returned %d\n", cdp->cd_name, - ret); - if (ret != 0) { - return (ret); - } - if (ctf_update(cdp->cd_ctfp) != 0) { - return (ctf_dwarf_error(cdp, cdp->cd_ctfp, 0, - "failed to update output ctf container")); - } - - ret = ctf_dwarf_fixup_die(cdp, B_TRUE); - ctf_dprintf("ctf_dwarf_fixup_die (%s) returned %d\n", cdp->cd_name, - ret); - if (ret != 0) { - return (ret); - } - if (ctf_update(cdp->cd_ctfp) != 0) { - return (ctf_dwarf_error(cdp, cdp->cd_ctfp, 0, - "failed to update output ctf container")); - } - - - if ((ret = ctf_dwarf_conv_funcvars(cdp)) != 0) { - return (ctf_dwarf_error(cdp, NULL, ret, - "failed to convert strong functions and variables")); - } - - if (ctf_update(cdp->cd_ctfp) != 0) { - return (ctf_dwarf_error(cdp, cdp->cd_ctfp, 0, - "failed to update output ctf container")); - } - - if (cdp->cd_doweaks == B_TRUE) { - if ((ret = ctf_dwarf_conv_weaks(cdp)) != 0) { - return (ctf_dwarf_error(cdp, NULL, ret, - "failed to convert weak functions and variables")); - } - - if (ctf_update(cdp->cd_ctfp) != 0) { - return (ctf_dwarf_error(cdp, cdp->cd_ctfp, 0, - "failed to update output ctf container")); - } - } - - ctf_phase_dump(cdp->cd_ctfp, "pre-dedup"); - ctf_dprintf("adding inputs for dedup\n"); - if ((ret = ctf_merge_add(cdp->cd_cmh, cdp->cd_ctfp)) != 0) { - return (ctf_dwarf_error(cdp, NULL, ret, - "failed to add inputs for merge")); - } - - ctf_dprintf("starting merge\n"); - if ((ret = ctf_merge_dedup(cdp->cd_cmh, &dedup)) != 0) { - return (ctf_dwarf_error(cdp, NULL, ret, - "failed to deduplicate die")); - } - ctf_close(cdp->cd_ctfp); - cdp->cd_ctfp = dedup; - - return (0); -} - /* * Note, we expect that if we're returning a ctf_file_t from one of the dies, * say in the single node case, it's been saved and the entry here has been set @@ -2594,7 +2510,6 @@ ctf_dwarf_free_die(ctf_die_t *cdp) ctf_dwbitf_t *cdb, *ndb; ctf_dwmap_t *map; void *cookie; - Dwarf_Error derr; ctf_dprintf("Beginning to free die: %p\n", cdp); cdp->cd_elf = NULL; @@ -2631,10 +2546,6 @@ ctf_dwarf_free_die(ctf_die_t *cdp) ctf_free(cdb, sizeof (ctf_dwbitf_t)); } - /* How do we clean up die usage? */ - ctf_dprintf("Trying to clean up dwarf_t: %p\n", cdp->cd_dwarf); - (void) dwarf_finish(cdp->cd_dwarf, &derr); - cdp->cd_dwarf = NULL; ctf_close(cdp->cd_ctfp); cookie = NULL; @@ -2700,24 +2611,41 @@ ctf_dwarf_count_dies(Dwarf_Debug dw, Dwarf_Error *derr, int *ndies, * No merge needed and only a single Dwarf_Debug as well. */ static int -ctf_dwarf_init_die(int fd, Elf *elf, ctf_die_t *cdp, int ndie, char *errbuf, - size_t errlen) +ctf_dwarf_init_die(ctf_die_t *cdp) { - int ret; + int ret, n; Dwarf_Unsigned hdrlen, abboff, nexthdr; Dwarf_Half addrsz; Dwarf_Unsigned offset = 0; Dwarf_Error derr; + ret = dwarf_elf_init(cdp->cd_elf, DW_DLC_READ, NULL, NULL, + &cdp->cd_dwarf, &derr); + if (ret != DW_DLV_OK) { + (void) snprintf(cdp->cd_errbuf, cdp->cd_errlen, + "failed to initialize DWARF: %s\n", + dwarf_errmsg(derr)); + return (ECTF_CONVBKERR); + } + + n = cdp->cd_ndie; + while ((ret = dwarf_next_cu_header(cdp->cd_dwarf, &hdrlen, NULL, &abboff, &addrsz, &nexthdr, &derr)) != DW_DLV_NO_ENTRY) { char *name; Dwarf_Die cu, child; + if (ret != DW_DLV_OK) { + (void) snprintf(cdp->cd_errbuf, cdp->cd_errlen, + "failed to read DWARF: %s\n", + dwarf_errmsg(derr)); + return (ECTF_CONVBKERR); + } + /* Based on the counting above, we should be good to go */ VERIFY(ret == DW_DLV_OK); - if (ndie > 0) { - ndie--; + if (n > 0) { + n--; offset = nexthdr; continue; } @@ -2728,23 +2656,20 @@ ctf_dwarf_init_die(int fd, Elf *elf, ctf_die_t *cdp, int ndie, char *errbuf, */ cdp->cd_voidtid = CTF_ERR; cdp->cd_longtid = CTF_ERR; - cdp->cd_elf = elf; cdp->cd_maxoff = nexthdr - 1; - cdp->cd_ctfp = ctf_fdcreate(fd, &ret); + cdp->cd_ctfp = ctf_fdcreate(cdp->cd_fd, &ret); if (cdp->cd_ctfp == NULL) { ctf_free(cdp, sizeof (ctf_die_t)); return (ret); } avl_create(&cdp->cd_map, ctf_dwmap_comp, sizeof (ctf_dwmap_t), offsetof(ctf_dwmap_t, cdm_avl)); - cdp->cd_errbuf = errbuf; - cdp->cd_errlen = errlen; bzero(&cdp->cd_vars, sizeof (ctf_list_t)); bzero(&cdp->cd_funcs, sizeof (ctf_list_t)); bzero(&cdp->cd_bitfields, sizeof (ctf_list_t)); - if ((ret = ctf_dwarf_die_elfenc(elf, cdp, errbuf, - errlen)) != 0) { + if ((ret = ctf_dwarf_die_elfenc(cdp->cd_elf, cdp, + cdp->cd_errbuf, cdp->cd_errlen)) != 0) { avl_destroy(&cdp->cd_map); ctf_free(cdp, sizeof (ctf_die_t)); return (ret); @@ -2756,7 +2681,7 @@ ctf_dwarf_init_die(int fd, Elf *elf, ctf_die_t *cdp, int ndie, char *errbuf, return (ret); } if (cu == NULL) { - (void) snprintf(errbuf, errlen, + (void) snprintf(cdp->cd_errbuf, cdp->cd_errlen, "file does not contain DWARF data\n"); avl_destroy(&cdp->cd_map); ctf_free(cdp, sizeof (ctf_die_t)); @@ -2769,7 +2694,7 @@ ctf_dwarf_init_die(int fd, Elf *elf, ctf_die_t *cdp, int ndie, char *errbuf, return (ret); } if (child == NULL) { - (void) snprintf(errbuf, errlen, + (void) snprintf(cdp->cd_errbuf, cdp->cd_errlen, "file does not contain DWARF data\n"); avl_destroy(&cdp->cd_map); ctf_free(cdp, sizeof (ctf_die_t)); @@ -2779,7 +2704,7 @@ ctf_dwarf_init_die(int fd, Elf *elf, ctf_die_t *cdp, int ndie, char *errbuf, cdp->cd_cuoff = offset; cdp->cd_cu = child; - if ((cdp->cd_cmh = ctf_merge_init(fd, &ret)) == NULL) { + if ((cdp->cd_cmh = ctf_merge_init(cdp->cd_fd, &ret)) == NULL) { avl_destroy(&cdp->cd_map); ctf_free(cdp, sizeof (ctf_die_t)); return (ret); @@ -2797,15 +2722,112 @@ ctf_dwarf_init_die(int fd, Elf *elf, ctf_die_t *cdp, int ndie, char *errbuf, return (0); } +/* ARGSUSED */ +static int +ctf_dwarf_convert_one(void *arg, void *unused) +{ + int ret; + ctf_file_t *dedup; + ctf_die_t *cdp = arg; + Dwarf_Error derr; + + VERIFY(cdp != NULL); + + if ((ret = ctf_dwarf_init_die(cdp)) != 0) { + return (ret); + } + + ctf_dprintf("converting die: %s\n", cdp->cd_name); + ctf_dprintf("max offset: %x\n", cdp->cd_maxoff); + + ret = ctf_dwarf_convert_die(cdp, cdp->cd_cu); + ctf_dprintf("ctf_dwarf_convert_die (%s) returned %d\n", cdp->cd_name, + ret); + if (ret != 0) { + return (ret); + } + if (ctf_update(cdp->cd_ctfp) != 0) { + return (ctf_dwarf_error(cdp, cdp->cd_ctfp, 0, + "failed to update output ctf container")); + } + + ret = ctf_dwarf_fixup_die(cdp, B_FALSE); + ctf_dprintf("ctf_dwarf_fixup_die (%s) returned %d\n", cdp->cd_name, + ret); + if (ret != 0) { + return (ret); + } + if (ctf_update(cdp->cd_ctfp) != 0) { + return (ctf_dwarf_error(cdp, cdp->cd_ctfp, 0, + "failed to update output ctf container")); + } + + ret = ctf_dwarf_fixup_die(cdp, B_TRUE); + ctf_dprintf("ctf_dwarf_fixup_die (%s) returned %d\n", cdp->cd_name, + ret); + if (ret != 0) { + return (ret); + } + if (ctf_update(cdp->cd_ctfp) != 0) { + return (ctf_dwarf_error(cdp, cdp->cd_ctfp, 0, + "failed to update output ctf container")); + } + + + if ((ret = ctf_dwarf_conv_funcvars(cdp)) != 0) { + return (ctf_dwarf_error(cdp, NULL, ret, + "failed to convert strong functions and variables")); + } + + if (ctf_update(cdp->cd_ctfp) != 0) { + return (ctf_dwarf_error(cdp, cdp->cd_ctfp, 0, + "failed to update output ctf container")); + } + + if (cdp->cd_doweaks == B_TRUE) { + if ((ret = ctf_dwarf_conv_weaks(cdp)) != 0) { + return (ctf_dwarf_error(cdp, NULL, ret, + "failed to convert weak functions and variables")); + } + + if (ctf_update(cdp->cd_ctfp) != 0) { + return (ctf_dwarf_error(cdp, cdp->cd_ctfp, 0, + "failed to update output ctf container")); + } + } + + ctf_phase_dump(cdp->cd_ctfp, "pre-dedup"); + ctf_dprintf("adding inputs for dedup\n"); + if ((ret = ctf_merge_add(cdp->cd_cmh, cdp->cd_ctfp)) != 0) { + return (ctf_dwarf_error(cdp, NULL, ret, + "failed to add inputs for merge")); + } + + ctf_dprintf("starting merge\n"); + if ((ret = ctf_merge_dedup(cdp->cd_cmh, &dedup)) != 0) { + return (ctf_dwarf_error(cdp, NULL, ret, + "failed to deduplicate die")); + } + + ctf_dprintf("Trying to clean up dwarf_t: %p\n", cdp->cd_dwarf); + if ((ret = dwarf_finish(cdp->cd_dwarf, &derr)) != DW_DLV_OK) + ctf_dprintf("dwarf_finish fail: %s\n", dwarf_errmsg(derr)); + cdp->cd_dwarf = NULL; + ctf_close(cdp->cd_ctfp); + cdp->cd_ctfp = dedup; + + return (0); +} ctf_conv_status_t -ctf_dwarf_convert(int fd, Elf *elf, uint_t nthrs, int *errp, ctf_file_t **fpp, - char *errmsg, size_t errlen) +ctf_dwarf_convert(int fd, Elf *elf, uint_t bsize, uint_t nthrs, int *errp, + ctf_file_t **fpp, char *errmsg, size_t errlen) { int err, ret, ndies, i; Dwarf_Debug dw; Dwarf_Error derr; ctf_die_t *cdies = NULL, *cdp; + ctf_file_t *fpprev; workq_t *wqp = NULL; if (errp == NULL) @@ -2848,65 +2870,72 @@ ctf_dwarf_convert(int fd, Elf *elf, uint_t nthrs, int *errp, ctf_file_t **fpp, return (CTF_CONV_ERROR); } + /* + * Fill out just enough of the ctf_die_t for the conversion process to + * be able to finish the rest in a (potentially) multithreaded context. + */ for (i = 0; i < ndies; i++) { cdp = &cdies[i]; - ret = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, - &cdp->cd_dwarf, &derr); - if (ret != 0) { - ctf_free(cdies, sizeof (ctf_die_t) * ndies); - (void) snprintf(errmsg, errlen, - "failed to initialize DWARF: %s\n", - dwarf_errmsg(derr)); - *errp = ECTF_CONVBKERR; - return (CTF_CONV_ERROR); - } - - ret = ctf_dwarf_init_die(fd, elf, &cdies[i], i, errmsg, errlen); - if (ret != 0) { - *errp = ret; - goto out; - } + cdp->cd_elf = elf; + cdp->cd_fd = fd; + cdp->cd_ndie = i; + cdp->cd_errbuf = errmsg; + cdp->cd_errlen = errlen; cdp->cd_doweaks = ndies > 1 ? B_FALSE : B_TRUE; } ctf_dprintf("found %d DWARF die(s)\n", ndies); /* - * If we only have one die, there's no reason to use multiple threads, - * even if the user requested them. After all, they just gave us an - * upper bound. + * There's no need to have either more threads or a batch size larger + * than the total number of dies, even if the user requested them. + * After all, they just gave us an upper bound. */ - if (ndies == 1) - nthrs = 1; + if (nthrs > ndies) + nthrs = ndies; + if (bsize > ndies) + bsize = ndies; if (workq_init(&wqp, nthrs) == -1) { *errp = errno; goto out; } - for (i = 0; i < ndies; i++) { - cdp = &cdies[i]; - ctf_dprintf("adding die %s: %p, %x %x\n", cdp->cd_name, - cdp->cd_cu, cdp->cd_cuoff, cdp->cd_maxoff); - if (workq_add(wqp, cdp) == -1) { + /* + * In order to avoid exhausting memory limits when converting files + * with a large number of dies, we process them in batches. + */ + for (i = 0; i < ndies; i += bsize) { + ctf_merge_t *cmp; + int j; + + ctf_dprintf("adding dies\n"); + for (j = i; j < ndies; j++) { + if (j - i >= bsize) + break; + cdp = &cdies[j]; + if (workq_add(wqp, cdp) == -1) { + *errp = errno; + goto out; + } + } + + ret = workq_work(wqp, ctf_dwarf_convert_one, NULL, errp); + if (ret == WORKQ_ERROR) { *errp = errno; goto out; + } else if (ret == WORKQ_UERROR) { + ctf_dprintf("internal convert failed: %s\n", + ctf_errmsg(*errp)); + goto out; } - } - - ret = workq_work(wqp, ctf_dwarf_convert_one, NULL, errp); - if (ret == WORKQ_ERROR) { - *errp = errno; - goto out; - } else if (ret == WORKQ_UERROR) { - ctf_dprintf("internal convert failed: %s\n", - ctf_errmsg(*errp)); - goto out; - } - ctf_dprintf("Determining next phase: have %d dies\n", ndies); - if (ndies != 1) { - ctf_merge_t *cmp; + /* Only one die, no merge required */ + if (ndies == 1) { + *fpp = cdies->cd_ctfp; + cdies->cd_ctfp = NULL; + goto success; + } cmp = ctf_merge_init(fd, &ret); if (cmp == NULL) { @@ -2921,11 +2950,32 @@ ctf_dwarf_convert(int fd, Elf *elf, uint_t nthrs, int *errp, ctf_file_t **fpp, goto out; } - ctf_dprintf("adding dies\n"); - for (i = 0; i < ndies; i++) { - cdp = &cdies[i]; + /* + * If we have the result of a previous merge then go ahead and + * add it as an input to the next one, as well as saving the + * ctf_file_t so that it can be freed afterwards when it is no + * longer required. + */ + fpprev = NULL; + if (*fpp) { + ctf_dprintf("adding previous merge die\n"); + fpprev = *fpp; + if ((ret = ctf_merge_add(cmp, *fpp)) != 0) { + ctf_merge_fini(cmp); + *fpp = NULL; + *errp = ret; + goto out; + } + } + + ctf_dprintf("adding dies to merge\n"); + for (j = i; j < ndies; j++) { + if (j - i >= bsize) + break; + cdp = &cdies[j]; if ((ret = ctf_merge_add(cmp, cdp->cd_ctfp)) != 0) { ctf_merge_fini(cmp); + *fpp = NULL; *errp = ret; goto out; } @@ -2940,15 +2990,21 @@ ctf_dwarf_convert(int fd, Elf *elf, uint_t nthrs, int *errp, ctf_file_t **fpp, *errp = ret; goto out; } + + ctf_dprintf("freeing dies\n"); + for (j = i; j < ndies; j++) { + if (j - i >= bsize) + break; + cdp = &cdies[j]; + ctf_dprintf("freeing die %d\n", j); + ctf_dwarf_free_die(cdp); + } + ctf_close(fpprev); ctf_merge_fini(cmp); - *errp = 0; - ctf_dprintf("successfully converted!\n"); - } else { - *errp = 0; - *fpp = cdies->cd_ctfp; - cdies->cd_ctfp = NULL; - ctf_dprintf("successfully converted!\n"); } +success: + *errp = 0; + ctf_dprintf("successfully converted!\n"); out: workq_fini(wqp); diff --git a/usr/src/lib/libctf/common/libctf.h b/usr/src/lib/libctf/common/libctf.h index a5c5027048..f014737b43 100644 --- a/usr/src/lib/libctf/common/libctf.h +++ b/usr/src/lib/libctf/common/libctf.h @@ -77,9 +77,9 @@ extern void ctf_diff_fini(ctf_diff_t *); #define CTF_CONVERT_F_IGNNONC 0x01 extern ctf_file_t *ctf_elfconvert(int, Elf *, const char *, uint_t, uint_t, + uint_t, int *, char *, size_t); +extern ctf_file_t *ctf_fdconvert(int, const char *, uint_t, 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 struct ctf_merge_handle ctf_merge_t; extern ctf_merge_t *ctf_merge_init(int, int *); diff --git a/usr/src/lib/libctf/common/libctf_impl.h b/usr/src/lib/libctf/common/libctf_impl.h index 11193e97d0..8a9fdd3013 100644 --- a/usr/src/lib/libctf/common/libctf_impl.h +++ b/usr/src/lib/libctf/common/libctf_impl.h @@ -35,9 +35,9 @@ typedef enum ctf_conv_status { CTF_CONV_NOTSUP = 2 } ctf_conv_status_t; -typedef ctf_conv_status_t (*ctf_convert_f)(int, Elf *, uint_t, int *, +typedef ctf_conv_status_t (*ctf_convert_f)(int, Elf *, uint_t, uint_t, int *, ctf_file_t **, char *, size_t); -extern ctf_conv_status_t ctf_dwarf_convert(int, Elf *, uint_t, int *, +extern ctf_conv_status_t ctf_dwarf_convert(int, Elf *, uint_t, uint_t, int *, ctf_file_t **, char *, size_t); /* |
