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