125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print information from ELF file in human-readable form.
225b3c049e70834cf33790a28643ab058b507b35cBen Cheng   Copyright (C) 2005, 2006, 2007, 2009, 2011, 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 <error.h>
3325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <fcntl.h>
3425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <inttypes.h>
3525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <libintl.h>
3625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <locale.h>
3725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <mcheck.h>
3825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdbool.h>
3925b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdio.h>
4025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdio_ext.h>
4125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdlib.h>
4225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <string.h>
4325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <unistd.h>
4425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <sys/param.h>
4525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
4625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <system.h>
4725b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "../libebl/libeblP.h"
4825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
4925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
5025b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Name and version of program.  */
5125b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void print_version (FILE *stream, struct argp_state *state);
5225b3c049e70834cf33790a28643ab058b507b35cBen ChengARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
5325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
5425b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Bug report address.  */
5525b3c049e70834cf33790a28643ab058b507b35cBen ChengARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
5625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
5725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
5825b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Definitions of arguments for argp functions.  */
5925b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const struct argp_option options[] =
6025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
6125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  { NULL, 0, NULL, 0, N_("Mode selection:"), 0 },
6225b3c049e70834cf33790a28643ab058b507b35cBen Cheng  { "reloc", 'r', NULL, 0, N_("Display relocation information."), 0 },
6325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  { "full-contents", 's', NULL, 0,
6425b3c049e70834cf33790a28643ab058b507b35cBen Cheng    N_("Display the full contents of all sections requested"), 0 },
6525b3c049e70834cf33790a28643ab058b507b35cBen Cheng  { "disassemble", 'd', NULL, 0,
6625b3c049e70834cf33790a28643ab058b507b35cBen Cheng    N_("Display assembler code of executable sections"), 0 },
6725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
6825b3c049e70834cf33790a28643ab058b507b35cBen Cheng  { NULL, 0, NULL, 0, N_("Output content selection:"), 0 },
6925b3c049e70834cf33790a28643ab058b507b35cBen Cheng  { "section", 'j', "NAME", 0,
7025b3c049e70834cf33790a28643ab058b507b35cBen Cheng    N_("Only display information for section NAME."), 0 },
7125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
7225b3c049e70834cf33790a28643ab058b507b35cBen Cheng  { NULL, 0, NULL, 0, NULL, 0 }
7325b3c049e70834cf33790a28643ab058b507b35cBen Cheng};
7425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
7525b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Short description of program.  */
7625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char doc[] = N_("\
7725b3c049e70834cf33790a28643ab058b507b35cBen ChengShow information from FILEs (a.out by default).");
7825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
7925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Strings for arguments in help texts.  */
8025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const char args_doc[] = N_("[FILE...]");
8125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
8225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Prototype for option handler.  */
8325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic error_t parse_opt (int key, char *arg, struct argp_state *state);
8425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
8525b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Parser children.  */
8625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic struct argp_child argp_children[] =
8725b3c049e70834cf33790a28643ab058b507b35cBen Cheng  {
8825b3c049e70834cf33790a28643ab058b507b35cBen Cheng    { &color_argp, 0, N_("Output formatting"), 2 },
8925b3c049e70834cf33790a28643ab058b507b35cBen Cheng    { NULL, 0, NULL, 0}
9025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  };
9125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
9225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Data structure to communicate with argp functions.  */
9325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic const struct argp argp =
9425b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
9525b3c049e70834cf33790a28643ab058b507b35cBen Cheng  options, parse_opt, args_doc, doc, argp_children, NULL, NULL
9625b3c049e70834cf33790a28643ab058b507b35cBen Cheng};
9725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
9825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
9925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Print symbols in file named FNAME.  */
10025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int process_file (const char *fname, bool more_than_one);
10125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
10225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Handle content of archive.  */
10325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
10425b3c049e70834cf33790a28643ab058b507b35cBen Cheng		      const char *suffix);
10525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
10625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Handle ELF file.  */
10725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int handle_elf (Elf *elf, const char *prefix, const char *fname,
10825b3c049e70834cf33790a28643ab058b507b35cBen Cheng		       const char *suffix);
10925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
11025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
11125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define INTERNAL_ERROR(fname) \
11225b3c049e70834cf33790a28643ab058b507b35cBen Cheng  error (EXIT_FAILURE, 0, gettext ("%s: INTERNAL ERROR %d (%s-%s): %s"),      \
11325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	 fname, __LINE__, PACKAGE_VERSION, __DATE__, elf_errmsg (-1))
11425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
11525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
11625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* List of sections which should be used.  */
11725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic struct section_list
11825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
11925b3c049e70834cf33790a28643ab058b507b35cBen Cheng  bool is_name;
12025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  union
12125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  {
12225b3c049e70834cf33790a28643ab058b507b35cBen Cheng    const char *name;
12325b3c049e70834cf33790a28643ab058b507b35cBen Cheng    uint32_t scnndx;
12425b3c049e70834cf33790a28643ab058b507b35cBen Cheng  };
12525b3c049e70834cf33790a28643ab058b507b35cBen Cheng  struct section_list *next;
12625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} *section_list;
12725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
12825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
12925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* If true print archive index.  */
13025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_relocs;
13125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
13225b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* If true print full contents of requested sections.  */
13325b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_full_content;
13425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
13525b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* If true print disassembled output..  */
13625b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool print_disasm;
13725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
13825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
13925b3c049e70834cf33790a28643ab058b507b35cBen Chengint
14025b3c049e70834cf33790a28643ab058b507b35cBen Chengmain (int argc, char *argv[])
14125b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
14225b3c049e70834cf33790a28643ab058b507b35cBen Cheng  /* Make memory leak detection possible.  */
14325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  mtrace ();
14425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
14525b3c049e70834cf33790a28643ab058b507b35cBen Cheng  /* We use no threads here which can interfere with handling a stream.  */
14625b3c049e70834cf33790a28643ab058b507b35cBen Cheng  (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER);
14725b3c049e70834cf33790a28643ab058b507b35cBen Cheng  (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
14825b3c049e70834cf33790a28643ab058b507b35cBen Cheng  (void) __fsetlocking (stderr, FSETLOCKING_BYCALLER);
14925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
15025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  /* Set locale.  */
15125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  (void) setlocale (LC_ALL, "");
15225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
15325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  /* Make sure the message catalog can be found.  */
15425b3c049e70834cf33790a28643ab058b507b35cBen Cheng  (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
15525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
15625b3c049e70834cf33790a28643ab058b507b35cBen Cheng  /* Initialize the message catalog.  */
15725b3c049e70834cf33790a28643ab058b507b35cBen Cheng  (void) textdomain (PACKAGE_TARNAME);
15825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
15925b3c049e70834cf33790a28643ab058b507b35cBen Cheng  /* Parse and process arguments.  */
16025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  int remaining;
16125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL);
16225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
16325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  /* Tell the library which version we are expecting.  */
16425b3c049e70834cf33790a28643ab058b507b35cBen Cheng  (void) elf_version (EV_CURRENT);
16525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
16625b3c049e70834cf33790a28643ab058b507b35cBen Cheng  int result = 0;
16725b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (remaining == argc)
16825b3c049e70834cf33790a28643ab058b507b35cBen Cheng    /* The user didn't specify a name so we use a.out.  */
16925b3c049e70834cf33790a28643ab058b507b35cBen Cheng    result = process_file ("a.out", false);
17025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  else
17125b3c049e70834cf33790a28643ab058b507b35cBen Cheng    {
17225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      /* Process all the remaining files.  */
17325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      const bool more_than_one = remaining + 1 < argc;
17425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
17525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      do
17625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	result |= process_file (argv[remaining], more_than_one);
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, "objdump (%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,
20125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	   struct argp_state *state __attribute__ ((unused)))
20225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
20325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  /* True if any of the control options is set.  */
20425b3c049e70834cf33790a28643ab058b507b35cBen Cheng  static bool any_control_option;
20525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
20625b3c049e70834cf33790a28643ab058b507b35cBen Cheng  switch (key)
20725b3c049e70834cf33790a28643ab058b507b35cBen Cheng    {
20825b3c049e70834cf33790a28643ab058b507b35cBen Cheng    case 'j':
20925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      {
21025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	struct section_list *newp = xmalloc (sizeof (*newp));
21125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	char *endp;
21225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	newp->scnndx = strtoul (arg, &endp, 0);
21325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	if (*endp == 0)
21425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  newp->is_name = false;
21525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	else
21625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  {
21725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    newp->name = arg;
21825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    newp->is_name = true;
21925b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  }
22025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	newp->next = section_list;
22125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	section_list = newp;
22225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      }
22325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      any_control_option = true;
22425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      break;
22525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
22625b3c049e70834cf33790a28643ab058b507b35cBen Cheng    case 'd':
22725b3c049e70834cf33790a28643ab058b507b35cBen Cheng      print_disasm = true;
22825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      any_control_option = true;
22925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      break;
23025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
23125b3c049e70834cf33790a28643ab058b507b35cBen Cheng    case 'r':
23225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      print_relocs = true;
23325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      any_control_option = true;
23425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      break;
23525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
23625b3c049e70834cf33790a28643ab058b507b35cBen Cheng    case 's':
23725b3c049e70834cf33790a28643ab058b507b35cBen Cheng      print_full_content = true;
23825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      any_control_option = true;
23925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      break;
24025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
24125b3c049e70834cf33790a28643ab058b507b35cBen Cheng    case ARGP_KEY_FINI:
24225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (! any_control_option)
24325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	{
24425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  fputs (gettext ("No operation specified.\n"), stderr);
24525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  argp_help (&argp, stderr, ARGP_HELP_SEE,
24625b3c049e70834cf33790a28643ab058b507b35cBen Cheng		     program_invocation_short_name);
24725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  exit (EXIT_FAILURE);
24825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	}
24925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
25025b3c049e70834cf33790a28643ab058b507b35cBen Cheng    default:
25125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      return ARGP_ERR_UNKNOWN;
25225b3c049e70834cf33790a28643ab058b507b35cBen Cheng    }
25325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  return 0;
25425b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
25525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
25625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
25725b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Open the file and determine the type.  */
25825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int
25925b3c049e70834cf33790a28643ab058b507b35cBen Chengprocess_file (const char *fname, bool more_than_one)
26025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
26125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  /* Open the file.  */
26225b3c049e70834cf33790a28643ab058b507b35cBen Cheng  int fd = open (fname, O_RDONLY);
26325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (fd == -1)
26425b3c049e70834cf33790a28643ab058b507b35cBen Cheng    {
26525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      error (0, errno, gettext ("cannot open %s"), fname);
26625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      return 1;
26725b3c049e70834cf33790a28643ab058b507b35cBen Cheng    }
26825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
26925b3c049e70834cf33790a28643ab058b507b35cBen Cheng  /* Now get the ELF descriptor.  */
27025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
27125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (elf != NULL)
27225b3c049e70834cf33790a28643ab058b507b35cBen Cheng    {
27325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (elf_kind (elf) == ELF_K_ELF)
27425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	{
27525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  int result = handle_elf (elf, more_than_one ? "" : NULL,
27625b3c049e70834cf33790a28643ab058b507b35cBen Cheng				   fname, NULL);
27725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
27825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  if (elf_end (elf) != 0)
27925b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    INTERNAL_ERROR (fname);
28025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
28125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  if (close (fd) != 0)
28225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    error (EXIT_FAILURE, errno, gettext ("while close `%s'"), fname);
28325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
28425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  return result;
28525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	}
28625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      else if (elf_kind (elf) == ELF_K_AR)
28725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	{
28825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  int result = handle_ar (fd, elf, NULL, fname, NULL);
28925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
29025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  if (elf_end (elf) != 0)
29125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    INTERNAL_ERROR (fname);
29225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
29325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  if (close (fd) != 0)
29425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    error (EXIT_FAILURE, errno, gettext ("while close `%s'"), fname);
29525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
29625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  return result;
29725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	}
29825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
29925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      /* We cannot handle this type.  Close the descriptor anyway.  */
30025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (elf_end (elf) != 0)
30125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	INTERNAL_ERROR (fname);
30225b3c049e70834cf33790a28643ab058b507b35cBen Cheng    }
30325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
30425b3c049e70834cf33790a28643ab058b507b35cBen Cheng  error (0, 0, gettext ("%s: File format not recognized"), fname);
30525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
30625b3c049e70834cf33790a28643ab058b507b35cBen Cheng  return 1;
30725b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
30825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
30925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
31025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int
31125b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
31225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	   const char *suffix)
31325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
31425b3c049e70834cf33790a28643ab058b507b35cBen Cheng  size_t fname_len = strlen (fname) + 1;
31525b3c049e70834cf33790a28643ab058b507b35cBen Cheng  size_t prefix_len = prefix != NULL ? strlen (prefix) : 0;
31625b3c049e70834cf33790a28643ab058b507b35cBen Cheng  char new_prefix[prefix_len + fname_len + 2];
31725b3c049e70834cf33790a28643ab058b507b35cBen Cheng  size_t suffix_len = suffix != NULL ? strlen (suffix) : 0;
31825b3c049e70834cf33790a28643ab058b507b35cBen Cheng  char new_suffix[suffix_len + 2];
31925b3c049e70834cf33790a28643ab058b507b35cBen Cheng  Elf *subelf;
32025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  Elf_Cmd cmd = ELF_C_READ_MMAP;
32125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  int result = 0;
32225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
32325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  char *cp = new_prefix;
32425b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (prefix != NULL)
32525b3c049e70834cf33790a28643ab058b507b35cBen Cheng    cp = stpcpy (cp, prefix);
32625b3c049e70834cf33790a28643ab058b507b35cBen Cheng  cp = stpcpy (cp, fname);
32725b3c049e70834cf33790a28643ab058b507b35cBen Cheng  stpcpy (cp, "[");
32825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
32925b3c049e70834cf33790a28643ab058b507b35cBen Cheng  cp = new_suffix;
33025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (suffix != NULL)
33125b3c049e70834cf33790a28643ab058b507b35cBen Cheng    cp = stpcpy (cp, suffix);
33225b3c049e70834cf33790a28643ab058b507b35cBen Cheng  stpcpy (cp, "]");
33325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
33425b3c049e70834cf33790a28643ab058b507b35cBen Cheng  /* Process all the files contained in the archive.  */
33525b3c049e70834cf33790a28643ab058b507b35cBen Cheng  while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
33625b3c049e70834cf33790a28643ab058b507b35cBen Cheng    {
33725b3c049e70834cf33790a28643ab058b507b35cBen Cheng      /* The the header for this element.  */
33825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      Elf_Arhdr *arhdr = elf_getarhdr (subelf);
33925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
34025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      /* Skip over the index entries.  */
34125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (strcmp (arhdr->ar_name, "/") != 0
34225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  && strcmp (arhdr->ar_name, "//") != 0)
34325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	{
34425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  if (elf_kind (subelf) == ELF_K_ELF)
34525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    result |= handle_elf (subelf, new_prefix, arhdr->ar_name,
34625b3c049e70834cf33790a28643ab058b507b35cBen Cheng				  new_suffix);
34725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  else if (elf_kind (subelf) == ELF_K_AR)
34825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name,
34925b3c049e70834cf33790a28643ab058b507b35cBen Cheng				 new_suffix);
35025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  else
35125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    {
35225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      error (0, 0, gettext ("%s%s%s: file format not recognized"),
35325b3c049e70834cf33790a28643ab058b507b35cBen Cheng		     new_prefix, arhdr->ar_name, new_suffix);
35425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      result = 1;
35525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    }
35625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	}
35725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
35825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      /* Get next archive element.  */
35925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      cmd = elf_next (subelf);
36025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (elf_end (subelf) != 0)
36125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	INTERNAL_ERROR (fname);
36225b3c049e70834cf33790a28643ab058b507b35cBen Cheng    }
36325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
36425b3c049e70834cf33790a28643ab058b507b35cBen Cheng  return result;
36525b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
36625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
36725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
36825b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void
36925b3c049e70834cf33790a28643ab058b507b35cBen Chengshow_relocs_x (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *symdata,
37025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	       Elf_Data *xndxdata, size_t symstrndx, size_t shstrndx,
37125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	       GElf_Addr r_offset, GElf_Xword r_info, GElf_Sxword r_addend)
37225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
37325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  int elfclass = gelf_getclass (ebl->elf);
37425b3c049e70834cf33790a28643ab058b507b35cBen Cheng  char buf[128];
37525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
37625b3c049e70834cf33790a28643ab058b507b35cBen Cheng  printf ("%0*" PRIx64 " %-20s ",
37725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  elfclass == ELFCLASS32 ? 8 : 16, r_offset,
37825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  ebl_reloc_type_name (ebl, GELF_R_TYPE (r_info), buf, sizeof (buf)));
37925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
38025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  Elf32_Word xndx;
38125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  GElf_Sym symmem;
38225b3c049e70834cf33790a28643ab058b507b35cBen Cheng  GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, GELF_R_SYM (r_info),
38325b3c049e70834cf33790a28643ab058b507b35cBen Cheng				    &symmem, &xndx);
38425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
38525b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (sym == NULL)
38625b3c049e70834cf33790a28643ab058b507b35cBen Cheng    printf ("<%s %ld>",
38725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    gettext ("INVALID SYMBOL"), (long int) GELF_R_SYM (r_info));
38825b3c049e70834cf33790a28643ab058b507b35cBen Cheng  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
38925b3c049e70834cf33790a28643ab058b507b35cBen Cheng    printf ("%s",
39025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    elf_strptr (ebl->elf, symstrndx, sym->st_name));
39125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  else
39225b3c049e70834cf33790a28643ab058b507b35cBen Cheng    {
39325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      GElf_Shdr destshdr_mem;
39425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      GElf_Shdr *destshdr;
39525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      destshdr = gelf_getshdr (elf_getscn (ebl->elf,
39625b3c049e70834cf33790a28643ab058b507b35cBen Cheng					   sym->st_shndx == SHN_XINDEX
39725b3c049e70834cf33790a28643ab058b507b35cBen Cheng					   ? xndx : sym->st_shndx),
39825b3c049e70834cf33790a28643ab058b507b35cBen Cheng			       &destshdr_mem);
39925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
40025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (shdr == NULL)
40125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	printf ("<%s %ld>",
40225b3c049e70834cf33790a28643ab058b507b35cBen Cheng		gettext ("INVALID SECTION"),
40325b3c049e70834cf33790a28643ab058b507b35cBen Cheng		(long int) (sym->st_shndx == SHN_XINDEX
40425b3c049e70834cf33790a28643ab058b507b35cBen Cheng			    ? xndx : sym->st_shndx));
40525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      else
40625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	printf ("%s",
40725b3c049e70834cf33790a28643ab058b507b35cBen Cheng		elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
40825b3c049e70834cf33790a28643ab058b507b35cBen Cheng    }
40925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
41025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (r_addend != 0)
41125b3c049e70834cf33790a28643ab058b507b35cBen Cheng    {
41225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      char sign = '+';
41325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (r_addend < 0)
41425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	{
41525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  sign = '-';
41625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  r_addend = -r_addend;
41725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	}
41825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      printf ("%c%#" PRIx64, sign, r_addend);
41925b3c049e70834cf33790a28643ab058b507b35cBen Cheng    }
42025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  putchar ('\n');
42125b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
42225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
42325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
42425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void
42525b3c049e70834cf33790a28643ab058b507b35cBen Chengshow_relocs_rel (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data,
42625b3c049e70834cf33790a28643ab058b507b35cBen Cheng		 Elf_Data *symdata, Elf_Data *xndxdata, size_t symstrndx,
42725b3c049e70834cf33790a28643ab058b507b35cBen Cheng		 size_t shstrndx)
42825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
42925b3c049e70834cf33790a28643ab058b507b35cBen Cheng  int nentries = shdr->sh_size / shdr->sh_entsize;
43025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
43125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  for (int cnt = 0; cnt < nentries; ++cnt)
43225b3c049e70834cf33790a28643ab058b507b35cBen Cheng    {
43325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      GElf_Rel relmem;
43425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      GElf_Rel *rel;
43525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
43625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      rel = gelf_getrel (data, cnt, &relmem);
43725b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (rel != NULL)
43825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	show_relocs_x (ebl, shdr, symdata, xndxdata, symstrndx, shstrndx,
43925b3c049e70834cf33790a28643ab058b507b35cBen Cheng		       rel->r_offset, rel->r_info, 0);
44025b3c049e70834cf33790a28643ab058b507b35cBen Cheng    }
44125b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
44225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
44325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
44425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic void
44525b3c049e70834cf33790a28643ab058b507b35cBen Chengshow_relocs_rela (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data,
44625b3c049e70834cf33790a28643ab058b507b35cBen Cheng		  Elf_Data *symdata, Elf_Data *xndxdata, size_t symstrndx,
44725b3c049e70834cf33790a28643ab058b507b35cBen Cheng		  size_t shstrndx)
44825b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
44925b3c049e70834cf33790a28643ab058b507b35cBen Cheng  int nentries = shdr->sh_size / shdr->sh_entsize;
45025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
45125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  for (int cnt = 0; cnt < nentries; ++cnt)
45225b3c049e70834cf33790a28643ab058b507b35cBen Cheng    {
45325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      GElf_Rela relmem;
45425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      GElf_Rela *rel;
45525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
45625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      rel = gelf_getrela (data, cnt, &relmem);
45725b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (rel != NULL)
45825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	show_relocs_x (ebl, shdr, symdata, xndxdata, symstrndx, shstrndx,
45925b3c049e70834cf33790a28643ab058b507b35cBen Cheng		       rel->r_offset, rel->r_info, rel->r_addend);
46025b3c049e70834cf33790a28643ab058b507b35cBen Cheng    }
46125b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
46225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
46325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
46425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic bool
46525b3c049e70834cf33790a28643ab058b507b35cBen Chengsection_match (Elf *elf, uint32_t scnndx, GElf_Shdr *shdr, size_t shstrndx)
46625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
46725b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (section_list == NULL)
46825b3c049e70834cf33790a28643ab058b507b35cBen Cheng    return true;
46925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
47025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  struct section_list *runp = section_list;
47125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
47225b3c049e70834cf33790a28643ab058b507b35cBen Cheng  do
47325b3c049e70834cf33790a28643ab058b507b35cBen Cheng    {
47425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (runp->is_name)
47525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	{
47625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  if (strcmp (runp->name,
47725b3c049e70834cf33790a28643ab058b507b35cBen Cheng		      elf_strptr (elf, shstrndx, shdr->sh_name)) == 0)
47825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    return true;
47925b3c049e70834cf33790a28643ab058b507b35cBen Cheng	}
48025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      else
48125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	{
48225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  if (runp->scnndx == scnndx)
48325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    return true;
48425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	}
48525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
48625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      runp = runp->next;
48725b3c049e70834cf33790a28643ab058b507b35cBen Cheng    }
48825b3c049e70834cf33790a28643ab058b507b35cBen Cheng  while (runp != NULL);
48925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
49025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  return false;
49125b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
49225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
49325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
49425b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int
49525b3c049e70834cf33790a28643ab058b507b35cBen Chengshow_relocs (Ebl *ebl, const char *fname, uint32_t shstrndx)
49625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
49725b3c049e70834cf33790a28643ab058b507b35cBen Cheng  int elfclass = gelf_getclass (ebl->elf);
49825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
49925b3c049e70834cf33790a28643ab058b507b35cBen Cheng  Elf_Scn *scn = NULL;
50025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
50125b3c049e70834cf33790a28643ab058b507b35cBen Cheng    {
50225b3c049e70834cf33790a28643ab058b507b35cBen Cheng      GElf_Shdr shdr_mem;
50325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
50425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
50525b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (shdr == NULL)
50625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	INTERNAL_ERROR (fname);
50725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
50825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
50925b3c049e70834cf33790a28643ab058b507b35cBen Cheng	{
51025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  if  (! section_match (ebl->elf, elf_ndxscn (scn), shdr, shstrndx))
51125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    continue;
51225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
51325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  GElf_Shdr destshdr_mem;
51425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf,
51525b3c049e70834cf33790a28643ab058b507b35cBen Cheng							  shdr->sh_info),
51625b3c049e70834cf33790a28643ab058b507b35cBen Cheng					      &destshdr_mem);
51725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
51825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  printf (gettext ("\nRELOCATION RECORDS FOR [%s]:\n"
51925b3c049e70834cf33790a28643ab058b507b35cBen Cheng			   "%-*s TYPE                 VALUE\n"),
52025b3c049e70834cf33790a28643ab058b507b35cBen Cheng		  elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
52125b3c049e70834cf33790a28643ab058b507b35cBen Cheng		  elfclass == ELFCLASS32 ? 8 : 16, gettext ("OFFSET"));
52225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
52325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  /* Get the data of the section.  */
52425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  Elf_Data *data = elf_getdata (scn, NULL);
52525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  if (data == NULL)
52625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    continue;
52725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
52825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  /* Get the symbol table information.  */
52925b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
53025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  GElf_Shdr symshdr_mem;
53125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
53225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  Elf_Data *symdata = elf_getdata (symscn, NULL);
53325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
53425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  /* Search for the optional extended section index table.  */
53525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  Elf_Data *xndxdata = NULL;
53625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  Elf_Scn *xndxscn = NULL;
53725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  while ((xndxscn = elf_nextscn (ebl->elf, xndxscn)) != NULL)
53825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    {
53925b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      GElf_Shdr xndxshdr_mem;
54025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      GElf_Shdr *xndxshdr;
54125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
54225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem);
54325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      if (xndxshdr != NULL && xndxshdr->sh_type == SHT_SYMTAB_SHNDX
54425b3c049e70834cf33790a28643ab058b507b35cBen Cheng		  && xndxshdr->sh_link == elf_ndxscn (symscn))
54525b3c049e70834cf33790a28643ab058b507b35cBen Cheng		{
54625b3c049e70834cf33790a28643ab058b507b35cBen Cheng		  /* Found it.  */
54725b3c049e70834cf33790a28643ab058b507b35cBen Cheng		  xndxdata = elf_getdata (xndxscn, NULL);
54825b3c049e70834cf33790a28643ab058b507b35cBen Cheng		  break;
54925b3c049e70834cf33790a28643ab058b507b35cBen Cheng		}
55025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    }
55125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
55225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  if (shdr->sh_type == SHT_REL)
55325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    show_relocs_rel (ebl, shdr, data, symdata, xndxdata,
55425b3c049e70834cf33790a28643ab058b507b35cBen Cheng			     symshdr->sh_link, shstrndx);
55525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  else
55625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    show_relocs_rela (ebl, shdr, data, symdata, xndxdata,
55725b3c049e70834cf33790a28643ab058b507b35cBen Cheng			      symshdr->sh_link, shstrndx);
55825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
55925b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  putchar ('\n');
56025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	}
56125b3c049e70834cf33790a28643ab058b507b35cBen Cheng    }
56225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
56325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  return 0;
56425b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
56525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
56625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
56725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int
56825b3c049e70834cf33790a28643ab058b507b35cBen Chengshow_full_content (Ebl *ebl, const char *fname, uint32_t shstrndx)
56925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
57025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  Elf_Scn *scn = NULL;
57125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
57225b3c049e70834cf33790a28643ab058b507b35cBen Cheng    {
57325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      GElf_Shdr shdr_mem;
57425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
57525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
57625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (shdr == NULL)
57725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	INTERNAL_ERROR (fname);
57825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
57925b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (shdr->sh_type == SHT_PROGBITS && shdr->sh_size > 0)
58025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	{
58125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  if  (! section_match (ebl->elf, elf_ndxscn (scn), shdr, shstrndx))
58225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    continue;
58325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
58425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  printf (gettext ("Contents of section %s:\n"),
58525b3c049e70834cf33790a28643ab058b507b35cBen Cheng		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
58625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
58725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  /* Get the data of the section.  */
58825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  Elf_Data *data = elf_getdata (scn, NULL);
58925b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  if (data == NULL)
59025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    continue;
59125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
59225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  unsigned char *cp = data->d_buf;
59325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  size_t cnt;
59425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  for (cnt = 0; cnt + 16 < data->d_size; cp += 16, cnt += 16)
59525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    {
59625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      printf (" %04zx ", cnt);
59725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
59825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      for (size_t inner = 0; inner < 16; inner += 4)
59925b3c049e70834cf33790a28643ab058b507b35cBen Cheng		printf ("%02hhx%02hhx%02hhx%02hhx ",
60025b3c049e70834cf33790a28643ab058b507b35cBen Cheng			cp[inner], cp[inner + 1], cp[inner + 2],
60125b3c049e70834cf33790a28643ab058b507b35cBen Cheng			cp[inner + 3]);
60225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      fputc_unlocked (' ', stdout);
60325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
60425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      for (size_t inner = 0; inner < 16; ++inner)
60525b3c049e70834cf33790a28643ab058b507b35cBen Cheng		fputc_unlocked (isascii (cp[inner]) && isprint (cp[inner])
60625b3c049e70834cf33790a28643ab058b507b35cBen Cheng				? cp[inner] : '.', stdout);
60725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      fputc_unlocked ('\n', stdout);
60825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    }
60925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
61025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  printf (" %04zx ", cnt);
61125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
61225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  size_t remaining = data->d_size - cnt;
61325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  size_t inner;
61425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  for (inner = 0; inner + 4 <= remaining; inner += 4)
61525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    printf ("%02hhx%02hhx%02hhx%02hhx ",
61625b3c049e70834cf33790a28643ab058b507b35cBen Cheng		    cp[inner], cp[inner + 1], cp[inner + 2], cp[inner + 3]);
61725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
61825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  for (; inner < remaining; ++inner)
61925b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    printf ("%02hhx", cp[inner]);
62025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
62125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  for (inner = 2 * (16 - inner) + (16 - inner + 3) / 4 + 1; inner > 0;
62225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	       --inner)
62325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    fputc_unlocked (' ', stdout);
62425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
62525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  for (inner = 0; inner < remaining; ++inner)
62625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    fputc_unlocked (isascii (cp[inner]) && isprint (cp[inner])
62725b3c049e70834cf33790a28643ab058b507b35cBen Cheng			    ? cp[inner] : '.', stdout);
62825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  fputc_unlocked ('\n', stdout);
62925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
63025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  fputc_unlocked ('\n', stdout);
63125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	}
63225b3c049e70834cf33790a28643ab058b507b35cBen Cheng    }
63325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
63425b3c049e70834cf33790a28643ab058b507b35cBen Cheng  return 0;
63525b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
63625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
63725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
63825b3c049e70834cf33790a28643ab058b507b35cBen Chengstruct disasm_info
63925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
64025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  GElf_Addr addr;
64125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  const uint8_t *cur;
64225b3c049e70834cf33790a28643ab058b507b35cBen Cheng  const uint8_t *last_end;
64325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  const char *address_color;
64425b3c049e70834cf33790a28643ab058b507b35cBen Cheng  const char *bytes_color;
64525b3c049e70834cf33790a28643ab058b507b35cBen Cheng};
64625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
64725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
64825b3c049e70834cf33790a28643ab058b507b35cBen Cheng// XXX This is not the preferred output for all architectures.  Needs
64925b3c049e70834cf33790a28643ab058b507b35cBen Cheng// XXX customization, too.
65025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int
65125b3c049e70834cf33790a28643ab058b507b35cBen Chengdisasm_output (char *buf, size_t buflen, void *arg)
65225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
65325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  struct disasm_info *info = (struct disasm_info *) arg;
65425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
65525b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (info->address_color != NULL)
65625b3c049e70834cf33790a28643ab058b507b35cBen Cheng    printf ("%s%8" PRIx64 "%s:   ",
65725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    info->address_color, (uint64_t) info->addr, color_off);
65825b3c049e70834cf33790a28643ab058b507b35cBen Cheng  else
65925b3c049e70834cf33790a28643ab058b507b35cBen Cheng    printf ("%8" PRIx64 ":   ", (uint64_t) info->addr);
66025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
66125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (info->bytes_color != NULL)
66225b3c049e70834cf33790a28643ab058b507b35cBen Cheng    fputs_unlocked (info->bytes_color, stdout);
66325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  size_t cnt;
66425b3c049e70834cf33790a28643ab058b507b35cBen Cheng  for (cnt = 0; cnt < (size_t) MIN (info->cur - info->last_end, 8); ++cnt)
66525b3c049e70834cf33790a28643ab058b507b35cBen Cheng    printf (" %02" PRIx8, info->last_end[cnt]);
66625b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (info->bytes_color != NULL)
66725b3c049e70834cf33790a28643ab058b507b35cBen Cheng    fputs_unlocked (color_off, stdout);
66825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
66925b3c049e70834cf33790a28643ab058b507b35cBen Cheng  printf ("%*s %.*s\n",
67025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  (int) (8 - cnt) * 3 + 1, "", (int) buflen, buf);
67125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
67225b3c049e70834cf33790a28643ab058b507b35cBen Cheng  info->addr += cnt;
67325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
67425b3c049e70834cf33790a28643ab058b507b35cBen Cheng  /* We limit the number of bytes printed before the mnemonic to 8.
67525b3c049e70834cf33790a28643ab058b507b35cBen Cheng     Print the rest on a separate, following line.  */
67625b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (info->cur - info->last_end > 8)
67725b3c049e70834cf33790a28643ab058b507b35cBen Cheng    {
67825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (info->address_color != NULL)
67925b3c049e70834cf33790a28643ab058b507b35cBen Cheng	printf ("%s%8" PRIx64 "%s:   ",
68025b3c049e70834cf33790a28643ab058b507b35cBen Cheng		info->address_color, (uint64_t) info->addr, color_off);
68125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      else
68225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	printf ("%8" PRIx64 ":   ", (uint64_t) info->addr);
68325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
68425b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (info->bytes_color != NULL)
68525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	fputs_unlocked (info->bytes_color, stdout);
68625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      for (; cnt < (size_t) (info->cur - info->last_end); ++cnt)
68725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	printf (" %02" PRIx8, info->last_end[cnt]);
68825b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (info->bytes_color != NULL)
68925b3c049e70834cf33790a28643ab058b507b35cBen Cheng	fputs_unlocked (color_off, stdout);
69025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      putchar_unlocked ('\n');
69125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      info->addr += info->cur - info->last_end - 8;
69225b3c049e70834cf33790a28643ab058b507b35cBen Cheng    }
69325b3c049e70834cf33790a28643ab058b507b35cBen Cheng
69425b3c049e70834cf33790a28643ab058b507b35cBen Cheng  info->last_end = info->cur;
69525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
69625b3c049e70834cf33790a28643ab058b507b35cBen Cheng  return 0;
69725b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
69825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
69925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
70025b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int
70125b3c049e70834cf33790a28643ab058b507b35cBen Chengshow_disasm (Ebl *ebl, const char *fname, uint32_t shstrndx)
70225b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
70325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  DisasmCtx_t *ctx = disasm_begin (ebl, ebl->elf, NULL /* XXX TODO */);
70425b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (ctx == NULL)
70525b3c049e70834cf33790a28643ab058b507b35cBen Cheng    error (EXIT_FAILURE, 0, gettext ("cannot disassemble"));
70625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
70725b3c049e70834cf33790a28643ab058b507b35cBen Cheng  Elf_Scn *scn = NULL;
70825b3c049e70834cf33790a28643ab058b507b35cBen Cheng  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
70925b3c049e70834cf33790a28643ab058b507b35cBen Cheng    {
71025b3c049e70834cf33790a28643ab058b507b35cBen Cheng      GElf_Shdr shdr_mem;
71125b3c049e70834cf33790a28643ab058b507b35cBen Cheng      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
71225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
71325b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (shdr == NULL)
71425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	INTERNAL_ERROR (fname);
71525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
71625b3c049e70834cf33790a28643ab058b507b35cBen Cheng      if (shdr->sh_type == SHT_PROGBITS && shdr->sh_size > 0
71725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  && (shdr->sh_flags & SHF_EXECINSTR) != 0)
71825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	{
71925b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  if  (! section_match (ebl->elf, elf_ndxscn (scn), shdr, shstrndx))
72025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    continue;
72125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
72225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  Elf_Data *data = elf_getdata (scn, NULL);
72325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  if (data == NULL)
72425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    continue;
72525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
72625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  printf ("Disassembly of section %s:\n\n",
72725b3c049e70834cf33790a28643ab058b507b35cBen Cheng		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
72825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
72925b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  struct disasm_info info;
73025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  info.addr = shdr->sh_addr;
73125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  info.last_end = info.cur = data->d_buf;
73225b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  char *fmt;
73325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  if (color_mode)
73425b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    {
73525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      info.address_color = color_address;
73625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      info.bytes_color = color_bytes;
73725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
73825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      if (asprintf (&fmt, "%s%%7m %s%%.1o,%s%%.2o,%s%%.3o%%34a %s%%l",
73925b3c049e70834cf33790a28643ab058b507b35cBen Cheng			    color_mnemonic ?: "",
74025b3c049e70834cf33790a28643ab058b507b35cBen Cheng			    color_operand1 ?: "",
74125b3c049e70834cf33790a28643ab058b507b35cBen Cheng			    color_operand2 ?: "",
74225b3c049e70834cf33790a28643ab058b507b35cBen Cheng			    color_operand3 ?: "",
74325b3c049e70834cf33790a28643ab058b507b35cBen Cheng			    color_label ?: "") < 0)
74425b3c049e70834cf33790a28643ab058b507b35cBen Cheng		error (EXIT_FAILURE, errno, _("cannot allocate memory"));
74525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    }
74625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  else
74725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    {
74825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      info.address_color = info.bytes_color = NULL;
74925b3c049e70834cf33790a28643ab058b507b35cBen Cheng
75025b3c049e70834cf33790a28643ab058b507b35cBen Cheng	      fmt = "%7m %.1o,%.2o,%.3o%34a %l";
75125b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    }
75225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
75325b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  disasm_cb (ctx, &info.cur, info.cur + data->d_size, info.addr,
75425b3c049e70834cf33790a28643ab058b507b35cBen Cheng		     fmt, disasm_output, &info, NULL /* XXX */);
75525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
75625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  if (color_mode)
75725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    free (fmt);
75825b3c049e70834cf33790a28643ab058b507b35cBen Cheng	}
75925b3c049e70834cf33790a28643ab058b507b35cBen Cheng    }
76025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
76125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  (void) disasm_end (ctx);
76225b3c049e70834cf33790a28643ab058b507b35cBen Cheng
76325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  return 0;
76425b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
76525b3c049e70834cf33790a28643ab058b507b35cBen Cheng
76625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
76725b3c049e70834cf33790a28643ab058b507b35cBen Chengstatic int
76825b3c049e70834cf33790a28643ab058b507b35cBen Chenghandle_elf (Elf *elf, const char *prefix, const char *fname,
76925b3c049e70834cf33790a28643ab058b507b35cBen Cheng	    const char *suffix)
77025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{
77125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
77225b3c049e70834cf33790a28643ab058b507b35cBen Cheng  /* Get the backend for this object file type.  */
77325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  Ebl *ebl = ebl_openbackend (elf);
77425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
77525b3c049e70834cf33790a28643ab058b507b35cBen Cheng  printf ("%s: elf%d-%s\n\n",
77625b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  fname, gelf_getclass (elf) == ELFCLASS32 ? 32 : 64,
77725b3c049e70834cf33790a28643ab058b507b35cBen Cheng	  ebl_backend_name (ebl));
77825b3c049e70834cf33790a28643ab058b507b35cBen Cheng
77925b3c049e70834cf33790a28643ab058b507b35cBen Cheng  /* Create the full name of the file.  */
78025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
78125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  size_t suffix_len = suffix == NULL ? 0 : strlen (suffix);
78225b3c049e70834cf33790a28643ab058b507b35cBen Cheng  size_t fname_len = strlen (fname) + 1;
78325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  char fullname[prefix_len + 1 + fname_len + suffix_len];
78425b3c049e70834cf33790a28643ab058b507b35cBen Cheng  char *cp = fullname;
78525b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (prefix != NULL)
78625b3c049e70834cf33790a28643ab058b507b35cBen Cheng    cp = mempcpy (cp, prefix, prefix_len);
78725b3c049e70834cf33790a28643ab058b507b35cBen Cheng  cp = mempcpy (cp, fname, fname_len);
78825b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (suffix != NULL)
78925b3c049e70834cf33790a28643ab058b507b35cBen Cheng    memcpy (cp - 1, suffix, suffix_len + 1);
79025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
79125b3c049e70834cf33790a28643ab058b507b35cBen Cheng  /* Get the section header string table index.  */
79225b3c049e70834cf33790a28643ab058b507b35cBen Cheng  size_t shstrndx;
79325b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
79425b3c049e70834cf33790a28643ab058b507b35cBen Cheng    error (EXIT_FAILURE, 0,
79525b3c049e70834cf33790a28643ab058b507b35cBen Cheng	   gettext ("cannot get section header string table index"));
79625b3c049e70834cf33790a28643ab058b507b35cBen Cheng
79725b3c049e70834cf33790a28643ab058b507b35cBen Cheng  int result = 0;
79825b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (print_disasm)
79925b3c049e70834cf33790a28643ab058b507b35cBen Cheng    result = show_disasm (ebl, fullname, shstrndx);
80025b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (print_relocs && !print_disasm)
80125b3c049e70834cf33790a28643ab058b507b35cBen Cheng    result = show_relocs (ebl, fullname, shstrndx);
80225b3c049e70834cf33790a28643ab058b507b35cBen Cheng  if (print_full_content)
80325b3c049e70834cf33790a28643ab058b507b35cBen Cheng    result = show_full_content (ebl, fullname, shstrndx);
80425b3c049e70834cf33790a28643ab058b507b35cBen Cheng
80525b3c049e70834cf33790a28643ab058b507b35cBen Cheng  /* Close the ELF backend library descriptor.  */
80625b3c049e70834cf33790a28643ab058b507b35cBen Cheng  ebl_closebackend (ebl);
80725b3c049e70834cf33790a28643ab058b507b35cBen Cheng
80825b3c049e70834cf33790a28643ab058b507b35cBen Cheng  return result;
80925b3c049e70834cf33790a28643ab058b507b35cBen Cheng}
81025b3c049e70834cf33790a28643ab058b507b35cBen Cheng
81125b3c049e70834cf33790a28643ab058b507b35cBen Cheng
81225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "debugpred.h"
813