125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Locate source files and line information for given addresses 225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Copyright (C) 2005-2010, 2012 Red Hat, Inc. 325b3c049e70834cf33790a28643ab058b507b35cBen Cheng This file is part of Red Hat elfutils. 425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Written by Ulrich Drepper <drepper@redhat.com>, 2005. 525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Red Hat elfutils is free software; you can redistribute it and/or modify 725b3c049e70834cf33790a28643ab058b507b35cBen Cheng it under the terms of the GNU General Public License as published by the 825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Free Software Foundation; version 2 of the License. 925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Red Hat elfutils is distributed in the hope that it will be useful, but 1125b3c049e70834cf33790a28643ab058b507b35cBen Cheng WITHOUT ANY WARRANTY; without even the implied warranty of 1225b3c049e70834cf33790a28643ab058b507b35cBen Cheng MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1325b3c049e70834cf33790a28643ab058b507b35cBen Cheng General Public License for more details. 1425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1525b3c049e70834cf33790a28643ab058b507b35cBen Cheng You should have received a copy of the GNU General Public License along 1625b3c049e70834cf33790a28643ab058b507b35cBen Cheng with Red Hat elfutils; if not, write to the Free Software Foundation, 1725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. 1825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Red Hat elfutils is an included package of the Open Invention Network. 2025b3c049e70834cf33790a28643ab058b507b35cBen Cheng An included package of the Open Invention Network is a package for which 2125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Open Invention Network licensees cross-license their patents. No patent 2225b3c049e70834cf33790a28643ab058b507b35cBen Cheng license is granted, either expressly or impliedly, by designation as an 2325b3c049e70834cf33790a28643ab058b507b35cBen Cheng included package. Should you wish to participate in the Open Invention 2425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Network licensing program, please visit www.openinventionnetwork.com 2525b3c049e70834cf33790a28643ab058b507b35cBen Cheng <http://www.openinventionnetwork.com>. */ 2625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 2725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifdef HAVE_CONFIG_H 2825b3c049e70834cf33790a28643ab058b507b35cBen Cheng# include <config.h> 2925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 3025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 3125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <argp.h> 3225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <assert.h> 3325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <errno.h> 3425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <error.h> 3525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <fcntl.h> 3625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <inttypes.h> 3725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <libdwfl.h> 3825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <dwarf.h> 3925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <libintl.h> 4025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <locale.h> 4125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <mcheck.h> 4225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdbool.h> 4325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdio.h> 4425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdio_ext.h> 4525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdlib.h> 4625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <string.h> 4725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <unistd.h> 4825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 4925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <system.h> 5025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 5125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 5225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Name and version of program. */ 5325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void print_version (FILE *stream, struct argp_state *state); 5425b3c049e70834cf33790a28643ab058b507b35cBen ChengARGP_PROGRAM_VERSION_HOOK_DEF = print_version; 5525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 5625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Bug report address. */ 5725b3c049e70834cf33790a28643ab058b507b35cBen ChengARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; 5825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 5925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 6025b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Values for the parameters which have no short form. */ 6125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define OPT_DEMANGLER 0x100 6225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 6325b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Definitions of arguments for argp functions. */ 6425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const struct argp_option options[] = 6525b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 6625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { NULL, 0, NULL, 0, N_("Output selection options:"), 2 }, 6725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "basenames", 's', NULL, 0, N_("Show only base names of source files"), 0 }, 6825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "absolute", 'A', NULL, 0, 6925b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("Show absolute file names using compilation directory"), 0 }, 7025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "functions", 'f', NULL, 0, N_("Also show function names"), 0 }, 7125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "symbols", 'S', NULL, 0, N_("Also show symbol or section names"), 0 }, 7225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "flags", 'F', NULL, 0, N_("Also show line table flags"), 0 }, 7325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "section", 'j', "NAME", 0, 7425b3c049e70834cf33790a28643ab058b507b35cBen Cheng N_("Treat addresses as offsets relative to NAME section."), 0 }, 7525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 7625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 }, 7725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Unsupported options. */ 7825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "target", 'b', "ARG", OPTION_HIDDEN, NULL, 0 }, 7925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "demangle", 'C', "ARG", OPTION_HIDDEN | OPTION_ARG_OPTIONAL, NULL, 0 }, 8025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { "demangler", OPT_DEMANGLER, "ARG", OPTION_HIDDEN, NULL, 0 }, 8125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { NULL, 0, NULL, 0, NULL, 0 } 8225b3c049e70834cf33790a28643ab058b507b35cBen Cheng}; 8325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 8425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Short description of program. */ 8525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char doc[] = N_("\ 8625b3c049e70834cf33790a28643ab058b507b35cBen ChengLocate source files and line information for ADDRs (in a.out by default)."); 8725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 8825b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Strings for arguments in help texts. */ 8925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char args_doc[] = N_("[ADDR...]"); 9025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 9125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Prototype for option handler. */ 9225b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic error_t parse_opt (int key, char *arg, struct argp_state *state); 9325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 9425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic struct argp_child argp_children[2]; /* [0] is set in main. */ 9525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 9625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Data structure to communicate with argp functions. */ 9725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const struct argp argp = 9825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 9925b3c049e70834cf33790a28643ab058b507b35cBen Cheng options, parse_opt, args_doc, doc, argp_children, NULL, NULL 10025b3c049e70834cf33790a28643ab058b507b35cBen Cheng}; 10125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 10225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 10325b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Handle ADDR. */ 10425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int handle_address (const char *addr, Dwfl *dwfl); 10525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 10625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 10725b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if only base names of files should be shown. */ 10825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool only_basenames; 10925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 11025b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if absolute file names based on DW_AT_comp_dir should be shown. */ 11125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool use_comp_dir; 11225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 11325b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if line flags should be shown. */ 11425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool show_flags; 11525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 11625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if function names should be shown. */ 11725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool show_functions; 11825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 11925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* True if ELF symbol or section info should be shown. */ 12025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool show_symbols; 12125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 12225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* If non-null, take address parameters as relative to named section. */ 12325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char *just_section; 12425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 12525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 12625b3c049e70834cf33790a28643ab058b507b35cBen Chengint 12725b3c049e70834cf33790a28643ab058b507b35cBen Chengmain (int argc, char *argv[]) 12825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 12925b3c049e70834cf33790a28643ab058b507b35cBen Cheng int remaining; 13025b3c049e70834cf33790a28643ab058b507b35cBen Cheng int result = 0; 13125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 13225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Make memory leak detection possible. */ 13325b3c049e70834cf33790a28643ab058b507b35cBen Cheng mtrace (); 13425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 13525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We use no threads here which can interfere with handling a stream. */ 13625b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER); 13725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 13825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Set locale. */ 13925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) setlocale (LC_ALL, ""); 14025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 14125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Make sure the message catalog can be found. */ 14225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); 14325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 14425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Initialize the message catalog. */ 14525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) textdomain (PACKAGE_TARNAME); 14625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 14725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Parse and process arguments. This includes opening the modules. */ 14825b3c049e70834cf33790a28643ab058b507b35cBen Cheng argp_children[0].argp = dwfl_standard_argp (); 14925b3c049e70834cf33790a28643ab058b507b35cBen Cheng argp_children[0].group = 1; 15025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwfl *dwfl = NULL; 15125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) argp_parse (&argp, argc, argv, 0, &remaining, &dwfl); 15225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (dwfl != NULL); 15325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 15425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Now handle the addresses. In case none are given on the command 15525b3c049e70834cf33790a28643ab058b507b35cBen Cheng line, read from stdin. */ 15625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (remaining == argc) 15725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 15825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We use no threads here which can interfere with handling a stream. */ 15925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER); 16025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 16125b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *buf = NULL; 16225b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t len = 0; 16325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (!feof_unlocked (stdin)) 16425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 16525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (getline (&buf, &len, stdin) < 0) 16625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 16725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 16825b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = handle_address (buf, dwfl); 16925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 17025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 17125b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (buf); 17225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 17325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 17425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 17525b3c049e70834cf33790a28643ab058b507b35cBen Cheng do 17625b3c049e70834cf33790a28643ab058b507b35cBen Cheng result = handle_address (argv[remaining], dwfl); 17725b3c049e70834cf33790a28643ab058b507b35cBen Cheng while (++remaining < argc); 17825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 17925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 18025b3c049e70834cf33790a28643ab058b507b35cBen Cheng return result; 18125b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 18225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 18325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 18425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print the version information. */ 18525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 18625b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) 18725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 18825b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stream, "addr2line (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 18925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stream, gettext ("\ 19025b3c049e70834cf33790a28643ab058b507b35cBen ChengCopyright (C) %s Red Hat, Inc.\n\ 19125b3c049e70834cf33790a28643ab058b507b35cBen ChengThis is free software; see the source for copying conditions. There is NO\n\ 19225b3c049e70834cf33790a28643ab058b507b35cBen Chengwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 19325b3c049e70834cf33790a28643ab058b507b35cBen Cheng"), "2012"); 19425b3c049e70834cf33790a28643ab058b507b35cBen Cheng fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 19525b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 19625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 19725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 19825b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Handle program arguments. */ 19925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic error_t 20025b3c049e70834cf33790a28643ab058b507b35cBen Chengparse_opt (int key, char *arg, struct argp_state *state) 20125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 20225b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (key) 20325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 20425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case ARGP_KEY_INIT: 20525b3c049e70834cf33790a28643ab058b507b35cBen Cheng state->child_inputs[0] = state->input; 20625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 20725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 20825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'b': 20925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'C': 21025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case OPT_DEMANGLER: 21125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Ignored for compatibility. */ 21225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 21325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 21425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 's': 21525b3c049e70834cf33790a28643ab058b507b35cBen Cheng only_basenames = true; 21625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 21725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 21825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'A': 21925b3c049e70834cf33790a28643ab058b507b35cBen Cheng use_comp_dir = true; 22025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 22125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 22225b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'f': 22325b3c049e70834cf33790a28643ab058b507b35cBen Cheng show_functions = true; 22425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 22525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 22625b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'F': 22725b3c049e70834cf33790a28643ab058b507b35cBen Cheng show_flags = true; 22825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 22925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 23025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'S': 23125b3c049e70834cf33790a28643ab058b507b35cBen Cheng show_symbols = true; 23225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 23325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 23425b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 'j': 23525b3c049e70834cf33790a28643ab058b507b35cBen Cheng just_section = arg; 23625b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 23725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 23825b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 23925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return ARGP_ERR_UNKNOWN; 24025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 24125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 24225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 24325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 24425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 24525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool 24625b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr) 24725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 24825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Addr bias = 0; 24925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Die *cudie = dwfl_module_addrdie (mod, addr, &bias); 25025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 25125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Die *scopes; 25225b3c049e70834cf33790a28643ab058b507b35cBen Cheng int nscopes = dwarf_getscopes (cudie, addr - bias, &scopes); 25325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (nscopes <= 0) 25425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return false; 25525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 25625b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (int i = 0; i < nscopes; ++i) 25725b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (dwarf_tag (&scopes[i])) 25825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 25925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_TAG_subprogram: 26025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 26125b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name = dwarf_diename (&scopes[i]); 26225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (name == NULL) 26325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return false; 26425b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (name); 26525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return true; 26625b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 26725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 26825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case DW_TAG_inlined_subroutine: 26925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 27025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name = dwarf_diename (&scopes[i]); 27125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (name == NULL) 27225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return false; 27325b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%s inlined", name); 27425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 27525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Files *files; 27625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dwarf_getsrcfiles (cudie, &files, NULL) == 0) 27725b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 27825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Attribute attr_mem; 27925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Word val; 28025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dwarf_formudata (dwarf_attr (&scopes[i], 28125b3c049e70834cf33790a28643ab058b507b35cBen Cheng DW_AT_call_file, 28225b3c049e70834cf33790a28643ab058b507b35cBen Cheng &attr_mem), &val) == 0) 28325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 28425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *file = dwarf_filesrc (files, val, NULL, NULL); 28525b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int lineno = 0; 28625b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int colno = 0; 28725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dwarf_formudata (dwarf_attr (&scopes[i], 28825b3c049e70834cf33790a28643ab058b507b35cBen Cheng DW_AT_call_line, 28925b3c049e70834cf33790a28643ab058b507b35cBen Cheng &attr_mem), &val) == 0) 29025b3c049e70834cf33790a28643ab058b507b35cBen Cheng lineno = val; 29125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dwarf_formudata (dwarf_attr (&scopes[i], 29225b3c049e70834cf33790a28643ab058b507b35cBen Cheng DW_AT_call_column, 29325b3c049e70834cf33790a28643ab058b507b35cBen Cheng &attr_mem), &val) == 0) 29425b3c049e70834cf33790a28643ab058b507b35cBen Cheng colno = val; 29525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 29625b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *comp_dir = ""; 29725b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *comp_dir_sep = ""; 29825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 29925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (file == NULL) 30025b3c049e70834cf33790a28643ab058b507b35cBen Cheng file = "???"; 30125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (only_basenames) 30225b3c049e70834cf33790a28643ab058b507b35cBen Cheng file = basename (file); 30325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (use_comp_dir && file[0] != '/') 30425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 30525b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *const *dirs; 30625b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t ndirs; 30725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dwarf_getsrcdirs (files, &dirs, &ndirs) == 0 30825b3c049e70834cf33790a28643ab058b507b35cBen Cheng && dirs[0] != NULL) 30925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 31025b3c049e70834cf33790a28643ab058b507b35cBen Cheng comp_dir = dirs[0]; 31125b3c049e70834cf33790a28643ab058b507b35cBen Cheng comp_dir_sep = "/"; 31225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 31325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 31425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 31525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (lineno == 0) 31625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" from %s%s%s", 31725b3c049e70834cf33790a28643ab058b507b35cBen Cheng comp_dir, comp_dir_sep, file); 31825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (colno == 0) 31925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" at %s%s%s:%u", 32025b3c049e70834cf33790a28643ab058b507b35cBen Cheng comp_dir, comp_dir_sep, file, lineno); 32125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 32225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" at %s%s%s:%u:%u", 32325b3c049e70834cf33790a28643ab058b507b35cBen Cheng comp_dir, comp_dir_sep, file, lineno, colno); 32425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 32525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 32625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" in "); 32725b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 32825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 32925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 33025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 33125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return false; 33225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 33325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 33425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void 33525b3c049e70834cf33790a28643ab058b507b35cBen Chengprint_addrsym (Dwfl_Module *mod, GElf_Addr addr) 33625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 33725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Sym s; 33825b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Word shndx; 33925b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name = dwfl_module_addrsym (mod, addr, &s, &shndx); 34025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (name == NULL) 34125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 34225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* No symbol name. Get a section name instead. */ 34325b3c049e70834cf33790a28643ab058b507b35cBen Cheng int i = dwfl_module_relocate_address (mod, &addr); 34425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (i >= 0) 34525b3c049e70834cf33790a28643ab058b507b35cBen Cheng name = dwfl_module_relocation_info (mod, i, NULL); 34625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (name == NULL) 34725b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts ("??"); 34825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 34925b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("(%s)+%#" PRIx64 "\n", name, addr); 35025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 35125b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (addr == s.st_value) 35225b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (name); 35325b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 35425b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%s+%#" PRIx64 "\n", name, addr - s.st_value); 35525b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 35625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 35725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 35825b3c049e70834cf33790a28643ab058b507b35cBen Chengsee_one_module (Dwfl_Module *mod, 35925b3c049e70834cf33790a28643ab058b507b35cBen Cheng void **userdata __attribute__ ((unused)), 36025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name __attribute__ ((unused)), 36125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Addr start __attribute__ ((unused)), 36225b3c049e70834cf33790a28643ab058b507b35cBen Cheng void *arg) 36325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 36425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwfl_Module **result = arg; 36525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (*result != NULL) 36625b3c049e70834cf33790a28643ab058b507b35cBen Cheng return DWARF_CB_ABORT; 36725b3c049e70834cf33790a28643ab058b507b35cBen Cheng *result = mod; 36825b3c049e70834cf33790a28643ab058b507b35cBen Cheng return DWARF_CB_OK; 36925b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 37025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 37125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 37225b3c049e70834cf33790a28643ab058b507b35cBen Chengfind_symbol (Dwfl_Module *mod, 37325b3c049e70834cf33790a28643ab058b507b35cBen Cheng void **userdata __attribute__ ((unused)), 37425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name __attribute__ ((unused)), 37525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Addr start __attribute__ ((unused)), 37625b3c049e70834cf33790a28643ab058b507b35cBen Cheng void *arg) 37725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 37825b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *looking_for = ((void **) arg)[0]; 37925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Sym *symbol = ((void **) arg)[1]; 38025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 38125b3c049e70834cf33790a28643ab058b507b35cBen Cheng int n = dwfl_module_getsymtab (mod); 38225b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (int i = 1; i < n; ++i) 38325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 38425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *symbol_name = dwfl_module_getsym (mod, i, symbol, NULL); 38525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symbol_name == NULL || symbol_name[0] == '\0') 38625b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 38725b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (GELF_ST_TYPE (symbol->st_info)) 38825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 38925b3c049e70834cf33790a28643ab058b507b35cBen Cheng case STT_SECTION: 39025b3c049e70834cf33790a28643ab058b507b35cBen Cheng case STT_FILE: 39125b3c049e70834cf33790a28643ab058b507b35cBen Cheng case STT_TLS: 39225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 39325b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 39425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!strcmp (symbol_name, looking_for)) 39525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 39625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ((void **) arg)[0] = NULL; 39725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return DWARF_CB_ABORT; 39825b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 39925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 40025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 40125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 40225b3c049e70834cf33790a28643ab058b507b35cBen Cheng return DWARF_CB_OK; 40325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 40425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 40525b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool 40625b3c049e70834cf33790a28643ab058b507b35cBen Chengadjust_to_section (const char *name, uintmax_t *addr, Dwfl *dwfl) 40725b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 40825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* It was (section)+offset. This makes sense if there is 40925b3c049e70834cf33790a28643ab058b507b35cBen Cheng only one module to look in for a section. */ 41025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwfl_Module *mod = NULL; 41125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (dwfl_getmodules (dwfl, &see_one_module, &mod, 0) != 0 41225b3c049e70834cf33790a28643ab058b507b35cBen Cheng || mod == NULL) 41325b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("Section syntax requires" 41425b3c049e70834cf33790a28643ab058b507b35cBen Cheng " exactly one module")); 41525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 41625b3c049e70834cf33790a28643ab058b507b35cBen Cheng int nscn = dwfl_module_relocations (mod); 41725b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (int i = 0; i < nscn; ++i) 41825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 41925b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Word shndx; 42025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *scn = dwfl_module_relocation_info (mod, i, &shndx); 42125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (scn == NULL)) 42225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 42325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!strcmp (scn, name)) 42425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 42525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Found the section. */ 42625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 42725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Addr shdr_bias; 42825b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr 42925b3c049e70834cf33790a28643ab058b507b35cBen Cheng (elf_getscn (dwfl_module_getelf (mod, &shdr_bias), shndx), 43025b3c049e70834cf33790a28643ab058b507b35cBen Cheng &shdr_mem); 43125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (unlikely (shdr == NULL)) 43225b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 43325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 43425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (*addr >= shdr->sh_size) 43525b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, 43625b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("offset %#" PRIxMAX " lies outside" 43725b3c049e70834cf33790a28643ab058b507b35cBen Cheng " section '%s'"), 43825b3c049e70834cf33790a28643ab058b507b35cBen Cheng *addr, scn); 43925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 44025b3c049e70834cf33790a28643ab058b507b35cBen Cheng *addr += shdr->sh_addr + shdr_bias; 44125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return true; 44225b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 44325b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 44425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 44525b3c049e70834cf33790a28643ab058b507b35cBen Cheng return false; 44625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 44725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 44825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int 44925b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_address (const char *string, Dwfl *dwfl) 45025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 45125b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *endp; 45225b3c049e70834cf33790a28643ab058b507b35cBen Cheng uintmax_t addr = strtoumax (string, &endp, 0); 45325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (endp == string) 45425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 45525b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool parsed = false; 45625b3c049e70834cf33790a28643ab058b507b35cBen Cheng int i, j; 45725b3c049e70834cf33790a28643ab058b507b35cBen Cheng char *name = NULL; 45825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sscanf (string, "(%m[^)])%" PRIiMAX "%n", &name, &addr, &i) == 2 45925b3c049e70834cf33790a28643ab058b507b35cBen Cheng && string[i] == '\0') 46025b3c049e70834cf33790a28643ab058b507b35cBen Cheng parsed = adjust_to_section (name, &addr, dwfl); 46125b3c049e70834cf33790a28643ab058b507b35cBen Cheng switch (sscanf (string, "%m[^-+]%n%" PRIiMAX "%n", &name, &i, &addr, &j)) 46225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 46325b3c049e70834cf33790a28643ab058b507b35cBen Cheng default: 46425b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 46525b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 1: 46625b3c049e70834cf33790a28643ab058b507b35cBen Cheng addr = 0; 46725b3c049e70834cf33790a28643ab058b507b35cBen Cheng j = i; 46825b3c049e70834cf33790a28643ab058b507b35cBen Cheng case 2: 46925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (string[j] != '\0') 47025b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 47125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 47225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* It was symbol[+offset]. */ 47325b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Sym sym; 47425b3c049e70834cf33790a28643ab058b507b35cBen Cheng void *arg[2] = { name, &sym }; 47525b3c049e70834cf33790a28643ab058b507b35cBen Cheng (void) dwfl_getmodules (dwfl, &find_symbol, arg, 0); 47625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (arg[0] != NULL) 47725b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, gettext ("cannot find symbol '%s'"), name); 47825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 47925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 48025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym.st_size != 0 && addr >= sym.st_size) 48125b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (0, 0, 48225b3c049e70834cf33790a28643ab058b507b35cBen Cheng gettext ("offset %#" PRIxMAX " lies outside" 48325b3c049e70834cf33790a28643ab058b507b35cBen Cheng " contents of '%s'"), 48425b3c049e70834cf33790a28643ab058b507b35cBen Cheng addr, name); 48525b3c049e70834cf33790a28643ab058b507b35cBen Cheng addr += sym.st_value; 48625b3c049e70834cf33790a28643ab058b507b35cBen Cheng parsed = true; 48725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 48825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 48925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 49025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 49125b3c049e70834cf33790a28643ab058b507b35cBen Cheng free (name); 49225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (!parsed) 49325b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 49425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 49525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (just_section != NULL 49625b3c049e70834cf33790a28643ab058b507b35cBen Cheng && !adjust_to_section (just_section, &addr, dwfl)) 49725b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 1; 49825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 49925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwfl_Module *mod = dwfl_addrmodule (dwfl, addr); 50025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 50125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (show_functions) 50225b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 50325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* First determine the function name. Use the DWARF information if 50425b3c049e70834cf33790a28643ab058b507b35cBen Cheng possible. */ 50525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (! print_dwarf_function (mod, addr) && !show_symbols) 50625b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts (dwfl_module_addrname (mod, addr) ?: "??"); 50725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 50825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 50925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (show_symbols) 51025b3c049e70834cf33790a28643ab058b507b35cBen Cheng print_addrsym (mod, addr); 51125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 51225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwfl_Line *line = dwfl_module_getsrc (mod, addr); 51325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 51425b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *src; 51525b3c049e70834cf33790a28643ab058b507b35cBen Cheng int lineno, linecol; 51625b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (line != NULL && (src = dwfl_lineinfo (line, &addr, &lineno, &linecol, 51725b3c049e70834cf33790a28643ab058b507b35cBen Cheng NULL, NULL)) != NULL) 51825b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 51925b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *comp_dir = ""; 52025b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *comp_dir_sep = ""; 52125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 52225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (only_basenames) 52325b3c049e70834cf33790a28643ab058b507b35cBen Cheng src = basename (src); 52425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (use_comp_dir && src[0] != '/') 52525b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 52625b3c049e70834cf33790a28643ab058b507b35cBen Cheng comp_dir = dwfl_line_comp_dir (line); 52725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (comp_dir != NULL) 52825b3c049e70834cf33790a28643ab058b507b35cBen Cheng comp_dir_sep = "/"; 52925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 53025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 53125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (linecol != 0) 53225b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%s%s%s:%d:%d", 53325b3c049e70834cf33790a28643ab058b507b35cBen Cheng comp_dir, comp_dir_sep, src, lineno, linecol); 53425b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 53525b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf ("%s%s%s:%d", 53625b3c049e70834cf33790a28643ab058b507b35cBen Cheng comp_dir, comp_dir_sep, src, lineno); 53725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 53825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (show_flags) 53925b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 54025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Addr bias; 54125b3c049e70834cf33790a28643ab058b507b35cBen Cheng Dwarf_Line *info = dwfl_dwarf_line (line, &bias); 54225b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (info != NULL); 54325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 54425b3c049e70834cf33790a28643ab058b507b35cBen Cheng inline void show (int (*get) (Dwarf_Line *, bool *), 54525b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *note) 54625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 54725b3c049e70834cf33790a28643ab058b507b35cBen Cheng bool flag; 54825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((*get) (info, &flag) == 0 && flag) 54925b3c049e70834cf33790a28643ab058b507b35cBen Cheng fputs (note, stdout); 55025b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 55125b3c049e70834cf33790a28643ab058b507b35cBen Cheng inline void show_int (int (*get) (Dwarf_Line *, unsigned int *), 55225b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *name) 55325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 55425b3c049e70834cf33790a28643ab058b507b35cBen Cheng unsigned int val; 55525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((*get) (info, &val) == 0 && val != 0) 55625b3c049e70834cf33790a28643ab058b507b35cBen Cheng printf (" (%s %u)", name, val); 55725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 55825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 55925b3c049e70834cf33790a28643ab058b507b35cBen Cheng show (&dwarf_linebeginstatement, " (is_stmt)"); 56025b3c049e70834cf33790a28643ab058b507b35cBen Cheng show (&dwarf_lineblock, " (basic_block)"); 56125b3c049e70834cf33790a28643ab058b507b35cBen Cheng show (&dwarf_lineprologueend, " (prologue_end)"); 56225b3c049e70834cf33790a28643ab058b507b35cBen Cheng show (&dwarf_lineepiloguebegin, " (epilogue_begin)"); 56325b3c049e70834cf33790a28643ab058b507b35cBen Cheng show_int (&dwarf_lineisa, "isa"); 56425b3c049e70834cf33790a28643ab058b507b35cBen Cheng show_int (&dwarf_linediscriminator, "discriminator"); 56525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 56625b3c049e70834cf33790a28643ab058b507b35cBen Cheng putchar ('\n'); 56725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 56825b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 56925b3c049e70834cf33790a28643ab058b507b35cBen Cheng puts ("??:0"); 57025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 57125b3c049e70834cf33790a28643ab058b507b35cBen Cheng return 0; 57225b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 57325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 57425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 57525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "debugpred.h" 576