xref: /openbsd-src/gnu/usr.bin/binutils-2.17/binutils/objdump.c (revision c1f838d9e76e0a1f34f7e2784d8627328f33dd46)
13d8817e4Smiod /* objdump.c -- dump information about an object file.
23d8817e4Smiod    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
33d8817e4Smiod    2000, 2001, 2002, 2003, 2004, 2005, 2006
43d8817e4Smiod    Free Software Foundation, Inc.
53d8817e4Smiod 
63d8817e4Smiod    This file is part of GNU Binutils.
73d8817e4Smiod 
83d8817e4Smiod    This program is free software; you can redistribute it and/or modify
93d8817e4Smiod    it under the terms of the GNU General Public License as published by
103d8817e4Smiod    the Free Software Foundation; either version 2, or (at your option)
113d8817e4Smiod    any later version.
123d8817e4Smiod 
133d8817e4Smiod    This program is distributed in the hope that it will be useful,
143d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
153d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
163d8817e4Smiod    GNU General Public License for more details.
173d8817e4Smiod 
183d8817e4Smiod    You should have received a copy of the GNU General Public License
193d8817e4Smiod    along with this program; if not, write to the Free Software
203d8817e4Smiod    Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
213d8817e4Smiod 
223d8817e4Smiod /* Objdump overview.
233d8817e4Smiod 
243d8817e4Smiod    Objdump displays information about one or more object files, either on
253d8817e4Smiod    their own, or inside libraries.  It is commonly used as a disassembler,
263d8817e4Smiod    but it can also display information about file headers, symbol tables,
273d8817e4Smiod    relocations, debugging directives and more.
283d8817e4Smiod 
293d8817e4Smiod    The flow of execution is as follows:
303d8817e4Smiod 
313d8817e4Smiod    1. Command line arguments are checked for control switches and the
323d8817e4Smiod       information to be displayed is selected.
333d8817e4Smiod 
343d8817e4Smiod    2. Any remaining arguments are assumed to be object files, and they are
353d8817e4Smiod       processed in order by display_bfd().  If the file is an archive each
363d8817e4Smiod       of its elements is processed in turn.
373d8817e4Smiod 
383d8817e4Smiod    3. The file's target architecture and binary file format are determined
393d8817e4Smiod       by bfd_check_format().  If they are recognised, then dump_bfd() is
403d8817e4Smiod       called.
413d8817e4Smiod 
423d8817e4Smiod    4. dump_bfd() in turn calls separate functions to display the requested
433d8817e4Smiod       item(s) of information(s).  For example disassemble_data() is called if
443d8817e4Smiod       a disassembly has been requested.
453d8817e4Smiod 
463d8817e4Smiod    When disassembling the code loops through blocks of instructions bounded
473d8817e4Smiod    by symbols, calling disassemble_bytes() on each block.  The actual
483d8817e4Smiod    disassembling is done by the libopcodes library, via a function pointer
493d8817e4Smiod    supplied by the disassembler() function.  */
503d8817e4Smiod 
513d8817e4Smiod #include "bfd.h"
523d8817e4Smiod #include "bfdver.h"
533d8817e4Smiod #include "progress.h"
543d8817e4Smiod #include "bucomm.h"
553d8817e4Smiod #include "dwarf.h"
563d8817e4Smiod #include "budemang.h"
573d8817e4Smiod #include "getopt.h"
583d8817e4Smiod #include "safe-ctype.h"
593d8817e4Smiod #include "dis-asm.h"
603d8817e4Smiod #include "libiberty.h"
613d8817e4Smiod #include "demangle.h"
623d8817e4Smiod #include "debug.h"
633d8817e4Smiod #include "budbg.h"
643d8817e4Smiod 
653d8817e4Smiod /* Internal headers for the ELF .stab-dump code - sorry.  */
663d8817e4Smiod #define	BYTES_IN_WORD	32
673d8817e4Smiod #include "aout/aout64.h"
683d8817e4Smiod 
693d8817e4Smiod /* Exit status.  */
703d8817e4Smiod static int exit_status = 0;
713d8817e4Smiod 
723d8817e4Smiod static char *default_target = NULL;	/* Default at runtime.  */
733d8817e4Smiod 
743d8817e4Smiod /* The following variables are set based on arguments passed on the
753d8817e4Smiod    command line.  */
763d8817e4Smiod static int show_version = 0;		/* Show the version number.  */
773d8817e4Smiod static int dump_section_contents;	/* -s */
783d8817e4Smiod static int dump_section_headers;	/* -h */
793d8817e4Smiod static bfd_boolean dump_file_header;	/* -f */
803d8817e4Smiod static int dump_symtab;			/* -t */
813d8817e4Smiod static int dump_dynamic_symtab;		/* -T */
823d8817e4Smiod static int dump_reloc_info;		/* -r */
833d8817e4Smiod static int dump_dynamic_reloc_info;	/* -R */
843d8817e4Smiod static int dump_ar_hdrs;		/* -a */
853d8817e4Smiod static int dump_private_headers;	/* -p */
863d8817e4Smiod static int prefix_addresses;		/* --prefix-addresses */
873d8817e4Smiod static int with_line_numbers;		/* -l */
883d8817e4Smiod static bfd_boolean with_source_code;	/* -S */
893d8817e4Smiod static int show_raw_insn;		/* --show-raw-insn */
903d8817e4Smiod static int dump_dwarf_section_info;	/* --dwarf */
913d8817e4Smiod static int dump_stab_section_info;	/* --stabs */
923d8817e4Smiod static int do_demangle;			/* -C, --demangle */
933d8817e4Smiod static bfd_boolean disassemble;		/* -d */
943d8817e4Smiod static bfd_boolean disassemble_all;	/* -D */
953d8817e4Smiod static int disassemble_zeroes;		/* --disassemble-zeroes */
963d8817e4Smiod static bfd_boolean formats_info;	/* -i */
973d8817e4Smiod static int wide_output;			/* -w */
983d8817e4Smiod static bfd_vma start_address = (bfd_vma) -1; /* --start-address */
993d8817e4Smiod static bfd_vma stop_address = (bfd_vma) -1;  /* --stop-address */
1003d8817e4Smiod static int dump_debugging;		/* --debugging */
1013d8817e4Smiod static int dump_debugging_tags;		/* --debugging-tags */
1023d8817e4Smiod static int dump_special_syms = 0;	/* --special-syms */
1033d8817e4Smiod static bfd_vma adjust_section_vma = 0;	/* --adjust-vma */
1043d8817e4Smiod static int file_start_context = 0;      /* --file-start-context */
1053d8817e4Smiod 
1063d8817e4Smiod /* Pointer to an array of section names provided by
1073d8817e4Smiod    one or more "-j secname" command line options.  */
1083d8817e4Smiod static char **only;
1093d8817e4Smiod /* The total number of slots in the only[] array.  */
1103d8817e4Smiod static size_t only_size = 0;
1113d8817e4Smiod /* The number of occupied slots in the only[] array.  */
1123d8817e4Smiod static size_t only_used = 0;
1133d8817e4Smiod 
1143d8817e4Smiod /* Variables for handling include file path table.  */
1153d8817e4Smiod static const char **include_paths;
1163d8817e4Smiod static int include_path_count;
1173d8817e4Smiod 
1183d8817e4Smiod /* Extra info to pass to the section disassembler and address printing
1193d8817e4Smiod    function.  */
1203d8817e4Smiod struct objdump_disasm_info
1213d8817e4Smiod {
1223d8817e4Smiod   bfd *              abfd;
1233d8817e4Smiod   asection *         sec;
1243d8817e4Smiod   bfd_boolean        require_sec;
1253d8817e4Smiod   arelent **         dynrelbuf;
1263d8817e4Smiod   long               dynrelcount;
1273d8817e4Smiod   disassembler_ftype disassemble_fn;
1283d8817e4Smiod   arelent *          reloc;
1293d8817e4Smiod };
1303d8817e4Smiod 
1313d8817e4Smiod /* Architecture to disassemble for, or default if NULL.  */
1323d8817e4Smiod static char *machine = NULL;
1333d8817e4Smiod 
1343d8817e4Smiod /* Target specific options to the disassembler.  */
1353d8817e4Smiod static char *disassembler_options = NULL;
1363d8817e4Smiod 
1373d8817e4Smiod /* Endianness to disassemble for, or default if BFD_ENDIAN_UNKNOWN.  */
1383d8817e4Smiod static enum bfd_endian endian = BFD_ENDIAN_UNKNOWN;
1393d8817e4Smiod 
1403d8817e4Smiod /* The symbol table.  */
1413d8817e4Smiod static asymbol **syms;
1423d8817e4Smiod 
1433d8817e4Smiod /* Number of symbols in `syms'.  */
1443d8817e4Smiod static long symcount = 0;
1453d8817e4Smiod 
1463d8817e4Smiod /* The sorted symbol table.  */
1473d8817e4Smiod static asymbol **sorted_syms;
1483d8817e4Smiod 
1493d8817e4Smiod /* Number of symbols in `sorted_syms'.  */
1503d8817e4Smiod static long sorted_symcount = 0;
1513d8817e4Smiod 
1523d8817e4Smiod /* The dynamic symbol table.  */
1533d8817e4Smiod static asymbol **dynsyms;
1543d8817e4Smiod 
1553d8817e4Smiod /* The synthetic symbol table.  */
1563d8817e4Smiod static asymbol *synthsyms;
1573d8817e4Smiod static long synthcount = 0;
1583d8817e4Smiod 
1593d8817e4Smiod /* Number of symbols in `dynsyms'.  */
1603d8817e4Smiod static long dynsymcount = 0;
1613d8817e4Smiod 
1623d8817e4Smiod static bfd_byte *stabs;
1633d8817e4Smiod static bfd_size_type stab_size;
1643d8817e4Smiod 
1653d8817e4Smiod static char *strtab;
1663d8817e4Smiod static bfd_size_type stabstr_size;
1673d8817e4Smiod 
1683d8817e4Smiod static void
usage(FILE * stream,int status)1693d8817e4Smiod usage (FILE *stream, int status)
1703d8817e4Smiod {
1713d8817e4Smiod   fprintf (stream, _("Usage: %s <option(s)> <file(s)>\n"), program_name);
1723d8817e4Smiod   fprintf (stream, _(" Display information from object <file(s)>.\n"));
1733d8817e4Smiod   fprintf (stream, _(" At least one of the following switches must be given:\n"));
1743d8817e4Smiod   fprintf (stream, _("\
1753d8817e4Smiod   -a, --archive-headers    Display archive header information\n\
1763d8817e4Smiod   -f, --file-headers       Display the contents of the overall file header\n\
1773d8817e4Smiod   -p, --private-headers    Display object format specific file header contents\n\
1783d8817e4Smiod   -h, --[section-]headers  Display the contents of the section headers\n\
1793d8817e4Smiod   -x, --all-headers        Display the contents of all headers\n\
1803d8817e4Smiod   -d, --disassemble        Display assembler contents of executable sections\n\
1813d8817e4Smiod   -D, --disassemble-all    Display assembler contents of all sections\n\
1823d8817e4Smiod   -S, --source             Intermix source code with disassembly\n\
1833d8817e4Smiod   -s, --full-contents      Display the full contents of all sections requested\n\
1843d8817e4Smiod   -g, --debugging          Display debug information in object file\n\
1853d8817e4Smiod   -e, --debugging-tags     Display debug information using ctags style\n\
1863d8817e4Smiod   -G, --stabs              Display (in raw form) any STABS info in the file\n\
1873d8817e4Smiod   -W, --dwarf              Display DWARF info in the file\n\
1883d8817e4Smiod   -t, --syms               Display the contents of the symbol table(s)\n\
1893d8817e4Smiod   -T, --dynamic-syms       Display the contents of the dynamic symbol table\n\
1903d8817e4Smiod   -r, --reloc              Display the relocation entries in the file\n\
1913d8817e4Smiod   -R, --dynamic-reloc      Display the dynamic relocation entries in the file\n\
1923d8817e4Smiod   @<file>                  Read options from <file>\n\
1933d8817e4Smiod   -v, --version            Display this program's version number\n\
1943d8817e4Smiod   -i, --info               List object formats and architectures supported\n\
1953d8817e4Smiod   -H, --help               Display this information\n\
1963d8817e4Smiod "));
1973d8817e4Smiod   if (status != 2)
1983d8817e4Smiod     {
1993d8817e4Smiod       fprintf (stream, _("\n The following switches are optional:\n"));
2003d8817e4Smiod       fprintf (stream, _("\
2013d8817e4Smiod   -b, --target=BFDNAME           Specify the target object format as BFDNAME\n\
2023d8817e4Smiod   -m, --architecture=MACHINE     Specify the target architecture as MACHINE\n\
2033d8817e4Smiod   -j, --section=NAME             Only display information for section NAME\n\
2043d8817e4Smiod   -M, --disassembler-options=OPT Pass text OPT on to the disassembler\n\
2053d8817e4Smiod   -EB --endian=big               Assume big endian format when disassembling\n\
2063d8817e4Smiod   -EL --endian=little            Assume little endian format when disassembling\n\
2073d8817e4Smiod       --file-start-context       Include context from start of file (with -S)\n\
2083d8817e4Smiod   -I, --include=DIR              Add DIR to search list for source files\n\
2093d8817e4Smiod   -l, --line-numbers             Include line numbers and filenames in output\n\
2103d8817e4Smiod   -C, --demangle[=STYLE]         Decode mangled/processed symbol names\n\
2113d8817e4Smiod                                   The STYLE, if specified, can be `auto', `gnu',\n\
2123d8817e4Smiod                                   `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
2133d8817e4Smiod                                   or `gnat'\n\
2143d8817e4Smiod   -w, --wide                     Format output for more than 80 columns\n\
2153d8817e4Smiod   -z, --disassemble-zeroes       Do not skip blocks of zeroes when disassembling\n\
2163d8817e4Smiod       --start-address=ADDR       Only process data whose address is >= ADDR\n\
2173d8817e4Smiod       --stop-address=ADDR        Only process data whose address is <= ADDR\n\
2183d8817e4Smiod       --prefix-addresses         Print complete address alongside disassembly\n\
2193d8817e4Smiod       --[no-]show-raw-insn       Display hex alongside symbolic disassembly\n\
2203d8817e4Smiod       --adjust-vma=OFFSET        Add OFFSET to all displayed section addresses\n\
2213d8817e4Smiod       --special-syms             Include special symbols in symbol dumps\n\
2223d8817e4Smiod \n"));
2233d8817e4Smiod       list_supported_targets (program_name, stream);
2243d8817e4Smiod       list_supported_architectures (program_name, stream);
2253d8817e4Smiod 
2263d8817e4Smiod       disassembler_usage (stream);
2273d8817e4Smiod     }
2283d8817e4Smiod   if (status == 0)
2293d8817e4Smiod     fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO);
2303d8817e4Smiod   exit (status);
2313d8817e4Smiod }
2323d8817e4Smiod 
2333d8817e4Smiod /* 150 isn't special; it's just an arbitrary non-ASCII char value.  */
2343d8817e4Smiod enum option_values
2353d8817e4Smiod   {
2363d8817e4Smiod     OPTION_ENDIAN=150,
2373d8817e4Smiod     OPTION_START_ADDRESS,
2383d8817e4Smiod     OPTION_STOP_ADDRESS,
2393d8817e4Smiod     OPTION_ADJUST_VMA
2403d8817e4Smiod   };
2413d8817e4Smiod 
2423d8817e4Smiod static struct option long_options[]=
2433d8817e4Smiod {
2443d8817e4Smiod   {"adjust-vma", required_argument, NULL, OPTION_ADJUST_VMA},
2453d8817e4Smiod   {"all-headers", no_argument, NULL, 'x'},
2463d8817e4Smiod   {"private-headers", no_argument, NULL, 'p'},
2473d8817e4Smiod   {"architecture", required_argument, NULL, 'm'},
2483d8817e4Smiod   {"archive-headers", no_argument, NULL, 'a'},
2493d8817e4Smiod   {"debugging", no_argument, NULL, 'g'},
2503d8817e4Smiod   {"debugging-tags", no_argument, NULL, 'e'},
2513d8817e4Smiod   {"demangle", optional_argument, NULL, 'C'},
2523d8817e4Smiod   {"disassemble", no_argument, NULL, 'd'},
2533d8817e4Smiod   {"disassemble-all", no_argument, NULL, 'D'},
2543d8817e4Smiod   {"disassembler-options", required_argument, NULL, 'M'},
2553d8817e4Smiod   {"disassemble-zeroes", no_argument, NULL, 'z'},
2563d8817e4Smiod   {"dynamic-reloc", no_argument, NULL, 'R'},
2573d8817e4Smiod   {"dynamic-syms", no_argument, NULL, 'T'},
2583d8817e4Smiod   {"endian", required_argument, NULL, OPTION_ENDIAN},
2593d8817e4Smiod   {"file-headers", no_argument, NULL, 'f'},
2603d8817e4Smiod   {"file-start-context", no_argument, &file_start_context, 1},
2613d8817e4Smiod   {"full-contents", no_argument, NULL, 's'},
2623d8817e4Smiod   {"headers", no_argument, NULL, 'h'},
2633d8817e4Smiod   {"help", no_argument, NULL, 'H'},
2643d8817e4Smiod   {"info", no_argument, NULL, 'i'},
2653d8817e4Smiod   {"line-numbers", no_argument, NULL, 'l'},
2663d8817e4Smiod   {"no-show-raw-insn", no_argument, &show_raw_insn, -1},
2673d8817e4Smiod   {"prefix-addresses", no_argument, &prefix_addresses, 1},
2683d8817e4Smiod   {"reloc", no_argument, NULL, 'r'},
2693d8817e4Smiod   {"section", required_argument, NULL, 'j'},
2703d8817e4Smiod   {"section-headers", no_argument, NULL, 'h'},
2713d8817e4Smiod   {"show-raw-insn", no_argument, &show_raw_insn, 1},
2723d8817e4Smiod   {"source", no_argument, NULL, 'S'},
2733d8817e4Smiod   {"special-syms", no_argument, &dump_special_syms, 1},
2743d8817e4Smiod   {"include", required_argument, NULL, 'I'},
2753d8817e4Smiod   {"dwarf", no_argument, NULL, 'W'},
2763d8817e4Smiod   {"stabs", no_argument, NULL, 'G'},
2773d8817e4Smiod   {"start-address", required_argument, NULL, OPTION_START_ADDRESS},
2783d8817e4Smiod   {"stop-address", required_argument, NULL, OPTION_STOP_ADDRESS},
2793d8817e4Smiod   {"syms", no_argument, NULL, 't'},
2803d8817e4Smiod   {"target", required_argument, NULL, 'b'},
2813d8817e4Smiod   {"version", no_argument, NULL, 'V'},
2823d8817e4Smiod   {"wide", no_argument, NULL, 'w'},
2833d8817e4Smiod   {0, no_argument, 0, 0}
2843d8817e4Smiod };
2853d8817e4Smiod 
2863d8817e4Smiod static void
nonfatal(const char * msg)2873d8817e4Smiod nonfatal (const char *msg)
2883d8817e4Smiod {
2893d8817e4Smiod   bfd_nonfatal (msg);
2903d8817e4Smiod   exit_status = 1;
2913d8817e4Smiod }
2923d8817e4Smiod 
2933d8817e4Smiod static void
dump_section_header(bfd * abfd,asection * section,void * ignored ATTRIBUTE_UNUSED)2943d8817e4Smiod dump_section_header (bfd *abfd, asection *section,
2953d8817e4Smiod 		     void *ignored ATTRIBUTE_UNUSED)
2963d8817e4Smiod {
2973d8817e4Smiod   char *comma = "";
2983d8817e4Smiod   unsigned int opb = bfd_octets_per_byte (abfd);
2993d8817e4Smiod 
3003d8817e4Smiod   /* Ignore linker created section.  See elfNN_ia64_object_p in
3013d8817e4Smiod      bfd/elfxx-ia64.c.  */
3023d8817e4Smiod   if (section->flags & SEC_LINKER_CREATED)
3033d8817e4Smiod     return;
3043d8817e4Smiod 
3053d8817e4Smiod   printf ("%3d %-13s %08lx  ", section->index,
3063d8817e4Smiod 	  bfd_get_section_name (abfd, section),
3073d8817e4Smiod 	  (unsigned long) bfd_section_size (abfd, section) / opb);
3083d8817e4Smiod   bfd_printf_vma (abfd, bfd_get_section_vma (abfd, section));
3093d8817e4Smiod   printf ("  ");
3103d8817e4Smiod   bfd_printf_vma (abfd, section->lma);
3113d8817e4Smiod   printf ("  %08lx  2**%u", (unsigned long) section->filepos,
3123d8817e4Smiod 	  bfd_get_section_alignment (abfd, section));
3133d8817e4Smiod   if (! wide_output)
3143d8817e4Smiod     printf ("\n                ");
3153d8817e4Smiod   printf ("  ");
3163d8817e4Smiod 
3173d8817e4Smiod #define PF(x, y) \
3183d8817e4Smiod   if (section->flags & x) { printf ("%s%s", comma, y); comma = ", "; }
3193d8817e4Smiod 
3203d8817e4Smiod   PF (SEC_HAS_CONTENTS, "CONTENTS");
3213d8817e4Smiod   PF (SEC_ALLOC, "ALLOC");
3223d8817e4Smiod   PF (SEC_CONSTRUCTOR, "CONSTRUCTOR");
3233d8817e4Smiod   PF (SEC_LOAD, "LOAD");
3243d8817e4Smiod   PF (SEC_RELOC, "RELOC");
3253d8817e4Smiod   PF (SEC_READONLY, "READONLY");
3263d8817e4Smiod   PF (SEC_CODE, "CODE");
3273d8817e4Smiod   PF (SEC_DATA, "DATA");
3283d8817e4Smiod   PF (SEC_ROM, "ROM");
3293d8817e4Smiod   PF (SEC_DEBUGGING, "DEBUGGING");
3303d8817e4Smiod   PF (SEC_NEVER_LOAD, "NEVER_LOAD");
3313d8817e4Smiod   PF (SEC_EXCLUDE, "EXCLUDE");
3323d8817e4Smiod   PF (SEC_SORT_ENTRIES, "SORT_ENTRIES");
3333d8817e4Smiod   if (bfd_get_arch (abfd) == bfd_arch_tic54x)
3343d8817e4Smiod     {
3353d8817e4Smiod       PF (SEC_TIC54X_BLOCK, "BLOCK");
3363d8817e4Smiod       PF (SEC_TIC54X_CLINK, "CLINK");
3373d8817e4Smiod     }
3383d8817e4Smiod   PF (SEC_SMALL_DATA, "SMALL_DATA");
3393d8817e4Smiod   if (bfd_get_flavour (abfd) == bfd_target_coff_flavour)
3403d8817e4Smiod     PF (SEC_COFF_SHARED, "SHARED");
3413d8817e4Smiod   PF (SEC_THREAD_LOCAL, "THREAD_LOCAL");
3423d8817e4Smiod   PF (SEC_GROUP, "GROUP");
3433d8817e4Smiod 
3443d8817e4Smiod   if ((section->flags & SEC_LINK_ONCE) != 0)
3453d8817e4Smiod     {
3463d8817e4Smiod       const char *ls;
3473d8817e4Smiod       struct coff_comdat_info *comdat;
3483d8817e4Smiod 
3493d8817e4Smiod       switch (section->flags & SEC_LINK_DUPLICATES)
3503d8817e4Smiod 	{
3513d8817e4Smiod 	default:
3523d8817e4Smiod 	  abort ();
3533d8817e4Smiod 	case SEC_LINK_DUPLICATES_DISCARD:
3543d8817e4Smiod 	  ls = "LINK_ONCE_DISCARD";
3553d8817e4Smiod 	  break;
3563d8817e4Smiod 	case SEC_LINK_DUPLICATES_ONE_ONLY:
3573d8817e4Smiod 	  ls = "LINK_ONCE_ONE_ONLY";
3583d8817e4Smiod 	  break;
3593d8817e4Smiod 	case SEC_LINK_DUPLICATES_SAME_SIZE:
3603d8817e4Smiod 	  ls = "LINK_ONCE_SAME_SIZE";
3613d8817e4Smiod 	  break;
3623d8817e4Smiod 	case SEC_LINK_DUPLICATES_SAME_CONTENTS:
3633d8817e4Smiod 	  ls = "LINK_ONCE_SAME_CONTENTS";
3643d8817e4Smiod 	  break;
3653d8817e4Smiod 	}
3663d8817e4Smiod       printf ("%s%s", comma, ls);
3673d8817e4Smiod 
3683d8817e4Smiod       comdat = bfd_coff_get_comdat_section (abfd, section);
3693d8817e4Smiod       if (comdat != NULL)
3703d8817e4Smiod 	printf (" (COMDAT %s %ld)", comdat->name, comdat->symbol);
3713d8817e4Smiod 
3723d8817e4Smiod       comma = ", ";
3733d8817e4Smiod     }
3743d8817e4Smiod 
3753d8817e4Smiod   printf ("\n");
3763d8817e4Smiod #undef PF
3773d8817e4Smiod }
3783d8817e4Smiod 
3793d8817e4Smiod static void
dump_headers(bfd * abfd)3803d8817e4Smiod dump_headers (bfd *abfd)
3813d8817e4Smiod {
3823d8817e4Smiod   printf (_("Sections:\n"));
3833d8817e4Smiod 
3843d8817e4Smiod #ifndef BFD64
3853d8817e4Smiod   printf (_("Idx Name          Size      VMA       LMA       File off  Algn"));
3863d8817e4Smiod #else
3873d8817e4Smiod   /* With BFD64, non-ELF returns -1 and wants always 64 bit addresses.  */
3883d8817e4Smiod   if (bfd_get_arch_size (abfd) == 32)
3893d8817e4Smiod     printf (_("Idx Name          Size      VMA       LMA       File off  Algn"));
3903d8817e4Smiod   else
3913d8817e4Smiod     printf (_("Idx Name          Size      VMA               LMA               File off  Algn"));
3923d8817e4Smiod #endif
3933d8817e4Smiod 
3943d8817e4Smiod   if (wide_output)
3953d8817e4Smiod     printf (_("  Flags"));
3963d8817e4Smiod   if (abfd->flags & HAS_LOAD_PAGE)
3973d8817e4Smiod     printf (_("  Pg"));
3983d8817e4Smiod   printf ("\n");
3993d8817e4Smiod 
4003d8817e4Smiod   bfd_map_over_sections (abfd, dump_section_header, NULL);
4013d8817e4Smiod }
4023d8817e4Smiod 
4033d8817e4Smiod static asymbol **
slurp_symtab(bfd * abfd)4043d8817e4Smiod slurp_symtab (bfd *abfd)
4053d8817e4Smiod {
4063d8817e4Smiod   asymbol **sy = NULL;
4073d8817e4Smiod   long storage;
4083d8817e4Smiod 
4093d8817e4Smiod   if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
4103d8817e4Smiod     {
4113d8817e4Smiod       symcount = 0;
4123d8817e4Smiod       return NULL;
4133d8817e4Smiod     }
4143d8817e4Smiod 
4153d8817e4Smiod   storage = bfd_get_symtab_upper_bound (abfd);
4163d8817e4Smiod   if (storage < 0)
4173d8817e4Smiod     bfd_fatal (bfd_get_filename (abfd));
4183d8817e4Smiod   if (storage)
4193d8817e4Smiod     sy = xmalloc (storage);
4203d8817e4Smiod 
4213d8817e4Smiod   symcount = bfd_canonicalize_symtab (abfd, sy);
4223d8817e4Smiod   if (symcount < 0)
4233d8817e4Smiod     bfd_fatal (bfd_get_filename (abfd));
4243d8817e4Smiod   return sy;
4253d8817e4Smiod }
4263d8817e4Smiod 
4273d8817e4Smiod /* Read in the dynamic symbols.  */
4283d8817e4Smiod 
4293d8817e4Smiod static asymbol **
slurp_dynamic_symtab(bfd * abfd)4303d8817e4Smiod slurp_dynamic_symtab (bfd *abfd)
4313d8817e4Smiod {
4323d8817e4Smiod   asymbol **sy = NULL;
4333d8817e4Smiod   long storage;
4343d8817e4Smiod 
4353d8817e4Smiod   storage = bfd_get_dynamic_symtab_upper_bound (abfd);
4363d8817e4Smiod   if (storage < 0)
4373d8817e4Smiod     {
4383d8817e4Smiod       if (!(bfd_get_file_flags (abfd) & DYNAMIC))
4393d8817e4Smiod 	{
4403d8817e4Smiod 	  non_fatal (_("%s: not a dynamic object"), bfd_get_filename (abfd));
4413d8817e4Smiod 	  dynsymcount = 0;
4423d8817e4Smiod 	  return NULL;
4433d8817e4Smiod 	}
4443d8817e4Smiod 
4453d8817e4Smiod       bfd_fatal (bfd_get_filename (abfd));
4463d8817e4Smiod     }
4473d8817e4Smiod   if (storage)
4483d8817e4Smiod     sy = xmalloc (storage);
4493d8817e4Smiod 
4503d8817e4Smiod   dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, sy);
4513d8817e4Smiod   if (dynsymcount < 0)
4523d8817e4Smiod     bfd_fatal (bfd_get_filename (abfd));
4533d8817e4Smiod   return sy;
4543d8817e4Smiod }
4553d8817e4Smiod 
4563d8817e4Smiod /* Filter out (in place) symbols that are useless for disassembly.
4573d8817e4Smiod    COUNT is the number of elements in SYMBOLS.
4583d8817e4Smiod    Return the number of useful symbols.  */
4593d8817e4Smiod 
4603d8817e4Smiod static long
remove_useless_symbols(asymbol ** symbols,long count)4613d8817e4Smiod remove_useless_symbols (asymbol **symbols, long count)
4623d8817e4Smiod {
4633d8817e4Smiod   asymbol **in_ptr = symbols, **out_ptr = symbols;
4643d8817e4Smiod 
4653d8817e4Smiod   while (--count >= 0)
4663d8817e4Smiod     {
4673d8817e4Smiod       asymbol *sym = *in_ptr++;
4683d8817e4Smiod 
4693d8817e4Smiod       if (sym->name == NULL || sym->name[0] == '\0')
4703d8817e4Smiod 	continue;
4713d8817e4Smiod       if (sym->flags & (BSF_DEBUGGING | BSF_SECTION_SYM))
4723d8817e4Smiod 	continue;
4733d8817e4Smiod       if (bfd_is_und_section (sym->section)
4743d8817e4Smiod 	  || bfd_is_com_section (sym->section))
4753d8817e4Smiod 	continue;
4763d8817e4Smiod 
4773d8817e4Smiod       *out_ptr++ = sym;
4783d8817e4Smiod     }
4793d8817e4Smiod   return out_ptr - symbols;
4803d8817e4Smiod }
4813d8817e4Smiod 
4823d8817e4Smiod /* Sort symbols into value order.  */
4833d8817e4Smiod 
4843d8817e4Smiod static int
compare_symbols(const void * ap,const void * bp)4853d8817e4Smiod compare_symbols (const void *ap, const void *bp)
4863d8817e4Smiod {
4873d8817e4Smiod   const asymbol *a = * (const asymbol **) ap;
4883d8817e4Smiod   const asymbol *b = * (const asymbol **) bp;
4893d8817e4Smiod   const char *an;
4903d8817e4Smiod   const char *bn;
4913d8817e4Smiod   size_t anl;
4923d8817e4Smiod   size_t bnl;
4933d8817e4Smiod   bfd_boolean af;
4943d8817e4Smiod   bfd_boolean bf;
4953d8817e4Smiod   flagword aflags;
4963d8817e4Smiod   flagword bflags;
4973d8817e4Smiod 
4983d8817e4Smiod   if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
4993d8817e4Smiod     return 1;
5003d8817e4Smiod   else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
5013d8817e4Smiod     return -1;
5023d8817e4Smiod 
5033d8817e4Smiod   if (a->section > b->section)
5043d8817e4Smiod     return 1;
5053d8817e4Smiod   else if (a->section < b->section)
5063d8817e4Smiod     return -1;
5073d8817e4Smiod 
5083d8817e4Smiod   an = bfd_asymbol_name (a);
5093d8817e4Smiod   bn = bfd_asymbol_name (b);
5103d8817e4Smiod   anl = strlen (an);
5113d8817e4Smiod   bnl = strlen (bn);
5123d8817e4Smiod 
5133d8817e4Smiod   /* The symbols gnu_compiled and gcc2_compiled convey no real
5143d8817e4Smiod      information, so put them after other symbols with the same value.  */
5153d8817e4Smiod   af = (strstr (an, "gnu_compiled") != NULL
5163d8817e4Smiod 	|| strstr (an, "gcc2_compiled") != NULL);
5173d8817e4Smiod   bf = (strstr (bn, "gnu_compiled") != NULL
5183d8817e4Smiod 	|| strstr (bn, "gcc2_compiled") != NULL);
5193d8817e4Smiod 
5203d8817e4Smiod   if (af && ! bf)
5213d8817e4Smiod     return 1;
5223d8817e4Smiod   if (! af && bf)
5233d8817e4Smiod     return -1;
5243d8817e4Smiod 
5253d8817e4Smiod   /* We use a heuristic for the file name, to try to sort it after
5263d8817e4Smiod      more useful symbols.  It may not work on non Unix systems, but it
5273d8817e4Smiod      doesn't really matter; the only difference is precisely which
5283d8817e4Smiod      symbol names get printed.  */
5293d8817e4Smiod 
5303d8817e4Smiod #define file_symbol(s, sn, snl)			\
5313d8817e4Smiod   (((s)->flags & BSF_FILE) != 0			\
5323d8817e4Smiod    || ((sn)[(snl) - 2] == '.'			\
5333d8817e4Smiod        && ((sn)[(snl) - 1] == 'o'		\
5343d8817e4Smiod 	   || (sn)[(snl) - 1] == 'a')))
5353d8817e4Smiod 
5363d8817e4Smiod   af = file_symbol (a, an, anl);
5373d8817e4Smiod   bf = file_symbol (b, bn, bnl);
5383d8817e4Smiod 
5393d8817e4Smiod   if (af && ! bf)
5403d8817e4Smiod     return 1;
5413d8817e4Smiod   if (! af && bf)
5423d8817e4Smiod     return -1;
5433d8817e4Smiod 
5443d8817e4Smiod   /* Try to sort global symbols before local symbols before function
5453d8817e4Smiod      symbols before debugging symbols.  */
5463d8817e4Smiod 
5473d8817e4Smiod   aflags = a->flags;
5483d8817e4Smiod   bflags = b->flags;
5493d8817e4Smiod 
5503d8817e4Smiod   if ((aflags & BSF_DEBUGGING) != (bflags & BSF_DEBUGGING))
5513d8817e4Smiod     {
5523d8817e4Smiod       if ((aflags & BSF_DEBUGGING) != 0)
5533d8817e4Smiod 	return 1;
5543d8817e4Smiod       else
5553d8817e4Smiod 	return -1;
5563d8817e4Smiod     }
5573d8817e4Smiod   if ((aflags & BSF_FUNCTION) != (bflags & BSF_FUNCTION))
5583d8817e4Smiod     {
5593d8817e4Smiod       if ((aflags & BSF_FUNCTION) != 0)
5603d8817e4Smiod 	return -1;
5613d8817e4Smiod       else
5623d8817e4Smiod 	return 1;
5633d8817e4Smiod     }
5643d8817e4Smiod   if ((aflags & BSF_LOCAL) != (bflags & BSF_LOCAL))
5653d8817e4Smiod     {
5663d8817e4Smiod       if ((aflags & BSF_LOCAL) != 0)
5673d8817e4Smiod 	return 1;
5683d8817e4Smiod       else
5693d8817e4Smiod 	return -1;
5703d8817e4Smiod     }
5713d8817e4Smiod   if ((aflags & BSF_GLOBAL) != (bflags & BSF_GLOBAL))
5723d8817e4Smiod     {
5733d8817e4Smiod       if ((aflags & BSF_GLOBAL) != 0)
5743d8817e4Smiod 	return -1;
5753d8817e4Smiod       else
5763d8817e4Smiod 	return 1;
5773d8817e4Smiod     }
5783d8817e4Smiod 
5793d8817e4Smiod   /* Symbols that start with '.' might be section names, so sort them
5803d8817e4Smiod      after symbols that don't start with '.'.  */
5813d8817e4Smiod   if (an[0] == '.' && bn[0] != '.')
5823d8817e4Smiod     return 1;
5833d8817e4Smiod   if (an[0] != '.' && bn[0] == '.')
5843d8817e4Smiod     return -1;
5853d8817e4Smiod 
5863d8817e4Smiod   /* Finally, if we can't distinguish them in any other way, try to
5873d8817e4Smiod      get consistent results by sorting the symbols by name.  */
5883d8817e4Smiod   return strcmp (an, bn);
5893d8817e4Smiod }
5903d8817e4Smiod 
5913d8817e4Smiod /* Sort relocs into address order.  */
5923d8817e4Smiod 
5933d8817e4Smiod static int
compare_relocs(const void * ap,const void * bp)5943d8817e4Smiod compare_relocs (const void *ap, const void *bp)
5953d8817e4Smiod {
5963d8817e4Smiod   const arelent *a = * (const arelent **) ap;
5973d8817e4Smiod   const arelent *b = * (const arelent **) bp;
5983d8817e4Smiod 
5993d8817e4Smiod   if (a->address > b->address)
6003d8817e4Smiod     return 1;
6013d8817e4Smiod   else if (a->address < b->address)
6023d8817e4Smiod     return -1;
6033d8817e4Smiod 
6043d8817e4Smiod   /* So that associated relocations tied to the same address show up
6053d8817e4Smiod      in the correct order, we don't do any further sorting.  */
6063d8817e4Smiod   if (a > b)
6073d8817e4Smiod     return 1;
6083d8817e4Smiod   else if (a < b)
6093d8817e4Smiod     return -1;
6103d8817e4Smiod   else
6113d8817e4Smiod     return 0;
6123d8817e4Smiod }
6133d8817e4Smiod 
6143d8817e4Smiod /* Print an address (VMA) to the output stream in INFO.
6153d8817e4Smiod    If SKIP_ZEROES is TRUE, omit leading zeroes.  */
6163d8817e4Smiod 
6173d8817e4Smiod static void
objdump_print_value(bfd_vma vma,struct disassemble_info * info,bfd_boolean skip_zeroes)6183d8817e4Smiod objdump_print_value (bfd_vma vma, struct disassemble_info *info,
6193d8817e4Smiod 		     bfd_boolean skip_zeroes)
6203d8817e4Smiod {
6213d8817e4Smiod   char buf[30];
6223d8817e4Smiod   char *p;
6233d8817e4Smiod   struct objdump_disasm_info *aux;
6243d8817e4Smiod 
6253d8817e4Smiod   aux = (struct objdump_disasm_info *) info->application_data;
6263d8817e4Smiod   bfd_sprintf_vma (aux->abfd, buf, vma);
6273d8817e4Smiod   if (! skip_zeroes)
6283d8817e4Smiod     p = buf;
6293d8817e4Smiod   else
6303d8817e4Smiod     {
6313d8817e4Smiod       for (p = buf; *p == '0'; ++p)
6323d8817e4Smiod 	;
6333d8817e4Smiod       if (*p == '\0')
6343d8817e4Smiod 	--p;
6353d8817e4Smiod     }
6363d8817e4Smiod   (*info->fprintf_func) (info->stream, "%s", p);
6373d8817e4Smiod }
6383d8817e4Smiod 
6393d8817e4Smiod /* Print the name of a symbol.  */
6403d8817e4Smiod 
6413d8817e4Smiod static void
objdump_print_symname(bfd * abfd,struct disassemble_info * info,asymbol * sym)6423d8817e4Smiod objdump_print_symname (bfd *abfd, struct disassemble_info *info,
6433d8817e4Smiod 		       asymbol *sym)
6443d8817e4Smiod {
6453d8817e4Smiod   char *alloc;
6463d8817e4Smiod   const char *name;
6473d8817e4Smiod 
6483d8817e4Smiod   alloc = NULL;
6493d8817e4Smiod   name = bfd_asymbol_name (sym);
6503d8817e4Smiod   if (do_demangle && name[0] != '\0')
6513d8817e4Smiod     {
6523d8817e4Smiod       /* Demangle the name.  */
6533d8817e4Smiod       alloc = demangle (abfd, name);
6543d8817e4Smiod       name = alloc;
6553d8817e4Smiod     }
6563d8817e4Smiod 
6573d8817e4Smiod   if (info != NULL)
6583d8817e4Smiod     (*info->fprintf_func) (info->stream, "%s", name);
6593d8817e4Smiod   else
6603d8817e4Smiod     printf ("%s", name);
6613d8817e4Smiod 
6623d8817e4Smiod   if (alloc != NULL)
6633d8817e4Smiod     free (alloc);
6643d8817e4Smiod }
6653d8817e4Smiod 
6663d8817e4Smiod /* Locate a symbol given a bfd and a section (from INFO->application_data),
6673d8817e4Smiod    and a VMA.  If INFO->application_data->require_sec is TRUE, then always
6683d8817e4Smiod    require the symbol to be in the section.  Returns NULL if there is no
6693d8817e4Smiod    suitable symbol.  If PLACE is not NULL, then *PLACE is set to the index
6703d8817e4Smiod    of the symbol in sorted_syms.  */
6713d8817e4Smiod 
6723d8817e4Smiod static asymbol *
find_symbol_for_address(bfd_vma vma,struct disassemble_info * info,long * place)6733d8817e4Smiod find_symbol_for_address (bfd_vma vma,
6743d8817e4Smiod 			 struct disassemble_info *info,
6753d8817e4Smiod 			 long *place)
6763d8817e4Smiod {
6773d8817e4Smiod   /* @@ Would it speed things up to cache the last two symbols returned,
6783d8817e4Smiod      and maybe their address ranges?  For many processors, only one memory
6793d8817e4Smiod      operand can be present at a time, so the 2-entry cache wouldn't be
6803d8817e4Smiod      constantly churned by code doing heavy memory accesses.  */
6813d8817e4Smiod 
6823d8817e4Smiod   /* Indices in `sorted_syms'.  */
6833d8817e4Smiod   long min = 0;
6843d8817e4Smiod   long max = sorted_symcount;
6853d8817e4Smiod   long thisplace;
6863d8817e4Smiod   struct objdump_disasm_info *aux;
6873d8817e4Smiod   bfd *abfd;
6883d8817e4Smiod   asection *sec;
6893d8817e4Smiod   unsigned int opb;
6903d8817e4Smiod 
6913d8817e4Smiod   if (sorted_symcount < 1)
6923d8817e4Smiod     return NULL;
6933d8817e4Smiod 
6943d8817e4Smiod   aux = (struct objdump_disasm_info *) info->application_data;
6953d8817e4Smiod   abfd = aux->abfd;
6963d8817e4Smiod   sec = aux->sec;
6973d8817e4Smiod   opb = bfd_octets_per_byte (abfd);
6983d8817e4Smiod 
6993d8817e4Smiod   /* Perform a binary search looking for the closest symbol to the
7003d8817e4Smiod      required value.  We are searching the range (min, max].  */
7013d8817e4Smiod   while (min + 1 < max)
7023d8817e4Smiod     {
7033d8817e4Smiod       asymbol *sym;
7043d8817e4Smiod 
7053d8817e4Smiod       thisplace = (max + min) / 2;
7063d8817e4Smiod       sym = sorted_syms[thisplace];
7073d8817e4Smiod 
7083d8817e4Smiod       if (bfd_asymbol_value (sym) > vma)
7093d8817e4Smiod 	max = thisplace;
7103d8817e4Smiod       else if (bfd_asymbol_value (sym) < vma)
7113d8817e4Smiod 	min = thisplace;
7123d8817e4Smiod       else
7133d8817e4Smiod 	{
7143d8817e4Smiod 	  min = thisplace;
7153d8817e4Smiod 	  break;
7163d8817e4Smiod 	}
7173d8817e4Smiod     }
7183d8817e4Smiod 
7193d8817e4Smiod   /* The symbol we want is now in min, the low end of the range we
7203d8817e4Smiod      were searching.  If there are several symbols with the same
7213d8817e4Smiod      value, we want the first one.  */
7223d8817e4Smiod   thisplace = min;
7233d8817e4Smiod   while (thisplace > 0
7243d8817e4Smiod 	 && (bfd_asymbol_value (sorted_syms[thisplace])
7253d8817e4Smiod 	     == bfd_asymbol_value (sorted_syms[thisplace - 1])))
7263d8817e4Smiod     --thisplace;
7273d8817e4Smiod 
7283d8817e4Smiod   /* If the file is relocatable, and the symbol could be from this
7293d8817e4Smiod      section, prefer a symbol from this section over symbols from
7303d8817e4Smiod      others, even if the other symbol's value might be closer.
7313d8817e4Smiod 
7323d8817e4Smiod      Note that this may be wrong for some symbol references if the
7333d8817e4Smiod      sections have overlapping memory ranges, but in that case there's
7343d8817e4Smiod      no way to tell what's desired without looking at the relocation
7353d8817e4Smiod      table.  */
7363d8817e4Smiod   if (sorted_syms[thisplace]->section != sec
7373d8817e4Smiod       && (aux->require_sec
7383d8817e4Smiod 	  || ((abfd->flags & HAS_RELOC) != 0
7393d8817e4Smiod 	      && vma >= bfd_get_section_vma (abfd, sec)
7403d8817e4Smiod 	      && vma < (bfd_get_section_vma (abfd, sec)
7413d8817e4Smiod 			+ bfd_section_size (abfd, sec) / opb))))
7423d8817e4Smiod     {
7433d8817e4Smiod       long i;
7443d8817e4Smiod 
7453d8817e4Smiod       for (i = thisplace + 1; i < sorted_symcount; i++)
7463d8817e4Smiod 	{
7473d8817e4Smiod 	  if (bfd_asymbol_value (sorted_syms[i])
7483d8817e4Smiod 	      != bfd_asymbol_value (sorted_syms[thisplace]))
7493d8817e4Smiod 	    break;
7503d8817e4Smiod 	}
7513d8817e4Smiod 
7523d8817e4Smiod       --i;
7533d8817e4Smiod 
7543d8817e4Smiod       for (; i >= 0; i--)
7553d8817e4Smiod 	{
7563d8817e4Smiod 	  if (sorted_syms[i]->section == sec
7573d8817e4Smiod 	      && (i == 0
7583d8817e4Smiod 		  || sorted_syms[i - 1]->section != sec
7593d8817e4Smiod 		  || (bfd_asymbol_value (sorted_syms[i])
7603d8817e4Smiod 		      != bfd_asymbol_value (sorted_syms[i - 1]))))
7613d8817e4Smiod 	    {
7623d8817e4Smiod 	      thisplace = i;
7633d8817e4Smiod 	      break;
7643d8817e4Smiod 	    }
7653d8817e4Smiod 	}
7663d8817e4Smiod 
7673d8817e4Smiod       if (sorted_syms[thisplace]->section != sec)
7683d8817e4Smiod 	{
7693d8817e4Smiod 	  /* We didn't find a good symbol with a smaller value.
7703d8817e4Smiod 	     Look for one with a larger value.  */
7713d8817e4Smiod 	  for (i = thisplace + 1; i < sorted_symcount; i++)
7723d8817e4Smiod 	    {
7733d8817e4Smiod 	      if (sorted_syms[i]->section == sec)
7743d8817e4Smiod 		{
7753d8817e4Smiod 		  thisplace = i;
7763d8817e4Smiod 		  break;
7773d8817e4Smiod 		}
7783d8817e4Smiod 	    }
7793d8817e4Smiod 	}
7803d8817e4Smiod 
7813d8817e4Smiod       if (sorted_syms[thisplace]->section != sec
7823d8817e4Smiod 	  && (aux->require_sec
7833d8817e4Smiod 	      || ((abfd->flags & HAS_RELOC) != 0
7843d8817e4Smiod 		  && vma >= bfd_get_section_vma (abfd, sec)
7853d8817e4Smiod 		  && vma < (bfd_get_section_vma (abfd, sec)
7863d8817e4Smiod 			    + bfd_section_size (abfd, sec)))))
7873d8817e4Smiod 	/* There is no suitable symbol.  */
7883d8817e4Smiod 	return NULL;
7893d8817e4Smiod     }
7903d8817e4Smiod 
7913d8817e4Smiod   /* Give the target a chance to reject the symbol.  */
7923d8817e4Smiod   while (! info->symbol_is_valid (sorted_syms [thisplace], info))
7933d8817e4Smiod     {
7943d8817e4Smiod       ++ thisplace;
7953d8817e4Smiod       if (thisplace >= sorted_symcount
7963d8817e4Smiod 	  || bfd_asymbol_value (sorted_syms [thisplace]) > vma)
7973d8817e4Smiod 	return NULL;
7983d8817e4Smiod     }
7993d8817e4Smiod 
8003d8817e4Smiod   if (place != NULL)
8013d8817e4Smiod     *place = thisplace;
8023d8817e4Smiod 
8033d8817e4Smiod   return sorted_syms[thisplace];
8043d8817e4Smiod }
8053d8817e4Smiod 
8063d8817e4Smiod /* Print an address and the offset to the nearest symbol.  */
8073d8817e4Smiod 
8083d8817e4Smiod static void
objdump_print_addr_with_sym(bfd * abfd,asection * sec,asymbol * sym,bfd_vma vma,struct disassemble_info * info,bfd_boolean skip_zeroes)8093d8817e4Smiod objdump_print_addr_with_sym (bfd *abfd, asection *sec, asymbol *sym,
8103d8817e4Smiod 			     bfd_vma vma, struct disassemble_info *info,
8113d8817e4Smiod 			     bfd_boolean skip_zeroes)
8123d8817e4Smiod {
8133d8817e4Smiod   objdump_print_value (vma, info, skip_zeroes);
8143d8817e4Smiod 
8153d8817e4Smiod   if (sym == NULL)
8163d8817e4Smiod     {
8173d8817e4Smiod       bfd_vma secaddr;
8183d8817e4Smiod 
8193d8817e4Smiod       (*info->fprintf_func) (info->stream, " <%s",
8203d8817e4Smiod 			     bfd_get_section_name (abfd, sec));
8213d8817e4Smiod       secaddr = bfd_get_section_vma (abfd, sec);
8223d8817e4Smiod       if (vma < secaddr)
8233d8817e4Smiod 	{
8243d8817e4Smiod 	  (*info->fprintf_func) (info->stream, "-0x");
8253d8817e4Smiod 	  objdump_print_value (secaddr - vma, info, TRUE);
8263d8817e4Smiod 	}
8273d8817e4Smiod       else if (vma > secaddr)
8283d8817e4Smiod 	{
8293d8817e4Smiod 	  (*info->fprintf_func) (info->stream, "+0x");
8303d8817e4Smiod 	  objdump_print_value (vma - secaddr, info, TRUE);
8313d8817e4Smiod 	}
8323d8817e4Smiod       (*info->fprintf_func) (info->stream, ">");
8333d8817e4Smiod     }
8343d8817e4Smiod   else
8353d8817e4Smiod     {
8363d8817e4Smiod       (*info->fprintf_func) (info->stream, " <");
8373d8817e4Smiod       objdump_print_symname (abfd, info, sym);
8383d8817e4Smiod       if (bfd_asymbol_value (sym) > vma)
8393d8817e4Smiod 	{
8403d8817e4Smiod 	  (*info->fprintf_func) (info->stream, "-0x");
8413d8817e4Smiod 	  objdump_print_value (bfd_asymbol_value (sym) - vma, info, TRUE);
8423d8817e4Smiod 	}
8433d8817e4Smiod       else if (vma > bfd_asymbol_value (sym))
8443d8817e4Smiod 	{
8453d8817e4Smiod 	  (*info->fprintf_func) (info->stream, "+0x");
8463d8817e4Smiod 	  objdump_print_value (vma - bfd_asymbol_value (sym), info, TRUE);
8473d8817e4Smiod 	}
8483d8817e4Smiod       (*info->fprintf_func) (info->stream, ">");
8493d8817e4Smiod     }
8503d8817e4Smiod }
8513d8817e4Smiod 
8523d8817e4Smiod /* Print an address (VMA), symbolically if possible.
8533d8817e4Smiod    If SKIP_ZEROES is TRUE, don't output leading zeroes.  */
8543d8817e4Smiod 
8553d8817e4Smiod static void
objdump_print_addr(bfd_vma vma,struct disassemble_info * info,bfd_boolean skip_zeroes)8563d8817e4Smiod objdump_print_addr (bfd_vma vma,
8573d8817e4Smiod 		    struct disassemble_info *info,
8583d8817e4Smiod 		    bfd_boolean skip_zeroes)
8593d8817e4Smiod {
8603d8817e4Smiod   struct objdump_disasm_info *aux;
8613d8817e4Smiod   asymbol *sym = NULL; /* Initialize to avoid compiler warning.  */
8623d8817e4Smiod   bfd_boolean skip_find = FALSE;
8633d8817e4Smiod 
8643d8817e4Smiod   if (sorted_symcount < 1)
8653d8817e4Smiod     {
8663d8817e4Smiod       (*info->fprintf_func) (info->stream, "0x");
8673d8817e4Smiod       objdump_print_value (vma, info, skip_zeroes);
8683d8817e4Smiod       return;
8693d8817e4Smiod     }
8703d8817e4Smiod 
8713d8817e4Smiod   aux = (struct objdump_disasm_info *) info->application_data;
8723d8817e4Smiod 
8733d8817e4Smiod   if (aux->reloc != NULL
8743d8817e4Smiod       && aux->reloc->sym_ptr_ptr != NULL
8753d8817e4Smiod       && * aux->reloc->sym_ptr_ptr != NULL)
8763d8817e4Smiod     {
8773d8817e4Smiod       sym = * aux->reloc->sym_ptr_ptr;
8783d8817e4Smiod 
8793d8817e4Smiod       /* Adjust the vma to the reloc.  */
8803d8817e4Smiod       vma += bfd_asymbol_value (sym);
8813d8817e4Smiod 
8823d8817e4Smiod       if (bfd_is_und_section (bfd_get_section (sym)))
8833d8817e4Smiod 	skip_find = TRUE;
8843d8817e4Smiod     }
8853d8817e4Smiod 
8863d8817e4Smiod   if (!skip_find)
8873d8817e4Smiod     sym = find_symbol_for_address (vma, info, NULL);
8883d8817e4Smiod 
8893d8817e4Smiod   objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, info,
8903d8817e4Smiod 			       skip_zeroes);
8913d8817e4Smiod }
8923d8817e4Smiod 
8933d8817e4Smiod /* Print VMA to INFO.  This function is passed to the disassembler
8943d8817e4Smiod    routine.  */
8953d8817e4Smiod 
8963d8817e4Smiod static void
objdump_print_address(bfd_vma vma,struct disassemble_info * info)8973d8817e4Smiod objdump_print_address (bfd_vma vma, struct disassemble_info *info)
8983d8817e4Smiod {
8993d8817e4Smiod   objdump_print_addr (vma, info, ! prefix_addresses);
9003d8817e4Smiod }
9013d8817e4Smiod 
9023d8817e4Smiod /* Determine if the given address has a symbol associated with it.  */
9033d8817e4Smiod 
9043d8817e4Smiod static int
objdump_symbol_at_address(bfd_vma vma,struct disassemble_info * info)9053d8817e4Smiod objdump_symbol_at_address (bfd_vma vma, struct disassemble_info * info)
9063d8817e4Smiod {
9073d8817e4Smiod   asymbol * sym;
9083d8817e4Smiod 
9093d8817e4Smiod   sym = find_symbol_for_address (vma, info, NULL);
9103d8817e4Smiod 
9113d8817e4Smiod   return (sym != NULL && (bfd_asymbol_value (sym) == vma));
9123d8817e4Smiod }
9133d8817e4Smiod 
9143d8817e4Smiod /* Hold the last function name and the last line number we displayed
9153d8817e4Smiod    in a disassembly.  */
9163d8817e4Smiod 
9173d8817e4Smiod static char *prev_functionname;
9183d8817e4Smiod static unsigned int prev_line;
9193d8817e4Smiod 
9203d8817e4Smiod /* We keep a list of all files that we have seen when doing a
9213d8817e4Smiod    disassembly with source, so that we know how much of the file to
9223d8817e4Smiod    display.  This can be important for inlined functions.  */
9233d8817e4Smiod 
9243d8817e4Smiod struct print_file_list
9253d8817e4Smiod {
9263d8817e4Smiod   struct print_file_list *next;
9273d8817e4Smiod   const char *filename;
9283d8817e4Smiod   const char *modname;
9293d8817e4Smiod   unsigned int line;
9303d8817e4Smiod   FILE *f;
9313d8817e4Smiod };
9323d8817e4Smiod 
9333d8817e4Smiod static struct print_file_list *print_files;
9343d8817e4Smiod 
9353d8817e4Smiod /* The number of preceding context lines to show when we start
9363d8817e4Smiod    displaying a file for the first time.  */
9373d8817e4Smiod 
9383d8817e4Smiod #define SHOW_PRECEDING_CONTEXT_LINES (5)
9393d8817e4Smiod 
9403d8817e4Smiod /* Tries to open MODNAME, and if successful adds a node to print_files
9413d8817e4Smiod    linked list and returns that node.  Returns NULL on failure.  */
9423d8817e4Smiod 
9433d8817e4Smiod static struct print_file_list *
try_print_file_open(const char * origname,const char * modname)9443d8817e4Smiod try_print_file_open (const char *origname, const char *modname)
9453d8817e4Smiod {
9463d8817e4Smiod   struct print_file_list *p;
9473d8817e4Smiod   FILE *f;
9483d8817e4Smiod 
9493d8817e4Smiod   f = fopen (modname, "r");
9503d8817e4Smiod   if (f == NULL)
9513d8817e4Smiod     return NULL;
9523d8817e4Smiod 
9533d8817e4Smiod   if (print_files != NULL && print_files->f != NULL)
9543d8817e4Smiod     {
9553d8817e4Smiod       fclose (print_files->f);
9563d8817e4Smiod       print_files->f = NULL;
9573d8817e4Smiod     }
9583d8817e4Smiod 
9593d8817e4Smiod   p = xmalloc (sizeof (struct print_file_list));
9603d8817e4Smiod   p->filename = origname;
9613d8817e4Smiod   p->modname = modname;
9623d8817e4Smiod   p->line = 0;
9633d8817e4Smiod   p->f = f;
9643d8817e4Smiod   p->next = print_files;
9653d8817e4Smiod   print_files = p;
9663d8817e4Smiod   return p;
9673d8817e4Smiod }
9683d8817e4Smiod 
9693d8817e4Smiod /* If the the source file, as described in the symtab, is not found
9703d8817e4Smiod    try to locate it in one of the paths specified with -I
9713d8817e4Smiod    If found, add location to print_files linked list.  */
9723d8817e4Smiod 
9733d8817e4Smiod static struct print_file_list *
update_source_path(const char * filename)9743d8817e4Smiod update_source_path (const char *filename)
9753d8817e4Smiod {
9763d8817e4Smiod   struct print_file_list *p;
9773d8817e4Smiod   const char *fname;
9783d8817e4Smiod   int i;
9793d8817e4Smiod 
9803d8817e4Smiod   if (filename == NULL)
9813d8817e4Smiod     return NULL;
9823d8817e4Smiod 
9833d8817e4Smiod   p = try_print_file_open (filename, filename);
9843d8817e4Smiod   if (p != NULL)
9853d8817e4Smiod     return p;
9863d8817e4Smiod 
9873d8817e4Smiod   if (include_path_count == 0)
9883d8817e4Smiod     return NULL;
9893d8817e4Smiod 
9903d8817e4Smiod   /* Get the name of the file.  */
9913d8817e4Smiod   fname = strrchr (filename, '/');
9923d8817e4Smiod #ifdef HAVE_DOS_BASED_FILE_SYSTEM
9933d8817e4Smiod   {
9943d8817e4Smiod     /* We could have a mixed forward/back slash case.  */
9953d8817e4Smiod     char *backslash = strrchr (filename, '\\');
9963d8817e4Smiod     if (fname == NULL || (backslash != NULL && backslash > fname))
9973d8817e4Smiod       fname = backslash;
9983d8817e4Smiod     if (fname == NULL && filename[0] != '\0' && filename[1] == ':')
9993d8817e4Smiod       fname = filename + 1;
10003d8817e4Smiod   }
10013d8817e4Smiod #endif
10023d8817e4Smiod   if (fname == NULL)
10033d8817e4Smiod     fname = filename;
10043d8817e4Smiod   else
10053d8817e4Smiod     ++fname;
10063d8817e4Smiod 
10073d8817e4Smiod   /* If file exists under a new path, we need to add it to the list
10083d8817e4Smiod      so that show_line knows about it.  */
10093d8817e4Smiod   for (i = 0; i < include_path_count; i++)
10103d8817e4Smiod     {
10113d8817e4Smiod       char *modname = concat (include_paths[i], "/", fname, (const char *) 0);
10123d8817e4Smiod 
10133d8817e4Smiod       p = try_print_file_open (filename, modname);
10143d8817e4Smiod       if (p)
10153d8817e4Smiod 	return p;
10163d8817e4Smiod 
10173d8817e4Smiod       free (modname);
10183d8817e4Smiod     }
10193d8817e4Smiod 
10203d8817e4Smiod   return NULL;
10213d8817e4Smiod }
10223d8817e4Smiod 
10233d8817e4Smiod /* Skip ahead to a given line in a file, optionally printing each
10243d8817e4Smiod    line.  */
10253d8817e4Smiod 
10263d8817e4Smiod static void
skip_to_line(struct print_file_list * p,unsigned int line,bfd_boolean show)10273d8817e4Smiod skip_to_line (struct print_file_list *p, unsigned int line,
10283d8817e4Smiod 	      bfd_boolean show)
10293d8817e4Smiod {
10303d8817e4Smiod   while (p->line < line)
10313d8817e4Smiod     {
10323d8817e4Smiod       char buf[100];
10333d8817e4Smiod 
10343d8817e4Smiod       if (fgets (buf, sizeof buf, p->f) == NULL)
10353d8817e4Smiod 	{
10363d8817e4Smiod 	  fclose (p->f);
10373d8817e4Smiod 	  p->f = NULL;
10383d8817e4Smiod 	  break;
10393d8817e4Smiod 	}
10403d8817e4Smiod 
10413d8817e4Smiod       if (show)
10423d8817e4Smiod 	printf ("%s", buf);
10433d8817e4Smiod 
10443d8817e4Smiod       if (strchr (buf, '\n') != NULL)
10453d8817e4Smiod 	++p->line;
10463d8817e4Smiod     }
10473d8817e4Smiod }
10483d8817e4Smiod 
10493d8817e4Smiod /* Show the line number, or the source line, in a disassembly
10503d8817e4Smiod    listing.  */
10513d8817e4Smiod 
10523d8817e4Smiod static void
show_line(bfd * abfd,asection * section,bfd_vma addr_offset)10533d8817e4Smiod show_line (bfd *abfd, asection *section, bfd_vma addr_offset)
10543d8817e4Smiod {
10553d8817e4Smiod   const char *filename;
10563d8817e4Smiod   const char *functionname;
10573d8817e4Smiod   unsigned int line;
10583d8817e4Smiod 
10593d8817e4Smiod   if (! with_line_numbers && ! with_source_code)
10603d8817e4Smiod     return;
10613d8817e4Smiod 
10623d8817e4Smiod   if (! bfd_find_nearest_line (abfd, section, syms, addr_offset, &filename,
10633d8817e4Smiod 			       &functionname, &line))
10643d8817e4Smiod     return;
10653d8817e4Smiod 
10663d8817e4Smiod   if (filename != NULL && *filename == '\0')
10673d8817e4Smiod     filename = NULL;
10683d8817e4Smiod   if (functionname != NULL && *functionname == '\0')
10693d8817e4Smiod     functionname = NULL;
10703d8817e4Smiod 
10713d8817e4Smiod   if (with_line_numbers)
10723d8817e4Smiod     {
10733d8817e4Smiod       if (functionname != NULL
10743d8817e4Smiod 	  && (prev_functionname == NULL
10753d8817e4Smiod 	      || strcmp (functionname, prev_functionname) != 0))
10763d8817e4Smiod 	printf ("%s():\n", functionname);
10773d8817e4Smiod       if (line > 0 && line != prev_line)
10783d8817e4Smiod 	printf ("%s:%u\n", filename == NULL ? "???" : filename, line);
10793d8817e4Smiod     }
10803d8817e4Smiod 
10813d8817e4Smiod   if (with_source_code
10823d8817e4Smiod       && filename != NULL
10833d8817e4Smiod       && line > 0)
10843d8817e4Smiod     {
10853d8817e4Smiod       struct print_file_list **pp, *p;
10863d8817e4Smiod 
10873d8817e4Smiod       for (pp = &print_files; *pp != NULL; pp = &(*pp)->next)
10883d8817e4Smiod 	if (strcmp ((*pp)->filename, filename) == 0)
10893d8817e4Smiod 	  break;
10903d8817e4Smiod       p = *pp;
10913d8817e4Smiod 
10923d8817e4Smiod       if (p != NULL)
10933d8817e4Smiod 	{
10943d8817e4Smiod 	  if (p != print_files)
10953d8817e4Smiod 	    {
10963d8817e4Smiod 	      int l;
10973d8817e4Smiod 
10983d8817e4Smiod 	      /* We have reencountered a file name which we saw
10993d8817e4Smiod 		 earlier.  This implies that either we are dumping out
11003d8817e4Smiod 		 code from an included file, or the same file was
11013d8817e4Smiod 		 linked in more than once.  There are two common cases
11023d8817e4Smiod 		 of an included file: inline functions in a header
11033d8817e4Smiod 		 file, and a bison or flex skeleton file.  In the
11043d8817e4Smiod 		 former case we want to just start printing (but we
11053d8817e4Smiod 		 back up a few lines to give context); in the latter
11063d8817e4Smiod 		 case we want to continue from where we left off.  I
11073d8817e4Smiod 		 can't think of a good way to distinguish the cases,
11083d8817e4Smiod 		 so I used a heuristic based on the file name.  */
11093d8817e4Smiod 	      if (strcmp (p->filename + strlen (p->filename) - 2, ".h") != 0)
11103d8817e4Smiod 		l = p->line;
11113d8817e4Smiod 	      else
11123d8817e4Smiod 		{
11133d8817e4Smiod 		  l = line - SHOW_PRECEDING_CONTEXT_LINES;
11143d8817e4Smiod 		  if (l < 0)
11153d8817e4Smiod 		    l = 0;
11163d8817e4Smiod 		}
11173d8817e4Smiod 
11183d8817e4Smiod 	      if (p->f == NULL)
11193d8817e4Smiod 		{
11203d8817e4Smiod 		  p->f = fopen (p->modname, "r");
11213d8817e4Smiod 		  p->line = 0;
11223d8817e4Smiod 		}
11233d8817e4Smiod 	      if (p->f != NULL)
11243d8817e4Smiod 		skip_to_line (p, l, FALSE);
11253d8817e4Smiod 
11263d8817e4Smiod 	      if (print_files->f != NULL)
11273d8817e4Smiod 		{
11283d8817e4Smiod 		  fclose (print_files->f);
11293d8817e4Smiod 		  print_files->f = NULL;
11303d8817e4Smiod 		}
11313d8817e4Smiod 	    }
11323d8817e4Smiod 
11333d8817e4Smiod 	  if (p->f != NULL)
11343d8817e4Smiod 	    {
11353d8817e4Smiod 	      skip_to_line (p, line, TRUE);
11363d8817e4Smiod 	      *pp = p->next;
11373d8817e4Smiod 	      p->next = print_files;
11383d8817e4Smiod 	      print_files = p;
11393d8817e4Smiod 	    }
11403d8817e4Smiod 	}
11413d8817e4Smiod       else
11423d8817e4Smiod 	{
11433d8817e4Smiod 	  p = update_source_path (filename);
11443d8817e4Smiod 
11453d8817e4Smiod 	  if (p != NULL)
11463d8817e4Smiod 	    {
11473d8817e4Smiod 	      int l;
11483d8817e4Smiod 
11493d8817e4Smiod 	      if (file_start_context)
11503d8817e4Smiod 		l = 0;
11513d8817e4Smiod 	      else
11523d8817e4Smiod 		l = line - SHOW_PRECEDING_CONTEXT_LINES;
11533d8817e4Smiod 	      if (l < 0)
11543d8817e4Smiod 		l = 0;
11553d8817e4Smiod 	      skip_to_line (p, l, FALSE);
11563d8817e4Smiod 	      if (p->f != NULL)
11573d8817e4Smiod 		skip_to_line (p, line, TRUE);
11583d8817e4Smiod 	    }
11593d8817e4Smiod 	}
11603d8817e4Smiod     }
11613d8817e4Smiod 
11623d8817e4Smiod   if (functionname != NULL
11633d8817e4Smiod       && (prev_functionname == NULL
11643d8817e4Smiod 	  || strcmp (functionname, prev_functionname) != 0))
11653d8817e4Smiod     {
11663d8817e4Smiod       if (prev_functionname != NULL)
11673d8817e4Smiod 	free (prev_functionname);
11683d8817e4Smiod       prev_functionname = xmalloc (strlen (functionname) + 1);
11693d8817e4Smiod       strcpy (prev_functionname, functionname);
11703d8817e4Smiod     }
11713d8817e4Smiod 
11723d8817e4Smiod   if (line > 0 && line != prev_line)
11733d8817e4Smiod     prev_line = line;
11743d8817e4Smiod }
11753d8817e4Smiod 
11763d8817e4Smiod /* Pseudo FILE object for strings.  */
11773d8817e4Smiod typedef struct
11783d8817e4Smiod {
11793d8817e4Smiod   char *buffer;
11803d8817e4Smiod   size_t pos;
11813d8817e4Smiod   size_t alloc;
11823d8817e4Smiod } SFILE;
11833d8817e4Smiod 
11843d8817e4Smiod /* sprintf to a "stream".  */
11853d8817e4Smiod 
11863d8817e4Smiod static int ATTRIBUTE_PRINTF_2
objdump_sprintf(SFILE * f,const char * format,...)11873d8817e4Smiod objdump_sprintf (SFILE *f, const char *format, ...)
11883d8817e4Smiod {
11893d8817e4Smiod   size_t n;
11903d8817e4Smiod   va_list args;
11913d8817e4Smiod 
11923d8817e4Smiod   while (1)
11933d8817e4Smiod     {
11943d8817e4Smiod       size_t space = f->alloc - f->pos;
11953d8817e4Smiod 
11963d8817e4Smiod       va_start (args, format);
11973d8817e4Smiod       n = vsnprintf (f->buffer + f->pos, space, format, args);
11983d8817e4Smiod       va_end (args);
11993d8817e4Smiod 
12003d8817e4Smiod       if (space > n)
12013d8817e4Smiod 	break;
12023d8817e4Smiod 
12033d8817e4Smiod       f->alloc = (f->alloc + n) * 2;
12043d8817e4Smiod       f->buffer = xrealloc (f->buffer, f->alloc);
12053d8817e4Smiod     }
12063d8817e4Smiod   f->pos += n;
12073d8817e4Smiod 
12083d8817e4Smiod   return n;
12093d8817e4Smiod }
12103d8817e4Smiod 
12113d8817e4Smiod /* Returns TRUE if the specified section should be dumped.  */
12123d8817e4Smiod 
12133d8817e4Smiod static bfd_boolean
process_section_p(asection * section)12143d8817e4Smiod process_section_p (asection * section)
12153d8817e4Smiod {
12163d8817e4Smiod   size_t i;
12173d8817e4Smiod 
12183d8817e4Smiod   if (only == NULL)
12193d8817e4Smiod     return TRUE;
12203d8817e4Smiod 
12213d8817e4Smiod   for (i = 0; i < only_used; i++)
12223d8817e4Smiod     if (strcmp (only [i], section->name) == 0)
12233d8817e4Smiod       return TRUE;
12243d8817e4Smiod 
12253d8817e4Smiod   return FALSE;
12263d8817e4Smiod }
12273d8817e4Smiod 
12283d8817e4Smiod 
12293d8817e4Smiod /* The number of zeroes we want to see before we start skipping them.
12303d8817e4Smiod    The number is arbitrarily chosen.  */
12313d8817e4Smiod 
12323d8817e4Smiod #define DEFAULT_SKIP_ZEROES 8
12333d8817e4Smiod 
12343d8817e4Smiod /* The number of zeroes to skip at the end of a section.  If the
12353d8817e4Smiod    number of zeroes at the end is between SKIP_ZEROES_AT_END and
12363d8817e4Smiod    SKIP_ZEROES, they will be disassembled.  If there are fewer than
12373d8817e4Smiod    SKIP_ZEROES_AT_END, they will be skipped.  This is a heuristic
12383d8817e4Smiod    attempt to avoid disassembling zeroes inserted by section
12393d8817e4Smiod    alignment.  */
12403d8817e4Smiod 
12413d8817e4Smiod #define DEFAULT_SKIP_ZEROES_AT_END 3
12423d8817e4Smiod 
12433d8817e4Smiod /* Disassemble some data in memory between given values.  */
12443d8817e4Smiod 
12453d8817e4Smiod static void
disassemble_bytes(struct disassemble_info * info,disassembler_ftype disassemble_fn,bfd_boolean insns,bfd_byte * data,bfd_vma start_offset,bfd_vma stop_offset,bfd_vma rel_offset,arelent *** relppp,arelent ** relppend)12463d8817e4Smiod disassemble_bytes (struct disassemble_info * info,
12473d8817e4Smiod 		   disassembler_ftype        disassemble_fn,
12483d8817e4Smiod 		   bfd_boolean               insns,
12493d8817e4Smiod 		   bfd_byte *                data,
12503d8817e4Smiod 		   bfd_vma                   start_offset,
12513d8817e4Smiod 		   bfd_vma                   stop_offset,
12523d8817e4Smiod 		   bfd_vma		     rel_offset,
12533d8817e4Smiod 		   arelent ***               relppp,
12543d8817e4Smiod 		   arelent **                relppend)
12553d8817e4Smiod {
12563d8817e4Smiod   struct objdump_disasm_info *aux;
12573d8817e4Smiod   asection *section;
12583d8817e4Smiod   int octets_per_line;
12593d8817e4Smiod   bfd_boolean done_dot;
12603d8817e4Smiod   int skip_addr_chars;
12613d8817e4Smiod   bfd_vma addr_offset;
12623d8817e4Smiod   unsigned int opb = info->octets_per_byte;
12633d8817e4Smiod   unsigned int skip_zeroes = info->skip_zeroes;
12643d8817e4Smiod   unsigned int skip_zeroes_at_end = info->skip_zeroes_at_end;
12653d8817e4Smiod   int octets = opb;
12663d8817e4Smiod   SFILE sfile;
12673d8817e4Smiod 
12683d8817e4Smiod   aux = (struct objdump_disasm_info *) info->application_data;
12693d8817e4Smiod   section = aux->sec;
12703d8817e4Smiod 
12713d8817e4Smiod   sfile.alloc = 120;
12723d8817e4Smiod   sfile.buffer = xmalloc (sfile.alloc);
12733d8817e4Smiod   sfile.pos = 0;
12743d8817e4Smiod 
12753d8817e4Smiod   if (insns)
12763d8817e4Smiod     octets_per_line = 4;
12773d8817e4Smiod   else
12783d8817e4Smiod     octets_per_line = 16;
12793d8817e4Smiod 
12803d8817e4Smiod   /* Figure out how many characters to skip at the start of an
12813d8817e4Smiod      address, to make the disassembly look nicer.  We discard leading
12823d8817e4Smiod      zeroes in chunks of 4, ensuring that there is always a leading
12833d8817e4Smiod      zero remaining.  */
12843d8817e4Smiod   skip_addr_chars = 0;
12853d8817e4Smiod   if (! prefix_addresses)
12863d8817e4Smiod     {
12873d8817e4Smiod       char buf[30];
12883d8817e4Smiod       char *s;
12893d8817e4Smiod 
12903d8817e4Smiod       bfd_sprintf_vma
12913d8817e4Smiod 	(aux->abfd, buf,
12923d8817e4Smiod 	 (section->vma
12933d8817e4Smiod 	  + bfd_section_size (section->owner, section) / opb));
12943d8817e4Smiod       s = buf;
12953d8817e4Smiod       while (s[0] == '0' && s[1] == '0' && s[2] == '0' && s[3] == '0'
12963d8817e4Smiod 	     && s[4] == '0')
12973d8817e4Smiod 	{
12983d8817e4Smiod 	  skip_addr_chars += 4;
12993d8817e4Smiod 	  s += 4;
13003d8817e4Smiod 	}
13013d8817e4Smiod     }
13023d8817e4Smiod 
13033d8817e4Smiod   info->insn_info_valid = 0;
13043d8817e4Smiod 
13053d8817e4Smiod   done_dot = FALSE;
13063d8817e4Smiod   addr_offset = start_offset;
13073d8817e4Smiod   while (addr_offset < stop_offset)
13083d8817e4Smiod     {
13093d8817e4Smiod       bfd_vma z;
13103d8817e4Smiod       bfd_boolean need_nl = FALSE;
13113d8817e4Smiod       int previous_octets;
13123d8817e4Smiod 
13133d8817e4Smiod       /* Remember the length of the previous instruction.  */
13143d8817e4Smiod       previous_octets = octets;
13153d8817e4Smiod       octets = 0;
13163d8817e4Smiod 
13173d8817e4Smiod       /* If we see more than SKIP_ZEROES octets of zeroes, we just
13183d8817e4Smiod 	 print `...'.  */
13193d8817e4Smiod       for (z = addr_offset * opb; z < stop_offset * opb; z++)
13203d8817e4Smiod 	if (data[z] != 0)
13213d8817e4Smiod 	  break;
13223d8817e4Smiod       if (! disassemble_zeroes
13233d8817e4Smiod 	  && (info->insn_info_valid == 0
13243d8817e4Smiod 	      || info->branch_delay_insns == 0)
13253d8817e4Smiod 	  && (z - addr_offset * opb >= skip_zeroes
13263d8817e4Smiod 	      || (z == stop_offset * opb &&
13273d8817e4Smiod 		  z - addr_offset * opb < skip_zeroes_at_end)))
13283d8817e4Smiod 	{
13293d8817e4Smiod 	  printf ("\t...\n");
13303d8817e4Smiod 
13313d8817e4Smiod 	  /* If there are more nonzero octets to follow, we only skip
13323d8817e4Smiod 	     zeroes in multiples of 4, to try to avoid running over
13333d8817e4Smiod 	     the start of an instruction which happens to start with
13343d8817e4Smiod 	     zero.  */
13353d8817e4Smiod 	  if (z != stop_offset * opb)
13363d8817e4Smiod 	    z = addr_offset * opb + ((z - addr_offset * opb) &~ 3);
13373d8817e4Smiod 
13383d8817e4Smiod 	  octets = z - addr_offset * opb;
13393d8817e4Smiod 	}
13403d8817e4Smiod       else
13413d8817e4Smiod 	{
13423d8817e4Smiod 	  char buf[50];
13433d8817e4Smiod 	  int bpc = 0;
13443d8817e4Smiod 	  int pb = 0;
13453d8817e4Smiod 
13463d8817e4Smiod 	  done_dot = FALSE;
13473d8817e4Smiod 
13483d8817e4Smiod 	  if (with_line_numbers || with_source_code)
13493d8817e4Smiod 	    show_line (aux->abfd, section, addr_offset);
13503d8817e4Smiod 
13513d8817e4Smiod 	  if (! prefix_addresses)
13523d8817e4Smiod 	    {
13533d8817e4Smiod 	      char *s;
13543d8817e4Smiod 
13553d8817e4Smiod 	      bfd_sprintf_vma (aux->abfd, buf, section->vma + addr_offset);
13563d8817e4Smiod 	      for (s = buf + skip_addr_chars; *s == '0'; s++)
13573d8817e4Smiod 		*s = ' ';
13583d8817e4Smiod 	      if (*s == '\0')
13593d8817e4Smiod 		*--s = '0';
13603d8817e4Smiod 	      printf ("%s:\t", buf + skip_addr_chars);
13613d8817e4Smiod 	    }
13623d8817e4Smiod 	  else
13633d8817e4Smiod 	    {
13643d8817e4Smiod 	      aux->require_sec = TRUE;
13653d8817e4Smiod 	      objdump_print_address (section->vma + addr_offset, info);
13663d8817e4Smiod 	      aux->require_sec = FALSE;
13673d8817e4Smiod 	      putchar (' ');
13683d8817e4Smiod 	    }
13693d8817e4Smiod 
13703d8817e4Smiod 	  if (insns)
13713d8817e4Smiod 	    {
13723d8817e4Smiod 	      sfile.pos = 0;
13733d8817e4Smiod 	      info->fprintf_func = (fprintf_ftype) objdump_sprintf;
13743d8817e4Smiod 	      info->stream = &sfile;
13753d8817e4Smiod 	      info->bytes_per_line = 0;
13763d8817e4Smiod 	      info->bytes_per_chunk = 0;
13773d8817e4Smiod 	      info->flags = 0;
13783d8817e4Smiod 
13793d8817e4Smiod 	      if (info->disassembler_needs_relocs
13803d8817e4Smiod 		  && *relppp < relppend)
13813d8817e4Smiod 		{
13823d8817e4Smiod 		  bfd_signed_vma distance_to_rel;
13833d8817e4Smiod 
13843d8817e4Smiod 		  distance_to_rel = (**relppp)->address
13853d8817e4Smiod 		    - (rel_offset + addr_offset);
13863d8817e4Smiod 
13873d8817e4Smiod 		  /* Check to see if the current reloc is associated with
13883d8817e4Smiod 		     the instruction that we are about to disassemble.  */
13893d8817e4Smiod 		  if (distance_to_rel == 0
13903d8817e4Smiod 		      /* FIXME: This is wrong.  We are trying to catch
13913d8817e4Smiod 			 relocs that are addressed part way through the
13923d8817e4Smiod 			 current instruction, as might happen with a packed
13933d8817e4Smiod 			 VLIW instruction.  Unfortunately we do not know the
13943d8817e4Smiod 			 length of the current instruction since we have not
13953d8817e4Smiod 			 disassembled it yet.  Instead we take a guess based
13963d8817e4Smiod 			 upon the length of the previous instruction.  The
13973d8817e4Smiod 			 proper solution is to have a new target-specific
13983d8817e4Smiod 			 disassembler function which just returns the length
13993d8817e4Smiod 			 of an instruction at a given address without trying
14003d8817e4Smiod 			 to display its disassembly. */
14013d8817e4Smiod 		      || (distance_to_rel > 0
14023d8817e4Smiod 			  && distance_to_rel < (bfd_signed_vma) (previous_octets/ opb)))
14033d8817e4Smiod 		    {
14043d8817e4Smiod 		      info->flags = INSN_HAS_RELOC;
14053d8817e4Smiod 		      aux->reloc = **relppp;
14063d8817e4Smiod 		    }
14073d8817e4Smiod 		  else
14083d8817e4Smiod 		    aux->reloc = NULL;
14093d8817e4Smiod 		}
14103d8817e4Smiod 
14113d8817e4Smiod 	      octets = (*disassemble_fn) (section->vma + addr_offset, info);
14123d8817e4Smiod 	      info->fprintf_func = (fprintf_ftype) fprintf;
14133d8817e4Smiod 	      info->stream = stdout;
14143d8817e4Smiod 	      if (info->bytes_per_line != 0)
14153d8817e4Smiod 		octets_per_line = info->bytes_per_line;
14163d8817e4Smiod 	      if (octets < 0)
14173d8817e4Smiod 		{
14183d8817e4Smiod 		  if (sfile.pos)
14193d8817e4Smiod 		    printf ("%s\n", sfile.buffer);
14203d8817e4Smiod 		  break;
14213d8817e4Smiod 		}
14223d8817e4Smiod 	    }
14233d8817e4Smiod 	  else
14243d8817e4Smiod 	    {
14253d8817e4Smiod 	      bfd_vma j;
14263d8817e4Smiod 
14273d8817e4Smiod 	      octets = octets_per_line;
14283d8817e4Smiod 	      if (addr_offset + octets / opb > stop_offset)
14293d8817e4Smiod 		octets = (stop_offset - addr_offset) * opb;
14303d8817e4Smiod 
14313d8817e4Smiod 	      for (j = addr_offset * opb; j < addr_offset * opb + octets; ++j)
14323d8817e4Smiod 		{
14333d8817e4Smiod 		  if (ISPRINT (data[j]))
14343d8817e4Smiod 		    buf[j - addr_offset * opb] = data[j];
14353d8817e4Smiod 		  else
14363d8817e4Smiod 		    buf[j - addr_offset * opb] = '.';
14373d8817e4Smiod 		}
14383d8817e4Smiod 	      buf[j - addr_offset * opb] = '\0';
14393d8817e4Smiod 	    }
14403d8817e4Smiod 
14413d8817e4Smiod 	  if (prefix_addresses
14423d8817e4Smiod 	      ? show_raw_insn > 0
14433d8817e4Smiod 	      : show_raw_insn >= 0)
14443d8817e4Smiod 	    {
14453d8817e4Smiod 	      bfd_vma j;
14463d8817e4Smiod 
14473d8817e4Smiod 	      /* If ! prefix_addresses and ! wide_output, we print
14483d8817e4Smiod 		 octets_per_line octets per line.  */
14493d8817e4Smiod 	      pb = octets;
14503d8817e4Smiod 	      if (pb > octets_per_line && ! prefix_addresses && ! wide_output)
14513d8817e4Smiod 		pb = octets_per_line;
14523d8817e4Smiod 
14533d8817e4Smiod 	      if (info->bytes_per_chunk)
14543d8817e4Smiod 		bpc = info->bytes_per_chunk;
14553d8817e4Smiod 	      else
14563d8817e4Smiod 		bpc = 1;
14573d8817e4Smiod 
14583d8817e4Smiod 	      for (j = addr_offset * opb; j < addr_offset * opb + pb; j += bpc)
14593d8817e4Smiod 		{
14603d8817e4Smiod 		  int k;
14613d8817e4Smiod 
14623d8817e4Smiod 		  if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE)
14633d8817e4Smiod 		    {
14643d8817e4Smiod 		      for (k = bpc - 1; k >= 0; k--)
14653d8817e4Smiod 			printf ("%02x", (unsigned) data[j + k]);
14663d8817e4Smiod 		      putchar (' ');
14673d8817e4Smiod 		    }
14683d8817e4Smiod 		  else
14693d8817e4Smiod 		    {
14703d8817e4Smiod 		      for (k = 0; k < bpc; k++)
14713d8817e4Smiod 			printf ("%02x", (unsigned) data[j + k]);
14723d8817e4Smiod 		      putchar (' ');
14733d8817e4Smiod 		    }
14743d8817e4Smiod 		}
14753d8817e4Smiod 
14763d8817e4Smiod 	      for (; pb < octets_per_line; pb += bpc)
14773d8817e4Smiod 		{
14783d8817e4Smiod 		  int k;
14793d8817e4Smiod 
14803d8817e4Smiod 		  for (k = 0; k < bpc; k++)
14813d8817e4Smiod 		    printf ("  ");
14823d8817e4Smiod 		  putchar (' ');
14833d8817e4Smiod 		}
14843d8817e4Smiod 
14853d8817e4Smiod 	      /* Separate raw data from instruction by extra space.  */
14863d8817e4Smiod 	      if (insns)
14873d8817e4Smiod 		putchar ('\t');
14883d8817e4Smiod 	      else
14893d8817e4Smiod 		printf ("    ");
14903d8817e4Smiod 	    }
14913d8817e4Smiod 
14923d8817e4Smiod 	  if (! insns)
14933d8817e4Smiod 	    printf ("%s", buf);
14943d8817e4Smiod 	  else if (sfile.pos)
14953d8817e4Smiod 	    printf ("%s", sfile.buffer);
14963d8817e4Smiod 
14973d8817e4Smiod 	  if (prefix_addresses
14983d8817e4Smiod 	      ? show_raw_insn > 0
14993d8817e4Smiod 	      : show_raw_insn >= 0)
15003d8817e4Smiod 	    {
15013d8817e4Smiod 	      while (pb < octets)
15023d8817e4Smiod 		{
15033d8817e4Smiod 		  bfd_vma j;
15043d8817e4Smiod 		  char *s;
15053d8817e4Smiod 
15063d8817e4Smiod 		  putchar ('\n');
15073d8817e4Smiod 		  j = addr_offset * opb + pb;
15083d8817e4Smiod 
15093d8817e4Smiod 		  bfd_sprintf_vma (aux->abfd, buf, section->vma + j / opb);
15103d8817e4Smiod 		  for (s = buf + skip_addr_chars; *s == '0'; s++)
15113d8817e4Smiod 		    *s = ' ';
15123d8817e4Smiod 		  if (*s == '\0')
15133d8817e4Smiod 		    *--s = '0';
15143d8817e4Smiod 		  printf ("%s:\t", buf + skip_addr_chars);
15153d8817e4Smiod 
15163d8817e4Smiod 		  pb += octets_per_line;
15173d8817e4Smiod 		  if (pb > octets)
15183d8817e4Smiod 		    pb = octets;
15193d8817e4Smiod 		  for (; j < addr_offset * opb + pb; j += bpc)
15203d8817e4Smiod 		    {
15213d8817e4Smiod 		      int k;
15223d8817e4Smiod 
15233d8817e4Smiod 		      if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE)
15243d8817e4Smiod 			{
15253d8817e4Smiod 			  for (k = bpc - 1; k >= 0; k--)
15263d8817e4Smiod 			    printf ("%02x", (unsigned) data[j + k]);
15273d8817e4Smiod 			  putchar (' ');
15283d8817e4Smiod 			}
15293d8817e4Smiod 		      else
15303d8817e4Smiod 			{
15313d8817e4Smiod 			  for (k = 0; k < bpc; k++)
15323d8817e4Smiod 			    printf ("%02x", (unsigned) data[j + k]);
15333d8817e4Smiod 			  putchar (' ');
15343d8817e4Smiod 			}
15353d8817e4Smiod 		    }
15363d8817e4Smiod 		}
15373d8817e4Smiod 	    }
15383d8817e4Smiod 
15393d8817e4Smiod 	  if (!wide_output)
15403d8817e4Smiod 	    putchar ('\n');
15413d8817e4Smiod 	  else
15423d8817e4Smiod 	    need_nl = TRUE;
15433d8817e4Smiod 	}
15443d8817e4Smiod 
15453d8817e4Smiod       while ((*relppp) < relppend
15463d8817e4Smiod 	     && (**relppp)->address < rel_offset + addr_offset + octets / opb)
15473d8817e4Smiod 	{
15483d8817e4Smiod 	  if (dump_reloc_info || dump_dynamic_reloc_info)
15493d8817e4Smiod 	    {
15503d8817e4Smiod 	      arelent *q;
15513d8817e4Smiod 
15523d8817e4Smiod 	      q = **relppp;
15533d8817e4Smiod 
15543d8817e4Smiod 	      if (wide_output)
15553d8817e4Smiod 		putchar ('\t');
15563d8817e4Smiod 	      else
15573d8817e4Smiod 		printf ("\t\t\t");
15583d8817e4Smiod 
15593d8817e4Smiod 	      objdump_print_value (section->vma - rel_offset + q->address,
15603d8817e4Smiod 				   info, TRUE);
15613d8817e4Smiod 
15623d8817e4Smiod 	      if (q->howto == NULL)
15633d8817e4Smiod 		printf (": *unknown*\t");
15643d8817e4Smiod 	      else if (q->howto->name)
15653d8817e4Smiod 		printf (": %s\t", q->howto->name);
15663d8817e4Smiod 	      else
15673d8817e4Smiod 		printf (": %d\t", q->howto->type);
15683d8817e4Smiod 
15693d8817e4Smiod 	      if (q->sym_ptr_ptr == NULL || *q->sym_ptr_ptr == NULL)
15703d8817e4Smiod 		printf ("*unknown*");
15713d8817e4Smiod 	      else
15723d8817e4Smiod 		{
15733d8817e4Smiod 		  const char *sym_name;
15743d8817e4Smiod 
15753d8817e4Smiod 		  sym_name = bfd_asymbol_name (*q->sym_ptr_ptr);
15763d8817e4Smiod 		  if (sym_name != NULL && *sym_name != '\0')
15773d8817e4Smiod 		    objdump_print_symname (aux->abfd, info, *q->sym_ptr_ptr);
15783d8817e4Smiod 		  else
15793d8817e4Smiod 		    {
15803d8817e4Smiod 		      asection *sym_sec;
15813d8817e4Smiod 
15823d8817e4Smiod 		      sym_sec = bfd_get_section (*q->sym_ptr_ptr);
15833d8817e4Smiod 		      sym_name = bfd_get_section_name (aux->abfd, sym_sec);
15843d8817e4Smiod 		      if (sym_name == NULL || *sym_name == '\0')
15853d8817e4Smiod 			sym_name = "*unknown*";
15863d8817e4Smiod 		      printf ("%s", sym_name);
15873d8817e4Smiod 		    }
15883d8817e4Smiod 		}
15893d8817e4Smiod 
15903d8817e4Smiod 	      if (q->addend)
15913d8817e4Smiod 		{
15923d8817e4Smiod 		  printf ("+0x");
15933d8817e4Smiod 		  objdump_print_value (q->addend, info, TRUE);
15943d8817e4Smiod 		}
15953d8817e4Smiod 
15963d8817e4Smiod 	      printf ("\n");
15973d8817e4Smiod 	      need_nl = FALSE;
15983d8817e4Smiod 	    }
15993d8817e4Smiod 	  ++(*relppp);
16003d8817e4Smiod 	}
16013d8817e4Smiod 
16023d8817e4Smiod       if (need_nl)
16033d8817e4Smiod 	printf ("\n");
16043d8817e4Smiod 
16053d8817e4Smiod       addr_offset += octets / opb;
16063d8817e4Smiod     }
16073d8817e4Smiod 
16083d8817e4Smiod   free (sfile.buffer);
16093d8817e4Smiod }
16103d8817e4Smiod 
16113d8817e4Smiod static void
disassemble_section(bfd * abfd,asection * section,void * info)16123d8817e4Smiod disassemble_section (bfd *abfd, asection *section, void *info)
16133d8817e4Smiod {
16143d8817e4Smiod   struct disassemble_info *    pinfo = (struct disassemble_info *) info;
16153d8817e4Smiod   struct objdump_disasm_info * paux;
16163d8817e4Smiod   unsigned int                 opb = pinfo->octets_per_byte;
16173d8817e4Smiod   bfd_byte *                   data = NULL;
16183d8817e4Smiod   bfd_size_type                datasize = 0;
16193d8817e4Smiod   arelent **                   rel_pp = NULL;
16203d8817e4Smiod   arelent **                   rel_ppstart = NULL;
16213d8817e4Smiod   arelent **                   rel_ppend;
16223d8817e4Smiod   unsigned long                stop_offset;
16233d8817e4Smiod   asymbol *                    sym = NULL;
16243d8817e4Smiod   long                         place = 0;
16253d8817e4Smiod   long                         rel_count;
16263d8817e4Smiod   bfd_vma                      rel_offset;
16273d8817e4Smiod   unsigned long                addr_offset;
16283d8817e4Smiod 
16293d8817e4Smiod   /* Sections that do not contain machine
16303d8817e4Smiod      code are not normally disassembled.  */
16313d8817e4Smiod   if (! disassemble_all
16323d8817e4Smiod       && only == NULL
16333d8817e4Smiod       && ((section->flags & (SEC_CODE | SEC_HAS_CONTENTS))
16343d8817e4Smiod 	  != (SEC_CODE | SEC_HAS_CONTENTS)))
16353d8817e4Smiod     return;
16363d8817e4Smiod 
16373d8817e4Smiod   if (! process_section_p (section))
16383d8817e4Smiod     return;
16393d8817e4Smiod 
16403d8817e4Smiod   datasize = bfd_get_section_size (section);
16413d8817e4Smiod   if (datasize == 0)
16423d8817e4Smiod     return;
16433d8817e4Smiod 
16443d8817e4Smiod   /* Decide which set of relocs to use.  Load them if necessary.  */
16453d8817e4Smiod   paux = (struct objdump_disasm_info *) pinfo->application_data;
16463d8817e4Smiod   if (paux->dynrelbuf)
16473d8817e4Smiod     {
16483d8817e4Smiod       rel_pp = paux->dynrelbuf;
16493d8817e4Smiod       rel_count = paux->dynrelcount;
16503d8817e4Smiod       /* Dynamic reloc addresses are absolute, non-dynamic are section
16513d8817e4Smiod 	 relative.  REL_OFFSET specifies the reloc address corresponding
16523d8817e4Smiod 	 to the start of this section.  */
16533d8817e4Smiod       rel_offset = section->vma;
16543d8817e4Smiod     }
16553d8817e4Smiod   else
16563d8817e4Smiod     {
16573d8817e4Smiod       rel_count = 0;
16583d8817e4Smiod       rel_pp = NULL;
16593d8817e4Smiod       rel_offset = 0;
16603d8817e4Smiod 
16613d8817e4Smiod       if ((section->flags & SEC_RELOC) != 0
16623d8817e4Smiod 	  && (dump_reloc_info || pinfo->disassembler_needs_relocs))
16633d8817e4Smiod 	{
16643d8817e4Smiod 	  long relsize;
16653d8817e4Smiod 
16663d8817e4Smiod 	  relsize = bfd_get_reloc_upper_bound (abfd, section);
16673d8817e4Smiod 	  if (relsize < 0)
16683d8817e4Smiod 	    bfd_fatal (bfd_get_filename (abfd));
16693d8817e4Smiod 
16703d8817e4Smiod 	  if (relsize > 0)
16713d8817e4Smiod 	    {
16723d8817e4Smiod 	      rel_ppstart = rel_pp = xmalloc (relsize);
16733d8817e4Smiod 	      rel_count = bfd_canonicalize_reloc (abfd, section, rel_pp, syms);
16743d8817e4Smiod 	      if (rel_count < 0)
16753d8817e4Smiod 		bfd_fatal (bfd_get_filename (abfd));
16763d8817e4Smiod 
16773d8817e4Smiod 	      /* Sort the relocs by address.  */
16783d8817e4Smiod 	      qsort (rel_pp, rel_count, sizeof (arelent *), compare_relocs);
16793d8817e4Smiod 	    }
16803d8817e4Smiod 	}
16813d8817e4Smiod 
16823d8817e4Smiod     }
16833d8817e4Smiod   rel_ppend = rel_pp + rel_count;
16843d8817e4Smiod 
16853d8817e4Smiod   data = xmalloc (datasize);
16863d8817e4Smiod 
16873d8817e4Smiod   bfd_get_section_contents (abfd, section, data, 0, datasize);
16883d8817e4Smiod 
16893d8817e4Smiod   paux->sec = section;
16903d8817e4Smiod   pinfo->buffer = data;
16913d8817e4Smiod   pinfo->buffer_vma = section->vma;
16923d8817e4Smiod   pinfo->buffer_length = datasize;
16933d8817e4Smiod   pinfo->section = section;
16943d8817e4Smiod 
16953d8817e4Smiod   if (start_address == (bfd_vma) -1
16963d8817e4Smiod       || start_address < pinfo->buffer_vma)
16973d8817e4Smiod     addr_offset = 0;
16983d8817e4Smiod   else
16993d8817e4Smiod     addr_offset = start_address - pinfo->buffer_vma;
17003d8817e4Smiod 
17013d8817e4Smiod   if (stop_address == (bfd_vma) -1)
17023d8817e4Smiod     stop_offset = datasize / opb;
17033d8817e4Smiod   else
17043d8817e4Smiod     {
17053d8817e4Smiod       if (stop_address < pinfo->buffer_vma)
17063d8817e4Smiod 	stop_offset = 0;
17073d8817e4Smiod       else
17083d8817e4Smiod 	stop_offset = stop_address - pinfo->buffer_vma;
17093d8817e4Smiod       if (stop_offset > pinfo->buffer_length / opb)
17103d8817e4Smiod 	stop_offset = pinfo->buffer_length / opb;
17113d8817e4Smiod     }
17123d8817e4Smiod 
17133d8817e4Smiod   /* Skip over the relocs belonging to addresses below the
17143d8817e4Smiod      start address.  */
17153d8817e4Smiod   while (rel_pp < rel_ppend
17163d8817e4Smiod 	 && (*rel_pp)->address < rel_offset + addr_offset)
17173d8817e4Smiod     ++rel_pp;
17183d8817e4Smiod 
17193d8817e4Smiod   printf (_("Disassembly of section %s:\n"), section->name);
17203d8817e4Smiod 
17213d8817e4Smiod   /* Find the nearest symbol forwards from our current position.  */
17223d8817e4Smiod   paux->require_sec = TRUE;
17233d8817e4Smiod   sym = find_symbol_for_address (section->vma + addr_offset, info, &place);
17243d8817e4Smiod   paux->require_sec = FALSE;
17253d8817e4Smiod 
17263d8817e4Smiod   /* Disassemble a block of instructions up to the address associated with
17273d8817e4Smiod      the symbol we have just found.  Then print the symbol and find the
17283d8817e4Smiod      next symbol on.  Repeat until we have disassembled the entire section
17293d8817e4Smiod      or we have reached the end of the address range we are interested in.  */
17303d8817e4Smiod   while (addr_offset < stop_offset)
17313d8817e4Smiod     {
17323d8817e4Smiod       bfd_vma addr;
17333d8817e4Smiod       asymbol *nextsym;
17343d8817e4Smiod       unsigned long nextstop_offset;
17353d8817e4Smiod       bfd_boolean insns;
17363d8817e4Smiod 
17373d8817e4Smiod       addr = section->vma + addr_offset;
17383d8817e4Smiod 
17393d8817e4Smiod       if (sym != NULL && bfd_asymbol_value (sym) <= addr)
17403d8817e4Smiod 	{
17413d8817e4Smiod 	  int x;
17423d8817e4Smiod 
17433d8817e4Smiod 	  for (x = place;
17443d8817e4Smiod 	       (x < sorted_symcount
17453d8817e4Smiod 		&& (bfd_asymbol_value (sorted_syms[x]) <= addr));
17463d8817e4Smiod 	       ++x)
17473d8817e4Smiod 	    continue;
17483d8817e4Smiod 
17493d8817e4Smiod 	  pinfo->symbols = sorted_syms + place;
17503d8817e4Smiod 	  pinfo->num_symbols = x - place;
17513d8817e4Smiod 	}
17523d8817e4Smiod       else
17533d8817e4Smiod 	{
17543d8817e4Smiod 	  pinfo->symbols = NULL;
17553d8817e4Smiod 	  pinfo->num_symbols = 0;
17563d8817e4Smiod 	}
17573d8817e4Smiod 
17583d8817e4Smiod       if (! prefix_addresses)
17593d8817e4Smiod 	{
17603d8817e4Smiod 	  pinfo->fprintf_func (pinfo->stream, "\n");
17613d8817e4Smiod 	  objdump_print_addr_with_sym (abfd, section, sym, addr,
17623d8817e4Smiod 				       pinfo, FALSE);
17633d8817e4Smiod 	  pinfo->fprintf_func (pinfo->stream, ":\n");
17643d8817e4Smiod 	}
17653d8817e4Smiod 
17663d8817e4Smiod       if (sym != NULL && bfd_asymbol_value (sym) > addr)
17673d8817e4Smiod 	nextsym = sym;
17683d8817e4Smiod       else if (sym == NULL)
17693d8817e4Smiod 	nextsym = NULL;
17703d8817e4Smiod       else
17713d8817e4Smiod 	{
17723d8817e4Smiod #define is_valid_next_sym(SYM) \
17733d8817e4Smiod   ((SYM)->section == section \
17743d8817e4Smiod    && (bfd_asymbol_value (SYM) > bfd_asymbol_value (sym)) \
17753d8817e4Smiod    && pinfo->symbol_is_valid (SYM, pinfo))
17763d8817e4Smiod 
17773d8817e4Smiod 	  /* Search forward for the next appropriate symbol in
17783d8817e4Smiod 	     SECTION.  Note that all the symbols are sorted
17793d8817e4Smiod 	     together into one big array, and that some sections
17803d8817e4Smiod 	     may have overlapping addresses.  */
17813d8817e4Smiod 	  while (place < sorted_symcount
17823d8817e4Smiod 		 && ! is_valid_next_sym (sorted_syms [place]))
17833d8817e4Smiod 	    ++place;
17843d8817e4Smiod 
17853d8817e4Smiod 	  if (place >= sorted_symcount)
17863d8817e4Smiod 	    nextsym = NULL;
17873d8817e4Smiod 	  else
17883d8817e4Smiod 	    nextsym = sorted_syms[place];
17893d8817e4Smiod 	}
17903d8817e4Smiod 
17913d8817e4Smiod       if (sym != NULL && bfd_asymbol_value (sym) > addr)
17923d8817e4Smiod 	nextstop_offset = bfd_asymbol_value (sym) - section->vma;
17933d8817e4Smiod       else if (nextsym == NULL)
17943d8817e4Smiod 	nextstop_offset = stop_offset;
17953d8817e4Smiod       else
17963d8817e4Smiod 	nextstop_offset = bfd_asymbol_value (nextsym) - section->vma;
17973d8817e4Smiod 
17983d8817e4Smiod       if (nextstop_offset > stop_offset)
17993d8817e4Smiod 	nextstop_offset = stop_offset;
18003d8817e4Smiod 
18013d8817e4Smiod       /* If a symbol is explicitly marked as being an object
18023d8817e4Smiod 	 rather than a function, just dump the bytes without
18033d8817e4Smiod 	 disassembling them.  */
18043d8817e4Smiod       if (disassemble_all
18053d8817e4Smiod 	  || sym == NULL
18063d8817e4Smiod 	  || bfd_asymbol_value (sym) > addr
18073d8817e4Smiod 	  || ((sym->flags & BSF_OBJECT) == 0
18083d8817e4Smiod 	      && (strstr (bfd_asymbol_name (sym), "gnu_compiled")
18093d8817e4Smiod 		  == NULL)
18103d8817e4Smiod 	      && (strstr (bfd_asymbol_name (sym), "gcc2_compiled")
18113d8817e4Smiod 		  == NULL))
18123d8817e4Smiod 	  || (sym->flags & BSF_FUNCTION) != 0)
18133d8817e4Smiod 	insns = TRUE;
18143d8817e4Smiod       else
18153d8817e4Smiod 	insns = FALSE;
18163d8817e4Smiod 
18173d8817e4Smiod       disassemble_bytes (pinfo, paux->disassemble_fn, insns, data,
18183d8817e4Smiod 			 addr_offset, nextstop_offset,
18193d8817e4Smiod 			 rel_offset, &rel_pp, rel_ppend);
18203d8817e4Smiod 
18213d8817e4Smiod       addr_offset = nextstop_offset;
18223d8817e4Smiod       sym = nextsym;
18233d8817e4Smiod     }
18243d8817e4Smiod 
18253d8817e4Smiod   free (data);
18263d8817e4Smiod 
18273d8817e4Smiod   if (rel_ppstart != NULL)
18283d8817e4Smiod     free (rel_ppstart);
18293d8817e4Smiod }
18303d8817e4Smiod 
18313d8817e4Smiod /* Disassemble the contents of an object file.  */
18323d8817e4Smiod 
18333d8817e4Smiod static void
disassemble_data(bfd * abfd)18343d8817e4Smiod disassemble_data (bfd *abfd)
18353d8817e4Smiod {
18363d8817e4Smiod   struct disassemble_info disasm_info;
18373d8817e4Smiod   struct objdump_disasm_info aux;
18383d8817e4Smiod   long i;
18393d8817e4Smiod 
18403d8817e4Smiod   print_files = NULL;
18413d8817e4Smiod   prev_functionname = NULL;
18423d8817e4Smiod   prev_line = -1;
18433d8817e4Smiod 
18443d8817e4Smiod   /* We make a copy of syms to sort.  We don't want to sort syms
18453d8817e4Smiod      because that will screw up the relocs.  */
18463d8817e4Smiod   sorted_symcount = symcount ? symcount : dynsymcount;
18473d8817e4Smiod   sorted_syms = xmalloc ((sorted_symcount + synthcount) * sizeof (asymbol *));
18483d8817e4Smiod   memcpy (sorted_syms, symcount ? syms : dynsyms,
18493d8817e4Smiod 	  sorted_symcount * sizeof (asymbol *));
18503d8817e4Smiod 
18513d8817e4Smiod   sorted_symcount = remove_useless_symbols (sorted_syms, sorted_symcount);
18523d8817e4Smiod 
18533d8817e4Smiod   for (i = 0; i < synthcount; ++i)
18543d8817e4Smiod     {
18553d8817e4Smiod       sorted_syms[sorted_symcount] = synthsyms + i;
18563d8817e4Smiod       ++sorted_symcount;
18573d8817e4Smiod     }
18583d8817e4Smiod 
18593d8817e4Smiod   /* Sort the symbols into section and symbol order.  */
18603d8817e4Smiod   qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
18613d8817e4Smiod 
18623d8817e4Smiod   init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf);
18633d8817e4Smiod 
18643d8817e4Smiod   disasm_info.application_data = (void *) &aux;
18653d8817e4Smiod   aux.abfd = abfd;
18663d8817e4Smiod   aux.require_sec = FALSE;
18673d8817e4Smiod   aux.dynrelbuf = NULL;
18683d8817e4Smiod   aux.dynrelcount = 0;
18693d8817e4Smiod   aux.reloc = NULL;
18703d8817e4Smiod 
18713d8817e4Smiod   disasm_info.print_address_func = objdump_print_address;
18723d8817e4Smiod   disasm_info.symbol_at_address_func = objdump_symbol_at_address;
18733d8817e4Smiod 
18743d8817e4Smiod   if (machine != NULL)
18753d8817e4Smiod     {
18763d8817e4Smiod       const bfd_arch_info_type *info = bfd_scan_arch (machine);
18773d8817e4Smiod 
18783d8817e4Smiod       if (info == NULL)
18793d8817e4Smiod 	fatal (_("Can't use supplied machine %s"), machine);
18803d8817e4Smiod 
18813d8817e4Smiod       abfd->arch_info = info;
18823d8817e4Smiod     }
18833d8817e4Smiod 
18843d8817e4Smiod   if (endian != BFD_ENDIAN_UNKNOWN)
18853d8817e4Smiod     {
18863d8817e4Smiod       struct bfd_target *xvec;
18873d8817e4Smiod 
18883d8817e4Smiod       xvec = xmalloc (sizeof (struct bfd_target));
18893d8817e4Smiod       memcpy (xvec, abfd->xvec, sizeof (struct bfd_target));
18903d8817e4Smiod       xvec->byteorder = endian;
18913d8817e4Smiod       abfd->xvec = xvec;
18923d8817e4Smiod     }
18933d8817e4Smiod 
18943d8817e4Smiod   /* Use libopcodes to locate a suitable disassembler.  */
18953d8817e4Smiod   aux.disassemble_fn = disassembler (abfd);
18963d8817e4Smiod   if (!aux.disassemble_fn)
18973d8817e4Smiod     {
18983d8817e4Smiod       non_fatal (_("Can't disassemble for architecture %s\n"),
18993d8817e4Smiod 		 bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
19003d8817e4Smiod       exit_status = 1;
19013d8817e4Smiod       return;
19023d8817e4Smiod     }
19033d8817e4Smiod 
19043d8817e4Smiod   disasm_info.flavour = bfd_get_flavour (abfd);
19053d8817e4Smiod   disasm_info.arch = bfd_get_arch (abfd);
19063d8817e4Smiod   disasm_info.mach = bfd_get_mach (abfd);
19073d8817e4Smiod   disasm_info.disassembler_options = disassembler_options;
19083d8817e4Smiod   disasm_info.octets_per_byte = bfd_octets_per_byte (abfd);
19093d8817e4Smiod   disasm_info.skip_zeroes = DEFAULT_SKIP_ZEROES;
19103d8817e4Smiod   disasm_info.skip_zeroes_at_end = DEFAULT_SKIP_ZEROES_AT_END;
19113d8817e4Smiod   disasm_info.disassembler_needs_relocs = FALSE;
19123d8817e4Smiod 
19133d8817e4Smiod   if (bfd_big_endian (abfd))
19143d8817e4Smiod     disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_BIG;
19153d8817e4Smiod   else if (bfd_little_endian (abfd))
19163d8817e4Smiod     disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE;
19173d8817e4Smiod   else
19183d8817e4Smiod     /* ??? Aborting here seems too drastic.  We could default to big or little
19193d8817e4Smiod        instead.  */
19203d8817e4Smiod     disasm_info.endian = BFD_ENDIAN_UNKNOWN;
19213d8817e4Smiod 
19223d8817e4Smiod   /* Allow the target to customize the info structure.  */
19233d8817e4Smiod   disassemble_init_for_target (& disasm_info);
19243d8817e4Smiod 
19253d8817e4Smiod   /* Pre-load the dynamic relocs if we are going
19263d8817e4Smiod      to be dumping them along with the disassembly.  */
19273d8817e4Smiod   if (dump_dynamic_reloc_info)
19283d8817e4Smiod     {
19293d8817e4Smiod       long relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
19303d8817e4Smiod 
19313d8817e4Smiod       if (relsize < 0)
19323d8817e4Smiod 	bfd_fatal (bfd_get_filename (abfd));
19333d8817e4Smiod 
19343d8817e4Smiod       if (relsize > 0)
19353d8817e4Smiod 	{
19363d8817e4Smiod 	  aux.dynrelbuf = xmalloc (relsize);
19373d8817e4Smiod 	  aux.dynrelcount = bfd_canonicalize_dynamic_reloc (abfd,
19383d8817e4Smiod 							    aux.dynrelbuf,
19393d8817e4Smiod 							    dynsyms);
19403d8817e4Smiod 	  if (aux.dynrelcount < 0)
19413d8817e4Smiod 	    bfd_fatal (bfd_get_filename (abfd));
19423d8817e4Smiod 
19433d8817e4Smiod 	  /* Sort the relocs by address.  */
19443d8817e4Smiod 	  qsort (aux.dynrelbuf, aux.dynrelcount, sizeof (arelent *),
19453d8817e4Smiod 		 compare_relocs);
19463d8817e4Smiod 	}
19473d8817e4Smiod     }
19483d8817e4Smiod 
19493d8817e4Smiod   bfd_map_over_sections (abfd, disassemble_section, & disasm_info);
19503d8817e4Smiod 
19513d8817e4Smiod   if (aux.dynrelbuf != NULL)
19523d8817e4Smiod     free (aux.dynrelbuf);
19533d8817e4Smiod   free (sorted_syms);
19543d8817e4Smiod }
19553d8817e4Smiod 
19563d8817e4Smiod int
load_debug_section(enum dwarf_section_display_enum debug,void * file)19573d8817e4Smiod load_debug_section (enum dwarf_section_display_enum debug, void *file)
19583d8817e4Smiod {
19593d8817e4Smiod   struct dwarf_section *section = &debug_displays [debug].section;
19603d8817e4Smiod   bfd *abfd = file;
19613d8817e4Smiod   asection *sec;
19623d8817e4Smiod   bfd_boolean ret;
19633d8817e4Smiod 
19643d8817e4Smiod   /* If it is already loaded, do nothing.  */
19653d8817e4Smiod   if (section->start != NULL)
19663d8817e4Smiod     return 1;
19673d8817e4Smiod 
19683d8817e4Smiod   /* Locate the debug section.  */
19693d8817e4Smiod   sec = bfd_get_section_by_name (abfd, section->name);
19703d8817e4Smiod   if (sec == NULL)
19713d8817e4Smiod     return 0;
19723d8817e4Smiod 
19733d8817e4Smiod   section->address = bfd_get_section_vma (abfd, sec);
19743d8817e4Smiod   section->size = bfd_get_section_size (sec);
19753d8817e4Smiod   section->start = xmalloc (section->size);
19763d8817e4Smiod 
19773d8817e4Smiod   if (is_relocatable && debug_displays [debug].relocate)
19783d8817e4Smiod     ret = bfd_simple_get_relocated_section_contents (abfd,
19793d8817e4Smiod 						     sec,
19803d8817e4Smiod 						     section->start,
19813d8817e4Smiod 						     syms) != NULL;
19823d8817e4Smiod   else
19833d8817e4Smiod     ret = bfd_get_section_contents (abfd, sec, section->start, 0,
19843d8817e4Smiod 				    section->size);
19853d8817e4Smiod 
19863d8817e4Smiod   if (!ret)
19873d8817e4Smiod     {
19883d8817e4Smiod       free_debug_section (debug);
19893d8817e4Smiod       printf (_("\nCan't get contents for section '%s'.\n"),
19903d8817e4Smiod 	      section->name);
19913d8817e4Smiod     }
19923d8817e4Smiod 
19933d8817e4Smiod   return ret;
19943d8817e4Smiod }
19953d8817e4Smiod 
19963d8817e4Smiod void
free_debug_section(enum dwarf_section_display_enum debug)19973d8817e4Smiod free_debug_section (enum dwarf_section_display_enum debug)
19983d8817e4Smiod {
19993d8817e4Smiod   struct dwarf_section *section = &debug_displays [debug].section;
20003d8817e4Smiod 
20013d8817e4Smiod   if (section->start == NULL)
20023d8817e4Smiod     return;
20033d8817e4Smiod 
20043d8817e4Smiod   free ((char *) section->start);
20053d8817e4Smiod   section->start = NULL;
20063d8817e4Smiod   section->address = 0;
20073d8817e4Smiod   section->size = 0;
20083d8817e4Smiod }
20093d8817e4Smiod 
20103d8817e4Smiod static void
dump_dwarf_section(bfd * abfd,asection * section,void * arg ATTRIBUTE_UNUSED)20113d8817e4Smiod dump_dwarf_section (bfd *abfd, asection *section,
20123d8817e4Smiod 		    void *arg ATTRIBUTE_UNUSED)
20133d8817e4Smiod {
20143d8817e4Smiod   const char *name = bfd_get_section_name (abfd, section);
20153d8817e4Smiod   const char *match;
20163d8817e4Smiod   enum dwarf_section_display_enum i;
20173d8817e4Smiod 
20183d8817e4Smiod   if (strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
20193d8817e4Smiod     match = ".debug_info";
20203d8817e4Smiod   else
20213d8817e4Smiod     match = name;
20223d8817e4Smiod 
20233d8817e4Smiod   for (i = 0; i < max; i++)
20243d8817e4Smiod     if (strcmp (debug_displays[i].section.name, match) == 0)
20253d8817e4Smiod       {
20263d8817e4Smiod 	if (!debug_displays[i].eh_frame)
20273d8817e4Smiod 	  {
20283d8817e4Smiod 	    struct dwarf_section *sec = &debug_displays [i].section;
20293d8817e4Smiod 
20303d8817e4Smiod 	    if (load_debug_section (i, abfd))
20313d8817e4Smiod 	      {
20323d8817e4Smiod 		debug_displays[i].display (sec, abfd);
20333d8817e4Smiod 
20343d8817e4Smiod 		if (i != info && i != abbrev)
20353d8817e4Smiod 		  free_debug_section (i);
20363d8817e4Smiod 	      }
20373d8817e4Smiod 	  }
20383d8817e4Smiod 	break;
20393d8817e4Smiod       }
20403d8817e4Smiod }
20413d8817e4Smiod 
20423d8817e4Smiod static const char *mach_o_dwarf_sections [] = {
20433d8817e4Smiod   "LC_SEGMENT.__DWARFA.__debug_abbrev",		/* .debug_abbrev */
20443d8817e4Smiod   "LC_SEGMENT.__DWARFA.__debug_aranges",	/* .debug_aranges */
20453d8817e4Smiod   "LC_SEGMENT.__DWARFA.__debug_frame",		/* .debug_frame */
20463d8817e4Smiod   "LC_SEGMENT.__DWARFA.__debug_info",		/* .debug_info */
20473d8817e4Smiod   "LC_SEGMENT.__DWARFA.__debug_line",		/* .debug_line */
20483d8817e4Smiod   "LC_SEGMENT.__DWARFA.__debug_pubnames",	/* .debug_pubnames */
20493d8817e4Smiod   ".eh_frame",					/* .eh_frame */
20503d8817e4Smiod   "LC_SEGMENT.__DWARFA.__debug_macinfo",	/* .debug_macinfo */
20513d8817e4Smiod   "LC_SEGMENT.__DWARFA.__debug_str",		/* .debug_str */
20523d8817e4Smiod   "LC_SEGMENT.__DWARFA.__debug_loc",		/* .debug_loc */
20533d8817e4Smiod   "LC_SEGMENT.__DWARFA.__debug_pubtypes",	/* .debug_pubtypes */
20543d8817e4Smiod   "LC_SEGMENT.__DWARFA.__debug_ranges",		/* .debug_ranges */
20553d8817e4Smiod   "LC_SEGMENT.__DWARFA.__debug_static_func",	/* .debug_static_func */
20563d8817e4Smiod   "LC_SEGMENT.__DWARFA.__debug_static_vars",	/* .debug_static_vars */
20573d8817e4Smiod   "LC_SEGMENT.__DWARFA.__debug_types",		/* .debug_types */
20583d8817e4Smiod   "LC_SEGMENT.__DWARFA.__debug_weaknames"	/* .debug_weaknames */
20593d8817e4Smiod };
20603d8817e4Smiod 
20613d8817e4Smiod static const char *generic_dwarf_sections [max];
20623d8817e4Smiod 
20633d8817e4Smiod static void
check_mach_o_dwarf(bfd * abfd)20643d8817e4Smiod check_mach_o_dwarf (bfd *abfd)
20653d8817e4Smiod {
20663d8817e4Smiod   static enum bfd_flavour old_flavour = bfd_target_unknown_flavour;
20673d8817e4Smiod   enum bfd_flavour current_flavour = bfd_get_flavour (abfd);
20683d8817e4Smiod   enum dwarf_section_display_enum i;
20693d8817e4Smiod 
20703d8817e4Smiod   if (generic_dwarf_sections [0] == NULL)
20713d8817e4Smiod     for (i = 0; i < max; i++)
20723d8817e4Smiod       generic_dwarf_sections [i] = debug_displays[i].section.name;
20733d8817e4Smiod 
20743d8817e4Smiod   if (old_flavour != current_flavour)
20753d8817e4Smiod     {
20763d8817e4Smiod       if (current_flavour == bfd_target_mach_o_flavour)
20773d8817e4Smiod 	for (i = 0; i < max; i++)
20783d8817e4Smiod 	  debug_displays[i].section.name = mach_o_dwarf_sections [i];
20793d8817e4Smiod       else if (old_flavour == bfd_target_mach_o_flavour)
20803d8817e4Smiod 	for (i = 0; i < max; i++)
20813d8817e4Smiod 	  debug_displays[i].section.name = generic_dwarf_sections [i];
20823d8817e4Smiod 
20833d8817e4Smiod       old_flavour = current_flavour;
20843d8817e4Smiod     }
20853d8817e4Smiod }
20863d8817e4Smiod 
20873d8817e4Smiod /* Dump the dwarf debugging information.  */
20883d8817e4Smiod 
20893d8817e4Smiod static void
dump_dwarf(bfd * abfd)20903d8817e4Smiod dump_dwarf (bfd *abfd)
20913d8817e4Smiod {
20923d8817e4Smiod   is_relocatable = ((abfd->flags & (HAS_RELOC | EXEC_P | DYNAMIC))
20933d8817e4Smiod 		    == HAS_RELOC);
20943d8817e4Smiod 
20953d8817e4Smiod   /* FIXME: bfd_get_arch_size may return -1.  We assume that 64bit
20963d8817e4Smiod      targets will return 64.  */
20973d8817e4Smiod   eh_addr_size = bfd_get_arch_size (abfd) == 64 ? 8 : 4;
20983d8817e4Smiod 
20993d8817e4Smiod   if (bfd_big_endian (abfd))
21003d8817e4Smiod     byte_get = byte_get_big_endian;
21013d8817e4Smiod   else if (bfd_little_endian (abfd))
21023d8817e4Smiod     byte_get = byte_get_little_endian;
21033d8817e4Smiod   else
21043d8817e4Smiod     abort ();
21053d8817e4Smiod 
21063d8817e4Smiod   check_mach_o_dwarf (abfd);
21073d8817e4Smiod 
21083d8817e4Smiod   bfd_map_over_sections (abfd, dump_dwarf_section, NULL);
21093d8817e4Smiod 
21103d8817e4Smiod   free_debug_memory ();
21113d8817e4Smiod }
21123d8817e4Smiod 
21133d8817e4Smiod /* Read ABFD's stabs section STABSECT_NAME, and return a pointer to
21143d8817e4Smiod    it.  Return NULL on failure.   */
21153d8817e4Smiod 
21163d8817e4Smiod static char *
read_section_stabs(bfd * abfd,const char * sect_name,bfd_size_type * size_ptr)21173d8817e4Smiod read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr)
21183d8817e4Smiod {
21193d8817e4Smiod   asection *stabsect;
21203d8817e4Smiod   bfd_size_type size;
21213d8817e4Smiod   char *contents;
21223d8817e4Smiod 
21233d8817e4Smiod   stabsect = bfd_get_section_by_name (abfd, sect_name);
21243d8817e4Smiod   if (stabsect == NULL)
21253d8817e4Smiod     {
21263d8817e4Smiod       printf (_("No %s section present\n\n"), sect_name);
21273d8817e4Smiod       return FALSE;
21283d8817e4Smiod     }
21293d8817e4Smiod 
21303d8817e4Smiod   size = bfd_section_size (abfd, stabsect);
21313d8817e4Smiod   contents  = xmalloc (size);
21323d8817e4Smiod 
21333d8817e4Smiod   if (! bfd_get_section_contents (abfd, stabsect, contents, 0, size))
21343d8817e4Smiod     {
21353d8817e4Smiod       non_fatal (_("Reading %s section of %s failed: %s"),
21363d8817e4Smiod 		 sect_name, bfd_get_filename (abfd),
21373d8817e4Smiod 		 bfd_errmsg (bfd_get_error ()));
21383d8817e4Smiod       free (contents);
21393d8817e4Smiod       exit_status = 1;
21403d8817e4Smiod       return NULL;
21413d8817e4Smiod     }
21423d8817e4Smiod 
21433d8817e4Smiod   *size_ptr = size;
21443d8817e4Smiod 
21453d8817e4Smiod   return contents;
21463d8817e4Smiod }
21473d8817e4Smiod 
21483d8817e4Smiod /* Stabs entries use a 12 byte format:
21493d8817e4Smiod      4 byte string table index
21503d8817e4Smiod      1 byte stab type
21513d8817e4Smiod      1 byte stab other field
21523d8817e4Smiod      2 byte stab desc field
21533d8817e4Smiod      4 byte stab value
21543d8817e4Smiod    FIXME: This will have to change for a 64 bit object format.  */
21553d8817e4Smiod 
21563d8817e4Smiod #define STRDXOFF  (0)
21573d8817e4Smiod #define TYPEOFF   (4)
21583d8817e4Smiod #define OTHEROFF  (5)
21593d8817e4Smiod #define DESCOFF   (6)
21603d8817e4Smiod #define VALOFF    (8)
21613d8817e4Smiod #define STABSIZE (12)
21623d8817e4Smiod 
21633d8817e4Smiod /* Print ABFD's stabs section STABSECT_NAME (in `stabs'),
21643d8817e4Smiod    using string table section STRSECT_NAME (in `strtab').  */
21653d8817e4Smiod 
21663d8817e4Smiod static void
print_section_stabs(bfd * abfd,const char * stabsect_name,unsigned * string_offset_ptr)21673d8817e4Smiod print_section_stabs (bfd *abfd,
21683d8817e4Smiod 		     const char *stabsect_name,
21693d8817e4Smiod 		     unsigned *string_offset_ptr)
21703d8817e4Smiod {
21713d8817e4Smiod   int i;
21723d8817e4Smiod   unsigned file_string_table_offset = 0;
21733d8817e4Smiod   unsigned next_file_string_table_offset = *string_offset_ptr;
21743d8817e4Smiod   bfd_byte *stabp, *stabs_end;
21753d8817e4Smiod 
21763d8817e4Smiod   stabp = stabs;
21773d8817e4Smiod   stabs_end = stabp + stab_size;
21783d8817e4Smiod 
21793d8817e4Smiod   printf (_("Contents of %s section:\n\n"), stabsect_name);
21803d8817e4Smiod   printf ("Symnum n_type n_othr n_desc n_value  n_strx String\n");
21813d8817e4Smiod 
21823d8817e4Smiod   /* Loop through all symbols and print them.
21833d8817e4Smiod 
21843d8817e4Smiod      We start the index at -1 because there is a dummy symbol on
21853d8817e4Smiod      the front of stabs-in-{coff,elf} sections that supplies sizes.  */
21863d8817e4Smiod   for (i = -1; stabp < stabs_end; stabp += STABSIZE, i++)
21873d8817e4Smiod     {
21883d8817e4Smiod       const char *name;
21893d8817e4Smiod       unsigned long strx;
21903d8817e4Smiod       unsigned char type, other;
21913d8817e4Smiod       unsigned short desc;
21923d8817e4Smiod       bfd_vma value;
21933d8817e4Smiod 
21943d8817e4Smiod       strx = bfd_h_get_32 (abfd, stabp + STRDXOFF);
21953d8817e4Smiod       type = bfd_h_get_8 (abfd, stabp + TYPEOFF);
21963d8817e4Smiod       other = bfd_h_get_8 (abfd, stabp + OTHEROFF);
21973d8817e4Smiod       desc = bfd_h_get_16 (abfd, stabp + DESCOFF);
21983d8817e4Smiod       value = bfd_h_get_32 (abfd, stabp + VALOFF);
21993d8817e4Smiod 
22003d8817e4Smiod       printf ("\n%-6d ", i);
22013d8817e4Smiod       /* Either print the stab name, or, if unnamed, print its number
22023d8817e4Smiod 	 again (makes consistent formatting for tools like awk).  */
22033d8817e4Smiod       name = bfd_get_stab_name (type);
22043d8817e4Smiod       if (name != NULL)
22053d8817e4Smiod 	printf ("%-6s", name);
22063d8817e4Smiod       else if (type == N_UNDF)
22073d8817e4Smiod 	printf ("HdrSym");
22083d8817e4Smiod       else
22093d8817e4Smiod 	printf ("%-6d", type);
22103d8817e4Smiod       printf (" %-6d %-6d ", other, desc);
22113d8817e4Smiod       bfd_printf_vma (abfd, value);
22123d8817e4Smiod       printf (" %-6lu", strx);
22133d8817e4Smiod 
22143d8817e4Smiod       /* Symbols with type == 0 (N_UNDF) specify the length of the
22153d8817e4Smiod 	 string table associated with this file.  We use that info
22163d8817e4Smiod 	 to know how to relocate the *next* file's string table indices.  */
22173d8817e4Smiod       if (type == N_UNDF)
22183d8817e4Smiod 	{
22193d8817e4Smiod 	  file_string_table_offset = next_file_string_table_offset;
22203d8817e4Smiod 	  next_file_string_table_offset += value;
22213d8817e4Smiod 	}
22223d8817e4Smiod       else
22233d8817e4Smiod 	{
22243d8817e4Smiod 	  /* Using the (possibly updated) string table offset, print the
22253d8817e4Smiod 	     string (if any) associated with this symbol.  */
22263d8817e4Smiod 	  if ((strx + file_string_table_offset) < stabstr_size)
22273d8817e4Smiod 	    printf (" %s", &strtab[strx + file_string_table_offset]);
22283d8817e4Smiod 	  else
22293d8817e4Smiod 	    printf (" *");
22303d8817e4Smiod 	}
22313d8817e4Smiod     }
22323d8817e4Smiod   printf ("\n\n");
22333d8817e4Smiod   *string_offset_ptr = next_file_string_table_offset;
22343d8817e4Smiod }
22353d8817e4Smiod 
22363d8817e4Smiod typedef struct
22373d8817e4Smiod {
22383d8817e4Smiod   const char * section_name;
22393d8817e4Smiod   const char * string_section_name;
22403d8817e4Smiod   unsigned string_offset;
22413d8817e4Smiod }
22423d8817e4Smiod stab_section_names;
22433d8817e4Smiod 
22443d8817e4Smiod static void
find_stabs_section(bfd * abfd,asection * section,void * names)22453d8817e4Smiod find_stabs_section (bfd *abfd, asection *section, void *names)
22463d8817e4Smiod {
22473d8817e4Smiod   int len;
22483d8817e4Smiod   stab_section_names * sought = (stab_section_names *) names;
22493d8817e4Smiod 
22503d8817e4Smiod   /* Check for section names for which stabsect_name is a prefix, to
22513d8817e4Smiod      handle .stab.N, etc.  */
22523d8817e4Smiod   len = strlen (sought->section_name);
22533d8817e4Smiod 
22543d8817e4Smiod   /* If the prefix matches, and the files section name ends with a
22553d8817e4Smiod      nul or a digit, then we match.  I.e., we want either an exact
22563d8817e4Smiod      match or a section followed by a number.  */
22573d8817e4Smiod   if (strncmp (sought->section_name, section->name, len) == 0
22583d8817e4Smiod       && (section->name[len] == 0
22593d8817e4Smiod 	  || (section->name[len] == '.' && ISDIGIT (section->name[len + 1]))))
22603d8817e4Smiod     {
22613d8817e4Smiod       if (strtab == NULL)
22623d8817e4Smiod 	strtab = read_section_stabs (abfd, sought->string_section_name,
22633d8817e4Smiod 				     &stabstr_size);
22643d8817e4Smiod 
22653d8817e4Smiod       if (strtab)
22663d8817e4Smiod 	{
22673d8817e4Smiod 	  stabs = (bfd_byte *) read_section_stabs (abfd, section->name,
22683d8817e4Smiod 						   &stab_size);
22693d8817e4Smiod 	  if (stabs)
22703d8817e4Smiod 	    print_section_stabs (abfd, section->name, &sought->string_offset);
22713d8817e4Smiod 	}
22723d8817e4Smiod     }
22733d8817e4Smiod }
22743d8817e4Smiod 
22753d8817e4Smiod static void
dump_stabs_section(bfd * abfd,char * stabsect_name,char * strsect_name)22763d8817e4Smiod dump_stabs_section (bfd *abfd, char *stabsect_name, char *strsect_name)
22773d8817e4Smiod {
22783d8817e4Smiod   stab_section_names s;
22793d8817e4Smiod 
22803d8817e4Smiod   s.section_name = stabsect_name;
22813d8817e4Smiod   s.string_section_name = strsect_name;
22823d8817e4Smiod   s.string_offset = 0;
22833d8817e4Smiod 
22843d8817e4Smiod   bfd_map_over_sections (abfd, find_stabs_section, & s);
22853d8817e4Smiod 
22863d8817e4Smiod   free (strtab);
22873d8817e4Smiod   strtab = NULL;
22883d8817e4Smiod }
22893d8817e4Smiod 
22903d8817e4Smiod /* Dump the any sections containing stabs debugging information.  */
22913d8817e4Smiod 
22923d8817e4Smiod static void
dump_stabs(bfd * abfd)22933d8817e4Smiod dump_stabs (bfd *abfd)
22943d8817e4Smiod {
22953d8817e4Smiod   dump_stabs_section (abfd, ".stab", ".stabstr");
22963d8817e4Smiod   dump_stabs_section (abfd, ".stab.excl", ".stab.exclstr");
22973d8817e4Smiod   dump_stabs_section (abfd, ".stab.index", ".stab.indexstr");
22983d8817e4Smiod   dump_stabs_section (abfd, "$GDB_SYMBOLS$", "$GDB_STRINGS$");
22993d8817e4Smiod }
23003d8817e4Smiod 
23013d8817e4Smiod static void
dump_bfd_header(bfd * abfd)23023d8817e4Smiod dump_bfd_header (bfd *abfd)
23033d8817e4Smiod {
23043d8817e4Smiod   char *comma = "";
23053d8817e4Smiod 
23063d8817e4Smiod   printf (_("architecture: %s, "),
23073d8817e4Smiod 	  bfd_printable_arch_mach (bfd_get_arch (abfd),
23083d8817e4Smiod 				   bfd_get_mach (abfd)));
23093d8817e4Smiod   printf (_("flags 0x%08x:\n"), abfd->flags);
23103d8817e4Smiod 
23113d8817e4Smiod #define PF(x, y)    if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
23123d8817e4Smiod   PF (HAS_RELOC, "HAS_RELOC");
23133d8817e4Smiod   PF (EXEC_P, "EXEC_P");
23143d8817e4Smiod   PF (HAS_LINENO, "HAS_LINENO");
23153d8817e4Smiod   PF (HAS_DEBUG, "HAS_DEBUG");
23163d8817e4Smiod   PF (HAS_SYMS, "HAS_SYMS");
23173d8817e4Smiod   PF (HAS_LOCALS, "HAS_LOCALS");
23183d8817e4Smiod   PF (DYNAMIC, "DYNAMIC");
23193d8817e4Smiod   PF (WP_TEXT, "WP_TEXT");
23203d8817e4Smiod   PF (D_PAGED, "D_PAGED");
23213d8817e4Smiod   PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
23223d8817e4Smiod   PF (HAS_LOAD_PAGE, "HAS_LOAD_PAGE");
23233d8817e4Smiod   printf (_("\nstart address 0x"));
23243d8817e4Smiod   bfd_printf_vma (abfd, abfd->start_address);
23253d8817e4Smiod   printf ("\n");
23263d8817e4Smiod }
23273d8817e4Smiod 
23283d8817e4Smiod 
23293d8817e4Smiod static void
dump_bfd_private_header(bfd * abfd)23303d8817e4Smiod dump_bfd_private_header (bfd *abfd)
23313d8817e4Smiod {
23323d8817e4Smiod   bfd_print_private_bfd_data (abfd, stdout);
23333d8817e4Smiod }
23343d8817e4Smiod 
23353d8817e4Smiod 
23363d8817e4Smiod /* Display a section in hexadecimal format with associated characters.
23373d8817e4Smiod    Each line prefixed by the zero padded address.  */
23383d8817e4Smiod 
23393d8817e4Smiod static void
dump_section(bfd * abfd,asection * section,void * dummy ATTRIBUTE_UNUSED)23403d8817e4Smiod dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
23413d8817e4Smiod {
23423d8817e4Smiod   bfd_byte *data = 0;
23433d8817e4Smiod   bfd_size_type datasize;
23443d8817e4Smiod   bfd_size_type addr_offset;
23453d8817e4Smiod   bfd_size_type start_offset;
23463d8817e4Smiod   bfd_size_type stop_offset;
23473d8817e4Smiod   unsigned int opb = bfd_octets_per_byte (abfd);
23483d8817e4Smiod   /* Bytes per line.  */
23493d8817e4Smiod   const int onaline = 16;
23503d8817e4Smiod   char buf[64];
23513d8817e4Smiod   int count;
23523d8817e4Smiod   int width;
23533d8817e4Smiod 
23543d8817e4Smiod   if ((section->flags & SEC_HAS_CONTENTS) == 0)
23553d8817e4Smiod     return;
23563d8817e4Smiod 
23573d8817e4Smiod   if (! process_section_p (section))
23583d8817e4Smiod     return;
23593d8817e4Smiod 
23603d8817e4Smiod   if ((datasize = bfd_section_size (abfd, section)) == 0)
23613d8817e4Smiod     return;
23623d8817e4Smiod 
23633d8817e4Smiod   printf (_("Contents of section %s:\n"), section->name);
23643d8817e4Smiod 
23653d8817e4Smiod   data = xmalloc (datasize);
23663d8817e4Smiod 
23673d8817e4Smiod   bfd_get_section_contents (abfd, section, data, 0, datasize);
23683d8817e4Smiod 
23693d8817e4Smiod   /* Compute the address range to display.  */
23703d8817e4Smiod   if (start_address == (bfd_vma) -1
23713d8817e4Smiod       || start_address < section->vma)
23723d8817e4Smiod     start_offset = 0;
23733d8817e4Smiod   else
23743d8817e4Smiod     start_offset = start_address - section->vma;
23753d8817e4Smiod 
23763d8817e4Smiod   if (stop_address == (bfd_vma) -1)
23773d8817e4Smiod     stop_offset = datasize / opb;
23783d8817e4Smiod   else
23793d8817e4Smiod     {
23803d8817e4Smiod       if (stop_address < section->vma)
23813d8817e4Smiod 	stop_offset = 0;
23823d8817e4Smiod       else
23833d8817e4Smiod 	stop_offset = stop_address - section->vma;
23843d8817e4Smiod 
23853d8817e4Smiod       if (stop_offset > datasize / opb)
23863d8817e4Smiod 	stop_offset = datasize / opb;
23873d8817e4Smiod     }
23883d8817e4Smiod 
23893d8817e4Smiod   width = 4;
23903d8817e4Smiod 
23913d8817e4Smiod   bfd_sprintf_vma (abfd, buf, start_offset + section->vma);
23923d8817e4Smiod   if (strlen (buf) >= sizeof (buf))
23933d8817e4Smiod     abort ();
23943d8817e4Smiod 
23953d8817e4Smiod   count = 0;
23963d8817e4Smiod   while (buf[count] == '0' && buf[count+1] != '\0')
23973d8817e4Smiod     count++;
23983d8817e4Smiod   count = strlen (buf) - count;
23993d8817e4Smiod   if (count > width)
24003d8817e4Smiod     width = count;
24013d8817e4Smiod 
24023d8817e4Smiod   bfd_sprintf_vma (abfd, buf, stop_offset + section->vma - 1);
24033d8817e4Smiod   if (strlen (buf) >= sizeof (buf))
24043d8817e4Smiod     abort ();
24053d8817e4Smiod 
24063d8817e4Smiod   count = 0;
24073d8817e4Smiod   while (buf[count] == '0' && buf[count+1] != '\0')
24083d8817e4Smiod     count++;
24093d8817e4Smiod   count = strlen (buf) - count;
24103d8817e4Smiod   if (count > width)
24113d8817e4Smiod     width = count;
24123d8817e4Smiod 
24133d8817e4Smiod   for (addr_offset = start_offset;
24143d8817e4Smiod        addr_offset < stop_offset; addr_offset += onaline / opb)
24153d8817e4Smiod     {
24163d8817e4Smiod       bfd_size_type j;
24173d8817e4Smiod 
24183d8817e4Smiod       bfd_sprintf_vma (abfd, buf, (addr_offset + section->vma));
24193d8817e4Smiod       count = strlen (buf);
24203d8817e4Smiod       if ((size_t) count >= sizeof (buf))
24213d8817e4Smiod 	abort ();
24223d8817e4Smiod 
24233d8817e4Smiod       putchar (' ');
24243d8817e4Smiod       while (count < width)
24253d8817e4Smiod 	{
24263d8817e4Smiod 	  putchar ('0');
24273d8817e4Smiod 	  count++;
24283d8817e4Smiod 	}
24293d8817e4Smiod       fputs (buf + count - width, stdout);
24303d8817e4Smiod       putchar (' ');
24313d8817e4Smiod 
24323d8817e4Smiod       for (j = addr_offset * opb;
24333d8817e4Smiod 	   j < addr_offset * opb + onaline; j++)
24343d8817e4Smiod 	{
24353d8817e4Smiod 	  if (j < stop_offset * opb)
24363d8817e4Smiod 	    printf ("%02x", (unsigned) (data[j]));
24373d8817e4Smiod 	  else
24383d8817e4Smiod 	    printf ("  ");
24393d8817e4Smiod 	  if ((j & 3) == 3)
24403d8817e4Smiod 	    printf (" ");
24413d8817e4Smiod 	}
24423d8817e4Smiod 
24433d8817e4Smiod       printf (" ");
24443d8817e4Smiod       for (j = addr_offset * opb;
24453d8817e4Smiod 	   j < addr_offset * opb + onaline; j++)
24463d8817e4Smiod 	{
24473d8817e4Smiod 	  if (j >= stop_offset * opb)
24483d8817e4Smiod 	    printf (" ");
24493d8817e4Smiod 	  else
24503d8817e4Smiod 	    printf ("%c", ISPRINT (data[j]) ? data[j] : '.');
24513d8817e4Smiod 	}
24523d8817e4Smiod       putchar ('\n');
24533d8817e4Smiod     }
24543d8817e4Smiod   free (data);
24553d8817e4Smiod }
24563d8817e4Smiod 
24573d8817e4Smiod /* Actually display the various requested regions.  */
24583d8817e4Smiod 
24593d8817e4Smiod static void
dump_data(bfd * abfd)24603d8817e4Smiod dump_data (bfd *abfd)
24613d8817e4Smiod {
24623d8817e4Smiod   bfd_map_over_sections (abfd, dump_section, NULL);
24633d8817e4Smiod }
24643d8817e4Smiod 
24653d8817e4Smiod /* Should perhaps share code and display with nm?  */
24663d8817e4Smiod 
24673d8817e4Smiod static void
dump_symbols(bfd * abfd ATTRIBUTE_UNUSED,bfd_boolean dynamic)24683d8817e4Smiod dump_symbols (bfd *abfd ATTRIBUTE_UNUSED, bfd_boolean dynamic)
24693d8817e4Smiod {
24703d8817e4Smiod   asymbol **current;
24713d8817e4Smiod   long max;
24723d8817e4Smiod   long count;
24733d8817e4Smiod 
24743d8817e4Smiod   if (dynamic)
24753d8817e4Smiod     {
24763d8817e4Smiod       current = dynsyms;
24773d8817e4Smiod       max = dynsymcount;
24783d8817e4Smiod       printf ("DYNAMIC SYMBOL TABLE:\n");
24793d8817e4Smiod     }
24803d8817e4Smiod   else
24813d8817e4Smiod     {
24823d8817e4Smiod       current = syms;
24833d8817e4Smiod       max = symcount;
24843d8817e4Smiod       printf ("SYMBOL TABLE:\n");
24853d8817e4Smiod     }
24863d8817e4Smiod 
24873d8817e4Smiod   if (max == 0)
24883d8817e4Smiod     printf (_("no symbols\n"));
24893d8817e4Smiod 
24903d8817e4Smiod   for (count = 0; count < max; count++)
24913d8817e4Smiod     {
24923d8817e4Smiod       bfd *cur_bfd;
24933d8817e4Smiod 
24943d8817e4Smiod       if (*current == NULL)
24953d8817e4Smiod 	printf (_("no information for symbol number %ld\n"), count);
24963d8817e4Smiod 
24973d8817e4Smiod       else if ((cur_bfd = bfd_asymbol_bfd (*current)) == NULL)
24983d8817e4Smiod 	printf (_("could not determine the type of symbol number %ld\n"),
24993d8817e4Smiod 		count);
25003d8817e4Smiod 
25013d8817e4Smiod       else if (process_section_p ((* current)->section)
25023d8817e4Smiod 	       && (dump_special_syms
25033d8817e4Smiod 		   || !bfd_is_target_special_symbol (cur_bfd, *current)))
25043d8817e4Smiod 	{
25053d8817e4Smiod 	  const char *name = (*current)->name;
25063d8817e4Smiod 
25073d8817e4Smiod 	  if (do_demangle && name != NULL && *name != '\0')
25083d8817e4Smiod 	    {
25093d8817e4Smiod 	      char *alloc;
25103d8817e4Smiod 
25113d8817e4Smiod 	      /* If we want to demangle the name, we demangle it
25123d8817e4Smiod 		 here, and temporarily clobber it while calling
25133d8817e4Smiod 		 bfd_print_symbol.  FIXME: This is a gross hack.  */
25143d8817e4Smiod 	      alloc = demangle (cur_bfd, name);
25153d8817e4Smiod 	      (*current)->name = alloc;
25163d8817e4Smiod 	      bfd_print_symbol (cur_bfd, stdout, *current,
25173d8817e4Smiod 				bfd_print_symbol_all);
25183d8817e4Smiod 	      (*current)->name = name;
25193d8817e4Smiod 	      free (alloc);
25203d8817e4Smiod 	    }
25213d8817e4Smiod 	  else
25223d8817e4Smiod 	    bfd_print_symbol (cur_bfd, stdout, *current,
25233d8817e4Smiod 			      bfd_print_symbol_all);
25243d8817e4Smiod 	  printf ("\n");
25253d8817e4Smiod 	}
25263d8817e4Smiod 
25273d8817e4Smiod       current++;
25283d8817e4Smiod     }
25293d8817e4Smiod   printf ("\n\n");
25303d8817e4Smiod }
25313d8817e4Smiod 
25323d8817e4Smiod static void
dump_reloc_set(bfd * abfd,asection * sec,arelent ** relpp,long relcount)25333d8817e4Smiod dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
25343d8817e4Smiod {
25353d8817e4Smiod   arelent **p;
25363d8817e4Smiod   char *last_filename, *last_functionname;
25373d8817e4Smiod   unsigned int last_line;
25383d8817e4Smiod 
25393d8817e4Smiod   /* Get column headers lined up reasonably.  */
25403d8817e4Smiod   {
25413d8817e4Smiod     static int width;
25423d8817e4Smiod 
25433d8817e4Smiod     if (width == 0)
25443d8817e4Smiod       {
25453d8817e4Smiod 	char buf[30];
25463d8817e4Smiod 
25473d8817e4Smiod 	bfd_sprintf_vma (abfd, buf, (bfd_vma) -1);
25483d8817e4Smiod 	width = strlen (buf) - 7;
25493d8817e4Smiod       }
25503d8817e4Smiod     printf ("OFFSET %*s TYPE %*s VALUE \n", width, "", 12, "");
25513d8817e4Smiod   }
25523d8817e4Smiod 
25533d8817e4Smiod   last_filename = NULL;
25543d8817e4Smiod   last_functionname = NULL;
25553d8817e4Smiod   last_line = 0;
25563d8817e4Smiod 
25573d8817e4Smiod   for (p = relpp; relcount && *p != NULL; p++, relcount--)
25583d8817e4Smiod     {
25593d8817e4Smiod       arelent *q = *p;
25603d8817e4Smiod       const char *filename, *functionname;
25613d8817e4Smiod       unsigned int line;
25623d8817e4Smiod       const char *sym_name;
25633d8817e4Smiod       const char *section_name;
25643d8817e4Smiod 
25653d8817e4Smiod       if (start_address != (bfd_vma) -1
25663d8817e4Smiod 	  && q->address < start_address)
25673d8817e4Smiod 	continue;
25683d8817e4Smiod       if (stop_address != (bfd_vma) -1
25693d8817e4Smiod 	  && q->address > stop_address)
25703d8817e4Smiod 	continue;
25713d8817e4Smiod 
25723d8817e4Smiod       if (with_line_numbers
25733d8817e4Smiod 	  && sec != NULL
25743d8817e4Smiod 	  && bfd_find_nearest_line (abfd, sec, syms, q->address,
25753d8817e4Smiod 				    &filename, &functionname, &line))
25763d8817e4Smiod 	{
25773d8817e4Smiod 	  if (functionname != NULL
25783d8817e4Smiod 	      && (last_functionname == NULL
25793d8817e4Smiod 		  || strcmp (functionname, last_functionname) != 0))
25803d8817e4Smiod 	    {
25813d8817e4Smiod 	      printf ("%s():\n", functionname);
25823d8817e4Smiod 	      if (last_functionname != NULL)
25833d8817e4Smiod 		free (last_functionname);
25843d8817e4Smiod 	      last_functionname = xstrdup (functionname);
25853d8817e4Smiod 	    }
25863d8817e4Smiod 
25873d8817e4Smiod 	  if (line > 0
25883d8817e4Smiod 	      && (line != last_line
25893d8817e4Smiod 		  || (filename != NULL
25903d8817e4Smiod 		      && last_filename != NULL
25913d8817e4Smiod 		      && strcmp (filename, last_filename) != 0)))
25923d8817e4Smiod 	    {
25933d8817e4Smiod 	      printf ("%s:%u\n", filename == NULL ? "???" : filename, line);
25943d8817e4Smiod 	      last_line = line;
25953d8817e4Smiod 	      if (last_filename != NULL)
25963d8817e4Smiod 		free (last_filename);
25973d8817e4Smiod 	      if (filename == NULL)
25983d8817e4Smiod 		last_filename = NULL;
25993d8817e4Smiod 	      else
26003d8817e4Smiod 		last_filename = xstrdup (filename);
26013d8817e4Smiod 	    }
26023d8817e4Smiod 	}
26033d8817e4Smiod 
26043d8817e4Smiod       if (q->sym_ptr_ptr && *q->sym_ptr_ptr)
26053d8817e4Smiod 	{
26063d8817e4Smiod 	  sym_name = (*(q->sym_ptr_ptr))->name;
26073d8817e4Smiod 	  section_name = (*(q->sym_ptr_ptr))->section->name;
26083d8817e4Smiod 	}
26093d8817e4Smiod       else
26103d8817e4Smiod 	{
26113d8817e4Smiod 	  sym_name = NULL;
26123d8817e4Smiod 	  section_name = NULL;
26133d8817e4Smiod 	}
26143d8817e4Smiod 
26153d8817e4Smiod       bfd_printf_vma (abfd, q->address);
26163d8817e4Smiod       if (q->howto == NULL)
26173d8817e4Smiod 	printf (" *unknown*         ");
26183d8817e4Smiod       else if (q->howto->name)
26193d8817e4Smiod 	printf (" %-16s  ", q->howto->name);
26203d8817e4Smiod       else
26213d8817e4Smiod 	printf (" %-16d  ", q->howto->type);
26223d8817e4Smiod       if (sym_name)
26233d8817e4Smiod 	objdump_print_symname (abfd, NULL, *q->sym_ptr_ptr);
26243d8817e4Smiod       else
26253d8817e4Smiod 	{
26263d8817e4Smiod 	  if (section_name == NULL)
26273d8817e4Smiod 	    section_name = "*unknown*";
26283d8817e4Smiod 	  printf ("[%s]", section_name);
26293d8817e4Smiod 	}
26303d8817e4Smiod 
26313d8817e4Smiod       if (q->addend)
26323d8817e4Smiod 	{
26333d8817e4Smiod 	  printf ("+0x");
26343d8817e4Smiod 	  bfd_printf_vma (abfd, q->addend);
26353d8817e4Smiod 	}
26363d8817e4Smiod 
26373d8817e4Smiod       printf ("\n");
26383d8817e4Smiod     }
26393d8817e4Smiod }
26403d8817e4Smiod 
26413d8817e4Smiod static void
dump_relocs_in_section(bfd * abfd,asection * section,void * dummy ATTRIBUTE_UNUSED)26423d8817e4Smiod dump_relocs_in_section (bfd *abfd,
26433d8817e4Smiod 			asection *section,
26443d8817e4Smiod 			void *dummy ATTRIBUTE_UNUSED)
26453d8817e4Smiod {
26463d8817e4Smiod   arelent **relpp;
26473d8817e4Smiod   long relcount;
26483d8817e4Smiod   long relsize;
26493d8817e4Smiod 
26503d8817e4Smiod   if (   bfd_is_abs_section (section)
26513d8817e4Smiod       || bfd_is_und_section (section)
26523d8817e4Smiod       || bfd_is_com_section (section)
26533d8817e4Smiod       || (! process_section_p (section))
26543d8817e4Smiod       || ((section->flags & SEC_RELOC) == 0))
26553d8817e4Smiod     return;
26563d8817e4Smiod 
26573d8817e4Smiod   relsize = bfd_get_reloc_upper_bound (abfd, section);
26583d8817e4Smiod   if (relsize < 0)
26593d8817e4Smiod     bfd_fatal (bfd_get_filename (abfd));
26603d8817e4Smiod 
26613d8817e4Smiod   printf ("RELOCATION RECORDS FOR [%s]:", section->name);
26623d8817e4Smiod 
26633d8817e4Smiod   if (relsize == 0)
26643d8817e4Smiod     {
26653d8817e4Smiod       printf (" (none)\n\n");
26663d8817e4Smiod       return;
26673d8817e4Smiod     }
26683d8817e4Smiod 
26693d8817e4Smiod   relpp = xmalloc (relsize);
26703d8817e4Smiod   relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);
26713d8817e4Smiod 
26723d8817e4Smiod   if (relcount < 0)
26733d8817e4Smiod     bfd_fatal (bfd_get_filename (abfd));
26743d8817e4Smiod   else if (relcount == 0)
26753d8817e4Smiod     printf (" (none)\n\n");
26763d8817e4Smiod   else
26773d8817e4Smiod     {
26783d8817e4Smiod       printf ("\n");
26793d8817e4Smiod       dump_reloc_set (abfd, section, relpp, relcount);
26803d8817e4Smiod       printf ("\n\n");
26813d8817e4Smiod     }
26823d8817e4Smiod   free (relpp);
26833d8817e4Smiod }
26843d8817e4Smiod 
26853d8817e4Smiod static void
dump_relocs(bfd * abfd)26863d8817e4Smiod dump_relocs (bfd *abfd)
26873d8817e4Smiod {
26883d8817e4Smiod   bfd_map_over_sections (abfd, dump_relocs_in_section, NULL);
26893d8817e4Smiod }
26903d8817e4Smiod 
26913d8817e4Smiod static void
dump_dynamic_relocs(bfd * abfd)26923d8817e4Smiod dump_dynamic_relocs (bfd *abfd)
26933d8817e4Smiod {
26943d8817e4Smiod   long relsize;
26953d8817e4Smiod   arelent **relpp;
26963d8817e4Smiod   long relcount;
26973d8817e4Smiod 
26983d8817e4Smiod   relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
26993d8817e4Smiod   if (relsize < 0)
27003d8817e4Smiod     bfd_fatal (bfd_get_filename (abfd));
27013d8817e4Smiod 
27023d8817e4Smiod   printf ("DYNAMIC RELOCATION RECORDS");
27033d8817e4Smiod 
27043d8817e4Smiod   if (relsize == 0)
27053d8817e4Smiod     printf (" (none)\n\n");
27063d8817e4Smiod   else
27073d8817e4Smiod     {
27083d8817e4Smiod       relpp = xmalloc (relsize);
27093d8817e4Smiod       relcount = bfd_canonicalize_dynamic_reloc (abfd, relpp, dynsyms);
27103d8817e4Smiod 
27113d8817e4Smiod       if (relcount < 0)
27123d8817e4Smiod 	bfd_fatal (bfd_get_filename (abfd));
27133d8817e4Smiod       else if (relcount == 0)
27143d8817e4Smiod 	printf (" (none)\n\n");
27153d8817e4Smiod       else
27163d8817e4Smiod 	{
27173d8817e4Smiod 	  printf ("\n");
27183d8817e4Smiod 	  dump_reloc_set (abfd, NULL, relpp, relcount);
27193d8817e4Smiod 	  printf ("\n\n");
27203d8817e4Smiod 	}
27213d8817e4Smiod       free (relpp);
27223d8817e4Smiod     }
27233d8817e4Smiod }
27243d8817e4Smiod 
27253d8817e4Smiod /* Creates a table of paths, to search for source files.  */
27263d8817e4Smiod 
27273d8817e4Smiod static void
add_include_path(const char * path)27283d8817e4Smiod add_include_path (const char *path)
27293d8817e4Smiod {
27303d8817e4Smiod   if (path[0] == 0)
27313d8817e4Smiod     return;
27323d8817e4Smiod   include_path_count++;
27333d8817e4Smiod   include_paths = xrealloc (include_paths,
27343d8817e4Smiod 			    include_path_count * sizeof (*include_paths));
27353d8817e4Smiod #ifdef HAVE_DOS_BASED_FILE_SYSTEM
27363d8817e4Smiod   if (path[1] == ':' && path[2] == 0)
27373d8817e4Smiod     path = concat (path, ".", (const char *) 0);
27383d8817e4Smiod #endif
27393d8817e4Smiod   include_paths[include_path_count - 1] = path;
27403d8817e4Smiod }
27413d8817e4Smiod 
27423d8817e4Smiod static void
adjust_addresses(bfd * abfd ATTRIBUTE_UNUSED,asection * section,void * arg)27433d8817e4Smiod adjust_addresses (bfd *abfd ATTRIBUTE_UNUSED,
27443d8817e4Smiod 		  asection *section,
27453d8817e4Smiod 		  void *arg)
27463d8817e4Smiod {
27473d8817e4Smiod   if ((section->flags & SEC_DEBUGGING) == 0)
27483d8817e4Smiod     {
27493d8817e4Smiod       bfd_boolean *has_reloc_p = (bfd_boolean *) arg;
27503d8817e4Smiod       section->vma += adjust_section_vma;
27513d8817e4Smiod       if (*has_reloc_p)
27523d8817e4Smiod 	section->lma += adjust_section_vma;
27533d8817e4Smiod     }
27543d8817e4Smiod }
27553d8817e4Smiod 
27563d8817e4Smiod /* Dump selected contents of ABFD.  */
27573d8817e4Smiod 
27583d8817e4Smiod static void
dump_bfd(bfd * abfd)27593d8817e4Smiod dump_bfd (bfd *abfd)
27603d8817e4Smiod {
27613d8817e4Smiod   /* If we are adjusting section VMA's, change them all now.  Changing
27623d8817e4Smiod      the BFD information is a hack.  However, we must do it, or
27633d8817e4Smiod      bfd_find_nearest_line will not do the right thing.  */
27643d8817e4Smiod   if (adjust_section_vma != 0)
27653d8817e4Smiod     {
27663d8817e4Smiod       bfd_boolean has_reloc = (abfd->flags & HAS_RELOC);
27673d8817e4Smiod       bfd_map_over_sections (abfd, adjust_addresses, &has_reloc);
27683d8817e4Smiod     }
27693d8817e4Smiod 
27703d8817e4Smiod   if (! dump_debugging_tags)
27713d8817e4Smiod     printf (_("\n%s:     file format %s\n"), bfd_get_filename (abfd),
27723d8817e4Smiod 	    abfd->xvec->name);
27733d8817e4Smiod   if (dump_ar_hdrs)
27743d8817e4Smiod     print_arelt_descr (stdout, abfd, TRUE);
27753d8817e4Smiod   if (dump_file_header)
27763d8817e4Smiod     dump_bfd_header (abfd);
27773d8817e4Smiod   if (dump_private_headers)
27783d8817e4Smiod     dump_bfd_private_header (abfd);
27793d8817e4Smiod   if (! dump_debugging_tags)
27803d8817e4Smiod     putchar ('\n');
27813d8817e4Smiod   if (dump_section_headers)
27823d8817e4Smiod     dump_headers (abfd);
27833d8817e4Smiod 
27843d8817e4Smiod   if (dump_symtab
27853d8817e4Smiod       || dump_reloc_info
27863d8817e4Smiod       || disassemble
27873d8817e4Smiod       || dump_debugging
27883d8817e4Smiod       || dump_dwarf_section_info)
27893d8817e4Smiod     syms = slurp_symtab (abfd);
27903d8817e4Smiod   if (dump_dynamic_symtab || dump_dynamic_reloc_info
27913d8817e4Smiod       || (disassemble && bfd_get_dynamic_symtab_upper_bound (abfd) > 0))
27923d8817e4Smiod     dynsyms = slurp_dynamic_symtab (abfd);
27933d8817e4Smiod   if (disassemble)
27943d8817e4Smiod     {
27953d8817e4Smiod       synthcount = bfd_get_synthetic_symtab (abfd, symcount, syms,
27963d8817e4Smiod 					     dynsymcount, dynsyms, &synthsyms);
27973d8817e4Smiod       if (synthcount < 0)
27983d8817e4Smiod 	synthcount = 0;
27993d8817e4Smiod     }
28003d8817e4Smiod 
28013d8817e4Smiod   if (dump_symtab)
28023d8817e4Smiod     dump_symbols (abfd, FALSE);
28033d8817e4Smiod   if (dump_dynamic_symtab)
28043d8817e4Smiod     dump_symbols (abfd, TRUE);
28053d8817e4Smiod   if (dump_dwarf_section_info)
28063d8817e4Smiod     dump_dwarf (abfd);
28073d8817e4Smiod   if (dump_stab_section_info)
28083d8817e4Smiod     dump_stabs (abfd);
28093d8817e4Smiod   if (dump_reloc_info && ! disassemble)
28103d8817e4Smiod     dump_relocs (abfd);
28113d8817e4Smiod   if (dump_dynamic_reloc_info && ! disassemble)
28123d8817e4Smiod     dump_dynamic_relocs (abfd);
28133d8817e4Smiod   if (dump_section_contents)
28143d8817e4Smiod     dump_data (abfd);
28153d8817e4Smiod   if (disassemble)
28163d8817e4Smiod     disassemble_data (abfd);
28173d8817e4Smiod 
28183d8817e4Smiod   if (dump_debugging)
28193d8817e4Smiod     {
28203d8817e4Smiod       void *dhandle;
28213d8817e4Smiod 
28223d8817e4Smiod       dhandle = read_debugging_info (abfd, syms, symcount);
28233d8817e4Smiod       if (dhandle != NULL)
28243d8817e4Smiod 	{
28253d8817e4Smiod 	  if (! print_debugging_info (stdout, dhandle, abfd, syms, demangle,
28263d8817e4Smiod 	      dump_debugging_tags ? TRUE : FALSE))
28273d8817e4Smiod 	    {
28283d8817e4Smiod 	      non_fatal (_("%s: printing debugging information failed"),
28293d8817e4Smiod 			 bfd_get_filename (abfd));
28303d8817e4Smiod 	      exit_status = 1;
28313d8817e4Smiod 	    }
28323d8817e4Smiod 	}
28333d8817e4Smiod     }
28343d8817e4Smiod 
28353d8817e4Smiod   if (syms)
28363d8817e4Smiod     {
28373d8817e4Smiod       free (syms);
28383d8817e4Smiod       syms = NULL;
28393d8817e4Smiod     }
28403d8817e4Smiod 
28413d8817e4Smiod   if (dynsyms)
28423d8817e4Smiod     {
28433d8817e4Smiod       free (dynsyms);
28443d8817e4Smiod       dynsyms = NULL;
28453d8817e4Smiod     }
28463d8817e4Smiod 
28473d8817e4Smiod   if (synthsyms)
28483d8817e4Smiod     {
28493d8817e4Smiod       free (synthsyms);
28503d8817e4Smiod       synthsyms = NULL;
28513d8817e4Smiod     }
28523d8817e4Smiod 
28533d8817e4Smiod   symcount = 0;
28543d8817e4Smiod   dynsymcount = 0;
28553d8817e4Smiod   synthcount = 0;
28563d8817e4Smiod }
28573d8817e4Smiod 
28583d8817e4Smiod static void
display_bfd(bfd * abfd)28593d8817e4Smiod display_bfd (bfd *abfd)
28603d8817e4Smiod {
28613d8817e4Smiod   char **matching;
28623d8817e4Smiod 
28633d8817e4Smiod   if (bfd_check_format_matches (abfd, bfd_object, &matching))
28643d8817e4Smiod     {
28653d8817e4Smiod       dump_bfd (abfd);
28663d8817e4Smiod       return;
28673d8817e4Smiod     }
28683d8817e4Smiod 
28693d8817e4Smiod   if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
28703d8817e4Smiod     {
28713d8817e4Smiod       nonfatal (bfd_get_filename (abfd));
28723d8817e4Smiod       list_matching_formats (matching);
28733d8817e4Smiod       free (matching);
28743d8817e4Smiod       return;
28753d8817e4Smiod     }
28763d8817e4Smiod 
28773d8817e4Smiod   if (bfd_get_error () != bfd_error_file_not_recognized)
28783d8817e4Smiod     {
28793d8817e4Smiod       nonfatal (bfd_get_filename (abfd));
28803d8817e4Smiod       return;
28813d8817e4Smiod     }
28823d8817e4Smiod 
28833d8817e4Smiod   if (bfd_check_format_matches (abfd, bfd_core, &matching))
28843d8817e4Smiod     {
28853d8817e4Smiod       dump_bfd (abfd);
28863d8817e4Smiod       return;
28873d8817e4Smiod     }
28883d8817e4Smiod 
28893d8817e4Smiod   nonfatal (bfd_get_filename (abfd));
28903d8817e4Smiod 
28913d8817e4Smiod   if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
28923d8817e4Smiod     {
28933d8817e4Smiod       list_matching_formats (matching);
28943d8817e4Smiod       free (matching);
28953d8817e4Smiod     }
28963d8817e4Smiod }
28973d8817e4Smiod 
28983d8817e4Smiod static void
display_file(char * filename,char * target)28993d8817e4Smiod display_file (char *filename, char *target)
29003d8817e4Smiod {
29013d8817e4Smiod   bfd *file;
29023d8817e4Smiod   bfd *arfile = NULL;
29033d8817e4Smiod 
29043d8817e4Smiod   if (get_file_size (filename) < 1)
29053d8817e4Smiod     return;
29063d8817e4Smiod 
29073d8817e4Smiod   file = bfd_openr (filename, target);
29083d8817e4Smiod   if (file == NULL)
29093d8817e4Smiod     {
29103d8817e4Smiod       nonfatal (filename);
29113d8817e4Smiod       return;
29123d8817e4Smiod     }
29133d8817e4Smiod 
29143d8817e4Smiod   /* If the file is an archive, process all of its elements.  */
29153d8817e4Smiod   if (bfd_check_format (file, bfd_archive))
29163d8817e4Smiod     {
29173d8817e4Smiod       bfd *last_arfile = NULL;
29183d8817e4Smiod 
29193d8817e4Smiod       printf (_("In archive %s:\n"), bfd_get_filename (file));
29203d8817e4Smiod       for (;;)
29213d8817e4Smiod 	{
29223d8817e4Smiod 	  bfd_set_error (bfd_error_no_error);
29233d8817e4Smiod 
29243d8817e4Smiod 	  arfile = bfd_openr_next_archived_file (file, arfile);
29253d8817e4Smiod 	  if (arfile == NULL)
29263d8817e4Smiod 	    {
29273d8817e4Smiod 	      if (bfd_get_error () != bfd_error_no_more_archived_files)
29283d8817e4Smiod 		nonfatal (bfd_get_filename (file));
29293d8817e4Smiod 	      break;
29303d8817e4Smiod 	    }
29313d8817e4Smiod 
29323d8817e4Smiod 	  display_bfd (arfile);
29333d8817e4Smiod 
29343d8817e4Smiod 	  if (last_arfile != NULL)
29353d8817e4Smiod 	    bfd_close (last_arfile);
29363d8817e4Smiod 	  last_arfile = arfile;
29373d8817e4Smiod 	}
29383d8817e4Smiod 
29393d8817e4Smiod       if (last_arfile != NULL)
29403d8817e4Smiod 	bfd_close (last_arfile);
29413d8817e4Smiod     }
29423d8817e4Smiod   else
29433d8817e4Smiod     display_bfd (file);
29443d8817e4Smiod 
29453d8817e4Smiod   bfd_close (file);
29463d8817e4Smiod }
29473d8817e4Smiod 
29483d8817e4Smiod int
main(int argc,char ** argv)29493d8817e4Smiod main (int argc, char **argv)
29503d8817e4Smiod {
29513d8817e4Smiod   int c;
29523d8817e4Smiod   char *target = default_target;
29533d8817e4Smiod   bfd_boolean seenflag = FALSE;
29543d8817e4Smiod 
29553d8817e4Smiod #if defined (HAVE_SETLOCALE)
29563d8817e4Smiod #if defined (HAVE_LC_MESSAGES)
29573d8817e4Smiod   setlocale (LC_MESSAGES, "");
29583d8817e4Smiod #endif
29593d8817e4Smiod   setlocale (LC_CTYPE, "");
29603d8817e4Smiod #endif
29613d8817e4Smiod 
29623d8817e4Smiod   bindtextdomain (PACKAGE, LOCALEDIR);
29633d8817e4Smiod   textdomain (PACKAGE);
29643d8817e4Smiod 
2965*c1f838d9Spascal   if (pledge ("stdio rpath tmppath", NULL) == -1)
2966*c1f838d9Spascal     fatal (_("Failed to pledge"));
2967*c1f838d9Spascal 
29683d8817e4Smiod   program_name = *argv;
29693d8817e4Smiod   xmalloc_set_program_name (program_name);
29703d8817e4Smiod 
29713d8817e4Smiod   START_PROGRESS (program_name, 0);
29723d8817e4Smiod 
29733d8817e4Smiod   expandargv (&argc, &argv);
29743d8817e4Smiod 
29753d8817e4Smiod   bfd_init ();
29763d8817e4Smiod   set_default_bfd_target ();
29773d8817e4Smiod 
29783d8817e4Smiod   while ((c = getopt_long (argc, argv, "pib:m:M:VvCdDlfaHhrRtTxsSI:j:wE:zgeGW",
29793d8817e4Smiod 			   long_options, (int *) 0))
29803d8817e4Smiod 	 != EOF)
29813d8817e4Smiod     {
29823d8817e4Smiod       switch (c)
29833d8817e4Smiod 	{
29843d8817e4Smiod 	case 0:
29853d8817e4Smiod 	  break;		/* We've been given a long option.  */
29863d8817e4Smiod 	case 'm':
29873d8817e4Smiod 	  machine = optarg;
29883d8817e4Smiod 	  break;
29893d8817e4Smiod 	case 'M':
29903d8817e4Smiod 	  if (disassembler_options)
29913d8817e4Smiod 	    /* Ignore potential memory leak for now.  */
29923d8817e4Smiod 	    disassembler_options = concat (disassembler_options, ",",
29933d8817e4Smiod 					   optarg, NULL);
29943d8817e4Smiod 	  else
29953d8817e4Smiod 	    disassembler_options = optarg;
29963d8817e4Smiod 	  break;
29973d8817e4Smiod 	case 'j':
29983d8817e4Smiod 	  if (only_used == only_size)
29993d8817e4Smiod 	    {
30003d8817e4Smiod 	      only_size += 8;
30013d8817e4Smiod 	      only = xrealloc (only, only_size * sizeof (char *));
30023d8817e4Smiod 	    }
30033d8817e4Smiod 	  only [only_used++] = optarg;
30043d8817e4Smiod 	  break;
30053d8817e4Smiod 	case 'l':
30063d8817e4Smiod 	  with_line_numbers = TRUE;
30073d8817e4Smiod 	  break;
30083d8817e4Smiod 	case 'b':
30093d8817e4Smiod 	  target = optarg;
30103d8817e4Smiod 	  break;
30113d8817e4Smiod 	case 'C':
30123d8817e4Smiod 	  do_demangle = TRUE;
30133d8817e4Smiod 	  if (optarg != NULL)
30143d8817e4Smiod 	    {
30153d8817e4Smiod 	      enum demangling_styles style;
30163d8817e4Smiod 
30173d8817e4Smiod 	      style = cplus_demangle_name_to_style (optarg);
30183d8817e4Smiod 	      if (style == unknown_demangling)
30193d8817e4Smiod 		fatal (_("unknown demangling style `%s'"),
30203d8817e4Smiod 		       optarg);
30213d8817e4Smiod 
30223d8817e4Smiod 	      cplus_demangle_set_style (style);
30233d8817e4Smiod 	    }
30243d8817e4Smiod 	  break;
30253d8817e4Smiod 	case 'w':
30263d8817e4Smiod 	  wide_output = TRUE;
30273d8817e4Smiod 	  break;
30283d8817e4Smiod 	case OPTION_ADJUST_VMA:
30293d8817e4Smiod 	  adjust_section_vma = parse_vma (optarg, "--adjust-vma");
30303d8817e4Smiod 	  break;
30313d8817e4Smiod 	case OPTION_START_ADDRESS:
30323d8817e4Smiod 	  start_address = parse_vma (optarg, "--start-address");
30333d8817e4Smiod 	  break;
30343d8817e4Smiod 	case OPTION_STOP_ADDRESS:
30353d8817e4Smiod 	  stop_address = parse_vma (optarg, "--stop-address");
30363d8817e4Smiod 	  break;
30373d8817e4Smiod 	case 'E':
30383d8817e4Smiod 	  if (strcmp (optarg, "B") == 0)
30393d8817e4Smiod 	    endian = BFD_ENDIAN_BIG;
30403d8817e4Smiod 	  else if (strcmp (optarg, "L") == 0)
30413d8817e4Smiod 	    endian = BFD_ENDIAN_LITTLE;
30423d8817e4Smiod 	  else
30433d8817e4Smiod 	    {
30443d8817e4Smiod 	      non_fatal (_("unrecognized -E option"));
30453d8817e4Smiod 	      usage (stderr, 1);
30463d8817e4Smiod 	    }
30473d8817e4Smiod 	  break;
30483d8817e4Smiod 	case OPTION_ENDIAN:
30493d8817e4Smiod 	  if (strncmp (optarg, "big", strlen (optarg)) == 0)
30503d8817e4Smiod 	    endian = BFD_ENDIAN_BIG;
30513d8817e4Smiod 	  else if (strncmp (optarg, "little", strlen (optarg)) == 0)
30523d8817e4Smiod 	    endian = BFD_ENDIAN_LITTLE;
30533d8817e4Smiod 	  else
30543d8817e4Smiod 	    {
30553d8817e4Smiod 	      non_fatal (_("unrecognized --endian type `%s'"), optarg);
30563d8817e4Smiod 	      usage (stderr, 1);
30573d8817e4Smiod 	    }
30583d8817e4Smiod 	  break;
30593d8817e4Smiod 
30603d8817e4Smiod 	case 'f':
30613d8817e4Smiod 	  dump_file_header = TRUE;
30623d8817e4Smiod 	  seenflag = TRUE;
30633d8817e4Smiod 	  break;
30643d8817e4Smiod 	case 'i':
30653d8817e4Smiod 	  formats_info = TRUE;
30663d8817e4Smiod 	  seenflag = TRUE;
30673d8817e4Smiod 	  break;
30683d8817e4Smiod 	case 'I':
30693d8817e4Smiod 	  add_include_path (optarg);
30703d8817e4Smiod 	  break;
30713d8817e4Smiod 	case 'p':
30723d8817e4Smiod 	  dump_private_headers = TRUE;
30733d8817e4Smiod 	  seenflag = TRUE;
30743d8817e4Smiod 	  break;
30753d8817e4Smiod 	case 'x':
30763d8817e4Smiod 	  dump_private_headers = TRUE;
30773d8817e4Smiod 	  dump_symtab = TRUE;
30783d8817e4Smiod 	  dump_reloc_info = TRUE;
30793d8817e4Smiod 	  dump_file_header = TRUE;
30803d8817e4Smiod 	  dump_ar_hdrs = TRUE;
30813d8817e4Smiod 	  dump_section_headers = TRUE;
30823d8817e4Smiod 	  seenflag = TRUE;
30833d8817e4Smiod 	  break;
30843d8817e4Smiod 	case 't':
30853d8817e4Smiod 	  dump_symtab = TRUE;
30863d8817e4Smiod 	  seenflag = TRUE;
30873d8817e4Smiod 	  break;
30883d8817e4Smiod 	case 'T':
30893d8817e4Smiod 	  dump_dynamic_symtab = TRUE;
30903d8817e4Smiod 	  seenflag = TRUE;
30913d8817e4Smiod 	  break;
30923d8817e4Smiod 	case 'd':
30933d8817e4Smiod 	  disassemble = TRUE;
30943d8817e4Smiod 	  seenflag = TRUE;
30953d8817e4Smiod 	  break;
30963d8817e4Smiod 	case 'z':
30973d8817e4Smiod 	  disassemble_zeroes = TRUE;
30983d8817e4Smiod 	  break;
30993d8817e4Smiod 	case 'D':
31003d8817e4Smiod 	  disassemble = TRUE;
31013d8817e4Smiod 	  disassemble_all = TRUE;
31023d8817e4Smiod 	  seenflag = TRUE;
31033d8817e4Smiod 	  break;
31043d8817e4Smiod 	case 'S':
31053d8817e4Smiod 	  disassemble = TRUE;
31063d8817e4Smiod 	  with_source_code = TRUE;
31073d8817e4Smiod 	  seenflag = TRUE;
31083d8817e4Smiod 	  break;
31093d8817e4Smiod 	case 'g':
31103d8817e4Smiod 	  dump_debugging = 1;
31113d8817e4Smiod 	  seenflag = TRUE;
31123d8817e4Smiod 	  break;
31133d8817e4Smiod 	case 'e':
31143d8817e4Smiod 	  dump_debugging = 1;
31153d8817e4Smiod 	  dump_debugging_tags = 1;
31163d8817e4Smiod 	  do_demangle = TRUE;
31173d8817e4Smiod 	  seenflag = TRUE;
31183d8817e4Smiod 	  break;
31193d8817e4Smiod 	case 'W':
31203d8817e4Smiod 	  dump_dwarf_section_info = TRUE;
31213d8817e4Smiod 	  seenflag = TRUE;
31223d8817e4Smiod 	  do_debug_info = 1;
31233d8817e4Smiod 	  do_debug_abbrevs = 1;
31243d8817e4Smiod 	  do_debug_lines = 1;
31253d8817e4Smiod 	  do_debug_pubnames = 1;
31263d8817e4Smiod 	  do_debug_aranges = 1;
31273d8817e4Smiod 	  do_debug_ranges = 1;
31283d8817e4Smiod 	  do_debug_frames = 1;
31293d8817e4Smiod 	  do_debug_macinfo = 1;
31303d8817e4Smiod 	  do_debug_str = 1;
31313d8817e4Smiod 	  do_debug_loc = 1;
31323d8817e4Smiod 	  break;
31333d8817e4Smiod 	case 'G':
31343d8817e4Smiod 	  dump_stab_section_info = TRUE;
31353d8817e4Smiod 	  seenflag = TRUE;
31363d8817e4Smiod 	  break;
31373d8817e4Smiod 	case 's':
31383d8817e4Smiod 	  dump_section_contents = TRUE;
31393d8817e4Smiod 	  seenflag = TRUE;
31403d8817e4Smiod 	  break;
31413d8817e4Smiod 	case 'r':
31423d8817e4Smiod 	  dump_reloc_info = TRUE;
31433d8817e4Smiod 	  seenflag = TRUE;
31443d8817e4Smiod 	  break;
31453d8817e4Smiod 	case 'R':
31463d8817e4Smiod 	  dump_dynamic_reloc_info = TRUE;
31473d8817e4Smiod 	  seenflag = TRUE;
31483d8817e4Smiod 	  break;
31493d8817e4Smiod 	case 'a':
31503d8817e4Smiod 	  dump_ar_hdrs = TRUE;
31513d8817e4Smiod 	  seenflag = TRUE;
31523d8817e4Smiod 	  break;
31533d8817e4Smiod 	case 'h':
31543d8817e4Smiod 	  dump_section_headers = TRUE;
31553d8817e4Smiod 	  seenflag = TRUE;
31563d8817e4Smiod 	  break;
31573d8817e4Smiod 	case 'H':
31583d8817e4Smiod 	  usage (stdout, 0);
31593d8817e4Smiod 	  seenflag = TRUE;
31603d8817e4Smiod 	case 'v':
31613d8817e4Smiod 	case 'V':
31623d8817e4Smiod 	  show_version = TRUE;
31633d8817e4Smiod 	  seenflag = TRUE;
31643d8817e4Smiod 	  break;
31653d8817e4Smiod 
31663d8817e4Smiod 	default:
31673d8817e4Smiod 	  usage (stderr, 1);
31683d8817e4Smiod 	}
31693d8817e4Smiod     }
31703d8817e4Smiod 
31713d8817e4Smiod   if (show_version)
31723d8817e4Smiod     print_version ("objdump");
31733d8817e4Smiod 
31743d8817e4Smiod   if (!seenflag)
31753d8817e4Smiod     usage (stderr, 2);
31763d8817e4Smiod 
31773d8817e4Smiod   if (formats_info)
31783d8817e4Smiod     exit_status = display_info ();
31793d8817e4Smiod   else
31803d8817e4Smiod     {
31813d8817e4Smiod       if (optind == argc)
31823d8817e4Smiod 	display_file ("a.out", target);
31833d8817e4Smiod       else
31843d8817e4Smiod 	for (; optind < argc;)
31853d8817e4Smiod 	  display_file (argv[optind++], target);
31863d8817e4Smiod     }
31873d8817e4Smiod 
31883d8817e4Smiod   END_PROGRESS (program_name);
31893d8817e4Smiod 
31903d8817e4Smiod   return exit_status;
31913d8817e4Smiod }
3192