1cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Print information from ELF file in human-readable form.
2cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Copyright (C) 2005, 2006, 2007 Red Hat, Inc.
3cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   This file is part of Red Hat elfutils.
4cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
5cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
6cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Red Hat elfutils is free software; you can redistribute it and/or modify
7cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   it under the terms of the GNU General Public License as published by the
8cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Free Software Foundation; version 2 of the License.
9cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
10cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Red Hat elfutils is distributed in the hope that it will be useful, but
11cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   WITHOUT ANY WARRANTY; without even the implied warranty of
12cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   General Public License for more details.
14cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
15cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   You should have received a copy of the GNU General Public License along
16cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   with Red Hat elfutils; if not, write to the Free Software Foundation,
17cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
18cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
19cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Red Hat elfutils is an included package of the Open Invention Network.
20cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   An included package of the Open Invention Network is a package for which
21cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Open Invention Network licensees cross-license their patents.  No patent
22cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   license is granted, either expressly or impliedly, by designation as an
23cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   included package.  Should you wish to participate in the Open Invention
24cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Network licensing program, please visit www.openinventionnetwork.com
25cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   <http://www.openinventionnetwork.com>.  */
26cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
27cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#ifdef HAVE_CONFIG_H
28cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng# include <config.h>
29cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#endif
30cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
31cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <argp.h>
32cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <error.h>
33cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <fcntl.h>
34cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <inttypes.h>
35cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <libintl.h>
36cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <locale.h>
37cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <mcheck.h>
38cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <stdbool.h>
39cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <stdio.h>
40cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <stdio_ext.h>
41cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <stdlib.h>
42cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <string.h>
43cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <unistd.h>
44cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <sys/param.h>
45cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
46cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <system.h>
47cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include "../libebl/libeblP.h"
48cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
49cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
50cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Name and version of program.  */
51cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void print_version (FILE *stream, struct argp_state *state);
52cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengvoid (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
53cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
54cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Bug report address.  */
55cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengconst char *argp_program_bug_address = PACKAGE_BUGREPORT;
56cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
57cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
58cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Definitions of arguments for argp functions.  */
59cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic const struct argp_option options[] =
60cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
61cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { NULL, 0, NULL, 0, N_("Mode selection:"), 0 },
62cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "reloc", 'r', NULL, 0, N_("Display relocation information."), 0 },
63cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "full-contents", 's', NULL, 0,
64cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Display the full contents of all sections requested"), 0 },
65cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "disassemble", 'd', NULL, 0,
66cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Display assembler code of executable sections"), 0 },
67cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
68cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { NULL, 0, NULL, 0, N_("Output option selection:"), 0 },
69cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "section", 'j', "NAME", 0,
70cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Only display information for section NAME."), 0 },
71cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
72cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { NULL, 0, NULL, 0, NULL, 0 }
73cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng};
74cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
75cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Short description of program.  */
76cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic const char doc[] = N_("\
77cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben ChengShow information from FILEs (a.out by default).");
78cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
79cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Strings for arguments in help texts.  */
80cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic const char args_doc[] = N_("[FILE...]");
81cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
82cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Prototype for option handler.  */
83cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic error_t parse_opt (int key, char *arg, struct argp_state *state);
84cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
85cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Data structure to communicate with argp functions.  */
86cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic struct argp argp =
87cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
88cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  options, parse_opt, args_doc, doc, NULL, NULL, NULL
89cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng};
90cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
91cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
92cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Print symbols in file named FNAME.  */
93cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int process_file (const char *fname, bool more_than_one);
94cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
95cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Handle content of archive.  */
96cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
97cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		      const char *suffix);
98cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
99cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Handle ELF file.  */
100cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int handle_elf (Elf *elf, const char *prefix, const char *fname,
101cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		       const char *suffix);
102cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
103cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
104cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#define INTERNAL_ERROR(fname) \
105cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  error (EXIT_FAILURE, 0, gettext ("%s: INTERNAL ERROR %d (%s-%s): %s"),      \
106cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	 fname, __LINE__, PACKAGE_VERSION, __DATE__, elf_errmsg (-1))
107cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
108cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
109cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* List of sections which should be used.  */
110cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic struct section_list
111cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
112cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  bool is_name;
113cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  union
114cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  {
115cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    const char *name;
116cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    uint32_t scnndx;
117cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  };
118cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  struct section_list *next;
119cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng} *section_list;
120cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
121cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
122cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* If true print archive index.  */
123cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic bool print_relocs;
124cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
125cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* If true print full contents of requested sections.  */
126cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic bool print_full_content;
127cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
128cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* If true print disassembled output..  */
129cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic bool print_disasm;
130cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
131cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengint
132cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengmain (int argc, char *argv[])
133cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
134cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* Make memory leak detection possible.  */
135cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  mtrace ();
136cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
137cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* We use no threads here which can interfere with handling a stream.  */
138cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER);
139cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
140cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  (void) __fsetlocking (stderr, FSETLOCKING_BYCALLER);
141cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
142cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* Set locale.  */
143cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  (void) setlocale (LC_ALL, "");
144cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
145cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* Make sure the message catalog can be found.  */
146cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
147cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
148cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* Initialize the message catalog.  */
149cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  (void) textdomain (PACKAGE_TARNAME);
150cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
151cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* Parse and process arguments.  */
152cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  int remaining;
153cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL);
154cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
155cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* Tell the library which version we are expecting.  */
156cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  (void) elf_version (EV_CURRENT);
157cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
158cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  int result = 0;
159cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (remaining == argc)
160cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    /* The user didn't specify a name so we use a.out.  */
161cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    result = process_file ("a.out", false);
162cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  else
163cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    {
164cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      /* Process all the remaining files.  */
165cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      const bool more_than_one = remaining + 1 < argc;
166cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
167cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      do
168cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	result |= process_file (argv[remaining], more_than_one);
169cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      while (++remaining < argc);
170cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    }
171cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
172cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  return result;
173cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng}
174cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
175cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
176cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Print the version information.  */
177cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void
178cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
179cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
180cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  fprintf (stream, "objdump (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
181cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  fprintf (stream, gettext ("\
182cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben ChengCopyright (C) %s Red Hat, Inc.\n\
183cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben ChengThis is free software; see the source for copying conditions.  There is NO\n\
184cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
185cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng"), "2008");
186cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
187cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng}
188cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
189cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
190cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Handle program arguments.  */
191cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic error_t
192cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengparse_opt (int key, char *arg,
193cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	   struct argp_state *state __attribute__ ((unused)))
194cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
195cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* True if any of the control options is set.  */
196cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  static bool any_control_option;
197cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
198cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  switch (key)
199cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    {
200cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    case 'j':
201cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      {
202cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	struct section_list *newp = xmalloc (sizeof (*newp));
203cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	char *endp;
204cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	newp->scnndx = strtoul (arg, &endp, 0);
205cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	if (*endp == 0)
206cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  newp->is_name = false;
207cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	else
208cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  {
209cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    newp->name = arg;
210cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    newp->is_name = true;
211cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  }
212cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	newp->next = section_list;
213cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	section_list = newp;
214cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      }
215cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      any_control_option = true;
216cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      break;
217cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
218cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    case 'd':
219cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      print_disasm = true;
220cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      any_control_option = true;
221cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      break;
222cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
223cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    case 'r':
224cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      print_relocs = true;
225cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      any_control_option = true;
226cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      break;
227cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
228cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    case 's':
229cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      print_full_content = true;
230cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      any_control_option = true;
231cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      break;
232cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
233cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    case ARGP_KEY_FINI:
234cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      if (! any_control_option)
235cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	{
236cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  fputs (gettext ("No operation specified.\n"), stderr);
237cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  argp_help (&argp, stderr, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR,
238cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		     program_invocation_short_name);
239cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  exit (1);
240cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	}
241cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
242cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    default:
243cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      return ARGP_ERR_UNKNOWN;
244cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    }
245cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  return 0;
246cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng}
247cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
248cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
249cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Open the file and determine the type.  */
250cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int
251cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprocess_file (const char *fname, bool more_than_one)
252cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
253cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* Open the file.  */
254cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  int fd = open (fname, O_RDONLY);
255cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (fd == -1)
256cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    {
257cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      error (0, errno, gettext ("cannot open %s"), fname);
258cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      return 1;
259cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    }
260cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
261cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* Now get the ELF descriptor.  */
262cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
263cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (elf != NULL)
264cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    {
265cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      if (elf_kind (elf) == ELF_K_ELF)
266cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	{
267cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  int result = handle_elf (elf, more_than_one ? "" : NULL,
268cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng				   fname, NULL);
269cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
270cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  if (elf_end (elf) != 0)
271cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    INTERNAL_ERROR (fname);
272cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
273cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  if (close (fd) != 0)
274cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    error (EXIT_FAILURE, errno, gettext ("while close `%s'"), fname);
275cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
276cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  return result;
277cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	}
278cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      else if (elf_kind (elf) == ELF_K_AR)
279cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	{
280cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  int result = handle_ar (fd, elf, NULL, fname, NULL);
281cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
282cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  if (elf_end (elf) != 0)
283cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    INTERNAL_ERROR (fname);
284cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
285cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  if (close (fd) != 0)
286cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    error (EXIT_FAILURE, errno, gettext ("while close `%s'"), fname);
287cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
288cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  return result;
289cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	}
290cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
291cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      /* We cannot handle this type.  Close the descriptor anyway.  */
292cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      if (elf_end (elf) != 0)
293cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	INTERNAL_ERROR (fname);
294cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    }
295cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
296cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  error (0, 0, gettext ("%s: File format not recognized"), fname);
297cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
298cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  return 1;
299cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng}
300cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
301cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
302cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int
303cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
304cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	   const char *suffix)
305cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
306cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  size_t fname_len = strlen (fname) + 1;
307cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  size_t prefix_len = prefix != NULL ? strlen (prefix) : 0;
308cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  char new_prefix[prefix_len + fname_len + 2];
309cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  size_t suffix_len = suffix != NULL ? strlen (suffix) : 0;
310cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  char new_suffix[suffix_len + 2];
311cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  Elf *subelf;
312cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  Elf_Cmd cmd = ELF_C_READ_MMAP;
313cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  int result = 0;
314cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
315cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  char *cp = new_prefix;
316cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (prefix != NULL)
317cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    cp = stpcpy (cp, prefix);
318cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  cp = stpcpy (cp, fname);
319cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  stpcpy (cp, "[");
320cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
321cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  cp = new_suffix;
322cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (suffix != NULL)
323cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    cp = stpcpy (cp, suffix);
324cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  stpcpy (cp, "]");
325cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
326cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* Process all the files contained in the archive.  */
327cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
328cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    {
329cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      /* The the header for this element.  */
330cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      Elf_Arhdr *arhdr = elf_getarhdr (subelf);
331cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
332cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      /* Skip over the index entries.  */
333cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      if (strcmp (arhdr->ar_name, "/") != 0
334cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  && strcmp (arhdr->ar_name, "//") != 0)
335cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	{
336cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  if (elf_kind (subelf) == ELF_K_ELF)
337cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    result |= handle_elf (subelf, new_prefix, arhdr->ar_name,
338cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng				  new_suffix);
339cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  else if (elf_kind (subelf) == ELF_K_AR)
340cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name,
341cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng				 new_suffix);
342cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  else
343cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    {
344cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      error (0, 0, gettext ("%s%s%s: file format not recognized"),
345cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		     new_prefix, arhdr->ar_name, new_suffix);
346cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      result = 1;
347cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    }
348cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	}
349cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
350cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      /* Get next archive element.  */
351cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      cmd = elf_next (subelf);
352cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      if (elf_end (subelf) != 0)
353cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	INTERNAL_ERROR (fname);
354cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    }
355cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
356cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  return result;
357cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng}
358cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
359cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
360cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void
361cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengshow_relocs_rel (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data,
362cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		 Elf_Data *symdata, Elf_Data *xndxdata, size_t symstrndx,
363cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		 size_t shstrndx)
364cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
365cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  int elfclass = gelf_getclass (ebl->elf);
366cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  int nentries = shdr->sh_size / shdr->sh_entsize;
367cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
368cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  for (int cnt = 0; cnt < nentries; ++cnt)
369cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    {
370cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      GElf_Rel relmem;
371cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      GElf_Rel *rel;
372cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
373cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      rel = gelf_getrel (data, cnt, &relmem);
374cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      if (rel != NULL)
375cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	{
376cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  char buf[128];
377cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  GElf_Sym symmem;
378cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  GElf_Sym *sym;
379cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  Elf32_Word xndx;
380cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
381cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  sym = gelf_getsymshndx (symdata, xndxdata, GELF_R_SYM (rel->r_info),
382cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng				  &symmem, &xndx);
383cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  if (sym == NULL)
384cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    printf ("%0*" PRIx64 " %-20s <%s %ld>\n",
385cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    elfclass == ELFCLASS32 ? 8 : 16, rel->r_offset,
386cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
387cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
388cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng					   buf, sizeof (buf))
389cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    : gettext ("<INVALID RELOC>"),
390cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    gettext ("INVALID SYMBOL"),
391cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    (long int) GELF_R_SYM (rel->r_info));
392cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
393cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    printf ("%0*" PRIx64 " %-20s %s\n",
394cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    elfclass == ELFCLASS32 ? 8 : 16, rel->r_offset,
395cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
396cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
397cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng					   buf, sizeof (buf))
398cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    : gettext ("<INVALID RELOC>"),
399cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    elf_strptr (ebl->elf, symstrndx, sym->st_name));
400cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  else
401cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    {
402cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      GElf_Shdr destshdr_mem;
403cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      GElf_Shdr *destshdr;
404cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      destshdr = gelf_getshdr (elf_getscn (ebl->elf,
405cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng						   sym->st_shndx == SHN_XINDEX
406cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng						   ? xndx : sym->st_shndx),
407cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng				       &destshdr_mem);
408cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
409cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      if (shdr == NULL)
410cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		printf ("%0*" PRIx64 " %-20s <%s %ld>\n",
411cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			elfclass == ELFCLASS32 ? 8 : 16, rel->r_offset,
412cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
413cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
414cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng					       buf, sizeof (buf))
415cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			: gettext ("<INVALID RELOC>"),
416cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			gettext ("INVALID SECTION"),
417cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			(long int) (sym->st_shndx == SHN_XINDEX
418cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng				    ? xndx : sym->st_shndx));
419cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      else
420cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		printf ("%0*" PRIx64 " %-20s %s\n",
421cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			elfclass == ELFCLASS32 ? 8 : 16, rel->r_offset,
422cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
423cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
424cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng					       buf, sizeof (buf))
425cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			: gettext ("<INVALID RELOC>"),
426cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
427cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    }
428cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	}
429cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    }
430cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng}
431cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
432cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
433cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void
434cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengshow_relocs_rela (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data,
435cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		  Elf_Data *symdata, Elf_Data *xndxdata, size_t symstrndx,
436cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		  size_t shstrndx)
437cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
438cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  int elfclass = gelf_getclass (ebl->elf);
439cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  int nentries = shdr->sh_size / shdr->sh_entsize;
440cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
441cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  for (int cnt = 0; cnt < nentries; ++cnt)
442cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    {
443cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      GElf_Rela relmem;
444cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      GElf_Rela *rel;
445cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
446cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      rel = gelf_getrela (data, cnt, &relmem);
447cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      if (rel != NULL)
448cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	{
449cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  char buf[128];
450cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  GElf_Sym symmem;
451cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  GElf_Sym *sym;
452cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  Elf32_Word xndx;
453cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
454cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  sym = gelf_getsymshndx (symdata, xndxdata, GELF_R_SYM (rel->r_info),
455cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng				  &symmem, &xndx);
456cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  if (sym == NULL)
457cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    printf ("%0*" PRIx64 " %-20s <%s %ld>",
458cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    elfclass == ELFCLASS32 ? 8 : 16, rel->r_offset,
459cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
460cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
461cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng					   buf, sizeof (buf))
462cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    : gettext ("<INVALID RELOC>"),
463cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    gettext ("INVALID SYMBOL"),
464cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    (long int) GELF_R_SYM (rel->r_info));
465cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
466cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    printf ("%0*" PRIx64 " %-20s %s",
467cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    elfclass == ELFCLASS32 ? 8 : 16, rel->r_offset,
468cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
469cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
470cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng					   buf, sizeof (buf))
471cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    : gettext ("<INVALID RELOC>"),
472cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    elf_strptr (ebl->elf, symstrndx, sym->st_name));
473cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  else
474cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    {
475cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      GElf_Shdr destshdr_mem;
476cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      GElf_Shdr *destshdr;
477cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      destshdr = gelf_getshdr (elf_getscn (ebl->elf,
478cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng						   sym->st_shndx == SHN_XINDEX
479cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng						   ? xndx : sym->st_shndx),
480cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng				       &destshdr_mem);
481cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
482cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      if (shdr == NULL)
483cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		printf ("%0*" PRIx64 " %-20s <%s %ld>",
484cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			elfclass == ELFCLASS32 ? 8 : 16, rel->r_offset,
485cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
486cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
487cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng					       buf, sizeof (buf))
488cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			: gettext ("<INVALID RELOC>"),
489cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			gettext ("INVALID SECTION"),
490cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			(long int) (sym->st_shndx == SHN_XINDEX
491cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng				    ? xndx : sym->st_shndx));
492cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      else
493cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		printf ("%0*" PRIx64 " %-20s %s",
494cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			elfclass == ELFCLASS32 ? 8 : 16, rel->r_offset,
495cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
496cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
497cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng					       buf, sizeof (buf))
498cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			: gettext ("<INVALID RELOC>"),
499cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
500cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    }
501cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
502cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  if (rel->r_addend != 0)
503cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    printf ("+%#" PRIx64, rel->r_addend);
504cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  putchar ('\n');
505cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	}
506cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    }
507cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng}
508cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
509cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
510cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic bool
511cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengsection_match (Elf *elf, uint32_t scnndx, GElf_Shdr *shdr, size_t shstrndx)
512cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
513cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (section_list == NULL)
514cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    return true;
515cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
516cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  struct section_list *runp = section_list;
517cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
518cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  do
519cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    {
520cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      if (runp->is_name)
521cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	{
522cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  if (strcmp (runp->name,
523cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		      elf_strptr (elf, shstrndx, shdr->sh_name)) == 0)
524cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    return true;
525cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	}
526cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      else
527cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	{
528cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  if (runp->scnndx == scnndx)
529cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    return true;
530cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	}
531cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
532cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      runp = runp->next;
533cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    }
534cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  while (runp != NULL);
535cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
536cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  return false;
537cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng}
538cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
539cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
540cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int
541cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengshow_relocs (Ebl *ebl, const char *fname, uint32_t shstrndx)
542cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
543cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  int elfclass = gelf_getclass (ebl->elf);
544cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
545cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  Elf_Scn *scn = NULL;
546cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
547cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    {
548cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      GElf_Shdr shdr_mem;
549cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
550cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
551cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      if (shdr == NULL)
552cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	INTERNAL_ERROR (fname);
553cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
554cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
555cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	{
556cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 	  if  (! section_match (ebl->elf, elf_ndxscn (scn), shdr, shstrndx))
557cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    continue;
558cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
559cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  GElf_Shdr destshdr_mem;
560cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf,
561cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng							  shdr->sh_info),
562cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng					      &destshdr_mem);
563cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
564cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  printf (gettext ("RELOCATION RECORDS FOR [%s]:\n"
565cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			   "%-*s TYPE                 VALUE\n"),
566cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		  elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
567cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		  elfclass == ELFCLASS32 ? 8 : 16, gettext ("OFFSET"));
568cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
569cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  /* Get the data of the section.  */
570cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  Elf_Data *data = elf_getdata (scn, NULL);
571cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  if (data == NULL)
572cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    continue;
573cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
574cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  /* Get the symbol table information.  */
575cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
576cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  GElf_Shdr symshdr_mem;
577cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
578cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  Elf_Data *symdata = elf_getdata (symscn, NULL);
579cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
580cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  /* Search for the optional extended section index table.  */
581cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  Elf_Data *xndxdata = NULL;
582cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  Elf_Scn *xndxscn = NULL;
583cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  while ((xndxscn = elf_nextscn (ebl->elf, xndxscn)) != NULL)
584cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    {
585cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      GElf_Shdr xndxshdr_mem;
586cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      GElf_Shdr *xndxshdr;
587cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
588cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem);
589cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      if (xndxshdr != NULL && xndxshdr->sh_type == SHT_SYMTAB_SHNDX
590cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		  && xndxshdr->sh_link == elf_ndxscn (symscn))
591cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		{
592cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		  /* Found it.  */
593cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		  xndxdata = elf_getdata (xndxscn, NULL);
594cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		  break;
595cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		}
596cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    }
597cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
598cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  if (shdr->sh_type == SHT_REL)
599cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    show_relocs_rel (ebl, shdr, data, symdata, xndxdata,
600cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			     symshdr->sh_link, shstrndx);
601cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  else
602cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    show_relocs_rela (ebl, shdr, data, symdata, xndxdata,
603cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			      symshdr->sh_link, shstrndx);
604cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	}
605cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    }
606cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
607cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  fputs_unlocked ("\n\n", stdout);
608cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
609cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  return 0;
610cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng}
611cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
612cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
613cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int
614cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengshow_full_content (Ebl *ebl, const char *fname, uint32_t shstrndx)
615cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
616cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  Elf_Scn *scn = NULL;
617cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
618cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    {
619cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      GElf_Shdr shdr_mem;
620cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
621cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
622cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      if (shdr == NULL)
623cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	INTERNAL_ERROR (fname);
624cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
625cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      if (shdr->sh_type == SHT_PROGBITS && shdr->sh_size > 0)
626cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	{
627cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 	  if  (! section_match (ebl->elf, elf_ndxscn (scn), shdr, shstrndx))
628cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    continue;
629cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
630cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  printf (gettext ("Contents of section %s:\n"),
631cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
632cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
633cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  /* Get the data of the section.  */
634cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  Elf_Data *data = elf_getdata (scn, NULL);
635cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  if (data == NULL)
636cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    continue;
637cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
638cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  unsigned char *cp = data->d_buf;
639cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  size_t cnt;
640cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  for (cnt = 0; cnt + 16 < data->d_size; cp += 16, cnt += 16)
641cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    {
642cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      printf (" %04zx ", cnt);
643cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
644cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      for (size_t inner = 0; inner < 16; inner += 4)
645cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		printf ("%02hhx%02hhx%02hhx%02hhx ",
646cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			cp[inner], cp[inner + 1], cp[inner + 2],
647cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			cp[inner + 3]);
648cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      fputc_unlocked (' ', stdout);
649cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
650cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      for (size_t inner = 0; inner < 16; ++inner)
651cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		fputc_unlocked (isascii (cp[inner]) && isprint (cp[inner])
652cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng				? cp[inner] : '.', stdout);
653cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	      fputc_unlocked ('\n', stdout);
654cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    }
655cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
656cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  printf (" %04zx ", cnt);
657cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
658cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  size_t remaining = data->d_size - cnt;
659cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  size_t inner;
660cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  for (inner = 0; inner + 4 <= remaining; inner += 4)
661cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    printf ("%02hhx%02hhx%02hhx%02hhx ",
662cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		    cp[inner], cp[inner + 1], cp[inner + 2], cp[inner + 3]);
663cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
664cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  for (; inner < remaining; ++inner)
665cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    printf ("%02hhx", cp[inner]);
666cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
667cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  for (inner = 2 * (16 - inner) + (16 - inner + 3) / 4 + 1; inner > 0;
668cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	       --inner)
669cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    fputc_unlocked (' ', stdout);
670cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
671cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  for (inner = 0; inner < remaining; ++inner)
672cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    fputc_unlocked (isascii (cp[inner]) && isprint (cp[inner])
673cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng			    ? cp[inner] : '.', stdout);
674cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  fputc_unlocked ('\n', stdout);
675cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
676cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  fputc_unlocked ('\n', stdout);
677cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	}
678cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    }
679cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
680cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  return 0;
681cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng}
682cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
683cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
684cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstruct disasm_info
685cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
686cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  GElf_Addr addr;
687cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  const uint8_t *cur;
688cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  const uint8_t *last_end;
689cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng};
690cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
691cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
692cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng// XXX This is not the preferred output for all architectures.  Needs
693cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng// XXX customization, too.
694cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int
695cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengdisasm_output (char *buf, size_t buflen, void *arg)
696cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
697cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  struct disasm_info *info = (struct disasm_info *) arg;
698cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
699cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  printf ("%8" PRIx64 ":   ", (uint64_t) info->addr);
700cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  size_t cnt;
701cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  for (cnt = 0; cnt < (size_t) MIN (info->cur - info->last_end, 8); ++cnt)
702cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    printf (" %02" PRIx8, info->last_end[cnt]);
703cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  printf ("%*s %.*s\n",
704cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  (int) (8 - cnt) * 3 + 1, "", (int) buflen, buf);
705cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
706cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  info->addr += cnt;
707cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
708cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* We limit the number of bytes printed before the mnemonic to 8.
709cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng     Print the rest on a separate, following line.  */
710cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (info->cur - info->last_end > 8)
711cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    {
712cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      printf ("%8" PRIx64 ":   ", (uint64_t) info->addr);
713cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      for (; cnt < (size_t) (info->cur - info->last_end); ++cnt)
714cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	printf (" %02" PRIx8, info->last_end[cnt]);
715cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      putchar_unlocked ('\n');
716cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      info->addr += info->cur - info->last_end - 8;
717cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    }
718cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
719cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  info->last_end = info->cur;
720cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
721cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  return 0;
722cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng}
723cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
724cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
725cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int
726cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengshow_disasm (Ebl *ebl, const char *fname, uint32_t shstrndx)
727cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
728cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  DisasmCtx_t *ctx = disasm_begin (ebl, ebl->elf, NULL /* XXX TODO */);
729cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (ctx == NULL)
730cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    error (EXIT_FAILURE, 0, gettext ("cannot disassemble"));
731cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
732cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  Elf_Scn *scn = NULL;
733cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
734cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    {
735cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      GElf_Shdr shdr_mem;
736cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
737cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
738cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      if (shdr == NULL)
739cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	INTERNAL_ERROR (fname);
740cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
741cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      if (shdr->sh_type == SHT_PROGBITS && shdr->sh_size > 0
742cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  && (shdr->sh_flags & SHF_EXECINSTR) != 0)
743cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	{
744cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 	  if  (! section_match (ebl->elf, elf_ndxscn (scn), shdr, shstrndx))
745cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    continue;
746cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
747cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  Elf_Data *data = elf_getdata (scn, NULL);
748cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  if (data == NULL)
749cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    continue;
750cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
751cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  printf ("Disassembly of section %s:\n\n",
752cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
753cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
754cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  struct disasm_info info;
755cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  info.addr = shdr->sh_addr;
756cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  info.last_end = info.cur = data->d_buf;
757cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
758cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  disasm_cb (ctx, &info.cur, info.cur + data->d_size, info.addr,
759cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		     "%7m %.1o,%.2o,%.3o%34a %l", disasm_output, &info,
760cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		     NULL /* XXX */);
761cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	}
762cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    }
763cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
764cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  (void) disasm_end (ctx);
765cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
766cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  return 0;
767cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng}
768cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
769cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
770cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int
771cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenghandle_elf (Elf *elf, const char *prefix, const char *fname,
772cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    const char *suffix)
773cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
774cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
775cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* Get the backend for this object file type.  */
776cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  Ebl *ebl = ebl_openbackend (elf);
777cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
778cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  printf ("%s: elf%d-%s\n\n",
779cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  fname, gelf_getclass (elf) == ELFCLASS32 ? 32 : 64,
780cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  ebl_backend_name (ebl));
781cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
782cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* Create the full name of the file.  */
783cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
784cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  size_t suffix_len = suffix == NULL ? 0 : strlen (suffix);
785cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  size_t fname_len = strlen (fname) + 1;
786cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  char fullname[prefix_len + 1 + fname_len + suffix_len];
787cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  char *cp = fullname;
788cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (prefix != NULL)
789cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    cp = mempcpy (cp, prefix, prefix_len);
790cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  cp = mempcpy (cp, fname, fname_len);
791cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (suffix != NULL)
792cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    memcpy (cp - 1, suffix, suffix_len + 1);
793cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
794cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* Get the section header string table index.  */
795cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  size_t shstrndx;
796cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
797cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    error (EXIT_FAILURE, 0,
798cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	   gettext ("cannot get section header string table index"));
799cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
800cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  int result = 0;
801cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (print_disasm)
802cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    result = show_disasm (ebl, fullname, shstrndx);
803cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (print_relocs && !print_disasm)
804cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    result = show_relocs (ebl, fullname, shstrndx);
805cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (print_full_content)
806cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    result = show_full_content (ebl, fullname, shstrndx);
807cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
808cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* Close the ELF backend library descriptor.  */
809cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  ebl_closebackend (ebl);
810cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
811cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  return result;
812cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng}
813cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
814cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
815cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include "debugpred.h"
816