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