diff options
author | Ulrich Drepper <drepper@redhat.com> | 2005-07-26 05:00:05 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2005-07-26 05:00:05 +0000 |
commit | b08d5a8fb42f4586d756068065186b5af7e48dad (patch) | |
tree | 9f05f86be7877ed461b4dc05f53b29ea4fc0d2a1 /libdwfl/argp-std.c | |
download | elfutils-b08d5a8fb42f4586d756068065186b5af7e48dad.tar.gz |
Adjust for monotone.
Diffstat (limited to 'libdwfl/argp-std.c')
-rw-r--r-- | libdwfl/argp-std.c | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/libdwfl/argp-std.c b/libdwfl/argp-std.c new file mode 100644 index 00000000..ebddcfb1 --- /dev/null +++ b/libdwfl/argp-std.c @@ -0,0 +1,164 @@ +/* Standard argp argument parsers for tools using libdwfl. + Copyright (C) 2005 Red Hat, Inc. + + This program is Open Source software; you can redistribute it and/or + modify it under the terms of the Open Software License version 1.0 as + published by the Open Source Initiative. + + You should have received a copy of the Open Software License along + with this program; if not, you may obtain a copy of the Open Software + License version 1.0 from http://www.opensource.org/licenses/osl.php or + by writing the Open Source Initiative c/o Lawrence Rosen, Esq., + 3001 King Ranch Road, Ukiah, CA 95482. */ + +#include "libdwflP.h" +#include <argp.h> +#include <stdlib.h> +#include <assert.h> +#include <libintl.h> + +/* gettext helper macros. */ +#define _(Str) dgettext ("elfutils", Str) + + +#define OPT_DEBUGINFO 0x100 + +static const struct argp_option options[] = +{ + { NULL, 0, NULL, 0, N_("Input Selection:"), 0 }, + { "executable", 'e', "FILE", 0, N_("Find addresses in FILE"), 0 }, + { "pid", 'p', "PID", 0, + N_("Find addresses in files mapped into process PID"), 0 }, + { "kernel", 'k', NULL, 0, N_("Find addresses in the running kernel"), 0 }, + { "debuginfo-path", OPT_DEBUGINFO, "PATH", 0, + N_("Search path for separate debuginfo files"), 0 }, + { NULL, 0, NULL, 0, NULL, 0 } +}; + +static char *debuginfo_path; + +static const Dwfl_Callbacks proc_callbacks = + { + .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo), + .debuginfo_path = &debuginfo_path, + + .find_elf = INTUSE(dwfl_linux_proc_find_elf), + }; + +static const Dwfl_Callbacks kernel_callbacks = + { + .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo), + .debuginfo_path = &debuginfo_path, + + .find_elf = INTUSE(dwfl_linux_kernel_find_elf), + .section_address = INTUSE(dwfl_linux_kernel_module_section_address), + }; + +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + inline void failure (int errnum, const char *msg) + { + if (errnum == -1) + argp_failure (state, EXIT_FAILURE, 0, "%s: %s", + msg, INTUSE(dwfl_errmsg) (-1)); + else + argp_failure (state, EXIT_FAILURE, errnum, "%s", msg); + } + inline error_t fail (int errnum, const char *msg) + { + failure (errnum, msg); + return errnum == -1 ? EIO : errnum; + } + + switch (key) + { + case OPT_DEBUGINFO: + debuginfo_path = arg; + break; + + case 'e': + if (state->hook == NULL) + { + Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks); + if (INTUSE(dwfl_report_elf) (dwfl, "", arg, -1, 0) == NULL) + return fail (-1, arg); + state->hook = dwfl; + } + else + { + toomany: + argp_error (state, "%s", _("only one -e, -p, or -k option allowed")); + return EINVAL; + } + break; + + case 'p': + if (state->hook == NULL) + { + Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks); + int result = INTUSE(dwfl_linux_proc_report) (dwfl, atoi (arg)); + if (result != 0) + return fail (result, arg); + state->hook = dwfl; + } + else + goto toomany; + break; + + case 'k': + if (state->hook == NULL) + { + Dwfl *dwfl = INTUSE(dwfl_begin) (&kernel_callbacks); + int result = INTUSE(dwfl_linux_kernel_report_kernel) (dwfl); + if (result != 0) + return fail (result, _("cannot load kernel symbols")); + result = INTUSE(dwfl_linux_kernel_report_modules) (dwfl); + if (result != 0) + /* Non-fatal to have no modules since we do have the kernel. */ + failure (result, _("cannot find kernel modules")); + state->hook = dwfl; + } + else + goto toomany; + break; + + case ARGP_KEY_SUCCESS: + { + Dwfl *dwfl = state->hook; + + if (dwfl == NULL) + { + /* Default if no -e, -p, or -k, is "-e a.out". */ + arg = "a.out"; + dwfl = INTUSE(dwfl_begin) (&proc_callbacks); + if (INTUSE(dwfl_report_elf) (dwfl, "", arg, -1, 0) == NULL) + return fail (-1, arg); + state->hook = dwfl; + } + + /* One of the three flavors has done dwfl_begin and some reporting + if we got here. Tie up the Dwfl and return it to the caller of + argp_parse. */ + + int result = INTUSE(dwfl_report_end) (dwfl, NULL, NULL); + assert (result == 0); + + *(Dwfl **) state->input = dwfl; + } + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +static const struct argp libdwfl_argp = + { .options = options, .parser = parse_opt }; + +const struct argp * +dwfl_standard_argp (void) +{ + return &libdwfl_argp; +} |