diff options
author | Robert Mustacchi <rm@joyent.com> | 2015-07-27 00:35:52 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2015-07-28 19:05:39 +0000 |
commit | 14c3d85bba96b10c225341f4c7f4af93c314b508 (patch) | |
tree | 8ef3a2513e220291581564d4db16bd5b4fbf127e /usr/src/cmd/ctfmerge/ctfmerge.c | |
parent | 9211d9b4c9ccc64292132e8e87c92ad6084b29a8 (diff) | |
download | illumos-joyent-14c3d85bba96b10c225341f4c7f4af93c314b508.tar.gz |
OS-4548 CTF Everywhere: Phase 1
OS-4549 ctfconvert should be implemented in terms of libctf
OS-4550 ctfconvert could convert multiple compilation units
OS-4553 want multi-threaded ctfmerge
OS-4552 Want general workq
OS-4551 Want general mergeq
OS-4554 ctfdiff doesn't properly handle unknown options
OS-4555 ctfdiff's symbols could be more consistently prefixed
OS-4048 new ctfmerge uses tmpfile after freeing it
OS-4556 ctfdump should drive on when incomplete files exist
OS-4557 ctf_add_encoded assigns() incorrect byte size to types
OS-4558 ctf_add_{struct,union,enum} can reuse forwards
OS-4559 ctf_add_{struct,union,enum} occasionally forget to dirty the ctf_file_t
OS-4560 ctf_add_member could better handle bitfields
OS-4561 ctf_type_size() reports wrong size for forwards
OS-4563 diffing CTF typedefs needs to walk multiple definitions
OS-4564 build scripts shouldn't hardcode CTF paths
OS-4565 ctf_fdcreate could be more flexible
OS-4566 Want libctf ctf_kind_name() function
OS-4567 Want libctf function to set struct/union size
OS-4568 Want ctfmerge altexec
Diffstat (limited to 'usr/src/cmd/ctfmerge/ctfmerge.c')
-rw-r--r-- | usr/src/cmd/ctfmerge/ctfmerge.c | 81 |
1 files changed, 66 insertions, 15 deletions
diff --git a/usr/src/cmd/ctfmerge/ctfmerge.c b/usr/src/cmd/ctfmerge/ctfmerge.c index a64936ccbe..5dea32b3aa 100644 --- a/usr/src/cmd/ctfmerge/ctfmerge.c +++ b/usr/src/cmd/ctfmerge/ctfmerge.c @@ -33,6 +33,7 @@ #include <sys/mman.h> #include <libgen.h> #include <stdarg.h> +#include <limits.h> static char *g_progname; static char *g_unique; @@ -40,6 +41,13 @@ static char *g_outfile; static boolean_t g_req; static uint_t g_nctf; +#define CTFMERGE_OK 0 +#define CTFMERGE_FATAL 1 +#define CTFMERGE_USAGE 2 + +#define CTFMERGE_DEFAULT_NTHREADS 8 +#define CTFMERGE_ALTEXEC "CTFMERGE_ALTEXEC" + static void ctfmerge_fatal(const char *fmt, ...) { @@ -53,7 +61,7 @@ ctfmerge_fatal(const char *fmt, ...) if (g_outfile != NULL) (void) unlink(g_outfile); - exit(1); + exit(CTFMERGE_FATAL); } static boolean_t @@ -224,10 +232,9 @@ ctfmerge_elfopen(const char *name, Elf *elf, ctf_merge_t *cmh) name, ctf_errmsg(err)); } } else { - if (ctf_merge_add(cmh, fp) != 0) { + if ((err = ctf_merge_add(cmh, fp)) != 0) { ctfmerge_fatal("failed to add input %s: %s\n", - name, ctf_errmsg(ctf_errno(fp))); - exit(1); + name, ctf_errmsg(err)); } g_nctf++; } @@ -294,10 +301,11 @@ ctfmerge_usage(const char *fmt, ...) } (void) fprintf(stderr, "Usage: %s [-gt] [-d uniqfile] [-l label] " - "[-L labelenv] -o outfile file ...\n" + "[-L labelenv] [-j nthrs] -o outfile file ...\n" "\n" "\t-d uniquify merged output against uniqfile\n" "\t-g do not remove source debug information (STABS, DWARF)\n" + "\t-j use nthrs threads to perform the merge\n" "\t-l set output container's label to specified value\n" "\t-L set output container's label to value from environment\n" "\t-o file to add CTF data to\n" @@ -305,22 +313,49 @@ ctfmerge_usage(const char *fmt, ...) g_progname); } +static void +ctfmerge_altexec(char **argv) +{ + const char *alt; + char *altexec; + + alt = getenv(CTFMERGE_ALTEXEC); + if (alt == NULL || *alt == '\0') + return; + + altexec = strdup(alt); + if (altexec == NULL) + ctfmerge_fatal("failed to allocate memory for altexec\n"); + if (unsetenv(CTFMERGE_ALTEXEC) != 0) + ctfmerge_fatal("failed to unset %s from environment: %s\n", + CTFMERGE_ALTEXEC, strerror(errno)); + + (void) execv(altexec, argv); + ctfmerge_fatal("failed to execute alternate program %s: %s", + altexec, strerror(errno)); +} + int main(int argc, char *argv[]) { int err, i, c, ofd; + uint_t nthreads = CTFMERGE_DEFAULT_NTHREADS; char *tmpfile = NULL, *label = NULL; int wflags = CTF_ELFWRITE_F_COMPRESS; ctf_file_t *ofp; ctf_merge_t *cmh; + long argj; + char *eptr; g_progname = basename(argv[0]); + ctfmerge_altexec(argv); + /* * We support a subset of the old CTF merge flags, mostly for * compatability. */ - while ((c = getopt(argc, argv, ":d:fgL:o:t")) != -1) { + while ((c = getopt(argc, argv, ":d:fgj:L:o:t")) != -1) { switch (c) { case 'd': g_unique = optarg; @@ -331,6 +366,17 @@ main(int argc, char *argv[]) case 'g': /* Silently ignored for compatibility */ 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') { + ctfmerge_fatal("invalid argument for -j: %s\n", + optarg); + } + nthreads = (uint_t)argj; + break; case 'l': label = optarg; break; @@ -344,18 +390,18 @@ main(int argc, char *argv[]) g_req = B_TRUE; break; case ':': - ctfmerge_usage("ctfmerge: Option -%c requires an " - "operand\n", optopt); - return (2); + ctfmerge_usage("Option -%c requires an operand\n", + optopt); + return (CTFMERGE_USAGE); case '?': ctfmerge_usage("Unknown option: -%c\n", optopt); - return (2); + return (CTFMERGE_USAGE); } } if (g_outfile == NULL) { ctfmerge_usage("missing required -o output file\n"); - return (2); + return (CTFMERGE_USAGE); } (void) elf_version(EV_CURRENT); @@ -373,7 +419,7 @@ main(int argc, char *argv[]) if (argc < 1) { ctfmerge_usage("no input files specified"); - return (2); + return (CTFMERGE_USAGE); } cmh = ctf_merge_init(ofd, &err); @@ -381,6 +427,10 @@ main(int argc, char *argv[]) ctfmerge_fatal("failed to create merge handle: %s\n", ctf_errmsg(err)); + if ((err = ctf_merge_set_nthreads(cmh, nthreads)) != 0) + ctfmerge_fatal("failed to set parallelism to %d: %s\n", + nthreads, ctf_errmsg(err)); + for (i = 0; i < argc; i++) { ctf_file_t *ifp; int fd; @@ -449,7 +499,6 @@ main(int argc, char *argv[]) if (ufp == NULL) { ctfmerge_fatal("failed to open uniquify file %s: %s\n", g_unique, ctf_errmsg(err)); - return (1); } base = basename(g_unique); @@ -470,18 +519,20 @@ main(int argc, char *argv[]) if (asprintf(&tmpfile, "%s.ctf", g_outfile) == -1) ctfmerge_fatal("ran out of memory for temporary file name\n"); err = ctf_elfwrite(ofp, g_outfile, tmpfile, wflags); - free(tmpfile); if (err == CTF_ERR) { (void) unlink(tmpfile); + free(tmpfile); ctfmerge_fatal("encountered a libctf error: %s!\n", ctf_errmsg(ctf_errno(ofp))); } if (rename(tmpfile, g_outfile) != 0) { (void) unlink(tmpfile); + free(tmpfile); ctfmerge_fatal("failed to rename temporary file: %s\n", strerror(errno)); } + free(tmpfile); - return (0); + return (CTFMERGE_OK); } |