1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Standard argp argument parsers for tools using libdwfl. 2355b408bb9aa49703544fa4086e1ae463737fcf6Mark Wielaard Copyright (C) 2005-2010, 2012, 2015 Red Hat, Inc. 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is part of elfutils. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 5de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is free software; you can redistribute it and/or modify 6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard it under the terms of either 7b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 8de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU Lesser General Public License as published by the Free 9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 3 of the License, or (at 10de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 12de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or 13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU General Public License as published by the Free 15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 2 of the License, or (at 16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 18de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or both in parallel, as here. 19de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 20de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard elfutils is distributed in the hope that it will be useful, but 21361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper WITHOUT ANY WARRANTY; without even the implied warranty of 22361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper General Public License for more details. 24361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 25de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard You should have received copies of the GNU General Public License and 26de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard the GNU Lesser General Public License along with this program. If 27de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard not, see <http://www.gnu.org/licenses/>. */ 28b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "libdwflP.h" 30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <argp.h> 31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h> 32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <assert.h> 33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libintl.h> 34b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath#include <fcntl.h> 35b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath#include <unistd.h> 36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 37b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* gettext helper macros. */ 38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define _(Str) dgettext ("elfutils", Str) 39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 41b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath#define OPT_DEBUGINFO 0x100 42b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath#define OPT_COREFILE 0x101 43b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const struct argp_option options[] = 45b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 464be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath { NULL, 0, NULL, 0, N_("Input selection options:"), 0 }, 47b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "executable", 'e', "FILE", 0, N_("Find addresses in FILE"), 0 }, 48b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath { "core", OPT_COREFILE, "COREFILE", 0, 49b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath N_("Find addresses from signatures found in COREFILE"), 0 }, 50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "pid", 'p', "PID", 0, 51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper N_("Find addresses in files mapped into process PID"), 0 }, 521656bc00ae97fa16a941a8cefacc4e01488d0e8aRoland McGrath { "linux-process-map", 'M', "FILE", 0, 531656bc00ae97fa16a941a8cefacc4e01488d0e8aRoland McGrath N_("Find addresses in files mapped as read from FILE" 541656bc00ae97fa16a941a8cefacc4e01488d0e8aRoland McGrath " in Linux /proc/PID/maps format"), 0 }, 55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "kernel", 'k', NULL, 0, N_("Find addresses in the running kernel"), 0 }, 56d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath { "offline-kernel", 'K', "RELEASE", OPTION_ARG_OPTIONAL, 57d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath N_("Kernel with all modules"), 0 }, 58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "debuginfo-path", OPT_DEBUGINFO, "PATH", 0, 59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper N_("Search path for separate debuginfo files"), 0 }, 60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 0, NULL, 0, NULL, 0 } 61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic char *debuginfo_path; 64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 65d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrathstatic const Dwfl_Callbacks offline_callbacks = 66d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath { 67d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo), 68d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath .debuginfo_path = &debuginfo_path, 69d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 70d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath .section_address = INTUSE(dwfl_offline_section_address), 71b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath 72b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath /* We use this table for core files too. */ 73c53094634516313fb598d67e709f51f20d6acbbaJan Kratochvil .find_elf = INTUSE(dwfl_build_id_find_elf), 74d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath }; 75d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const Dwfl_Callbacks proc_callbacks = 77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo), 79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .debuginfo_path = &debuginfo_path, 80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .find_elf = INTUSE(dwfl_linux_proc_find_elf), 82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const Dwfl_Callbacks kernel_callbacks = 85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo), 87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .debuginfo_path = &debuginfo_path, 88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .find_elf = INTUSE(dwfl_linux_kernel_find_elf), 90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper .section_address = INTUSE(dwfl_linux_kernel_module_section_address), 91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper }; 92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 93d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil/* Structure held at state->HOOK. */ 94d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvilstruct parse_opt 95d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil{ 96d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil Dwfl *dwfl; 97d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil /* The -e|--executable parameter. */ 98d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil const char *e; 99d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil /* The --core parameter. */ 100d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil const char *core; 101d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil}; 102d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil 103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t 104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperparse_opt (int key, char *arg, struct argp_state *state) 105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1061656bc00ae97fa16a941a8cefacc4e01488d0e8aRoland McGrath inline void failure (Dwfl *dwfl, int errnum, const char *msg) 107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 108d11f9cbecac4a5ac3848a68597028d1924f3ff6bRoland McGrath if (dwfl != NULL) 109d11f9cbecac4a5ac3848a68597028d1924f3ff6bRoland McGrath dwfl_end (dwfl); 110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (errnum == -1) 111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper argp_failure (state, EXIT_FAILURE, 0, "%s: %s", 112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper msg, INTUSE(dwfl_errmsg) (-1)); 113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper argp_failure (state, EXIT_FAILURE, errnum, "%s", msg); 115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1161656bc00ae97fa16a941a8cefacc4e01488d0e8aRoland McGrath inline error_t fail (Dwfl *dwfl, int errnum, const char *msg) 117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 1181656bc00ae97fa16a941a8cefacc4e01488d0e8aRoland McGrath failure (dwfl, errnum, msg); 119b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return errnum == -1 ? EIO : errnum; 120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (key) 123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 124d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil case ARGP_KEY_INIT: 125d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil { 126d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil assert (state->hook == NULL); 127d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil struct parse_opt *opt = calloc (1, sizeof (*opt)); 128d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (opt == NULL) 129d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil failure (NULL, DWFL_E_ERRNO, "calloc"); 130d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil state->hook = opt; 131d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil } 132d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil break; 133d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil 134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case OPT_DEBUGINFO: 135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper debuginfo_path = arg; 136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'e': 139d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath { 140d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil struct parse_opt *opt = state->hook; 141d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil Dwfl *dwfl = opt->dwfl; 142d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath if (dwfl == NULL) 143d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath { 144d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath dwfl = INTUSE(dwfl_begin) (&offline_callbacks); 145d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath if (dwfl == NULL) 1461656bc00ae97fa16a941a8cefacc4e01488d0e8aRoland McGrath return fail (dwfl, -1, arg); 147d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil opt->dwfl = dwfl; 148aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper 149aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper /* Start at zero so if there is just one -e foo.so, 150aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper the DSO is shown without address bias. */ 151aa915fd3d70b4cbe4581f9ec170d986c6ba35063Ulrich Drepper dwfl->offline_next_address = 0; 152d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath } 153d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (dwfl->callbacks != &offline_callbacks) 154d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath { 155d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath toomany: 156b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath argp_error (state, "%s", 157b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath _("only one of -e, -p, -k, -K, or --core allowed")); 158d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath return EINVAL; 159d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath } 160d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil opt->e = arg; 161d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath } 162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'p': 165d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil { 166d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil struct parse_opt *opt = state->hook; 167d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (opt->dwfl == NULL) 168d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil { 169d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks); 170d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil int result = INTUSE(dwfl_linux_proc_report) (dwfl, atoi (arg)); 171d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (result != 0) 172d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil return fail (dwfl, result, arg); 17319108019192ab273c53ae324be448d29dac806caMark Wielaard 174824f393411acc4596ab557b6e7bff9e48c61f951Mark Wielaard /* Non-fatal to not be able to attach to process, ignore error. */ 175824f393411acc4596ab557b6e7bff9e48c61f951Mark Wielaard INTUSE(dwfl_linux_proc_attach) (dwfl, atoi (arg), false); 176824f393411acc4596ab557b6e7bff9e48c61f951Mark Wielaard 177d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil opt->dwfl = dwfl; 178d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil } 179d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil else 180d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil goto toomany; 181d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil } 1821656bc00ae97fa16a941a8cefacc4e01488d0e8aRoland McGrath break; 1831656bc00ae97fa16a941a8cefacc4e01488d0e8aRoland McGrath 1841656bc00ae97fa16a941a8cefacc4e01488d0e8aRoland McGrath case 'M': 185d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil { 186d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil struct parse_opt *opt = state->hook; 187d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (opt->dwfl == NULL) 188d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil { 189d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil FILE *f = fopen (arg, "r"); 190d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (f == NULL) 191d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil { 192d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil int code = errno; 193d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil argp_failure (state, EXIT_FAILURE, code, 194d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil "cannot open '%s'", arg); 195d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil return code; 196d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil } 197d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks); 198d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil int result = INTUSE(dwfl_linux_proc_maps_report) (dwfl, f); 199d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil fclose (f); 200d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (result != 0) 201d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil return fail (dwfl, result, arg); 202d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil opt->dwfl = dwfl; 203d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil } 204d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil else 205d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil goto toomany; 206d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil } 207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 209b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath case OPT_COREFILE: 210b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath { 211d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil struct parse_opt *opt = state->hook; 212d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil Dwfl *dwfl = opt->dwfl; 213b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath if (dwfl == NULL) 214d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil opt->dwfl = dwfl = INTUSE(dwfl_begin) (&offline_callbacks); 215b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath /* Permit -e and --core together. */ 216b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath else if (dwfl->callbacks != &offline_callbacks) 217b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath goto toomany; 218d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil opt->core = arg; 219b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath } 220b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath break; 221b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath 222b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'k': 223d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil { 224d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil struct parse_opt *opt = state->hook; 225d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (opt->dwfl == NULL) 226d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil { 227d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil Dwfl *dwfl = INTUSE(dwfl_begin) (&kernel_callbacks); 228d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil int result = INTUSE(dwfl_linux_kernel_report_kernel) (dwfl); 229d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (result != 0) 230d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil return fail (dwfl, result, _("cannot load kernel symbols")); 231d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil result = INTUSE(dwfl_linux_kernel_report_modules) (dwfl); 232d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (result != 0) 233d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil /* Non-fatal to have no modules since we do have the kernel. */ 234d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil failure (dwfl, result, _("cannot find kernel modules")); 235d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil opt->dwfl = dwfl; 236d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil } 237d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil else 238d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil goto toomany; 239d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil } 240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 242d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath case 'K': 243d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil { 244d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil struct parse_opt *opt = state->hook; 245d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (opt->dwfl == NULL) 246d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil { 247d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil Dwfl *dwfl = INTUSE(dwfl_begin) (&offline_callbacks); 248d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil int result = INTUSE(dwfl_linux_kernel_report_offline) (dwfl, arg, 249d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil NULL); 250d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (result != 0) 251d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil return fail (dwfl, result, _("cannot find kernel or modules")); 252d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil opt->dwfl = dwfl; 253d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil } 254d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil else 255d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil goto toomany; 256d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil } 257d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath break; 258d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath 259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case ARGP_KEY_SUCCESS: 260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 261d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil struct parse_opt *opt = state->hook; 262d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil Dwfl *dwfl = opt->dwfl; 263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (dwfl == NULL) 265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Default if no -e, -p, or -k, is "-e a.out". */ 267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper arg = "a.out"; 268d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath dwfl = INTUSE(dwfl_begin) (&offline_callbacks); 269d17fac7e89666b47811581b10b5ca0d253a3a82dRoland McGrath if (INTUSE(dwfl_report_offline) (dwfl, "", arg, -1) == NULL) 2701656bc00ae97fa16a941a8cefacc4e01488d0e8aRoland McGrath return fail (dwfl, -1, arg); 271d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil opt->dwfl = dwfl; 272d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil } 273d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil 274d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (opt->core) 275d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil { 2763425454a10d307fae891fb667cf7969e945cde79Josh Stone int fd = open (opt->core, O_RDONLY); 277d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (fd < 0) 27840025813dc9e5f2524c3c1851a99efd43cb59894Mark Wielaard { 27940025813dc9e5f2524c3c1851a99efd43cb59894Mark Wielaard int code = errno; 28040025813dc9e5f2524c3c1851a99efd43cb59894Mark Wielaard argp_failure (state, EXIT_FAILURE, code, 28140025813dc9e5f2524c3c1851a99efd43cb59894Mark Wielaard "cannot open '%s'", opt->core); 28240025813dc9e5f2524c3c1851a99efd43cb59894Mark Wielaard return code; 28340025813dc9e5f2524c3c1851a99efd43cb59894Mark Wielaard } 284d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil 285d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil Elf *core; 286d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil Dwfl_Error error = __libdw_open_file (&fd, &core, true, false); 287d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (error != DWFL_E_NOERROR) 288d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil { 289d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil argp_failure (state, EXIT_FAILURE, 0, 290d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil _("cannot read ELF core file: %s"), 291d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil INTUSE(dwfl_errmsg) (error)); 292d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil return error == DWFL_E_ERRNO ? errno : EIO; 293d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil } 294d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil 2953cf491ee10f10855a49e6a35cc9b8365a3197553Jan Kratochvil int result = INTUSE(dwfl_core_file_report) (dwfl, core, opt->e); 296d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (result < 0) 297d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil { 298d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil elf_end (core); 299d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil close (fd); 300d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil return fail (dwfl, result, opt->core); 301d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil } 302d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil 303824f393411acc4596ab557b6e7bff9e48c61f951Mark Wielaard /* Non-fatal to not be able to attach to core, ignore error. */ 304824f393411acc4596ab557b6e7bff9e48c61f951Mark Wielaard INTUSE(dwfl_core_file_attach) (dwfl, core); 30519108019192ab273c53ae324be448d29dac806caMark Wielaard 306355b408bb9aa49703544fa4086e1ae463737fcf6Mark Wielaard /* Store core Elf and fd in Dwfl to expose with dwfl_end. */ 307355b408bb9aa49703544fa4086e1ae463737fcf6Mark Wielaard if (dwfl->user_core == NULL) 308355b408bb9aa49703544fa4086e1ae463737fcf6Mark Wielaard { 309355b408bb9aa49703544fa4086e1ae463737fcf6Mark Wielaard dwfl->user_core = calloc (1, sizeof (struct Dwfl_User_Core)); 310355b408bb9aa49703544fa4086e1ae463737fcf6Mark Wielaard if (dwfl->user_core == NULL) 311355b408bb9aa49703544fa4086e1ae463737fcf6Mark Wielaard { 312355b408bb9aa49703544fa4086e1ae463737fcf6Mark Wielaard argp_failure (state, EXIT_FAILURE, 0, 313355b408bb9aa49703544fa4086e1ae463737fcf6Mark Wielaard _("Not enough memory")); 314355b408bb9aa49703544fa4086e1ae463737fcf6Mark Wielaard return ENOMEM; 315355b408bb9aa49703544fa4086e1ae463737fcf6Mark Wielaard } 316355b408bb9aa49703544fa4086e1ae463737fcf6Mark Wielaard } 317355b408bb9aa49703544fa4086e1ae463737fcf6Mark Wielaard dwfl->user_core->core = core; 318355b408bb9aa49703544fa4086e1ae463737fcf6Mark Wielaard dwfl->user_core->fd = fd; 319d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil 320d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (result == 0) 321d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil { 322d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil argp_failure (state, EXIT_FAILURE, 0, 323d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil _("No modules recognized in core file")); 324d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil return ENOENT; 325d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil } 326d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil } 327d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil else if (opt->e) 328d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil { 329d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (INTUSE(dwfl_report_offline) (dwfl, "", opt->e, -1) == NULL) 33040025813dc9e5f2524c3c1851a99efd43cb59894Mark Wielaard return fail (dwfl, -1, opt->e); 331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* One of the three flavors has done dwfl_begin and some reporting 334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if we got here. Tie up the Dwfl and return it to the caller of 335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper argp_parse. */ 336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int result = INTUSE(dwfl_report_end) (dwfl, NULL, NULL); 338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper assert (result == 0); 339d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil 340d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil /* Update the input all along, so a parent parser can see it. 341d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil As we free OPT the update below will be no longer active. */ 342d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil *(Dwfl **) state->input = dwfl; 343d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil free (opt); 344d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil state->hook = NULL; 345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3484be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath case ARGP_KEY_ERROR: 349d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil { 350d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil struct parse_opt *opt = state->hook; 351d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil dwfl_end (opt->dwfl); 352d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil free (opt); 353d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil state->hook = NULL; 354d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil } 3554be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath break; 3564be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ARGP_ERR_UNKNOWN; 359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3604be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath 3614be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath /* Update the input all along, so a parent parser can see it. */ 362d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil struct parse_opt *opt = state->hook; 363d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil if (opt) 364d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil *(Dwfl **) state->input = opt->dwfl; 365d5784afaf49cd59b9286e766cd9b1cf00cb43553Jan Kratochvil 366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const struct argp libdwfl_argp = 370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { .options = options, .parser = parse_opt }; 371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperconst struct argp * 373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperdwfl_standard_argp (void) 374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return &libdwfl_argp; 376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 377