diff options
| author | Roland McGrath <[email protected]> | 2008-08-25 22:55:17 +0000 |
|---|---|---|
| committer | Roland McGrath <[email protected]> | 2008-08-25 22:55:17 +0000 |
| commit | b4d6f0f8064f2b706ea9035ef0393d8299671390 (patch) | |
| tree | 58d3da51253302bc5b8f2198d8462942ff43f464 /libdwfl/argp-std.c | |
| parent | f729d77881262094d365d33ac51063e25a02e357 (diff) | |
Fix up bogon and missing log entries from .pmachata.threads branch.
Diffstat (limited to 'libdwfl/argp-std.c')
| -rw-r--r-- | libdwfl/argp-std.c | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/libdwfl/argp-std.c b/libdwfl/argp-std.c index 1abb568f..0a0f7ebf 100644 --- a/libdwfl/argp-std.c +++ b/libdwfl/argp-std.c @@ -52,17 +52,22 @@ #include <stdlib.h> #include <assert.h> #include <libintl.h> +#include <fcntl.h> +#include <unistd.h> /* gettext helper macros. */ #define _(Str) dgettext ("elfutils", Str) -#define OPT_DEBUGINFO 0x100 +#define OPT_DEBUGINFO 0x100 +#define OPT_COREFILE 0x101 static const struct argp_option options[] = { { NULL, 0, NULL, 0, N_("Input selection options:"), 0 }, { "executable", 'e', "FILE", 0, N_("Find addresses in FILE"), 0 }, + { "core", OPT_COREFILE, "COREFILE", 0, + N_("Find addresses from signatures found in COREFILE"), 0 }, { "pid", 'p', "PID", 0, N_("Find addresses in files mapped into process PID"), 0 }, { "linux-process-map", 'M', "FILE", 0, @@ -84,6 +89,9 @@ static const Dwfl_Callbacks offline_callbacks = .debuginfo_path = &debuginfo_path, .section_address = INTUSE(dwfl_offline_section_address), + + /* We use this table for core files too. */ + .find_elf = INTUSE(dwfl_build_id_find_elf), }; static const Dwfl_Callbacks proc_callbacks = @@ -151,8 +159,8 @@ parse_opt (int key, char *arg, struct argp_state *state) else { toomany: - argp_error (state, - "%s", _("only one of -e, -p, -k, or -K allowed")); + argp_error (state, "%s", + _("only one of -e, -p, -k, -K, or --core allowed")); return EINVAL; } } @@ -176,6 +184,7 @@ parse_opt (int key, char *arg, struct argp_state *state) { FILE *f = fopen (arg, "r"); if (f == NULL) + nofile: { int code = errno; argp_failure (state, EXIT_FAILURE, code, @@ -193,6 +202,50 @@ parse_opt (int key, char *arg, struct argp_state *state) goto toomany; break; + case OPT_COREFILE: + { + Dwfl *dwfl = state->hook; + if (dwfl == NULL) + state->hook = dwfl = INTUSE(dwfl_begin) (&offline_callbacks); + /* Permit -e and --core together. */ + else if (dwfl->callbacks != &offline_callbacks) + goto toomany; + + int fd = open64 (arg, O_RDONLY); + if (fd < 0) + goto nofile; + + Elf *core = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, NULL); + if (core == NULL) + { + close (fd); + argp_failure (state, EXIT_FAILURE, 0, + _("cannot read ELF core file: %s"), + elf_errmsg (-1)); + return EIO; + } + + GElf_Ehdr ehdr; + int result = INTUSE(dwfl_core_file_report) (dwfl, core, + gelf_getehdr (core, &ehdr)); + if (result < 0) + { + elf_end (core); + close (fd); + return fail (dwfl, result, arg); + } + + /* From now we leak FD and CORE. */ + + if (result == 0) + { + argp_failure (state, EXIT_FAILURE, 0, + _("No modules recognized in core file")); + return ENOENT; + } + } + break; + case 'k': if (state->hook == NULL) { |
