int main(int argc, char *argv[]) { int c, fd, err; const char *ufile = NULL, *parent = NULL; g_progname = basename(argv[0]); while ((c = getopt(argc, argv, ":dfhlp:sStu:")) != -1) { switch (c) { case 'd': g_dump |= CTFDUMP_OBJECTS; break; case 'f': g_dump |= CTFDUMP_FUNCTIONS; break; case 'h': g_dump |= CTFDUMP_HEADER; break; case 'l': g_dump |= CTFDUMP_LABELS; break; case 'p': parent = optarg; break; case 's': g_dump |= CTFDUMP_STRINGS; break; case 'S': g_dump |= CTFDUMP_STATS; break; case 't': g_dump |= CTFDUMP_TYPES; break; case 'u': g_dump |= CTFDUMP_OUTPUT; ufile = optarg; break; case '?': ctfdump_usage("Unknown option: -%c\n", optopt); return (2); case ':': ctfdump_usage("Option -%c requires an operand\n", optopt); return (2); } } argc -= optind; argv += optind; /* * Dump all information by default. */ if (g_dump == 0) g_dump = CTFDUMP_DEFAULT; if (argc != 1) { ctfdump_usage("no file to dump\n"); return (2); } if ((fd = open(argv[0], O_RDONLY)) < 0) ctfdump_fatal("failed to open file %s: %s\n", argv[0], strerror(errno)); g_fp = ctf_fdopen(fd, &err); if (g_fp == NULL) ctfdump_fatal("failed to open file %s: %s\n", argv[0], ctf_errmsg(err)); if (parent != NULL) { ctf_file_t *pfp = ctf_open(parent, &err); if (pfp == NULL) ctfdump_fatal("failed to open parent file %s: %s\n", parent, ctf_errmsg(err)); if (ctf_import(g_fp, pfp) != 0) ctfdump_fatal("failed to import parent %s: %s\n", parent, ctf_errmsg(ctf_errno(g_fp))); } /* * If stats is set, we must run through everything exect CTFDUMP_OUTPUT. * We also do CTFDUMP_STATS last as a result. */ if (g_dump & CTFDUMP_HEADER) ctfdump_header(); if (g_dump & (CTFDUMP_LABELS | CTFDUMP_STATS)) ctfdump_labels(); if (g_dump & (CTFDUMP_OBJECTS | CTFDUMP_STATS)) ctfdump_objects(); if (g_dump & (CTFDUMP_FUNCTIONS | CTFDUMP_STATS)) ctfdump_functions(); if (g_dump & (CTFDUMP_TYPES | CTFDUMP_STATS)) ctfdump_types(); if (g_dump & (CTFDUMP_STRINGS | CTFDUMP_STATS)) ctfdump_strings(); if (g_dump & CTFDUMP_STATS) ctfdump_stats(); if (g_dump & CTFDUMP_OUTPUT) ctfdump_output(ufile); return (g_exit); }
int main(int argc, char *argv[]) { int c, fd, err; const char *ufile = NULL, *parent = NULL; g_progname = basename(argv[0]); while ((c = getopt(argc, argv, ":cdfhlp:sStu:")) != -1) { switch (c) { case 'c': g_dump |= CTFDUMP_SOURCE; break; case 'd': g_dump |= CTFDUMP_OBJECTS; break; case 'f': g_dump |= CTFDUMP_FUNCTIONS; break; case 'h': g_dump |= CTFDUMP_HEADER; break; case 'l': g_dump |= CTFDUMP_LABELS; break; case 'p': parent = optarg; break; case 's': g_dump |= CTFDUMP_STRINGS; break; case 'S': g_dump |= CTFDUMP_STATS; break; case 't': g_dump |= CTFDUMP_TYPES; break; case 'u': g_dump |= CTFDUMP_OUTPUT; ufile = optarg; break; case '?': ctfdump_usage("Unknown option: -%c\n", optopt); return (2); case ':': ctfdump_usage("Option -%c requires an operand\n", optopt); return (2); } } argc -= optind; argv += optind; if ((g_dump & CTFDUMP_SOURCE) && !!(g_dump & ~CTFDUMP_SOURCE)) { ctfdump_usage("-c must be specified on its own\n"); return (2); } /* * Dump all information except C source by default. */ if (g_dump == 0) g_dump = CTFDUMP_DEFAULT; if (argc != 1) { ctfdump_usage("no file to dump\n"); return (2); } if ((fd = open(argv[0], O_RDONLY)) < 0) ctfdump_fatal("failed to open file %s: %s\n", argv[0], strerror(errno)); g_fp = ctf_fdopen(fd, &err); if (g_fp == NULL) ctfdump_fatal("failed to open file %s: %s\n", argv[0], ctf_errmsg(err)); /* * Check to see if this file needs a parent. If it does not and we were * given one, that should be an error. If it does need one and the * parent is not specified, that is fine, we just won't know how to * find child types. If we are given a parent, check at least that the * labels match. */ if (ctf_parent_name(g_fp) == NULL) { if (parent != NULL) ctfdump_fatal("cannot use %s as a parent file, %s is " "not a child\n", parent, argv[0]); } else if (parent != NULL) { const char *explabel, *label; ctf_file_t *pfp = ctf_open(parent, &err); if (pfp == NULL) ctfdump_fatal("failed to open parent file %s: %s\n", parent, ctf_errmsg(err)); /* * Before we import the parent into the child, check that the * labels match. While there is also the notion of the parent * name, it's less straightforward to match that. Require that * labels match. */ explabel = ctf_parent_label(g_fp); label = ctf_label_topmost(pfp); if (explabel == NULL || label == NULL || strcmp(explabel, label) != 0) { if (label == NULL) label = "<missing>"; if (explabel == NULL) explabel = "<missing>"; ctfdump_fatal("label mismatch between parent %s and " "child %s, parent has %s, child expects %s\n", parent, argv[0], label, explabel); } if (ctf_import(g_fp, pfp) != 0) ctfdump_fatal("failed to import parent %s: %s\n", parent, ctf_errmsg(ctf_errno(g_fp))); } if (g_dump & CTFDUMP_SOURCE) { ctfdump_source(); return (0); } /* * If stats is set, we must run through everything exect CTFDUMP_OUTPUT. * We also do CTFDUMP_STATS last as a result. */ if (g_dump & CTFDUMP_HEADER) ctfdump_header(); if (g_dump & (CTFDUMP_LABELS | CTFDUMP_STATS)) ctfdump_labels(); if (g_dump & (CTFDUMP_OBJECTS | CTFDUMP_STATS)) ctfdump_objects(); if (g_dump & (CTFDUMP_FUNCTIONS | CTFDUMP_STATS)) ctfdump_functions(); if (g_dump & (CTFDUMP_TYPES | CTFDUMP_STATS)) ctfdump_types(); if (g_dump & (CTFDUMP_STRINGS | CTFDUMP_STATS)) ctfdump_strings(); if (g_dump & CTFDUMP_STATS) ctfdump_stats(); if (g_dump & CTFDUMP_OUTPUT) ctfdump_output(ufile); return (g_exit); }