From dd4422524768709a579a2a93a10c78a88a6b0ecb Mon Sep 17 00:00:00 2001 From: Andy Fiddaman Date: Wed, 4 Nov 2020 12:07:58 +0000 Subject: 13280 CTF: provide option to truncate and continue Reviewed by: Robert Mustacchi Reviewed by: Igor Kozhukhov Approved by: Rich Lowe --- usr/src/lib/libctf/common/mapfile-vers | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'usr/src/lib/libctf/common/mapfile-vers') diff --git a/usr/src/lib/libctf/common/mapfile-vers b/usr/src/lib/libctf/common/mapfile-vers index 37ef440ab3..9f5c408406 100644 --- a/usr/src/lib/libctf/common/mapfile-vers +++ b/usr/src/lib/libctf/common/mapfile-vers @@ -24,6 +24,7 @@ # # Copyright 2019 Joyent, Inc. +# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # # @@ -66,6 +67,13 @@ SYMBOL_VERSION SUNWprivate_1.2 { ctf_add_typedef; ctf_add_union; ctf_add_volatile; + ctf_convert_fini; + ctf_convert_init; + ctf_convert_set_batchsize; + ctf_convert_set_flags; + ctf_convert_set_label; + ctf_convert_set_nthreads; + ctf_convert_set_warncb; ctf_create; ctf_dataptr; ctf_delete_type; -- cgit v1.2.3 From 88a08813800ed7ba7c927986421cee437f7f2233 Mon Sep 17 00:00:00 2001 From: Andy Fiddaman Date: Fri, 4 Dec 2020 11:41:39 +0000 Subject: 13363 ctfconvert could support more granular ignore for missing debug data Reviewed by: Robert Mustacchi Approved by: Rich Lowe --- usr/src/cmd/ctfconvert/ctfconvert.c | 43 +++++- usr/src/common/ctf/ctf_impl.h | 1 + usr/src/common/ctf/ctf_util.c | 11 ++ usr/src/lib/libctf/common/ctf_convert.c | 49 ++++-- usr/src/lib/libctf/common/ctf_dwarf.c | 93 ++++++------ usr/src/lib/libctf/common/ctf_merge.c | 23 +-- usr/src/lib/libctf/common/libctf.h | 1 + usr/src/lib/libctf/common/libctf_impl.h | 7 + usr/src/lib/libctf/common/mapfile-vers | 1 + usr/src/tools/ctf/common/list.c | 228 ---------------------------- usr/src/tools/ctf/common/list.h | 58 ------- usr/src/tools/ctf/stabs/Makefile.com | 6 +- usr/src/tools/ctf/stabs/common/fth_struct.c | 39 +++-- usr/src/tools/scripts/ctfconvert.1onbld | 20 ++- 14 files changed, 207 insertions(+), 373 deletions(-) delete mode 100644 usr/src/tools/ctf/common/list.c delete mode 100644 usr/src/tools/ctf/common/list.h (limited to 'usr/src/lib/libctf/common/mapfile-vers') diff --git a/usr/src/cmd/ctfconvert/ctfconvert.c b/usr/src/cmd/ctfconvert/ctfconvert.c index 064e665c26..121f1ed875 100644 --- a/usr/src/cmd/ctfconvert/ctfconvert.c +++ b/usr/src/cmd/ctfconvert/ctfconvert.c @@ -82,7 +82,7 @@ ctfconvert_usage(const char *fmt, ...) (void) fprintf(stderr, "Usage: %s [-fikms] [-j nthrs] [-l label | " "-L labelenv] [-b batchsize]\n" - " [-o outfile] input\n" + " [-o outfile] [-M ignorefile] input\n" "\n" "\t-b batch process this many dies at a time (default %d)\n" "\t-f always attempt to convert files\n" @@ -92,6 +92,7 @@ ctfconvert_usage(const char *fmt, ...) "\t-l set output container's label to specified value\n" "\t-L set output container's label to value from environment\n" "\t-m allow input to have missing debug info\n" + "\t-M allow files listed in ignorefile to have missing debug\n" "\t-o copy input to outfile and add CTF\n" "\t-s allow truncation of data that cannot be fully converted\n", ctfconvert_progname, @@ -250,6 +251,7 @@ main(int argc, char *argv[]) const char *outfile = NULL; const char *label = NULL; const char *infile = NULL; + const char *ignorefile = NULL; char *tmpfile; ctf_file_t *ofp; char buf[4096] = ""; @@ -259,7 +261,7 @@ main(int argc, char *argv[]) ctfconvert_progname = basename(argv[0]); - while ((c = getopt(argc, argv, ":b:fij:kl:L:mo:sX")) != -1) { + while ((c = getopt(argc, argv, ":b:fij:kl:L:mM:o:sX")) != -1) { switch (c) { case 'b': { long argno; @@ -303,6 +305,9 @@ main(int argc, char *argv[]) case 'm': flags |= CTF_ALLOW_MISSING_DEBUG; break; + case 'M': + ignorefile = optarg; + break; case 'o': outfile = optarg; break; @@ -370,6 +375,40 @@ main(int argc, char *argv[]) ctfconvert_fatal("Could not set warning callback: %s\n", strerror(err)); + if (ignorefile != NULL) { + char *buf = NULL; + ssize_t cnt; + size_t len = 0; + FILE *fp; + + if ((fp = fopen(ignorefile, "r")) == NULL) { + ctfconvert_fatal("Could not open ignorefile '%s': %s\n", + ignorefile, strerror(errno)); + } + + while ((cnt = getline(&buf, &len, fp)) != -1) { + char *p = buf; + + if (cnt == 0 || *p == '#') + continue; + + (void) strsep(&p, "\n"); + if ((err = ctf_convert_add_ignore(cch, buf)) != 0) { + ctfconvert_fatal( + "Failed to add '%s' to ignore list: %s\n", + buf, strerror(err)); + } + } + free(buf); + if (cnt == -1 && ferror(fp) != 0) { + ctfconvert_fatal( + "Error reading from ignorefile '%s': %s\n", + ignorefile, strerror(errno)); + } + + (void) fclose(fp); + } + ofp = ctf_fdconvert(cch, ifd, &err, buf, sizeof (buf)); ctf_convert_fini(cch); diff --git a/usr/src/common/ctf/ctf_impl.h b/usr/src/common/ctf/ctf_impl.h index b208cfb486..526e0f068c 100644 --- a/usr/src/common/ctf/ctf_impl.h +++ b/usr/src/common/ctf/ctf_impl.h @@ -312,6 +312,7 @@ extern void *ctf_alloc(size_t); extern void ctf_free(void *, size_t); extern char *ctf_strdup(const char *); +extern void ctf_strfree(char *); extern const char *ctf_strerror(int); extern void ctf_dprintf(const char *, ...); diff --git a/usr/src/common/ctf/ctf_util.c b/usr/src/common/ctf/ctf_util.c index 550195b5e1..f909bbc4af 100644 --- a/usr/src/common/ctf/ctf_util.c +++ b/usr/src/common/ctf/ctf_util.c @@ -148,6 +148,17 @@ ctf_strdup(const char *s1) return (s2); } +/* + * Free a string which was allocated via ctf_alloc() + */ +void +ctf_strfree(char *s) +{ + if (s == NULL) + return; + ctf_free(s, strlen(s) + 1); +} + /* * Store the specified error code into errp if it is non-NULL, and then * return NULL for the benefit of the caller. diff --git a/usr/src/lib/libctf/common/ctf_convert.c b/usr/src/lib/libctf/common/ctf_convert.c index dcf84e57c9..6dff7994f8 100644 --- a/usr/src/lib/libctf/common/ctf_convert.c +++ b/usr/src/lib/libctf/common/ctf_convert.c @@ -24,6 +24,7 @@ #include #include #include +#include static ctf_convert_f ctf_converters[] = { ctf_dwarf_convert @@ -209,17 +210,29 @@ ctf_convert_init(int *errp) cch->cch_batchsize = CTF_CONVERT_DEFAULT_BATCHSIZE; cch->cch_warncb = NULL; cch->cch_warncb_arg = NULL; + list_create(&cch->cch_nodebug, sizeof (ctf_convert_filelist_t), + offsetof(ctf_convert_filelist_t, ccf_node)); return (cch); } +static void +ctf_convert_fini_filelist(ctf_convert_filelist_t *ccf) +{ + ctf_strfree(ccf->ccf_basename); + ctf_free(ccf, sizeof (ctf_convert_filelist_t)); +} + void ctf_convert_fini(ctf_convert_t *cch) { - if (cch->cch_label != NULL) { - size_t len = strlen(cch->cch_label) + 1; - ctf_free(cch->cch_label, len); - } + ctf_convert_filelist_t *ccf; + + ctf_strfree(cch->cch_label); + while ((ccf = list_remove_head(&cch->cch_nodebug)) != NULL) + ctf_convert_fini_filelist(ccf); + list_destroy(&cch->cch_nodebug); + ctf_free(cch, sizeof (struct ctf_convert_handle)); } @@ -262,11 +275,7 @@ ctf_convert_set_label(ctf_convert_t *cch, const char *label) if (dup == NULL) return (ENOMEM); - if (cch->cch_label != NULL) { - size_t len = strlen(cch->cch_label) + 1; - ctf_free(cch->cch_label, len); - } - + ctf_strfree(cch->cch_label); cch->cch_label = dup; return (0); } @@ -279,6 +288,28 @@ ctf_convert_set_warncb(ctf_convert_t *cch, ctf_convert_warn_f cb, void *arg) return (0); } +int +ctf_convert_add_ignore(ctf_convert_t *cch, const char *basename) +{ + ctf_convert_filelist_t *ccf; + + if (strchr(basename, '/') != NULL) + return (EINVAL); + + ccf = ctf_alloc(sizeof (ctf_convert_filelist_t)); + if (ccf == NULL) + return (ENOMEM); + + ccf->ccf_basename = ctf_strdup(basename); + if (ccf->ccf_basename == NULL) { + ctf_free(ccf, sizeof (ctf_convert_filelist_t)); + return (ENOMEM); + } + list_insert_tail(&cch->cch_nodebug, ccf); + + return (0); +} + ctf_file_t * ctf_fdconvert(ctf_convert_t *cch, int fd, int *errp, char *errbuf, size_t errlen) diff --git a/usr/src/lib/libctf/common/ctf_dwarf.c b/usr/src/lib/libctf/common/ctf_dwarf.c index 58a0f5f4a7..b0b221f96e 100644 --- a/usr/src/lib/libctf/common/ctf_dwarf.c +++ b/usr/src/lib/libctf/common/ctf_dwarf.c @@ -202,6 +202,7 @@ #include #include #include +#include #include #include #include @@ -1152,7 +1153,7 @@ ctf_dwarf_create_base(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot, bzero(&enc, sizeof (ctf_encoding_t)); enc.cte_bits = sz * 8; if ((ret = ctf_dwarf_parse_int(name, &kind, &enc, &nname)) == 0) { - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); name = nname; } else { if (ret != EINVAL) { @@ -1167,7 +1168,7 @@ ctf_dwarf_create_base(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot, &enc, &nname)) != 0) { goto out; } else if (nname != NULL) { - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); name = nname; } } @@ -1180,7 +1181,7 @@ ctf_dwarf_create_base(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot, ret = ctf_dwmap_add(cup, id, die, B_FALSE); } out: - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); return (ret); } @@ -1440,7 +1441,7 @@ ctf_dwarf_fixup_sou(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t base, boolean_t add) } else if ((ret = ctf_dwarf_member_offset(cup, memb, mid, &memboff)) != 0) { if (mname != NULL) - ctf_free(mname, strlen(mname) + 1); + ctf_strfree(mname); return (ret); } @@ -1453,12 +1454,12 @@ ctf_dwarf_fixup_sou(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t base, boolean_t add) "failed to add member %s: %s\n", mname, ctf_errmsg(ctf_errno(cup->cu_ctfp))); if (mname != NULL) - ctf_free(mname, strlen(mname) + 1); + ctf_strfree(mname); return (ECTF_CONVBKERR); } if (mname != NULL) - ctf_free(mname, strlen(mname) + 1); + ctf_strfree(mname); next: if ((ret = ctf_dwarf_sib(cup, memb, &sib)) != 0) @@ -1530,7 +1531,7 @@ ctf_dwarf_create_sou(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, ctf_dprintf("added sou %s (%d) (%ld) forward=%d\n", name, kind, base, decl == B_TRUE); if (name != NULL) - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); if (base == CTF_ERR) return (ctf_errno(cup->cu_ctfp)); *idp = base; @@ -1845,33 +1846,28 @@ ctf_dwarf_create_reference(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, ctf_id_t id; Dwarf_Die tdie; char *name; - size_t namelen; if ((ret = ctf_dwarf_string(cup, die, DW_AT_name, &name)) != 0 && ret != ENOENT) return (ret); - if (ret == ENOENT) { + if (ret == ENOENT) name = NULL; - namelen = 0; - } else { - namelen = strlen(name); - } ctf_dprintf("reference kind %d %s\n", kind, name != NULL ? name : "<>"); if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_type, &tdie)) != 0) { if (ret != ENOENT) { - ctf_free(name, namelen); + ctf_strfree(name); return (ret); } if ((id = ctf_dwarf_void(cup)) == CTF_ERR) { - ctf_free(name, namelen); + ctf_strfree(name); return (ctf_errno(cup->cu_ctfp)); } } else { if ((ret = ctf_dwarf_convert_type(cup, tdie, &id, CTF_ADD_NONROOT)) != 0) { - ctf_free(name, namelen); + ctf_strfree(name); return (ret); } } @@ -1883,17 +1879,17 @@ ctf_dwarf_create_reference(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, *idp = id; } - ctf_free(name, namelen); + ctf_strfree(name); return (ret); } if ((*idp = ctf_add_reftype(cup->cu_ctfp, isroot, name, id, kind)) == CTF_ERR) { - ctf_free(name, namelen); + ctf_strfree(name); return (ctf_errno(cup->cu_ctfp)); } - ctf_free(name, namelen); + ctf_strfree(name); return (ctf_dwmap_add(cup, *idp, die, B_FALSE)); } @@ -1997,7 +1993,7 @@ ctf_dwarf_create_enum(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot) "value\n"); ret = ECTF_CONVBKERR; } - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); break; } @@ -2021,16 +2017,16 @@ ctf_dwarf_create_enum(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot) "to %s (%d)\n", name, eval, enumname == NULL ? "" : enumname, id); } - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); break; } - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); } out: if (enumname != NULL) - ctf_free(enumname, strlen(enumname) + 1); + ctf_strfree(enumname); return (ret); } @@ -2251,7 +2247,7 @@ ctf_dwarf_function_count(ctf_cu_t *cup, Dwarf_Die die, ctf_funcinfo_t *fip, fip->ctc_flags |= CTF_FUNC_VARARG; else fip->ctc_argc++; - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); } else if (tag == DW_TAG_formal_parameter) { fip->ctc_argc++; } else if (tag == DW_TAG_unspecified_parameters && @@ -2338,7 +2334,7 @@ ctf_dwarf_convert_function(ctf_cu_t *cup, Dwarf_Die die) if ((ret = ctf_dwarf_boolean(cup, die, DW_AT_declaration, &b)) != 0) { if (ret != ENOENT) { - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); return (ret); } } else if (b != 0) { @@ -2351,12 +2347,12 @@ ctf_dwarf_convert_function(ctf_cu_t *cup, Dwarf_Die die) */ ctf_dprintf("ignoring declaration of function %s (die %llx)\n", name, ctf_die_offset(cup, die)); - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); return (0); } if ((cdf = ctf_alloc(sizeof (ctf_dwfunc_t))) == NULL) { - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); return (ENOMEM); } bzero(cdf, sizeof (ctf_dwfunc_t)); @@ -2365,18 +2361,18 @@ ctf_dwarf_convert_function(ctf_cu_t *cup, Dwarf_Die die) if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_type, &tdie)) == 0) { if ((ret = ctf_dwarf_convert_type(cup, tdie, &(cdf->cdf_fip.ctc_return), CTF_ADD_ROOT)) != 0) { - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); ctf_free(cdf, sizeof (ctf_dwfunc_t)); return (ret); } } else if (ret != ENOENT) { - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); ctf_free(cdf, sizeof (ctf_dwfunc_t)); return (ret); } else { if ((cdf->cdf_fip.ctc_return = ctf_dwarf_void(cup)) == CTF_ERR) { - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); ctf_free(cdf, sizeof (ctf_dwfunc_t)); return (ctf_errno(cup->cu_ctfp)); } @@ -2394,7 +2390,7 @@ ctf_dwarf_convert_function(ctf_cu_t *cup, Dwarf_Die die) */ if ((ret = ctf_dwarf_function_count(cup, die, &cdf->cdf_fip, B_FALSE)) != 0) { - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); ctf_free(cdf, sizeof (ctf_dwfunc_t)); return (ret); } @@ -2404,14 +2400,14 @@ ctf_dwarf_convert_function(ctf_cu_t *cup, Dwarf_Die die) uint_t argc = cdf->cdf_fip.ctc_argc; cdf->cdf_argv = ctf_alloc(sizeof (ctf_id_t) * argc); if (cdf->cdf_argv == NULL) { - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); ctf_free(cdf, sizeof (ctf_dwfunc_t)); return (ENOMEM); } if ((ret = ctf_dwarf_convert_fargs(cup, die, &cdf->cdf_fip, cdf->cdf_argv)) != 0) { ctf_free(cdf->cdf_argv, sizeof (ctf_id_t) * argc); - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); ctf_free(cdf, sizeof (ctf_dwfunc_t)); return (ret); } @@ -2422,7 +2418,7 @@ ctf_dwarf_convert_function(ctf_cu_t *cup, Dwarf_Die die) if ((ret = ctf_dwarf_isglobal(cup, die, &cdf->cdf_global)) != 0) { ctf_free(cdf->cdf_argv, sizeof (ctf_id_t) * cdf->cdf_fip.ctc_argc); - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); ctf_free(cdf, sizeof (ctf_dwfunc_t)); return (ret); } @@ -2478,7 +2474,7 @@ ctf_dwarf_convert_variable(ctf_cu_t *cup, Dwarf_Die die) return (0); if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_type, &tdie)) != 0) { - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); return (ret); } @@ -2487,7 +2483,7 @@ ctf_dwarf_convert_variable(ctf_cu_t *cup, Dwarf_Die die) return (ret); if ((cdv = ctf_alloc(sizeof (ctf_dwvar_t))) == NULL) { - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); return (ENOMEM); } @@ -2496,7 +2492,7 @@ ctf_dwarf_convert_variable(ctf_cu_t *cup, Dwarf_Die die) if ((ret = ctf_dwarf_isglobal(cup, die, &cdv->cdv_global)) != 0) { ctf_free(cdv, sizeof (ctf_dwvar_t)); - ctf_free(name, strlen(name) + 1); + ctf_strfree(name); return (ret); } @@ -3082,7 +3078,7 @@ ctf_dwarf_free_die(ctf_cu_t *cup) ctf_dprintf("Trying to free name: %p\n", cup->cu_name); if (cup->cu_name != NULL) { - ctf_free(cup->cu_name, strlen(cup->cu_name) + 1); + ctf_strfree(cup->cu_name); cup->cu_name = NULL; } @@ -3095,7 +3091,7 @@ ctf_dwarf_free_die(ctf_cu_t *cup) ctf_dprintf("Trying to free functions\n"); for (cdf = ctf_list_next(&cup->cu_funcs); cdf != NULL; cdf = ndf) { ndf = ctf_list_next(cdf); - ctf_free(cdf->cdf_name, strlen(cdf->cdf_name) + 1); + ctf_strfree(cdf->cdf_name); if (cdf->cdf_fip.ctc_argc != 0) { ctf_free(cdf->cdf_argv, sizeof (ctf_id_t) * cdf->cdf_fip.ctc_argc); @@ -3106,7 +3102,7 @@ ctf_dwarf_free_die(ctf_cu_t *cup) ctf_dprintf("Trying to free variables\n"); for (cdv = ctf_list_next(&cup->cu_vars); cdv != NULL; cdv = ndv) { ndv = ctf_list_next(cdv); - ctf_free(cdv->cdv_name, strlen(cdv->cdv_name) + 1); + ctf_strfree(cdv->cdv_name); ctf_free(cdv, sizeof (ctf_dwvar_t)); } @@ -3228,11 +3224,10 @@ ctf_dwarf_preinit_dies(ctf_convert_t *cch, int fd, Elf *elf, Dwarf_Debug dw, } if (ctf_dwarf_string(cup, cu, DW_AT_name, &name) == 0) { - size_t len = strlen(name) + 1; char *b = basename(name); cup->cu_name = strdup(b); - ctf_free(name, len); + ctf_strfree(name); if (cup->cu_name == NULL) return (ENOMEM); } @@ -3329,9 +3324,11 @@ ctf_dwarf_init_die(ctf_cu_t *cup) * the -m option. */ static boolean_t -c_source_has_debug(const char *file, ctf_cu_t *cus, size_t nr_cus) +c_source_has_debug(ctf_convert_t *cch, const char *file, + ctf_cu_t *cus, size_t nr_cus) { const char *basename = strrchr(file, '/'); + ctf_convert_filelist_t *ccf; if (basename == NULL) basename = file; @@ -3347,6 +3344,14 @@ c_source_has_debug(const char *file, ctf_cu_t *cus, size_t nr_cus) strncmp(basename, "values-", strlen("values-")) == 0) return (B_TRUE); + for (ccf = list_head(&cch->cch_nodebug); ccf != NULL; + ccf = list_next(&cch->cch_nodebug, ccf)) { + if (ccf->ccf_basename != NULL && + strcmp(basename, ccf->ccf_basename) == 0) { + return (B_TRUE); + } + } + for (size_t i = 0; i < nr_cus; i++) { if (cus[i].cu_name != NULL && strcmp(basename, cus[i].cu_name) == 0) { @@ -3423,7 +3428,7 @@ ctf_dwarf_check_missing(ctf_convert_t *cch, ctf_cu_t *cus, size_t nr_cus, if (len < 2 || strncmp(".c", &file[len - 2], 2) != 0) continue; - if (!c_source_has_debug(file, cus, nr_cus)) { + if (!c_source_has_debug(cch, file, cus, nr_cus)) { if (cch->cch_warncb != NULL) { cch->cch_warncb( cch->cch_warncb_arg, diff --git a/usr/src/lib/libctf/common/ctf_merge.c b/usr/src/lib/libctf/common/ctf_merge.c index a5888de8c0..6b0d89784c 100644 --- a/usr/src/lib/libctf/common/ctf_merge.c +++ b/usr/src/lib/libctf/common/ctf_merge.c @@ -1003,18 +1003,10 @@ ctf_merge_fini_input(ctf_merge_input_t *cmi) void ctf_merge_fini(ctf_merge_t *cmh) { - size_t len; ctf_merge_input_t *cmi; - if (cmh->cmh_label != NULL) { - len = strlen(cmh->cmh_label) + 1; - ctf_free(cmh->cmh_label, len); - } - - if (cmh->cmh_pname != NULL) { - len = strlen(cmh->cmh_pname) + 1; - ctf_free(cmh->cmh_pname, len); - } + ctf_strfree(cmh->cmh_label); + ctf_strfree(cmh->cmh_pname); while ((cmi = list_remove_head(&cmh->cmh_inputs)) != NULL) ctf_merge_fini_input(cmi); @@ -1074,11 +1066,7 @@ ctf_merge_label(ctf_merge_t *cmh, const char *label) if (dup == NULL) return (EAGAIN); - if (cmh->cmh_label != NULL) { - size_t len = strlen(cmh->cmh_label) + 1; - ctf_free(cmh->cmh_label, len); - } - + ctf_strfree(cmh->cmh_label); cmh->cmh_label = dup; return (0); } @@ -1272,10 +1260,7 @@ ctf_merge_uniquify(ctf_merge_t *cmh, ctf_file_t *u, const char *pname) dup = ctf_strdup(pname); if (dup == NULL) return (EINVAL); - if (cmh->cmh_pname != NULL) { - size_t len = strlen(cmh->cmh_pname) + 1; - ctf_free(cmh->cmh_pname, len); - } + ctf_strfree(cmh->cmh_pname); cmh->cmh_pname = dup; cmh->cmh_unique = u; return (0); diff --git a/usr/src/lib/libctf/common/libctf.h b/usr/src/lib/libctf/common/libctf.h index 8f6a232057..9412143a91 100644 --- a/usr/src/lib/libctf/common/libctf.h +++ b/usr/src/lib/libctf/common/libctf.h @@ -118,6 +118,7 @@ extern int ctf_convert_set_batchsize(ctf_convert_t *, uint_t); extern int ctf_convert_set_flags(ctf_convert_t *, ctf_convert_flag_t); extern int ctf_convert_set_label(ctf_convert_t *, const char *); extern int ctf_convert_set_nthreads(ctf_convert_t *, uint_t); +extern int ctf_convert_add_ignore(ctf_convert_t *, const char *); extern ctf_file_t *ctf_fdconvert(ctf_convert_t *, int, int *, char *, size_t); diff --git a/usr/src/lib/libctf/common/libctf_impl.h b/usr/src/lib/libctf/common/libctf_impl.h index 6ed2665d11..8028dc0f8f 100644 --- a/usr/src/lib/libctf/common/libctf_impl.h +++ b/usr/src/lib/libctf/common/libctf_impl.h @@ -25,17 +25,24 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { #endif +typedef struct ctf_convert_filelist { + list_node_t ccf_node; + char *ccf_basename; +} ctf_convert_filelist_t; + struct ctf_convert_handle { char *cch_label; uint_t cch_flags; uint_t cch_nthreads; uint_t cch_batchsize; ctf_convert_warn_f cch_warncb; + list_t cch_nodebug; void *cch_warncb_arg; }; diff --git a/usr/src/lib/libctf/common/mapfile-vers b/usr/src/lib/libctf/common/mapfile-vers index 9f5c408406..1337fbba45 100644 --- a/usr/src/lib/libctf/common/mapfile-vers +++ b/usr/src/lib/libctf/common/mapfile-vers @@ -67,6 +67,7 @@ SYMBOL_VERSION SUNWprivate_1.2 { ctf_add_typedef; ctf_add_union; ctf_add_volatile; + ctf_convert_add_ignore; ctf_convert_fini; ctf_convert_init; ctf_convert_set_batchsize; diff --git a/usr/src/tools/ctf/common/list.c b/usr/src/tools/ctf/common/list.c deleted file mode 100644 index c01de9b924..0000000000 --- a/usr/src/tools/ctf/common/list.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Routines for manipulating linked lists - */ - -#include -#include -#include - -#include "list.h" -#include "memory.h" - -struct list { - void *l_data; - struct list *l_next; -}; - -/* Add an element to a list */ -void -list_add(list_t **list, void *data) -{ - list_t *le; - - le = xmalloc(sizeof (list_t)); - le->l_data = data; - le->l_next = *list; - *list = le; -} - -/* Add an element to a sorted list */ -void -slist_add(list_t **list, void *data, int (*cmp)(void *, void *)) -{ - list_t **nextp; - - for (nextp = list; *nextp; nextp = &((*nextp)->l_next)) { - if (cmp((*nextp)->l_data, data) > 0) - break; - } - - list_add(nextp, data); -} - -/*ARGSUSED2*/ -static int -list_defcmp(void *d1, void *d2, void *private) -{ - return (d1 != d2); -} - -void * -list_remove(list_t **list, void *data, int (*cmp)(void *, void *, void *), - void *private) -{ - list_t *le, **le2; - void *led; - - if (!cmp) - cmp = list_defcmp; - - for (le = *list, le2 = list; le; le2 = &le->l_next, le = le->l_next) { - if (cmp(le->l_data, data, private) == 0) { - *le2 = le->l_next; - led = le->l_data; - free(le); - return (led); - } - } - - return (NULL); -} - -void -list_free(list_t *list, void (*datafree)(void *, void *), void *private) -{ - list_t *le; - - while (list) { - le = list; - list = list->l_next; - if (le->l_data && datafree) - datafree(le->l_data, private); - free(le); - } -} - -/* - * This iterator is specifically designed to tolerate the deletion of the - * node being iterated over. - */ -int -list_iter(list_t *list, int (*func)(void *, void *), void *private) -{ - list_t *lnext; - int cumrc = 0; - int cbrc; - - while (list) { - lnext = list->l_next; - if ((cbrc = func(list->l_data, private)) < 0) - return (cbrc); - cumrc += cbrc; - list = lnext; - } - - return (cumrc); -} - -/*ARGSUSED*/ -static int -list_count_cb(void *data, void *private) -{ - return (1); -} - -int -list_count(list_t *list) -{ - return (list_iter(list, list_count_cb, NULL)); -} - -int -list_empty(list_t *list) -{ - return (list == NULL); -} - -void * -list_find(list_t *list, void *tmpl, int (*cmp)(void *, void *)) -{ - for (; list; list = list->l_next) { - if (cmp(list->l_data, tmpl) == 0) - return (list->l_data); - } - - return (NULL); -} - -void * -list_first(list_t *list) -{ - return (list ? list->l_data : NULL); -} - -void -list_concat(list_t **list1, list_t *list2) -{ - list_t *l, *last; - - for (l = *list1, last = NULL; l; last = l, l = l->l_next) - continue; - - if (last == NULL) - *list1 = list2; - else - last->l_next = list2; -} - -/* - * Merges two sorted lists. Equal nodes (as determined by cmp) are retained. - */ -void -slist_merge(list_t **list1p, list_t *list2, int (*cmp)(void *, void *)) -{ - list_t *list1, *next2; - list_t *last1 = NULL; - - if (*list1p == NULL) { - *list1p = list2; - return; - } - - list1 = *list1p; - while (list2 != NULL) { - if (cmp(list1->l_data, list2->l_data) > 0) { - next2 = list2->l_next; - - if (last1 == NULL) { - /* Insert at beginning */ - *list1p = last1 = list2; - list2->l_next = list1; - } else { - list2->l_next = list1; - last1->l_next = list2; - last1 = list2; - } - - list2 = next2; - } else { - - last1 = list1; - list1 = list1->l_next; - - if (list1 == NULL) { - /* Add the rest to the end of list1 */ - last1->l_next = list2; - list2 = NULL; - } - } - } -} diff --git a/usr/src/tools/ctf/common/list.h b/usr/src/tools/ctf/common/list.h deleted file mode 100644 index 2e41271d0f..0000000000 --- a/usr/src/tools/ctf/common/list.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2001-2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _LIST_H -#define _LIST_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Routines for manipulating linked lists - */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct list list_t; - -void list_add(list_t **, void *); -void slist_add(list_t **, void *, int (*)(void *, void *)); -void *list_remove(list_t **, void *, int (*)(void *, void *, void *), void *); -void list_free(list_t *, void (*)(void *, void *), void *); -void *list_find(list_t *, void *, int (*)(void *, void *)); -void *list_first(list_t *); -int list_iter(list_t *, int (*)(void *, void *), void *); -int list_count(list_t *); -int list_empty(list_t *); -void list_concat(list_t **, list_t *); -void slist_merge(list_t **, list_t *, int (*)(void *, void *)); - -#ifdef __cplusplus -} -#endif - -#endif /* _LIST_H */ diff --git a/usr/src/tools/ctf/stabs/Makefile.com b/usr/src/tools/ctf/stabs/Makefile.com index 901acd2584..06a2622d18 100644 --- a/usr/src/tools/ctf/stabs/Makefile.com +++ b/usr/src/tools/ctf/stabs/Makefile.com @@ -32,7 +32,6 @@ SRCS = \ fth_enum.c \ fth_struct.c \ genassym.c \ - list.c \ memory.c \ utils.c @@ -41,7 +40,7 @@ include ../../Makefile.ctf LDLIBS += -lctf NATIVE_LIBS += libctf.so -OBJS = $(SRCS:%.c=%.o) +OBJS = $(SRCS:%.c=%.o) list.o CERRWARN += $(CNOWARN_UNINIT) CERRWARN += -_gcc=-Wno-unused @@ -58,6 +57,9 @@ $(PROG): $(OBJS) %.o: ../common/%.c $(COMPILE.c) $< +%.o: $(SRC)/common/list/%.c + $(COMPILE.c) $< + $(ROOTONBLDMACHPROG): $(PROG) install: $(ROOTONBLDMACHPROG) diff --git a/usr/src/tools/ctf/stabs/common/fth_struct.c b/usr/src/tools/ctf/stabs/common/fth_struct.c index d3bd2ef0d1..30e450e9d5 100644 --- a/usr/src/tools/ctf/stabs/common/fth_struct.c +++ b/usr/src/tools/ctf/stabs/common/fth_struct.c @@ -24,7 +24,9 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. + */ /* * Used to dump structures and unions in forth mode. @@ -103,20 +105,21 @@ #include #include #include +#include #include "ctf_headers.h" #include "forth.h" -#include "list.h" #include "memory.h" static ctf_id_t fth_str_curtid; -static list_t *fth_str_curmems; +static list_t fth_str_curmems; /* * Node type for the member-storage list (fth_str_curmems) built by * fth_struct_members() */ typedef struct fth_str_mem { + list_node_t fsm_node; char *fsm_memname; char *fsm_format; ctf_id_t fsm_tid; @@ -146,6 +149,21 @@ fth_struct_memcmp(void *m1, void *m2) return (0); } +static void +fth_slist_add(fth_str_mem_t *mem) +{ + fth_str_mem_t *l; + + for (l = list_head(&fth_str_curmems); l != NULL; + l = list_next(&fth_str_curmems, l)) { + if (fth_struct_memcmp(l, mem) > 0) { + list_insert_before(&fth_str_curmems, l, mem); + return; + } + } + list_insert_tail(&fth_str_curmems, mem); +} + static void fth_free_str_mem(fth_str_mem_t *mem) { @@ -161,7 +179,8 @@ fth_struct_header(ctf_id_t tid) ssize_t sz; fth_str_curtid = tid; - fth_str_curmems = NULL; + list_create(&fth_str_curmems, sizeof (fth_str_mem_t), + offsetof(fth_str_mem_t, fsm_node)); if ((sz = ctf_type_size(ctf, fth_str_curtid)) == CTF_ERR) return (parse_warn("Can't get size for %s", fth_curtype)); @@ -418,7 +437,7 @@ fth_struct_members_cb(const char *memname, ctf_id_t tid, ulong_t off, void *arg) mem->fsm_tid = tid; mem->fsm_off = off; - slist_add(&fth_str_curmems, mem, fth_struct_memcmp); + fth_slist_add(mem); return (0); } @@ -453,20 +472,20 @@ fth_struct_members(char *memfilter, char *format) static int fth_struct_trailer(void) { - if (list_count(fth_str_curmems) == 0) { + fth_str_mem_t *mem; + + if (list_is_empty(&fth_str_curmems)) { if (fth_struct_members(NULL, NULL) < 0) return (-1); } - while (!list_empty(fth_str_curmems)) { - fth_str_mem_t *mem = list_remove(&fth_str_curmems, - list_first(fth_str_curmems), NULL, NULL); - + while ((mem = list_remove_head(&fth_str_curmems)) != NULL) { if (fth_print_member(mem, 0) < 0) return (-1); fth_free_str_mem(mem); } + list_destroy(&fth_str_curmems); (void) fprintf(out, "\n"); (void) fprintf(out, "kdbg-words definitions\n"); diff --git a/usr/src/tools/scripts/ctfconvert.1onbld b/usr/src/tools/scripts/ctfconvert.1onbld index c2fccf7e42..8d9e26b5da 100644 --- a/usr/src/tools/scripts/ctfconvert.1onbld +++ b/usr/src/tools/scripts/ctfconvert.1onbld @@ -10,7 +10,7 @@ .\" .\" Copyright 2020 OmniOS Community Edition (OmniOSce) Association. .\" -.Dd December 06, 2020 +.Dd December 07, 2020 .Dt ctfconvert 1ONBLD .Os .Sh NAME @@ -22,6 +22,7 @@ .Op Fl b Ar batchsize .Op Fl j Ar threads .Op Fl l Ar label | Fl L Ar labelenv +.Op Fl M Ar ignorefile .Op Fl o Ar outfile .Ar ELF_object .Sh DESCRIPTION @@ -89,6 +90,23 @@ Note that if the file contains no debug data in any of the compilation units then this flag will cause .Nm to exit successfully without taking any action, and can mask missing debug data. +.It Fl M Ar ignorefile +Allow +.Ar ELF_object +to have missing debug data in selected source files. +The source files to ignore are specified as a list of file basenames (without +any directory component) in +.Ar ignorefile . +Each file should be listed on its own line, separated by a newline. +It is not possible to encode a file name that contains a newline and any other +white-space within the line is considered to be part of the file name being +specified. +The +.Sq / +character may not appear in the file name. +Empty lines and any line which has a +.Sq # +character in the first column are ignored. .It Fl b Ar batchsize Batch-process this many compilation units from the source file at once (default 256). This helps to reduce memory usage when processing large objects which -- cgit v1.2.3