1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Locate source files and line information for given addresses 270a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard Copyright (C) 2005-2010, 2012, 2013, 2015 Red Hat, Inc. 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is part of elfutils. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper Written by Ulrich Drepper <drepper@redhat.com>, 2005. 5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is free software; you can redistribute it and/or modify 7de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard it under the terms of the GNU General Public License as published by 8de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard the Free Software Foundation; either version 3 of the License, or 9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard (at your option) any later version. 10b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard elfutils is distributed in the hope that it will be useful, but 12361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper WITHOUT ANY WARRANTY; without even the implied warranty of 13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard GNU General Public License for more details. 15361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard You should have received a copy of the GNU General Public License 17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 19b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H 20b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h> 21b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 22b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 23b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <argp.h> 24b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <assert.h> 25b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <errno.h> 26b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <error.h> 27b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <fcntl.h> 28b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <inttypes.h> 291c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath#include <libdwfl.h> 301c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath#include <dwarf.h> 31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libintl.h> 32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <locale.h> 33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdbool.h> 34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdio.h> 35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdio_ext.h> 36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h> 37b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <string.h> 38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <unistd.h> 39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 40fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich Drepper#include <system.h> 41fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich Drepper 42b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 43b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Name and version of program. */ 44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void print_version (FILE *stream, struct argp_state *state); 45fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich DrepperARGP_PROGRAM_VERSION_HOOK_DEF = print_version; 46b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 47b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Bug report address. */ 48fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich DrepperARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; 49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Values for the parameters which have no short form. */ 52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define OPT_DEMANGLER 0x100 53b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard#define OPT_PRETTY 0x101 /* 'p' is already used to select the process. */ 54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Definitions of arguments for argp functions. */ 56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const struct argp_option options[] = 57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 58472890f580a83f1511e1ad83c10ea2b1d364cc8dMark Wielaard { NULL, 0, NULL, 0, N_("Input format options:"), 2 }, 59472890f580a83f1511e1ad83c10ea2b1d364cc8dMark Wielaard { "section", 'j', "NAME", 0, 60472890f580a83f1511e1ad83c10ea2b1d364cc8dMark Wielaard N_("Treat addresses as offsets relative to NAME section."), 0 }, 61472890f580a83f1511e1ad83c10ea2b1d364cc8dMark Wielaard 62472890f580a83f1511e1ad83c10ea2b1d364cc8dMark Wielaard { NULL, 0, NULL, 0, N_("Output format options:"), 3 }, 6370a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard { "addresses", 'a', NULL, 0, N_("Print address before each entry"), 0 }, 64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "basenames", 's', NULL, 0, N_("Show only base names of source files"), 0 }, 65e1812e1d90090450e3d93be56a487e2f11affcedUlrich Drepper { "absolute", 'A', NULL, 0, 6647fd77e7bf5a3df32da9f05d6cbdd9d821edee90Roland McGrath N_("Show absolute file names using compilation directory"), 0 }, 67cc41562f94052f307da4429f33cc18c7d510b2f5Ulrich Drepper { "functions", 'f', NULL, 0, N_("Also show function names"), 0 }, 6860fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath { "symbols", 'S', NULL, 0, N_("Also show symbol or section names"), 0 }, 69159ac52b061c60947a943c102298cd692223274fMark Wielaard { "symbols-sections", 'x', NULL, 0, N_("Also show symbol and the section names"), 0 }, 70de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath { "flags", 'F', NULL, 0, N_("Also show line table flags"), 0 }, 714b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard { "inlines", 'i', NULL, 0, 724b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard N_("Show all source locations that caused inline expansion of subroutines at the address."), 734b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard 0 }, 74cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard { "demangle", 'C', "ARG", OPTION_ARG_OPTIONAL, 75cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard N_("Show demangled symbols (ARG is always ignored)"), 0 }, 76b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard { "pretty-print", OPT_PRETTY, NULL, 0, 77b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard N_("Print all information on one line, and indent inlines"), 0 }, 78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 }, 80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Unsupported options. */ 81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "target", 'b', "ARG", OPTION_HIDDEN, NULL, 0 }, 82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { "demangler", OPT_DEMANGLER, "ARG", OPTION_HIDDEN, NULL, 0 }, 83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { NULL, 0, NULL, 0, NULL, 0 } 84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Short description of program. */ 87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char doc[] = N_("\ 88b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperLocate source files and line information for ADDRs (in a.out by default)."); 89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Strings for arguments in help texts. */ 91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char args_doc[] = N_("[ADDR...]"); 92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Prototype for option handler. */ 94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t parse_opt (int key, char *arg, struct argp_state *state); 95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 961c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrathstatic struct argp_child argp_children[2]; /* [0] is set in main. */ 971c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath 98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Data structure to communicate with argp functions. */ 991c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrathstatic const struct argp argp = 100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 1011c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath options, parse_opt, args_doc, doc, argp_children, NULL, NULL 102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}; 103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Handle ADDR. */ 1061d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrathstatic int handle_address (const char *addr, Dwfl *dwfl); 107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 10870a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard/* True when we should print the address for each entry. */ 10970a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaardstatic bool print_addresses; 110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* True if only base names of files should be shown. */ 112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool only_basenames; 113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 114e1812e1d90090450e3d93be56a487e2f11affcedUlrich Drepper/* True if absolute file names based on DW_AT_comp_dir should be shown. */ 115e1812e1d90090450e3d93be56a487e2f11affcedUlrich Drepperstatic bool use_comp_dir; 116e1812e1d90090450e3d93be56a487e2f11affcedUlrich Drepper 117de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath/* True if line flags should be shown. */ 118de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrathstatic bool show_flags; 119de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath 120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* True if function names should be shown. */ 121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic bool show_functions; 122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 12360fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath/* True if ELF symbol or section info should be shown. */ 12460fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrathstatic bool show_symbols; 12560fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath 126159ac52b061c60947a943c102298cd692223274fMark Wielaard/* True if section associated with a symbol address should be shown. */ 127159ac52b061c60947a943c102298cd692223274fMark Wielaardstatic bool show_symbol_sections; 128159ac52b061c60947a943c102298cd692223274fMark Wielaard 129d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath/* If non-null, take address parameters as relative to named section. */ 130d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrathstatic const char *just_section; 131d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath 1324b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard/* True if all inlined subroutines of the current address should be shown. */ 1334b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaardstatic bool show_inlines; 1344b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard 135cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard/* True if all names need to be demangled. */ 136cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaardstatic bool demangle; 137cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard 138b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard/* True if all information should be printed on one line. */ 139b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaardstatic bool pretty; 140b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard 141cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard#ifdef USE_DEMANGLE 142cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaardstatic size_t demangle_buffer_len = 0; 143cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaardstatic char *demangle_buffer = NULL; 144cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard#endif 145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint 147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppermain (int argc, char *argv[]) 148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int remaining; 150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int result = 0; 151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We use no threads here which can interfere with handling a stream. */ 153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER); 154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Set locale. */ 156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (void) setlocale (LC_ALL, ""); 157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Make sure the message catalog can be found. */ 159b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); 160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Initialize the message catalog. */ 162b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper (void) textdomain (PACKAGE_TARNAME); 163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 1641c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath /* Parse and process arguments. This includes opening the modules. */ 1651c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath argp_children[0].argp = dwfl_standard_argp (); 1669aa8ef7fbb5ada14b7c4585d6c1361aa5eab6f88Roland McGrath argp_children[0].group = 1; 1671c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath Dwfl *dwfl = NULL; 1681c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath (void) argp_parse (&argp, argc, argv, 0, &remaining, &dwfl); 1691c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath assert (dwfl != NULL); 170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Now handle the addresses. In case none are given on the command 172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper line, read from stdin. */ 173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (remaining == argc) 174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* We use no threads here which can interfere with handling a stream. */ 176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER); 177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *buf = NULL; 179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size_t len = 0; 180d0f8501761b15b35dc52eaf5709a638276270077Mark Wielaard ssize_t chars; 181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (!feof_unlocked (stdin)) 182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 183d0f8501761b15b35dc52eaf5709a638276270077Mark Wielaard if ((chars = getline (&buf, &len, stdin)) < 0) 184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 185b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 186d0f8501761b15b35dc52eaf5709a638276270077Mark Wielaard if (buf[chars - 1] == '\n') 187d0f8501761b15b35dc52eaf5709a638276270077Mark Wielaard buf[chars - 1] = '\0'; 188d0f8501761b15b35dc52eaf5709a638276270077Mark Wielaard 1891d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath result = handle_address (buf, dwfl); 190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper free (buf); 193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 194b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper do 1971d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath result = handle_address (argv[remaining], dwfl); 198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (++remaining < argc); 199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 2015532404e1ad6dd64f87226702ab32c8f40106d55Mark Wielaard dwfl_end (dwfl); 202cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard 203cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard#ifdef USE_DEMANGLE 204cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard free (demangle_buffer); 205cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard#endif 206cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard 207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return result; 208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 210b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 211b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Print the version information. */ 212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprint_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) 214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 215b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper fprintf (stream, "addr2line (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stream, gettext ("\ 217b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperCopyright (C) %s Red Hat, Inc.\n\ 218b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperThis is free software; see the source for copying conditions. There is NO\n\ 219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 2203a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper"), "2012"); 221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 222b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Handle program arguments. */ 226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t 227d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrathparse_opt (int key, char *arg, struct argp_state *state) 228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper switch (key) 230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 2311c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath case ARGP_KEY_INIT: 2321c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath state->child_inputs[0] = state->input; 2331c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath break; 2341c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath 23570a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard case 'a': 23670a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard print_addresses = true; 23770a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard break; 23870a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard 239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'b': 240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'C': 241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case OPT_DEMANGLER: 242cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard demangle = true; 243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 's': 246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper only_basenames = true; 247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 249e1812e1d90090450e3d93be56a487e2f11affcedUlrich Drepper case 'A': 250e1812e1d90090450e3d93be56a487e2f11affcedUlrich Drepper use_comp_dir = true; 251e1812e1d90090450e3d93be56a487e2f11affcedUlrich Drepper break; 252e1812e1d90090450e3d93be56a487e2f11affcedUlrich Drepper 253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper case 'f': 254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper show_functions = true; 255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 257de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath case 'F': 258de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath show_flags = true; 259de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath break; 260de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath 26160fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath case 'S': 26260fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath show_symbols = true; 26360fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath break; 26460fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath 265159ac52b061c60947a943c102298cd692223274fMark Wielaard case 'x': 266159ac52b061c60947a943c102298cd692223274fMark Wielaard show_symbols = true; 267159ac52b061c60947a943c102298cd692223274fMark Wielaard show_symbol_sections = true; 268159ac52b061c60947a943c102298cd692223274fMark Wielaard break; 269159ac52b061c60947a943c102298cd692223274fMark Wielaard 270d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath case 'j': 271d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath just_section = arg; 272d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath break; 273d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath 2744b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard case 'i': 2754b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard show_inlines = true; 2764b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard break; 2774b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard 278b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard case OPT_PRETTY: 279b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard pretty = true; 280b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard break; 281b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard 282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper default: 283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ARGP_ERR_UNKNOWN; 284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 288cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaardstatic const char * 289cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaardsymname (const char *name) 290cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard{ 291cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard#ifdef USE_DEMANGLE 292cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard // Require GNU v3 ABI by the "_Z" prefix. 293cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard if (demangle && name[0] == '_' && name[1] == 'Z') 294cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard { 295cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard int status = -1; 296cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard char *dsymname = __cxa_demangle (name, demangle_buffer, 297cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard &demangle_buffer_len, &status); 298cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard if (status == 0) 299cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard name = demangle_buffer = dsymname; 300cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard } 301cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard#endif 302cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard return name; 303cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard} 304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 3052098b3d315b612d12b1425639707552e06131cdeJosh Stonestatic const char * 3062098b3d315b612d12b1425639707552e06131cdeJosh Stoneget_diename (Dwarf_Die *die) 3072098b3d315b612d12b1425639707552e06131cdeJosh Stone{ 3082098b3d315b612d12b1425639707552e06131cdeJosh Stone Dwarf_Attribute attr; 3092098b3d315b612d12b1425639707552e06131cdeJosh Stone const char *name; 3102098b3d315b612d12b1425639707552e06131cdeJosh Stone 3112098b3d315b612d12b1425639707552e06131cdeJosh Stone name = dwarf_formstring (dwarf_attr_integrate (die, DW_AT_MIPS_linkage_name, 3122098b3d315b612d12b1425639707552e06131cdeJosh Stone &attr) 3132098b3d315b612d12b1425639707552e06131cdeJosh Stone ?: dwarf_attr_integrate (die, DW_AT_linkage_name, 3142098b3d315b612d12b1425639707552e06131cdeJosh Stone &attr)); 3152098b3d315b612d12b1425639707552e06131cdeJosh Stone 3162098b3d315b612d12b1425639707552e06131cdeJosh Stone if (name == NULL) 3172098b3d315b612d12b1425639707552e06131cdeJosh Stone name = dwarf_diename (die) ?: "??"; 3182098b3d315b612d12b1425639707552e06131cdeJosh Stone 3192098b3d315b612d12b1425639707552e06131cdeJosh Stone return name; 3202098b3d315b612d12b1425639707552e06131cdeJosh Stone} 3212098b3d315b612d12b1425639707552e06131cdeJosh Stone 3221c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrathstatic bool 3231c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrathprint_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr) 324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 3251c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath Dwarf_Addr bias = 0; 3261c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath Dwarf_Die *cudie = dwfl_module_addrdie (mod, addr, &bias); 3271c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath 3281c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath Dwarf_Die *scopes; 3291c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath int nscopes = dwarf_getscopes (cudie, addr - bias, &scopes); 3301c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath if (nscopes <= 0) 3311c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath return false; 3321c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath 3335aa90b90adcce527ea3eb098990c809ab69cbf64Mark Wielaard bool res = false; 3341c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath for (int i = 0; i < nscopes; ++i) 3351c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath switch (dwarf_tag (&scopes[i])) 3361c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath { 3371c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath case DW_TAG_subprogram: 338faf4d19ddeaca1e7fd97b025ccd376eaa3afb30aUlrich Drepper { 3392098b3d315b612d12b1425639707552e06131cdeJosh Stone const char *name = get_diename (&scopes[i]); 3401c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath if (name == NULL) 3415aa90b90adcce527ea3eb098990c809ab69cbf64Mark Wielaard goto done; 342b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard printf ("%s%c", symname (name), pretty ? ' ' : '\n'); 3435aa90b90adcce527ea3eb098990c809ab69cbf64Mark Wielaard res = true; 3445aa90b90adcce527ea3eb098990c809ab69cbf64Mark Wielaard goto done; 345faf4d19ddeaca1e7fd97b025ccd376eaa3afb30aUlrich Drepper } 346ce4550aefd57ab68f6f279a5b662eb1716d7b361Roland McGrath 3471c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath case DW_TAG_inlined_subroutine: 3481c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath { 3492098b3d315b612d12b1425639707552e06131cdeJosh Stone const char *name = get_diename (&scopes[i]); 3501c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath if (name == NULL) 3515aa90b90adcce527ea3eb098990c809ab69cbf64Mark Wielaard goto done; 352b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard 353b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard /* When using --pretty-print we only show inlines on their 354b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard own line. Just print the first subroutine name. */ 355b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard if (pretty) 356b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard { 357b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard printf ("%s ", symname (name)); 3585aa90b90adcce527ea3eb098990c809ab69cbf64Mark Wielaard res = true; 3595aa90b90adcce527ea3eb098990c809ab69cbf64Mark Wielaard goto done; 360b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard } 361b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard else 362b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard printf ("%s inlined", symname (name)); 3631c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath 3641c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath Dwarf_Files *files; 3651c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath if (dwarf_getsrcfiles (cudie, &files, NULL) == 0) 3661c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath { 3671c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath Dwarf_Attribute attr_mem; 3681c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath Dwarf_Word val; 3691c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath if (dwarf_formudata (dwarf_attr (&scopes[i], 3701c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath DW_AT_call_file, 3711c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath &attr_mem), &val) == 0) 3721c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath { 3731c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath const char *file = dwarf_filesrc (files, val, NULL, NULL); 374697f4db2f34c054a2f93b45dbdbbaec82e34a409Ulrich Drepper unsigned int lineno = 0; 375697f4db2f34c054a2f93b45dbdbbaec82e34a409Ulrich Drepper unsigned int colno = 0; 3761c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath if (dwarf_formudata (dwarf_attr (&scopes[i], 3771c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath DW_AT_call_line, 3781c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath &attr_mem), &val) == 0) 3791c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath lineno = val; 3801c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath if (dwarf_formudata (dwarf_attr (&scopes[i], 3811c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath DW_AT_call_column, 3821c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath &attr_mem), &val) == 0) 3831c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath colno = val; 3848a59241b0cee642d16398d19adeab75f25768acaRoland McGrath 3858a59241b0cee642d16398d19adeab75f25768acaRoland McGrath const char *comp_dir = ""; 3868a59241b0cee642d16398d19adeab75f25768acaRoland McGrath const char *comp_dir_sep = ""; 3878a59241b0cee642d16398d19adeab75f25768acaRoland McGrath 3888a59241b0cee642d16398d19adeab75f25768acaRoland McGrath if (file == NULL) 3898a59241b0cee642d16398d19adeab75f25768acaRoland McGrath file = "???"; 3908a59241b0cee642d16398d19adeab75f25768acaRoland McGrath else if (only_basenames) 3918a59241b0cee642d16398d19adeab75f25768acaRoland McGrath file = basename (file); 3928a59241b0cee642d16398d19adeab75f25768acaRoland McGrath else if (use_comp_dir && file[0] != '/') 3931c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath { 3948a59241b0cee642d16398d19adeab75f25768acaRoland McGrath const char *const *dirs; 3958a59241b0cee642d16398d19adeab75f25768acaRoland McGrath size_t ndirs; 3968a59241b0cee642d16398d19adeab75f25768acaRoland McGrath if (dwarf_getsrcdirs (files, &dirs, &ndirs) == 0 3978a59241b0cee642d16398d19adeab75f25768acaRoland McGrath && dirs[0] != NULL) 3988a59241b0cee642d16398d19adeab75f25768acaRoland McGrath { 3998a59241b0cee642d16398d19adeab75f25768acaRoland McGrath comp_dir = dirs[0]; 4008a59241b0cee642d16398d19adeab75f25768acaRoland McGrath comp_dir_sep = "/"; 4018a59241b0cee642d16398d19adeab75f25768acaRoland McGrath } 4021c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath } 4038a59241b0cee642d16398d19adeab75f25768acaRoland McGrath 4048a59241b0cee642d16398d19adeab75f25768acaRoland McGrath if (lineno == 0) 4058a59241b0cee642d16398d19adeab75f25768acaRoland McGrath printf (" from %s%s%s", 4068a59241b0cee642d16398d19adeab75f25768acaRoland McGrath comp_dir, comp_dir_sep, file); 4071c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath else if (colno == 0) 4088a59241b0cee642d16398d19adeab75f25768acaRoland McGrath printf (" at %s%s%s:%u", 4098a59241b0cee642d16398d19adeab75f25768acaRoland McGrath comp_dir, comp_dir_sep, file, lineno); 4101c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath else 4118a59241b0cee642d16398d19adeab75f25768acaRoland McGrath printf (" at %s%s%s:%u:%u", 4128a59241b0cee642d16398d19adeab75f25768acaRoland McGrath comp_dir, comp_dir_sep, file, lineno, colno); 4131c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath } 4141c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath } 4151c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath printf (" in "); 4161c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath continue; 4171c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath } 4181c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath } 419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 4205aa90b90adcce527ea3eb098990c809ab69cbf64Mark Wielaarddone: 4215aa90b90adcce527ea3eb098990c809ab69cbf64Mark Wielaard free (scopes); 4225aa90b90adcce527ea3eb098990c809ab69cbf64Mark Wielaard return res; 423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void 42660fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrathprint_addrsym (Dwfl_Module *mod, GElf_Addr addr) 42760fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath{ 42860fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath GElf_Sym s; 429159ac52b061c60947a943c102298cd692223274fMark Wielaard GElf_Off off; 430159ac52b061c60947a943c102298cd692223274fMark Wielaard const char *name = dwfl_module_addrinfo (mod, addr, &off, &s, 431159ac52b061c60947a943c102298cd692223274fMark Wielaard NULL, NULL, NULL); 43260fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath if (name == NULL) 43360fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath { 43460fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath /* No symbol name. Get a section name instead. */ 43560fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath int i = dwfl_module_relocate_address (mod, &addr); 43660fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath if (i >= 0) 43760fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath name = dwfl_module_relocation_info (mod, i, NULL); 43860fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath if (name == NULL) 439b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard printf ("??%c", pretty ? ' ': '\n'); 44060fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath else 441b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard printf ("(%s)+%#" PRIx64 "%c", name, addr, pretty ? ' ' : '\n'); 44260fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath } 44360fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath else 444159ac52b061c60947a943c102298cd692223274fMark Wielaard { 445cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard name = symname (name); 446159ac52b061c60947a943c102298cd692223274fMark Wielaard if (off == 0) 447159ac52b061c60947a943c102298cd692223274fMark Wielaard printf ("%s", name); 448159ac52b061c60947a943c102298cd692223274fMark Wielaard else 449159ac52b061c60947a943c102298cd692223274fMark Wielaard printf ("%s+%#" PRIx64 "", name, off); 450159ac52b061c60947a943c102298cd692223274fMark Wielaard 451159ac52b061c60947a943c102298cd692223274fMark Wielaard // Also show section name for address. 452159ac52b061c60947a943c102298cd692223274fMark Wielaard if (show_symbol_sections) 453159ac52b061c60947a943c102298cd692223274fMark Wielaard { 454159ac52b061c60947a943c102298cd692223274fMark Wielaard Dwarf_Addr ebias; 455159ac52b061c60947a943c102298cd692223274fMark Wielaard Elf_Scn *scn = dwfl_module_address_section (mod, &addr, &ebias); 456159ac52b061c60947a943c102298cd692223274fMark Wielaard if (scn != NULL) 457159ac52b061c60947a943c102298cd692223274fMark Wielaard { 458159ac52b061c60947a943c102298cd692223274fMark Wielaard GElf_Shdr shdr_mem; 459159ac52b061c60947a943c102298cd692223274fMark Wielaard GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 460159ac52b061c60947a943c102298cd692223274fMark Wielaard if (shdr != NULL) 461159ac52b061c60947a943c102298cd692223274fMark Wielaard { 462159ac52b061c60947a943c102298cd692223274fMark Wielaard Elf *elf = dwfl_module_getelf (mod, &ebias); 463159ac52b061c60947a943c102298cd692223274fMark Wielaard GElf_Ehdr ehdr; 464159ac52b061c60947a943c102298cd692223274fMark Wielaard if (gelf_getehdr (elf, &ehdr) != NULL) 465159ac52b061c60947a943c102298cd692223274fMark Wielaard printf (" (%s)", elf_strptr (elf, ehdr.e_shstrndx, 466159ac52b061c60947a943c102298cd692223274fMark Wielaard shdr->sh_name)); 467159ac52b061c60947a943c102298cd692223274fMark Wielaard } 468159ac52b061c60947a943c102298cd692223274fMark Wielaard } 469159ac52b061c60947a943c102298cd692223274fMark Wielaard } 470b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard printf ("%c", pretty ? ' ' : '\n'); 471159ac52b061c60947a943c102298cd692223274fMark Wielaard } 47260fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath} 47360fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath 4741d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrathstatic int 4751d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrathsee_one_module (Dwfl_Module *mod, 4761d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath void **userdata __attribute__ ((unused)), 4771d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath const char *name __attribute__ ((unused)), 4781d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath Dwarf_Addr start __attribute__ ((unused)), 4791d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath void *arg) 4801d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath{ 4811d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath Dwfl_Module **result = arg; 4821d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath if (*result != NULL) 4831d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath return DWARF_CB_ABORT; 4841d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath *result = mod; 4851d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath return DWARF_CB_OK; 4861d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath} 4871d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath 4881d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrathstatic int 4891d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrathfind_symbol (Dwfl_Module *mod, 4901d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath void **userdata __attribute__ ((unused)), 4911d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath const char *name __attribute__ ((unused)), 4921d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath Dwarf_Addr start __attribute__ ((unused)), 4931d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath void *arg) 4941d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath{ 4951d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath const char *looking_for = ((void **) arg)[0]; 4961d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath GElf_Sym *symbol = ((void **) arg)[1]; 497159ac52b061c60947a943c102298cd692223274fMark Wielaard GElf_Addr *value = ((void **) arg)[2]; 4981d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath 4991d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath int n = dwfl_module_getsymtab (mod); 5001d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath for (int i = 1; i < n; ++i) 5011d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath { 502159ac52b061c60947a943c102298cd692223274fMark Wielaard const char *symbol_name = dwfl_module_getsym_info (mod, i, symbol, 503159ac52b061c60947a943c102298cd692223274fMark Wielaard value, NULL, NULL, 504159ac52b061c60947a943c102298cd692223274fMark Wielaard NULL); 50512e3d1f733cdb590a379a761ee092487931b8109Roland McGrath if (symbol_name == NULL || symbol_name[0] == '\0') 5061d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath continue; 5071d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath switch (GELF_ST_TYPE (symbol->st_info)) 5081d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath { 5091d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath case STT_SECTION: 5101d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath case STT_FILE: 5111d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath case STT_TLS: 5121d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath break; 5131d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath default: 5141d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath if (!strcmp (symbol_name, looking_for)) 5151d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath { 5161d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath ((void **) arg)[0] = NULL; 5171d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath return DWARF_CB_ABORT; 5181d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath } 5191d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath } 5201d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath } 5211d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath 5221d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath return DWARF_CB_OK; 5231d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath} 5241d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath 525d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrathstatic bool 526d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrathadjust_to_section (const char *name, uintmax_t *addr, Dwfl *dwfl) 527d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath{ 528d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath /* It was (section)+offset. This makes sense if there is 529d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath only one module to look in for a section. */ 530d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath Dwfl_Module *mod = NULL; 531d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath if (dwfl_getmodules (dwfl, &see_one_module, &mod, 0) != 0 532d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath || mod == NULL) 533d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath error (EXIT_FAILURE, 0, gettext ("Section syntax requires" 534d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath " exactly one module")); 535d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath 536d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath int nscn = dwfl_module_relocations (mod); 537d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath for (int i = 0; i < nscn; ++i) 538d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath { 539d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath GElf_Word shndx; 540d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath const char *scn = dwfl_module_relocation_info (mod, i, &shndx); 541d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath if (unlikely (scn == NULL)) 542d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath break; 543d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath if (!strcmp (scn, name)) 544d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath { 545d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath /* Found the section. */ 546d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath GElf_Shdr shdr_mem; 547d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath GElf_Addr shdr_bias; 548d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath GElf_Shdr *shdr = gelf_getshdr 549d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath (elf_getscn (dwfl_module_getelf (mod, &shdr_bias), shndx), 550d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath &shdr_mem); 551d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath if (unlikely (shdr == NULL)) 552d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath break; 553d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath 554d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath if (*addr >= shdr->sh_size) 555d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath error (0, 0, 556d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath gettext ("offset %#" PRIxMAX " lies outside" 557d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath " section '%s'"), 558d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath *addr, scn); 559d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath 560d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath *addr += shdr->sh_addr + shdr_bias; 561d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath return true; 562d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath } 563d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath } 564d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath 565d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath return false; 566d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath} 567d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath 5684b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaardstatic void 5694b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaardprint_src (const char *src, int lineno, int linecol, Dwarf_Die *cu) 5704b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard{ 5714b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard const char *comp_dir = ""; 5724b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard const char *comp_dir_sep = ""; 5734b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard 5744b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard if (only_basenames) 5754b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard src = basename (src); 5764b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard else if (use_comp_dir && src[0] != '/') 5774b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard { 5784b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard Dwarf_Attribute attr; 5794b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard comp_dir = dwarf_formstring (dwarf_attr (cu, DW_AT_comp_dir, &attr)); 5804b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard if (comp_dir != NULL) 5814b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard comp_dir_sep = "/"; 5824b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard } 5834b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard 5844b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard if (linecol != 0) 5854b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard printf ("%s%s%s:%d:%d", 5864b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard comp_dir, comp_dir_sep, src, lineno, linecol); 5874b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard else 5884b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard printf ("%s%s%s:%d", 5894b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard comp_dir, comp_dir_sep, src, lineno); 5904b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard} 5914b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard 5921d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrathstatic int 59370a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaardget_addr_width (Dwfl_Module *mod) 59470a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard{ 59570a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard // Try to find the address width if possible. 59670a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard static int width = 0; 59770a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard if (width == 0 && mod != NULL) 59870a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard { 59970a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard Dwarf_Addr bias; 60070a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard Elf *elf = dwfl_module_getelf (mod, &bias); 60170a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard if (elf != NULL) 60270a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard { 60370a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard GElf_Ehdr ehdr_mem; 60470a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 60570a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard if (ehdr != NULL) 60670a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard width = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16; 60770a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard } 60870a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard } 60970a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard if (width == 0) 61070a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard width = 16; 61170a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard 61270a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard return width; 61370a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard} 61470a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard 61570a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaardstatic int 6161d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrathhandle_address (const char *string, Dwfl *dwfl) 617b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 6181d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath char *endp; 619d76d73f490b1e097e650bb77277ae9ed1efd5b1aMark Wielaard uintmax_t addr = strtoumax (string, &endp, 16); 620d76d73f490b1e097e650bb77277ae9ed1efd5b1aMark Wielaard if (endp == string || *endp != '\0') 6211d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath { 6221d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath bool parsed = false; 62312e3d1f733cdb590a379a761ee092487931b8109Roland McGrath int i, j; 6241d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath char *name = NULL; 62512e3d1f733cdb590a379a761ee092487931b8109Roland McGrath if (sscanf (string, "(%m[^)])%" PRIiMAX "%n", &name, &addr, &i) == 2 62612e3d1f733cdb590a379a761ee092487931b8109Roland McGrath && string[i] == '\0') 627d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath parsed = adjust_to_section (name, &addr, dwfl); 62812e3d1f733cdb590a379a761ee092487931b8109Roland McGrath switch (sscanf (string, "%m[^-+]%n%" PRIiMAX "%n", &name, &i, &addr, &j)) 6291d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath { 63012e3d1f733cdb590a379a761ee092487931b8109Roland McGrath default: 63112e3d1f733cdb590a379a761ee092487931b8109Roland McGrath break; 63212e3d1f733cdb590a379a761ee092487931b8109Roland McGrath case 1: 63312e3d1f733cdb590a379a761ee092487931b8109Roland McGrath addr = 0; 63412e3d1f733cdb590a379a761ee092487931b8109Roland McGrath j = i; 63512e3d1f733cdb590a379a761ee092487931b8109Roland McGrath case 2: 63612e3d1f733cdb590a379a761ee092487931b8109Roland McGrath if (string[j] != '\0') 63712e3d1f733cdb590a379a761ee092487931b8109Roland McGrath break; 63812e3d1f733cdb590a379a761ee092487931b8109Roland McGrath 63912e3d1f733cdb590a379a761ee092487931b8109Roland McGrath /* It was symbol[+offset]. */ 6401d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath GElf_Sym sym; 641159ac52b061c60947a943c102298cd692223274fMark Wielaard GElf_Addr value = 0; 642159ac52b061c60947a943c102298cd692223274fMark Wielaard void *arg[3] = { name, &sym, &value }; 6431d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath (void) dwfl_getmodules (dwfl, &find_symbol, arg, 0); 6441d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath if (arg[0] != NULL) 6451d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath error (0, 0, gettext ("cannot find symbol '%s'"), name); 6461d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath else 6471d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath { 6481d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath if (sym.st_size != 0 && addr >= sym.st_size) 6491d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath error (0, 0, 6501d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath gettext ("offset %#" PRIxMAX " lies outside" 6511d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath " contents of '%s'"), 6521d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath addr, name); 653159ac52b061c60947a943c102298cd692223274fMark Wielaard addr += value; 6541d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath parsed = true; 6551d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath } 65612e3d1f733cdb590a379a761ee092487931b8109Roland McGrath break; 6571d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath } 6581d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath 6591d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath free (name); 6601d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath if (!parsed) 6611d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath return 1; 6621d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath } 663d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath else if (just_section != NULL 664d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath && !adjust_to_section (just_section, &addr, dwfl)) 665d86e183403704a287d33c99badcf8bea303c0fd7Roland McGrath return 1; 6661d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath 6671c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath Dwfl_Module *mod = dwfl_addrmodule (dwfl, addr); 668b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 66970a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard if (print_addresses) 67070a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard { 67170a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard int width = get_addr_width (mod); 672b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard printf ("0x%.*" PRIx64 "%s", width, addr, pretty ? ": " : "\n"); 67370a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard } 67470a504d1e19fe14cf34ab3e7a0179aa421f548e0Mark Wielaard 675b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (show_functions) 676b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 677b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* First determine the function name. Use the DWARF information if 678b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper possible. */ 67960fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath if (! print_dwarf_function (mod, addr) && !show_symbols) 680cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard { 681cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard const char *name = dwfl_module_addrname (mod, addr); 682b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard name = name != NULL ? symname (name) : "??"; 683b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard printf ("%s%c", name, pretty ? ' ' : '\n'); 684cd2da6c37b468c7ac66d2edcd83f8bcbaeb793ecMark Wielaard } 685b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 686b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 68760fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath if (show_symbols) 68860fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath print_addrsym (mod, addr); 68960fc84c4288cd6edda3a78dff95e52b5858bacb2Roland McGrath 690b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard if ((show_functions || show_symbols) && pretty) 691b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard printf ("at "); 692b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard 6931c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath Dwfl_Line *line = dwfl_module_getsrc (mod, addr); 694b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 695b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper const char *src; 6961c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath int lineno, linecol; 6974b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard 6981c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath if (line != NULL && (src = dwfl_lineinfo (line, &addr, &lineno, &linecol, 6991c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath NULL, NULL)) != NULL) 700b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper { 7014b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard print_src (src, lineno, linecol, dwfl_linecu (line)); 702de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath if (show_flags) 703de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath { 704de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath Dwarf_Addr bias; 705de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath Dwarf_Line *info = dwfl_dwarf_line (line, &bias); 706de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath assert (info != NULL); 707de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath 708de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath inline void show (int (*get) (Dwarf_Line *, bool *), 709de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath const char *note) 710de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath { 711de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath bool flag; 712de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath if ((*get) (info, &flag) == 0 && flag) 713de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath fputs (note, stdout); 714de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath } 715de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath inline void show_int (int (*get) (Dwarf_Line *, unsigned int *), 716de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath const char *name) 717de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath { 718de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath unsigned int val; 719de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath if ((*get) (info, &val) == 0 && val != 0) 720de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath printf (" (%s %u)", name, val); 721de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath } 722de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath 723de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath show (&dwarf_linebeginstatement, " (is_stmt)"); 724de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath show (&dwarf_lineblock, " (basic_block)"); 725de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath show (&dwarf_lineprologueend, " (prologue_end)"); 726de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath show (&dwarf_lineepiloguebegin, " (epilogue_begin)"); 727de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath show_int (&dwarf_lineisa, "isa"); 728de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath show_int (&dwarf_linediscriminator, "discriminator"); 729de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath } 730de44f133b20ecdd3e8dab9743fe6dce5c69ab85dRoland McGrath putchar ('\n'); 731b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 732b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper else 733b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper puts ("??:0"); 7341d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath 7354b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard if (show_inlines) 7364b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard { 7374b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard Dwarf_Addr bias = 0; 7384b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard Dwarf_Die *cudie = dwfl_module_addrdie (mod, addr, &bias); 7394b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard 740247f85869852e5f0fc461c4c9827d1347e75204aMark Wielaard Dwarf_Die *scopes = NULL; 7414b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard int nscopes = dwarf_getscopes (cudie, addr - bias, &scopes); 7424b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard if (nscopes < 0) 7434b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard return 1; 7444b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard 7454b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard if (nscopes > 0) 7464b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard { 7474b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard Dwarf_Die subroutine; 7484b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard Dwarf_Off dieoff = dwarf_dieoffset (&scopes[0]); 7494b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard dwarf_offdie (dwfl_module_getdwarf (mod, &bias), 7504b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard dieoff, &subroutine); 7514b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard free (scopes); 7526f2e64a03bdf10d5b0ab730e58aedb8dfb76b6d8Mark Wielaard scopes = NULL; 7534b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard 7544b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard nscopes = dwarf_getscopes_die (&subroutine, &scopes); 7554b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard if (nscopes > 1) 7564b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard { 7574b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard Dwarf_Die cu; 7584b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard Dwarf_Files *files; 7594b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard if (dwarf_diecu (&scopes[0], &cu, NULL, NULL) != NULL 7604b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard && dwarf_getsrcfiles (cudie, &files, NULL) == 0) 7614b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard { 7624b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard for (int i = 0; i < nscopes - 1; i++) 7634b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard { 7644b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard Dwarf_Word val; 7654b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard Dwarf_Attribute attr; 7664b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard Dwarf_Die *die = &scopes[i]; 7674b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard if (dwarf_tag (die) != DW_TAG_inlined_subroutine) 7684b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard continue; 7694b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard 770b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard if (pretty) 771b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard printf (" (inlined by) "); 772b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard 7734b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard if (show_functions) 774aecdf2670c027adde8ff800397a48b1b2403dd89Josh Stone { 775aecdf2670c027adde8ff800397a48b1b2403dd89Josh Stone /* Search for the parent inline or function. It 776aecdf2670c027adde8ff800397a48b1b2403dd89Josh Stone might not be directly above this inline -- e.g. 777aecdf2670c027adde8ff800397a48b1b2403dd89Josh Stone there could be a lexical_block in between. */ 778aecdf2670c027adde8ff800397a48b1b2403dd89Josh Stone for (int j = i + 1; j < nscopes; j++) 779aecdf2670c027adde8ff800397a48b1b2403dd89Josh Stone { 780aecdf2670c027adde8ff800397a48b1b2403dd89Josh Stone Dwarf_Die *parent = &scopes[j]; 781aecdf2670c027adde8ff800397a48b1b2403dd89Josh Stone int tag = dwarf_tag (parent); 782aecdf2670c027adde8ff800397a48b1b2403dd89Josh Stone if (tag == DW_TAG_inlined_subroutine 783aecdf2670c027adde8ff800397a48b1b2403dd89Josh Stone || tag == DW_TAG_entry_point 784aecdf2670c027adde8ff800397a48b1b2403dd89Josh Stone || tag == DW_TAG_subprogram) 785aecdf2670c027adde8ff800397a48b1b2403dd89Josh Stone { 786b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard printf ("%s%s", 787b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard symname (get_diename (parent)), 788b23a5b2dda2a0beaaa12c8174808b5d0bd5996eaMark Wielaard pretty ? " at " : "\n"); 789aecdf2670c027adde8ff800397a48b1b2403dd89Josh Stone break; 790aecdf2670c027adde8ff800397a48b1b2403dd89Josh Stone } 791aecdf2670c027adde8ff800397a48b1b2403dd89Josh Stone } 792aecdf2670c027adde8ff800397a48b1b2403dd89Josh Stone } 7934b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard 7944b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard src = NULL; 7954b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard lineno = 0; 7964b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard linecol = 0; 7974b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard if (dwarf_formudata (dwarf_attr (die, DW_AT_call_file, 7984b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard &attr), &val) == 0) 7994b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard src = dwarf_filesrc (files, val, NULL, NULL); 8004b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard 8014b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard if (dwarf_formudata (dwarf_attr (die, DW_AT_call_line, 8024b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard &attr), &val) == 0) 8034b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard lineno = val; 8044b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard 8054b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard if (dwarf_formudata (dwarf_attr (die, DW_AT_call_column, 8064b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard &attr), &val) == 0) 8074b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard linecol = val; 8084b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard 8094b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard if (src != NULL) 8104b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard { 8114b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard print_src (src, lineno, linecol, &cu); 8124b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard putchar ('\n'); 8134b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard } 8144b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard else 8154b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard puts ("??:0"); 8164b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard } 8174b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard } 8184b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard } 8194b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard } 8204b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard free (scopes); 8214b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard } 8224b9e639d314e1ba63dbf661eb1fd7df1a8ee7d4aMark Wielaard 8231d8bb25cac06b5af57f8733e5ea7a068a79edfe0Roland McGrath return 0; 824b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 8253cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper 8263cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper 8273cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper#include "debugpred.h" 828