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