1*a9fa9459Szrj /* objdump.c -- dump information about an object file.
2*a9fa9459Szrj    Copyright (C) 1990-2016 Free Software Foundation, Inc.
3*a9fa9459Szrj 
4*a9fa9459Szrj    This file is part of GNU Binutils.
5*a9fa9459Szrj 
6*a9fa9459Szrj    This program is free software; you can redistribute it and/or modify
7*a9fa9459Szrj    it under the terms of the GNU General Public License as published by
8*a9fa9459Szrj    the Free Software Foundation; either version 3, or (at your option)
9*a9fa9459Szrj    any later version.
10*a9fa9459Szrj 
11*a9fa9459Szrj    This program is distributed in the hope that it will be useful,
12*a9fa9459Szrj    but WITHOUT ANY WARRANTY; without even the implied warranty of
13*a9fa9459Szrj    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*a9fa9459Szrj    GNU General Public License for more details.
15*a9fa9459Szrj 
16*a9fa9459Szrj    You should have received a copy of the GNU General Public License
17*a9fa9459Szrj    along with this program; if not, write to the Free Software
18*a9fa9459Szrj    Foundation, 51 Franklin Street - Fifth Floor, Boston,
19*a9fa9459Szrj    MA 02110-1301, USA.  */
20*a9fa9459Szrj 
21*a9fa9459Szrj 
22*a9fa9459Szrj /* Objdump overview.
23*a9fa9459Szrj 
24*a9fa9459Szrj    Objdump displays information about one or more object files, either on
25*a9fa9459Szrj    their own, or inside libraries.  It is commonly used as a disassembler,
26*a9fa9459Szrj    but it can also display information about file headers, symbol tables,
27*a9fa9459Szrj    relocations, debugging directives and more.
28*a9fa9459Szrj 
29*a9fa9459Szrj    The flow of execution is as follows:
30*a9fa9459Szrj 
31*a9fa9459Szrj    1. Command line arguments are checked for control switches and the
32*a9fa9459Szrj       information to be displayed is selected.
33*a9fa9459Szrj 
34*a9fa9459Szrj    2. Any remaining arguments are assumed to be object files, and they are
35*a9fa9459Szrj       processed in order by display_bfd().  If the file is an archive each
36*a9fa9459Szrj       of its elements is processed in turn.
37*a9fa9459Szrj 
38*a9fa9459Szrj    3. The file's target architecture and binary file format are determined
39*a9fa9459Szrj       by bfd_check_format().  If they are recognised, then dump_bfd() is
40*a9fa9459Szrj       called.
41*a9fa9459Szrj 
42*a9fa9459Szrj    4. dump_bfd() in turn calls separate functions to display the requested
43*a9fa9459Szrj       item(s) of information(s).  For example disassemble_data() is called if
44*a9fa9459Szrj       a disassembly has been requested.
45*a9fa9459Szrj 
46*a9fa9459Szrj    When disassembling the code loops through blocks of instructions bounded
47*a9fa9459Szrj    by symbols, calling disassemble_bytes() on each block.  The actual
48*a9fa9459Szrj    disassembling is done by the libopcodes library, via a function pointer
49*a9fa9459Szrj    supplied by the disassembler() function.  */
50*a9fa9459Szrj 
51*a9fa9459Szrj #include "sysdep.h"
52*a9fa9459Szrj #include "bfd.h"
53*a9fa9459Szrj #include "elf-bfd.h"
54*a9fa9459Szrj #include "coff-bfd.h"
55*a9fa9459Szrj #include "progress.h"
56*a9fa9459Szrj #include "bucomm.h"
57*a9fa9459Szrj #include "elfcomm.h"
58*a9fa9459Szrj #include "dwarf.h"
59*a9fa9459Szrj #include "getopt.h"
60*a9fa9459Szrj #include "safe-ctype.h"
61*a9fa9459Szrj #include "dis-asm.h"
62*a9fa9459Szrj #include "libiberty.h"
63*a9fa9459Szrj #include "demangle.h"
64*a9fa9459Szrj #include "filenames.h"
65*a9fa9459Szrj #include "debug.h"
66*a9fa9459Szrj #include "budbg.h"
67*a9fa9459Szrj #include "objdump.h"
68*a9fa9459Szrj 
69*a9fa9459Szrj #ifdef HAVE_MMAP
70*a9fa9459Szrj #include <sys/mman.h>
71*a9fa9459Szrj #endif
72*a9fa9459Szrj 
73*a9fa9459Szrj /* Internal headers for the ELF .stab-dump code - sorry.  */
74*a9fa9459Szrj #define	BYTES_IN_WORD	32
75*a9fa9459Szrj #include "aout/aout64.h"
76*a9fa9459Szrj 
77*a9fa9459Szrj /* Exit status.  */
78*a9fa9459Szrj static int exit_status = 0;
79*a9fa9459Szrj 
80*a9fa9459Szrj static char *default_target = NULL;	/* Default at runtime.  */
81*a9fa9459Szrj 
82*a9fa9459Szrj /* The following variables are set based on arguments passed on the
83*a9fa9459Szrj    command line.  */
84*a9fa9459Szrj static int show_version = 0;		/* Show the version number.  */
85*a9fa9459Szrj static int dump_section_contents;	/* -s */
86*a9fa9459Szrj static int dump_section_headers;	/* -h */
87*a9fa9459Szrj static bfd_boolean dump_file_header;	/* -f */
88*a9fa9459Szrj static int dump_symtab;			/* -t */
89*a9fa9459Szrj static int dump_dynamic_symtab;		/* -T */
90*a9fa9459Szrj static int dump_reloc_info;		/* -r */
91*a9fa9459Szrj static int dump_dynamic_reloc_info;	/* -R */
92*a9fa9459Szrj static int dump_ar_hdrs;		/* -a */
93*a9fa9459Szrj static int dump_private_headers;	/* -p */
94*a9fa9459Szrj static char *dump_private_options;	/* -P */
95*a9fa9459Szrj static int prefix_addresses;		/* --prefix-addresses */
96*a9fa9459Szrj static int with_line_numbers;		/* -l */
97*a9fa9459Szrj static bfd_boolean with_source_code;	/* -S */
98*a9fa9459Szrj static int show_raw_insn;		/* --show-raw-insn */
99*a9fa9459Szrj static int dump_dwarf_section_info;	/* --dwarf */
100*a9fa9459Szrj static int dump_stab_section_info;	/* --stabs */
101*a9fa9459Szrj static int do_demangle;			/* -C, --demangle */
102*a9fa9459Szrj static bfd_boolean disassemble;		/* -d */
103*a9fa9459Szrj static bfd_boolean disassemble_all;	/* -D */
104*a9fa9459Szrj static int disassemble_zeroes;		/* --disassemble-zeroes */
105*a9fa9459Szrj static bfd_boolean formats_info;	/* -i */
106*a9fa9459Szrj static int wide_output;			/* -w */
107*a9fa9459Szrj static int insn_width;			/* --insn-width */
108*a9fa9459Szrj static bfd_vma start_address = (bfd_vma) -1; /* --start-address */
109*a9fa9459Szrj static bfd_vma stop_address = (bfd_vma) -1;  /* --stop-address */
110*a9fa9459Szrj static int dump_debugging;		/* --debugging */
111*a9fa9459Szrj static int dump_debugging_tags;		/* --debugging-tags */
112*a9fa9459Szrj static int suppress_bfd_header;
113*a9fa9459Szrj static int dump_special_syms = 0;	/* --special-syms */
114*a9fa9459Szrj static bfd_vma adjust_section_vma = 0;	/* --adjust-vma */
115*a9fa9459Szrj static int file_start_context = 0;      /* --file-start-context */
116*a9fa9459Szrj static bfd_boolean display_file_offsets;/* -F */
117*a9fa9459Szrj static const char *prefix;		/* --prefix */
118*a9fa9459Szrj static int prefix_strip;		/* --prefix-strip */
119*a9fa9459Szrj static size_t prefix_length;
120*a9fa9459Szrj 
121*a9fa9459Szrj /* A structure to record the sections mentioned in -j switches.  */
122*a9fa9459Szrj struct only
123*a9fa9459Szrj {
124*a9fa9459Szrj   const char * name; /* The name of the section.  */
125*a9fa9459Szrj   bfd_boolean  seen; /* A flag to indicate that the section has been found in one or more input files.  */
126*a9fa9459Szrj   struct only * next; /* Pointer to the next structure in the list.  */
127*a9fa9459Szrj };
128*a9fa9459Szrj /* Pointer to an array of 'only' structures.
129*a9fa9459Szrj    This pointer is NULL if the -j switch has not been used.  */
130*a9fa9459Szrj static struct only * only_list = NULL;
131*a9fa9459Szrj 
132*a9fa9459Szrj /* Variables for handling include file path table.  */
133*a9fa9459Szrj static const char **include_paths;
134*a9fa9459Szrj static int include_path_count;
135*a9fa9459Szrj 
136*a9fa9459Szrj /* Extra info to pass to the section disassembler and address printing
137*a9fa9459Szrj    function.  */
138*a9fa9459Szrj struct objdump_disasm_info
139*a9fa9459Szrj {
140*a9fa9459Szrj   bfd *              abfd;
141*a9fa9459Szrj   asection *         sec;
142*a9fa9459Szrj   bfd_boolean        require_sec;
143*a9fa9459Szrj   arelent **         dynrelbuf;
144*a9fa9459Szrj   long               dynrelcount;
145*a9fa9459Szrj   disassembler_ftype disassemble_fn;
146*a9fa9459Szrj   arelent *          reloc;
147*a9fa9459Szrj };
148*a9fa9459Szrj 
149*a9fa9459Szrj /* Architecture to disassemble for, or default if NULL.  */
150*a9fa9459Szrj static char *machine = NULL;
151*a9fa9459Szrj 
152*a9fa9459Szrj /* Target specific options to the disassembler.  */
153*a9fa9459Szrj static char *disassembler_options = NULL;
154*a9fa9459Szrj 
155*a9fa9459Szrj /* Endianness to disassemble for, or default if BFD_ENDIAN_UNKNOWN.  */
156*a9fa9459Szrj static enum bfd_endian endian = BFD_ENDIAN_UNKNOWN;
157*a9fa9459Szrj 
158*a9fa9459Szrj /* The symbol table.  */
159*a9fa9459Szrj static asymbol **syms;
160*a9fa9459Szrj 
161*a9fa9459Szrj /* Number of symbols in `syms'.  */
162*a9fa9459Szrj static long symcount = 0;
163*a9fa9459Szrj 
164*a9fa9459Szrj /* The sorted symbol table.  */
165*a9fa9459Szrj static asymbol **sorted_syms;
166*a9fa9459Szrj 
167*a9fa9459Szrj /* Number of symbols in `sorted_syms'.  */
168*a9fa9459Szrj static long sorted_symcount = 0;
169*a9fa9459Szrj 
170*a9fa9459Szrj /* The dynamic symbol table.  */
171*a9fa9459Szrj static asymbol **dynsyms;
172*a9fa9459Szrj 
173*a9fa9459Szrj /* The synthetic symbol table.  */
174*a9fa9459Szrj static asymbol *synthsyms;
175*a9fa9459Szrj static long synthcount = 0;
176*a9fa9459Szrj 
177*a9fa9459Szrj /* Number of symbols in `dynsyms'.  */
178*a9fa9459Szrj static long dynsymcount = 0;
179*a9fa9459Szrj 
180*a9fa9459Szrj static bfd_byte *stabs;
181*a9fa9459Szrj static bfd_size_type stab_size;
182*a9fa9459Szrj 
183*a9fa9459Szrj static char *strtab;
184*a9fa9459Szrj static bfd_size_type stabstr_size;
185*a9fa9459Szrj 
186*a9fa9459Szrj static bfd_boolean is_relocatable = FALSE;
187*a9fa9459Szrj 
188*a9fa9459Szrj /* Handlers for -P/--private.  */
189*a9fa9459Szrj static const struct objdump_private_desc * const objdump_private_vectors[] =
190*a9fa9459Szrj   {
191*a9fa9459Szrj     OBJDUMP_PRIVATE_VECTORS
192*a9fa9459Szrj     NULL
193*a9fa9459Szrj   };
194*a9fa9459Szrj 
195*a9fa9459Szrj static void usage (FILE *, int) ATTRIBUTE_NORETURN;
196*a9fa9459Szrj static void
usage(FILE * stream,int status)197*a9fa9459Szrj usage (FILE *stream, int status)
198*a9fa9459Szrj {
199*a9fa9459Szrj   fprintf (stream, _("Usage: %s <option(s)> <file(s)>\n"), program_name);
200*a9fa9459Szrj   fprintf (stream, _(" Display information from object <file(s)>.\n"));
201*a9fa9459Szrj   fprintf (stream, _(" At least one of the following switches must be given:\n"));
202*a9fa9459Szrj   fprintf (stream, _("\
203*a9fa9459Szrj   -a, --archive-headers    Display archive header information\n\
204*a9fa9459Szrj   -f, --file-headers       Display the contents of the overall file header\n\
205*a9fa9459Szrj   -p, --private-headers    Display object format specific file header contents\n\
206*a9fa9459Szrj   -P, --private=OPT,OPT... Display object format specific contents\n\
207*a9fa9459Szrj   -h, --[section-]headers  Display the contents of the section headers\n\
208*a9fa9459Szrj   -x, --all-headers        Display the contents of all headers\n\
209*a9fa9459Szrj   -d, --disassemble        Display assembler contents of executable sections\n\
210*a9fa9459Szrj   -D, --disassemble-all    Display assembler contents of all sections\n\
211*a9fa9459Szrj   -S, --source             Intermix source code with disassembly\n\
212*a9fa9459Szrj   -s, --full-contents      Display the full contents of all sections requested\n\
213*a9fa9459Szrj   -g, --debugging          Display debug information in object file\n\
214*a9fa9459Szrj   -e, --debugging-tags     Display debug information using ctags style\n\
215*a9fa9459Szrj   -G, --stabs              Display (in raw form) any STABS info in the file\n\
216*a9fa9459Szrj   -W[lLiaprmfFsoRt] or\n\
217*a9fa9459Szrj   --dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
218*a9fa9459Szrj           =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
219*a9fa9459Szrj           =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
220*a9fa9459Szrj           =addr,=cu_index]\n\
221*a9fa9459Szrj                            Display DWARF info in the file\n\
222*a9fa9459Szrj   -t, --syms               Display the contents of the symbol table(s)\n\
223*a9fa9459Szrj   -T, --dynamic-syms       Display the contents of the dynamic symbol table\n\
224*a9fa9459Szrj   -r, --reloc              Display the relocation entries in the file\n\
225*a9fa9459Szrj   -R, --dynamic-reloc      Display the dynamic relocation entries in the file\n\
226*a9fa9459Szrj   @<file>                  Read options from <file>\n\
227*a9fa9459Szrj   -v, --version            Display this program's version number\n\
228*a9fa9459Szrj   -i, --info               List object formats and architectures supported\n\
229*a9fa9459Szrj   -H, --help               Display this information\n\
230*a9fa9459Szrj "));
231*a9fa9459Szrj   if (status != 2)
232*a9fa9459Szrj     {
233*a9fa9459Szrj       const struct objdump_private_desc * const *desc;
234*a9fa9459Szrj 
235*a9fa9459Szrj       fprintf (stream, _("\n The following switches are optional:\n"));
236*a9fa9459Szrj       fprintf (stream, _("\
237*a9fa9459Szrj   -b, --target=BFDNAME           Specify the target object format as BFDNAME\n\
238*a9fa9459Szrj   -m, --architecture=MACHINE     Specify the target architecture as MACHINE\n\
239*a9fa9459Szrj   -j, --section=NAME             Only display information for section NAME\n\
240*a9fa9459Szrj   -M, --disassembler-options=OPT Pass text OPT on to the disassembler\n\
241*a9fa9459Szrj   -EB --endian=big               Assume big endian format when disassembling\n\
242*a9fa9459Szrj   -EL --endian=little            Assume little endian format when disassembling\n\
243*a9fa9459Szrj       --file-start-context       Include context from start of file (with -S)\n\
244*a9fa9459Szrj   -I, --include=DIR              Add DIR to search list for source files\n\
245*a9fa9459Szrj   -l, --line-numbers             Include line numbers and filenames in output\n\
246*a9fa9459Szrj   -F, --file-offsets             Include file offsets when displaying information\n\
247*a9fa9459Szrj   -C, --demangle[=STYLE]         Decode mangled/processed symbol names\n\
248*a9fa9459Szrj                                   The STYLE, if specified, can be `auto', `gnu',\n\
249*a9fa9459Szrj                                   `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
250*a9fa9459Szrj                                   or `gnat'\n\
251*a9fa9459Szrj   -w, --wide                     Format output for more than 80 columns\n\
252*a9fa9459Szrj   -z, --disassemble-zeroes       Do not skip blocks of zeroes when disassembling\n\
253*a9fa9459Szrj       --start-address=ADDR       Only process data whose address is >= ADDR\n\
254*a9fa9459Szrj       --stop-address=ADDR        Only process data whose address is <= ADDR\n\
255*a9fa9459Szrj       --prefix-addresses         Print complete address alongside disassembly\n\
256*a9fa9459Szrj       --[no-]show-raw-insn       Display hex alongside symbolic disassembly\n\
257*a9fa9459Szrj       --insn-width=WIDTH         Display WIDTH bytes on a single line for -d\n\
258*a9fa9459Szrj       --adjust-vma=OFFSET        Add OFFSET to all displayed section addresses\n\
259*a9fa9459Szrj       --special-syms             Include special symbols in symbol dumps\n\
260*a9fa9459Szrj       --prefix=PREFIX            Add PREFIX to absolute paths for -S\n\
261*a9fa9459Szrj       --prefix-strip=LEVEL       Strip initial directory names for -S\n"));
262*a9fa9459Szrj       fprintf (stream, _("\
263*a9fa9459Szrj       --dwarf-depth=N        Do not display DIEs at depth N or greater\n\
264*a9fa9459Szrj       --dwarf-start=N        Display DIEs starting with N, at the same depth\n\
265*a9fa9459Szrj                              or deeper\n\
266*a9fa9459Szrj       --dwarf-check          Make additional dwarf internal consistency checks.\
267*a9fa9459Szrj       \n\n"));
268*a9fa9459Szrj       list_supported_targets (program_name, stream);
269*a9fa9459Szrj       list_supported_architectures (program_name, stream);
270*a9fa9459Szrj 
271*a9fa9459Szrj       disassembler_usage (stream);
272*a9fa9459Szrj 
273*a9fa9459Szrj       if (objdump_private_vectors[0] != NULL)
274*a9fa9459Szrj         {
275*a9fa9459Szrj           fprintf (stream,
276*a9fa9459Szrj                    _("\nOptions supported for -P/--private switch:\n"));
277*a9fa9459Szrj           for (desc = objdump_private_vectors; *desc != NULL; desc++)
278*a9fa9459Szrj             (*desc)->help (stream);
279*a9fa9459Szrj         }
280*a9fa9459Szrj     }
281*a9fa9459Szrj   if (REPORT_BUGS_TO[0] && status == 0)
282*a9fa9459Szrj     fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO);
283*a9fa9459Szrj   exit (status);
284*a9fa9459Szrj }
285*a9fa9459Szrj 
286*a9fa9459Szrj /* 150 isn't special; it's just an arbitrary non-ASCII char value.  */
287*a9fa9459Szrj enum option_values
288*a9fa9459Szrj   {
289*a9fa9459Szrj     OPTION_ENDIAN=150,
290*a9fa9459Szrj     OPTION_START_ADDRESS,
291*a9fa9459Szrj     OPTION_STOP_ADDRESS,
292*a9fa9459Szrj     OPTION_DWARF,
293*a9fa9459Szrj     OPTION_PREFIX,
294*a9fa9459Szrj     OPTION_PREFIX_STRIP,
295*a9fa9459Szrj     OPTION_INSN_WIDTH,
296*a9fa9459Szrj     OPTION_ADJUST_VMA,
297*a9fa9459Szrj     OPTION_DWARF_DEPTH,
298*a9fa9459Szrj     OPTION_DWARF_CHECK,
299*a9fa9459Szrj     OPTION_DWARF_START
300*a9fa9459Szrj   };
301*a9fa9459Szrj 
302*a9fa9459Szrj static struct option long_options[]=
303*a9fa9459Szrj {
304*a9fa9459Szrj   {"adjust-vma", required_argument, NULL, OPTION_ADJUST_VMA},
305*a9fa9459Szrj   {"all-headers", no_argument, NULL, 'x'},
306*a9fa9459Szrj   {"private-headers", no_argument, NULL, 'p'},
307*a9fa9459Szrj   {"private", required_argument, NULL, 'P'},
308*a9fa9459Szrj   {"architecture", required_argument, NULL, 'm'},
309*a9fa9459Szrj   {"archive-headers", no_argument, NULL, 'a'},
310*a9fa9459Szrj   {"debugging", no_argument, NULL, 'g'},
311*a9fa9459Szrj   {"debugging-tags", no_argument, NULL, 'e'},
312*a9fa9459Szrj   {"demangle", optional_argument, NULL, 'C'},
313*a9fa9459Szrj   {"disassemble", no_argument, NULL, 'd'},
314*a9fa9459Szrj   {"disassemble-all", no_argument, NULL, 'D'},
315*a9fa9459Szrj   {"disassembler-options", required_argument, NULL, 'M'},
316*a9fa9459Szrj   {"disassemble-zeroes", no_argument, NULL, 'z'},
317*a9fa9459Szrj   {"dynamic-reloc", no_argument, NULL, 'R'},
318*a9fa9459Szrj   {"dynamic-syms", no_argument, NULL, 'T'},
319*a9fa9459Szrj   {"endian", required_argument, NULL, OPTION_ENDIAN},
320*a9fa9459Szrj   {"file-headers", no_argument, NULL, 'f'},
321*a9fa9459Szrj   {"file-offsets", no_argument, NULL, 'F'},
322*a9fa9459Szrj   {"file-start-context", no_argument, &file_start_context, 1},
323*a9fa9459Szrj   {"full-contents", no_argument, NULL, 's'},
324*a9fa9459Szrj   {"headers", no_argument, NULL, 'h'},
325*a9fa9459Szrj   {"help", no_argument, NULL, 'H'},
326*a9fa9459Szrj   {"info", no_argument, NULL, 'i'},
327*a9fa9459Szrj   {"line-numbers", no_argument, NULL, 'l'},
328*a9fa9459Szrj   {"no-show-raw-insn", no_argument, &show_raw_insn, -1},
329*a9fa9459Szrj   {"prefix-addresses", no_argument, &prefix_addresses, 1},
330*a9fa9459Szrj   {"reloc", no_argument, NULL, 'r'},
331*a9fa9459Szrj   {"section", required_argument, NULL, 'j'},
332*a9fa9459Szrj   {"section-headers", no_argument, NULL, 'h'},
333*a9fa9459Szrj   {"show-raw-insn", no_argument, &show_raw_insn, 1},
334*a9fa9459Szrj   {"source", no_argument, NULL, 'S'},
335*a9fa9459Szrj   {"special-syms", no_argument, &dump_special_syms, 1},
336*a9fa9459Szrj   {"include", required_argument, NULL, 'I'},
337*a9fa9459Szrj   {"dwarf", optional_argument, NULL, OPTION_DWARF},
338*a9fa9459Szrj   {"stabs", no_argument, NULL, 'G'},
339*a9fa9459Szrj   {"start-address", required_argument, NULL, OPTION_START_ADDRESS},
340*a9fa9459Szrj   {"stop-address", required_argument, NULL, OPTION_STOP_ADDRESS},
341*a9fa9459Szrj   {"syms", no_argument, NULL, 't'},
342*a9fa9459Szrj   {"target", required_argument, NULL, 'b'},
343*a9fa9459Szrj   {"version", no_argument, NULL, 'V'},
344*a9fa9459Szrj   {"wide", no_argument, NULL, 'w'},
345*a9fa9459Szrj   {"prefix", required_argument, NULL, OPTION_PREFIX},
346*a9fa9459Szrj   {"prefix-strip", required_argument, NULL, OPTION_PREFIX_STRIP},
347*a9fa9459Szrj   {"insn-width", required_argument, NULL, OPTION_INSN_WIDTH},
348*a9fa9459Szrj   {"dwarf-depth",      required_argument, 0, OPTION_DWARF_DEPTH},
349*a9fa9459Szrj   {"dwarf-start",      required_argument, 0, OPTION_DWARF_START},
350*a9fa9459Szrj   {"dwarf-check",      no_argument, 0, OPTION_DWARF_CHECK},
351*a9fa9459Szrj   {0, no_argument, 0, 0}
352*a9fa9459Szrj };
353*a9fa9459Szrj 
354*a9fa9459Szrj static void
nonfatal(const char * msg)355*a9fa9459Szrj nonfatal (const char *msg)
356*a9fa9459Szrj {
357*a9fa9459Szrj   bfd_nonfatal (msg);
358*a9fa9459Szrj   exit_status = 1;
359*a9fa9459Szrj }
360*a9fa9459Szrj 
361*a9fa9459Szrj /* Returns TRUE if the specified section should be dumped.  */
362*a9fa9459Szrj 
363*a9fa9459Szrj static bfd_boolean
process_section_p(asection * section)364*a9fa9459Szrj process_section_p (asection * section)
365*a9fa9459Szrj {
366*a9fa9459Szrj   struct only * only;
367*a9fa9459Szrj 
368*a9fa9459Szrj   if (only_list == NULL)
369*a9fa9459Szrj     return TRUE;
370*a9fa9459Szrj 
371*a9fa9459Szrj   for (only = only_list; only; only = only->next)
372*a9fa9459Szrj     if (strcmp (only->name, section->name) == 0)
373*a9fa9459Szrj       {
374*a9fa9459Szrj 	only->seen = TRUE;
375*a9fa9459Szrj 	return TRUE;
376*a9fa9459Szrj       }
377*a9fa9459Szrj 
378*a9fa9459Szrj   return FALSE;
379*a9fa9459Szrj }
380*a9fa9459Szrj 
381*a9fa9459Szrj /* Add an entry to the 'only' list.  */
382*a9fa9459Szrj 
383*a9fa9459Szrj static void
add_only(char * name)384*a9fa9459Szrj add_only (char * name)
385*a9fa9459Szrj {
386*a9fa9459Szrj   struct only * only;
387*a9fa9459Szrj 
388*a9fa9459Szrj   /* First check to make sure that we do not
389*a9fa9459Szrj      already have an entry for this name.  */
390*a9fa9459Szrj   for (only = only_list; only; only = only->next)
391*a9fa9459Szrj     if (strcmp (only->name, name) == 0)
392*a9fa9459Szrj       return;
393*a9fa9459Szrj 
394*a9fa9459Szrj   only = xmalloc (sizeof * only);
395*a9fa9459Szrj   only->name = name;
396*a9fa9459Szrj   only->seen = FALSE;
397*a9fa9459Szrj   only->next = only_list;
398*a9fa9459Szrj   only_list = only;
399*a9fa9459Szrj }
400*a9fa9459Szrj 
401*a9fa9459Szrj /* Release the memory used by the 'only' list.
402*a9fa9459Szrj    PR 11225: Issue a warning message for unseen sections.
403*a9fa9459Szrj    Only do this if none of the sections were seen.  This is mainly to support
404*a9fa9459Szrj    tools like the GAS testsuite where an object file is dumped with a list of
405*a9fa9459Szrj    generic section names known to be present in a range of different file
406*a9fa9459Szrj    formats.  */
407*a9fa9459Szrj 
408*a9fa9459Szrj static void
free_only_list(void)409*a9fa9459Szrj free_only_list (void)
410*a9fa9459Szrj {
411*a9fa9459Szrj   bfd_boolean at_least_one_seen = FALSE;
412*a9fa9459Szrj   struct only * only;
413*a9fa9459Szrj   struct only * next;
414*a9fa9459Szrj 
415*a9fa9459Szrj   if (only_list == NULL)
416*a9fa9459Szrj     return;
417*a9fa9459Szrj 
418*a9fa9459Szrj   for (only = only_list; only; only = only->next)
419*a9fa9459Szrj     if (only->seen)
420*a9fa9459Szrj       {
421*a9fa9459Szrj 	at_least_one_seen = TRUE;
422*a9fa9459Szrj 	break;
423*a9fa9459Szrj       }
424*a9fa9459Szrj 
425*a9fa9459Szrj   for (only = only_list; only; only = next)
426*a9fa9459Szrj     {
427*a9fa9459Szrj       if (! at_least_one_seen)
428*a9fa9459Szrj 	{
429*a9fa9459Szrj 	  non_fatal (_("section '%s' mentioned in a -j option, "
430*a9fa9459Szrj 		       "but not found in any input file"),
431*a9fa9459Szrj 		     only->name);
432*a9fa9459Szrj 	  exit_status = 1;
433*a9fa9459Szrj 	}
434*a9fa9459Szrj       next = only->next;
435*a9fa9459Szrj       free (only);
436*a9fa9459Szrj     }
437*a9fa9459Szrj }
438*a9fa9459Szrj 
439*a9fa9459Szrj 
440*a9fa9459Szrj static void
dump_section_header(bfd * abfd,asection * section,void * ignored ATTRIBUTE_UNUSED)441*a9fa9459Szrj dump_section_header (bfd *abfd, asection *section,
442*a9fa9459Szrj 		     void *ignored ATTRIBUTE_UNUSED)
443*a9fa9459Szrj {
444*a9fa9459Szrj   char *comma = "";
445*a9fa9459Szrj   unsigned int opb = bfd_octets_per_byte (abfd);
446*a9fa9459Szrj 
447*a9fa9459Szrj   /* Ignore linker created section.  See elfNN_ia64_object_p in
448*a9fa9459Szrj      bfd/elfxx-ia64.c.  */
449*a9fa9459Szrj   if (section->flags & SEC_LINKER_CREATED)
450*a9fa9459Szrj     return;
451*a9fa9459Szrj 
452*a9fa9459Szrj   /* PR 10413: Skip sections that we are ignoring.  */
453*a9fa9459Szrj   if (! process_section_p (section))
454*a9fa9459Szrj     return;
455*a9fa9459Szrj 
456*a9fa9459Szrj   printf ("%3d %-13s %08lx  ", section->index,
457*a9fa9459Szrj 	  bfd_get_section_name (abfd, section),
458*a9fa9459Szrj 	  (unsigned long) bfd_section_size (abfd, section) / opb);
459*a9fa9459Szrj   bfd_printf_vma (abfd, bfd_get_section_vma (abfd, section));
460*a9fa9459Szrj   printf ("  ");
461*a9fa9459Szrj   bfd_printf_vma (abfd, section->lma);
462*a9fa9459Szrj   printf ("  %08lx  2**%u", (unsigned long) section->filepos,
463*a9fa9459Szrj 	  bfd_get_section_alignment (abfd, section));
464*a9fa9459Szrj   if (! wide_output)
465*a9fa9459Szrj     printf ("\n                ");
466*a9fa9459Szrj   printf ("  ");
467*a9fa9459Szrj 
468*a9fa9459Szrj #define PF(x, y) \
469*a9fa9459Szrj   if (section->flags & x) { printf ("%s%s", comma, y); comma = ", "; }
470*a9fa9459Szrj 
471*a9fa9459Szrj   PF (SEC_HAS_CONTENTS, "CONTENTS");
472*a9fa9459Szrj   PF (SEC_ALLOC, "ALLOC");
473*a9fa9459Szrj   PF (SEC_CONSTRUCTOR, "CONSTRUCTOR");
474*a9fa9459Szrj   PF (SEC_LOAD, "LOAD");
475*a9fa9459Szrj   PF (SEC_RELOC, "RELOC");
476*a9fa9459Szrj   PF (SEC_READONLY, "READONLY");
477*a9fa9459Szrj   PF (SEC_CODE, "CODE");
478*a9fa9459Szrj   PF (SEC_DATA, "DATA");
479*a9fa9459Szrj   PF (SEC_ROM, "ROM");
480*a9fa9459Szrj   PF (SEC_DEBUGGING, "DEBUGGING");
481*a9fa9459Szrj   PF (SEC_NEVER_LOAD, "NEVER_LOAD");
482*a9fa9459Szrj   PF (SEC_EXCLUDE, "EXCLUDE");
483*a9fa9459Szrj   PF (SEC_SORT_ENTRIES, "SORT_ENTRIES");
484*a9fa9459Szrj   if (bfd_get_arch (abfd) == bfd_arch_tic54x)
485*a9fa9459Szrj     {
486*a9fa9459Szrj       PF (SEC_TIC54X_BLOCK, "BLOCK");
487*a9fa9459Szrj       PF (SEC_TIC54X_CLINK, "CLINK");
488*a9fa9459Szrj     }
489*a9fa9459Szrj   PF (SEC_SMALL_DATA, "SMALL_DATA");
490*a9fa9459Szrj   if (bfd_get_flavour (abfd) == bfd_target_coff_flavour)
491*a9fa9459Szrj     {
492*a9fa9459Szrj       PF (SEC_COFF_SHARED, "SHARED");
493*a9fa9459Szrj       PF (SEC_COFF_NOREAD, "NOREAD");
494*a9fa9459Szrj     }
495*a9fa9459Szrj   else if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
496*a9fa9459Szrj     {
497*a9fa9459Szrj       /* Note - sections can have both the READONLY and NOREAD attributes
498*a9fa9459Szrj 	 set.  In this case the NOREAD takes precedence, but we report both
499*a9fa9459Szrj 	 since the user may need to know that both bits are set.  */
500*a9fa9459Szrj       PF (SEC_ELF_NOREAD, "NOREAD");
501*a9fa9459Szrj     }
502*a9fa9459Szrj   PF (SEC_THREAD_LOCAL, "THREAD_LOCAL");
503*a9fa9459Szrj   PF (SEC_GROUP, "GROUP");
504*a9fa9459Szrj   if (bfd_get_arch (abfd) == bfd_arch_mep)
505*a9fa9459Szrj     {
506*a9fa9459Szrj       PF (SEC_MEP_VLIW, "VLIW");
507*a9fa9459Szrj     }
508*a9fa9459Szrj 
509*a9fa9459Szrj   if ((section->flags & SEC_LINK_ONCE) != 0)
510*a9fa9459Szrj     {
511*a9fa9459Szrj       const char *ls;
512*a9fa9459Szrj       struct coff_comdat_info *comdat;
513*a9fa9459Szrj 
514*a9fa9459Szrj       switch (section->flags & SEC_LINK_DUPLICATES)
515*a9fa9459Szrj 	{
516*a9fa9459Szrj 	default:
517*a9fa9459Szrj 	  abort ();
518*a9fa9459Szrj 	case SEC_LINK_DUPLICATES_DISCARD:
519*a9fa9459Szrj 	  ls = "LINK_ONCE_DISCARD";
520*a9fa9459Szrj 	  break;
521*a9fa9459Szrj 	case SEC_LINK_DUPLICATES_ONE_ONLY:
522*a9fa9459Szrj 	  ls = "LINK_ONCE_ONE_ONLY";
523*a9fa9459Szrj 	  break;
524*a9fa9459Szrj 	case SEC_LINK_DUPLICATES_SAME_SIZE:
525*a9fa9459Szrj 	  ls = "LINK_ONCE_SAME_SIZE";
526*a9fa9459Szrj 	  break;
527*a9fa9459Szrj 	case SEC_LINK_DUPLICATES_SAME_CONTENTS:
528*a9fa9459Szrj 	  ls = "LINK_ONCE_SAME_CONTENTS";
529*a9fa9459Szrj 	  break;
530*a9fa9459Szrj 	}
531*a9fa9459Szrj       printf ("%s%s", comma, ls);
532*a9fa9459Szrj 
533*a9fa9459Szrj       comdat = bfd_coff_get_comdat_section (abfd, section);
534*a9fa9459Szrj       if (comdat != NULL)
535*a9fa9459Szrj 	printf (" (COMDAT %s %ld)", comdat->name, comdat->symbol);
536*a9fa9459Szrj 
537*a9fa9459Szrj       comma = ", ";
538*a9fa9459Szrj     }
539*a9fa9459Szrj 
540*a9fa9459Szrj   printf ("\n");
541*a9fa9459Szrj #undef PF
542*a9fa9459Szrj }
543*a9fa9459Szrj 
544*a9fa9459Szrj static void
dump_headers(bfd * abfd)545*a9fa9459Szrj dump_headers (bfd *abfd)
546*a9fa9459Szrj {
547*a9fa9459Szrj   printf (_("Sections:\n"));
548*a9fa9459Szrj 
549*a9fa9459Szrj #ifndef BFD64
550*a9fa9459Szrj   printf (_("Idx Name          Size      VMA       LMA       File off  Algn"));
551*a9fa9459Szrj #else
552*a9fa9459Szrj   /* With BFD64, non-ELF returns -1 and wants always 64 bit addresses.  */
553*a9fa9459Szrj   if (bfd_get_arch_size (abfd) == 32)
554*a9fa9459Szrj     printf (_("Idx Name          Size      VMA       LMA       File off  Algn"));
555*a9fa9459Szrj   else
556*a9fa9459Szrj     printf (_("Idx Name          Size      VMA               LMA               File off  Algn"));
557*a9fa9459Szrj #endif
558*a9fa9459Szrj 
559*a9fa9459Szrj   if (wide_output)
560*a9fa9459Szrj     printf (_("  Flags"));
561*a9fa9459Szrj   printf ("\n");
562*a9fa9459Szrj 
563*a9fa9459Szrj   bfd_map_over_sections (abfd, dump_section_header, NULL);
564*a9fa9459Szrj }
565*a9fa9459Szrj 
566*a9fa9459Szrj static asymbol **
slurp_symtab(bfd * abfd)567*a9fa9459Szrj slurp_symtab (bfd *abfd)
568*a9fa9459Szrj {
569*a9fa9459Szrj   asymbol **sy = NULL;
570*a9fa9459Szrj   long storage;
571*a9fa9459Szrj 
572*a9fa9459Szrj   if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
573*a9fa9459Szrj     {
574*a9fa9459Szrj       symcount = 0;
575*a9fa9459Szrj       return NULL;
576*a9fa9459Szrj     }
577*a9fa9459Szrj 
578*a9fa9459Szrj   storage = bfd_get_symtab_upper_bound (abfd);
579*a9fa9459Szrj   if (storage < 0)
580*a9fa9459Szrj     {
581*a9fa9459Szrj       non_fatal (_("failed to read symbol table from: %s"), bfd_get_filename (abfd));
582*a9fa9459Szrj       bfd_fatal (_("error message was"));
583*a9fa9459Szrj     }
584*a9fa9459Szrj   if (storage)
585*a9fa9459Szrj     sy = (asymbol **) xmalloc (storage);
586*a9fa9459Szrj 
587*a9fa9459Szrj   symcount = bfd_canonicalize_symtab (abfd, sy);
588*a9fa9459Szrj   if (symcount < 0)
589*a9fa9459Szrj     bfd_fatal (bfd_get_filename (abfd));
590*a9fa9459Szrj   return sy;
591*a9fa9459Szrj }
592*a9fa9459Szrj 
593*a9fa9459Szrj /* Read in the dynamic symbols.  */
594*a9fa9459Szrj 
595*a9fa9459Szrj static asymbol **
slurp_dynamic_symtab(bfd * abfd)596*a9fa9459Szrj slurp_dynamic_symtab (bfd *abfd)
597*a9fa9459Szrj {
598*a9fa9459Szrj   asymbol **sy = NULL;
599*a9fa9459Szrj   long storage;
600*a9fa9459Szrj 
601*a9fa9459Szrj   storage = bfd_get_dynamic_symtab_upper_bound (abfd);
602*a9fa9459Szrj   if (storage < 0)
603*a9fa9459Szrj     {
604*a9fa9459Szrj       if (!(bfd_get_file_flags (abfd) & DYNAMIC))
605*a9fa9459Szrj 	{
606*a9fa9459Szrj 	  non_fatal (_("%s: not a dynamic object"), bfd_get_filename (abfd));
607*a9fa9459Szrj 	  exit_status = 1;
608*a9fa9459Szrj 	  dynsymcount = 0;
609*a9fa9459Szrj 	  return NULL;
610*a9fa9459Szrj 	}
611*a9fa9459Szrj 
612*a9fa9459Szrj       bfd_fatal (bfd_get_filename (abfd));
613*a9fa9459Szrj     }
614*a9fa9459Szrj   if (storage)
615*a9fa9459Szrj     sy = (asymbol **) xmalloc (storage);
616*a9fa9459Szrj 
617*a9fa9459Szrj   dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, sy);
618*a9fa9459Szrj   if (dynsymcount < 0)
619*a9fa9459Szrj     bfd_fatal (bfd_get_filename (abfd));
620*a9fa9459Szrj   return sy;
621*a9fa9459Szrj }
622*a9fa9459Szrj 
623*a9fa9459Szrj /* Filter out (in place) symbols that are useless for disassembly.
624*a9fa9459Szrj    COUNT is the number of elements in SYMBOLS.
625*a9fa9459Szrj    Return the number of useful symbols.  */
626*a9fa9459Szrj 
627*a9fa9459Szrj static long
remove_useless_symbols(asymbol ** symbols,long count)628*a9fa9459Szrj remove_useless_symbols (asymbol **symbols, long count)
629*a9fa9459Szrj {
630*a9fa9459Szrj   asymbol **in_ptr = symbols, **out_ptr = symbols;
631*a9fa9459Szrj 
632*a9fa9459Szrj   while (--count >= 0)
633*a9fa9459Szrj     {
634*a9fa9459Szrj       asymbol *sym = *in_ptr++;
635*a9fa9459Szrj 
636*a9fa9459Szrj       if (sym->name == NULL || sym->name[0] == '\0')
637*a9fa9459Szrj 	continue;
638*a9fa9459Szrj       if (sym->flags & (BSF_DEBUGGING | BSF_SECTION_SYM))
639*a9fa9459Szrj 	continue;
640*a9fa9459Szrj       if (bfd_is_und_section (sym->section)
641*a9fa9459Szrj 	  || bfd_is_com_section (sym->section))
642*a9fa9459Szrj 	continue;
643*a9fa9459Szrj 
644*a9fa9459Szrj       *out_ptr++ = sym;
645*a9fa9459Szrj     }
646*a9fa9459Szrj   return out_ptr - symbols;
647*a9fa9459Szrj }
648*a9fa9459Szrj 
649*a9fa9459Szrj /* Sort symbols into value order.  */
650*a9fa9459Szrj 
651*a9fa9459Szrj static int
compare_symbols(const void * ap,const void * bp)652*a9fa9459Szrj compare_symbols (const void *ap, const void *bp)
653*a9fa9459Szrj {
654*a9fa9459Szrj   const asymbol *a = * (const asymbol **) ap;
655*a9fa9459Szrj   const asymbol *b = * (const asymbol **) bp;
656*a9fa9459Szrj   const char *an;
657*a9fa9459Szrj   const char *bn;
658*a9fa9459Szrj   size_t anl;
659*a9fa9459Szrj   size_t bnl;
660*a9fa9459Szrj   bfd_boolean af;
661*a9fa9459Szrj   bfd_boolean bf;
662*a9fa9459Szrj   flagword aflags;
663*a9fa9459Szrj   flagword bflags;
664*a9fa9459Szrj 
665*a9fa9459Szrj   if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
666*a9fa9459Szrj     return 1;
667*a9fa9459Szrj   else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
668*a9fa9459Szrj     return -1;
669*a9fa9459Szrj 
670*a9fa9459Szrj   if (a->section > b->section)
671*a9fa9459Szrj     return 1;
672*a9fa9459Szrj   else if (a->section < b->section)
673*a9fa9459Szrj     return -1;
674*a9fa9459Szrj 
675*a9fa9459Szrj   an = bfd_asymbol_name (a);
676*a9fa9459Szrj   bn = bfd_asymbol_name (b);
677*a9fa9459Szrj   anl = strlen (an);
678*a9fa9459Szrj   bnl = strlen (bn);
679*a9fa9459Szrj 
680*a9fa9459Szrj   /* The symbols gnu_compiled and gcc2_compiled convey no real
681*a9fa9459Szrj      information, so put them after other symbols with the same value.  */
682*a9fa9459Szrj   af = (strstr (an, "gnu_compiled") != NULL
683*a9fa9459Szrj 	|| strstr (an, "gcc2_compiled") != NULL);
684*a9fa9459Szrj   bf = (strstr (bn, "gnu_compiled") != NULL
685*a9fa9459Szrj 	|| strstr (bn, "gcc2_compiled") != NULL);
686*a9fa9459Szrj 
687*a9fa9459Szrj   if (af && ! bf)
688*a9fa9459Szrj     return 1;
689*a9fa9459Szrj   if (! af && bf)
690*a9fa9459Szrj     return -1;
691*a9fa9459Szrj 
692*a9fa9459Szrj   /* We use a heuristic for the file name, to try to sort it after
693*a9fa9459Szrj      more useful symbols.  It may not work on non Unix systems, but it
694*a9fa9459Szrj      doesn't really matter; the only difference is precisely which
695*a9fa9459Szrj      symbol names get printed.  */
696*a9fa9459Szrj 
697*a9fa9459Szrj #define file_symbol(s, sn, snl)			\
698*a9fa9459Szrj   (((s)->flags & BSF_FILE) != 0			\
699*a9fa9459Szrj    || ((sn)[(snl) - 2] == '.'			\
700*a9fa9459Szrj        && ((sn)[(snl) - 1] == 'o'		\
701*a9fa9459Szrj 	   || (sn)[(snl) - 1] == 'a')))
702*a9fa9459Szrj 
703*a9fa9459Szrj   af = file_symbol (a, an, anl);
704*a9fa9459Szrj   bf = file_symbol (b, bn, bnl);
705*a9fa9459Szrj 
706*a9fa9459Szrj   if (af && ! bf)
707*a9fa9459Szrj     return 1;
708*a9fa9459Szrj   if (! af && bf)
709*a9fa9459Szrj     return -1;
710*a9fa9459Szrj 
711*a9fa9459Szrj   /* Try to sort global symbols before local symbols before function
712*a9fa9459Szrj      symbols before debugging symbols.  */
713*a9fa9459Szrj 
714*a9fa9459Szrj   aflags = a->flags;
715*a9fa9459Szrj   bflags = b->flags;
716*a9fa9459Szrj 
717*a9fa9459Szrj   if ((aflags & BSF_DEBUGGING) != (bflags & BSF_DEBUGGING))
718*a9fa9459Szrj     {
719*a9fa9459Szrj       if ((aflags & BSF_DEBUGGING) != 0)
720*a9fa9459Szrj 	return 1;
721*a9fa9459Szrj       else
722*a9fa9459Szrj 	return -1;
723*a9fa9459Szrj     }
724*a9fa9459Szrj   if ((aflags & BSF_FUNCTION) != (bflags & BSF_FUNCTION))
725*a9fa9459Szrj     {
726*a9fa9459Szrj       if ((aflags & BSF_FUNCTION) != 0)
727*a9fa9459Szrj 	return -1;
728*a9fa9459Szrj       else
729*a9fa9459Szrj 	return 1;
730*a9fa9459Szrj     }
731*a9fa9459Szrj   if ((aflags & BSF_LOCAL) != (bflags & BSF_LOCAL))
732*a9fa9459Szrj     {
733*a9fa9459Szrj       if ((aflags & BSF_LOCAL) != 0)
734*a9fa9459Szrj 	return 1;
735*a9fa9459Szrj       else
736*a9fa9459Szrj 	return -1;
737*a9fa9459Szrj     }
738*a9fa9459Szrj   if ((aflags & BSF_GLOBAL) != (bflags & BSF_GLOBAL))
739*a9fa9459Szrj     {
740*a9fa9459Szrj       if ((aflags & BSF_GLOBAL) != 0)
741*a9fa9459Szrj 	return -1;
742*a9fa9459Szrj       else
743*a9fa9459Szrj 	return 1;
744*a9fa9459Szrj     }
745*a9fa9459Szrj 
746*a9fa9459Szrj   /* Symbols that start with '.' might be section names, so sort them
747*a9fa9459Szrj      after symbols that don't start with '.'.  */
748*a9fa9459Szrj   if (an[0] == '.' && bn[0] != '.')
749*a9fa9459Szrj     return 1;
750*a9fa9459Szrj   if (an[0] != '.' && bn[0] == '.')
751*a9fa9459Szrj     return -1;
752*a9fa9459Szrj 
753*a9fa9459Szrj   /* Finally, if we can't distinguish them in any other way, try to
754*a9fa9459Szrj      get consistent results by sorting the symbols by name.  */
755*a9fa9459Szrj   return strcmp (an, bn);
756*a9fa9459Szrj }
757*a9fa9459Szrj 
758*a9fa9459Szrj /* Sort relocs into address order.  */
759*a9fa9459Szrj 
760*a9fa9459Szrj static int
compare_relocs(const void * ap,const void * bp)761*a9fa9459Szrj compare_relocs (const void *ap, const void *bp)
762*a9fa9459Szrj {
763*a9fa9459Szrj   const arelent *a = * (const arelent **) ap;
764*a9fa9459Szrj   const arelent *b = * (const arelent **) bp;
765*a9fa9459Szrj 
766*a9fa9459Szrj   if (a->address > b->address)
767*a9fa9459Szrj     return 1;
768*a9fa9459Szrj   else if (a->address < b->address)
769*a9fa9459Szrj     return -1;
770*a9fa9459Szrj 
771*a9fa9459Szrj   /* So that associated relocations tied to the same address show up
772*a9fa9459Szrj      in the correct order, we don't do any further sorting.  */
773*a9fa9459Szrj   if (a > b)
774*a9fa9459Szrj     return 1;
775*a9fa9459Szrj   else if (a < b)
776*a9fa9459Szrj     return -1;
777*a9fa9459Szrj   else
778*a9fa9459Szrj     return 0;
779*a9fa9459Szrj }
780*a9fa9459Szrj 
781*a9fa9459Szrj /* Print an address (VMA) to the output stream in INFO.
782*a9fa9459Szrj    If SKIP_ZEROES is TRUE, omit leading zeroes.  */
783*a9fa9459Szrj 
784*a9fa9459Szrj static void
objdump_print_value(bfd_vma vma,struct disassemble_info * inf,bfd_boolean skip_zeroes)785*a9fa9459Szrj objdump_print_value (bfd_vma vma, struct disassemble_info *inf,
786*a9fa9459Szrj 		     bfd_boolean skip_zeroes)
787*a9fa9459Szrj {
788*a9fa9459Szrj   char buf[30];
789*a9fa9459Szrj   char *p;
790*a9fa9459Szrj   struct objdump_disasm_info *aux;
791*a9fa9459Szrj 
792*a9fa9459Szrj   aux = (struct objdump_disasm_info *) inf->application_data;
793*a9fa9459Szrj   bfd_sprintf_vma (aux->abfd, buf, vma);
794*a9fa9459Szrj   if (! skip_zeroes)
795*a9fa9459Szrj     p = buf;
796*a9fa9459Szrj   else
797*a9fa9459Szrj     {
798*a9fa9459Szrj       for (p = buf; *p == '0'; ++p)
799*a9fa9459Szrj 	;
800*a9fa9459Szrj       if (*p == '\0')
801*a9fa9459Szrj 	--p;
802*a9fa9459Szrj     }
803*a9fa9459Szrj   (*inf->fprintf_func) (inf->stream, "%s", p);
804*a9fa9459Szrj }
805*a9fa9459Szrj 
806*a9fa9459Szrj /* Print the name of a symbol.  */
807*a9fa9459Szrj 
808*a9fa9459Szrj static void
objdump_print_symname(bfd * abfd,struct disassemble_info * inf,asymbol * sym)809*a9fa9459Szrj objdump_print_symname (bfd *abfd, struct disassemble_info *inf,
810*a9fa9459Szrj 		       asymbol *sym)
811*a9fa9459Szrj {
812*a9fa9459Szrj   char *alloc;
813*a9fa9459Szrj   const char *name, *version_string = NULL;
814*a9fa9459Szrj   bfd_boolean hidden = FALSE;
815*a9fa9459Szrj 
816*a9fa9459Szrj   alloc = NULL;
817*a9fa9459Szrj   name = bfd_asymbol_name (sym);
818*a9fa9459Szrj   if (do_demangle && name[0] != '\0')
819*a9fa9459Szrj     {
820*a9fa9459Szrj       /* Demangle the name.  */
821*a9fa9459Szrj       alloc = bfd_demangle (abfd, name, DMGL_ANSI | DMGL_PARAMS);
822*a9fa9459Szrj       if (alloc != NULL)
823*a9fa9459Szrj 	name = alloc;
824*a9fa9459Szrj     }
825*a9fa9459Szrj 
826*a9fa9459Szrj   if ((sym->flags & BSF_SYNTHETIC) == 0)
827*a9fa9459Szrj     version_string = bfd_get_symbol_version_string (abfd, sym, &hidden);
828*a9fa9459Szrj 
829*a9fa9459Szrj   if (bfd_is_und_section (bfd_get_section (sym)))
830*a9fa9459Szrj     hidden = TRUE;
831*a9fa9459Szrj 
832*a9fa9459Szrj   if (inf != NULL)
833*a9fa9459Szrj     {
834*a9fa9459Szrj       (*inf->fprintf_func) (inf->stream, "%s", name);
835*a9fa9459Szrj       if (version_string && *version_string != '\0')
836*a9fa9459Szrj 	(*inf->fprintf_func) (inf->stream, hidden ? "@%s" : "@@%s",
837*a9fa9459Szrj 			      version_string);
838*a9fa9459Szrj     }
839*a9fa9459Szrj   else
840*a9fa9459Szrj     {
841*a9fa9459Szrj       printf ("%s", name);
842*a9fa9459Szrj       if (version_string && *version_string != '\0')
843*a9fa9459Szrj 	printf (hidden ? "@%s" : "@@%s", version_string);
844*a9fa9459Szrj     }
845*a9fa9459Szrj 
846*a9fa9459Szrj   if (alloc != NULL)
847*a9fa9459Szrj     free (alloc);
848*a9fa9459Szrj }
849*a9fa9459Szrj 
850*a9fa9459Szrj /* Locate a symbol given a bfd and a section (from INFO->application_data),
851*a9fa9459Szrj    and a VMA.  If INFO->application_data->require_sec is TRUE, then always
852*a9fa9459Szrj    require the symbol to be in the section.  Returns NULL if there is no
853*a9fa9459Szrj    suitable symbol.  If PLACE is not NULL, then *PLACE is set to the index
854*a9fa9459Szrj    of the symbol in sorted_syms.  */
855*a9fa9459Szrj 
856*a9fa9459Szrj static asymbol *
find_symbol_for_address(bfd_vma vma,struct disassemble_info * inf,long * place)857*a9fa9459Szrj find_symbol_for_address (bfd_vma vma,
858*a9fa9459Szrj 			 struct disassemble_info *inf,
859*a9fa9459Szrj 			 long *place)
860*a9fa9459Szrj {
861*a9fa9459Szrj   /* @@ Would it speed things up to cache the last two symbols returned,
862*a9fa9459Szrj      and maybe their address ranges?  For many processors, only one memory
863*a9fa9459Szrj      operand can be present at a time, so the 2-entry cache wouldn't be
864*a9fa9459Szrj      constantly churned by code doing heavy memory accesses.  */
865*a9fa9459Szrj 
866*a9fa9459Szrj   /* Indices in `sorted_syms'.  */
867*a9fa9459Szrj   long min = 0;
868*a9fa9459Szrj   long max_count = sorted_symcount;
869*a9fa9459Szrj   long thisplace;
870*a9fa9459Szrj   struct objdump_disasm_info *aux;
871*a9fa9459Szrj   bfd *abfd;
872*a9fa9459Szrj   asection *sec;
873*a9fa9459Szrj   unsigned int opb;
874*a9fa9459Szrj   bfd_boolean want_section;
875*a9fa9459Szrj 
876*a9fa9459Szrj   if (sorted_symcount < 1)
877*a9fa9459Szrj     return NULL;
878*a9fa9459Szrj 
879*a9fa9459Szrj   aux = (struct objdump_disasm_info *) inf->application_data;
880*a9fa9459Szrj   abfd = aux->abfd;
881*a9fa9459Szrj   sec = aux->sec;
882*a9fa9459Szrj   opb = inf->octets_per_byte;
883*a9fa9459Szrj 
884*a9fa9459Szrj   /* Perform a binary search looking for the closest symbol to the
885*a9fa9459Szrj      required value.  We are searching the range (min, max_count].  */
886*a9fa9459Szrj   while (min + 1 < max_count)
887*a9fa9459Szrj     {
888*a9fa9459Szrj       asymbol *sym;
889*a9fa9459Szrj 
890*a9fa9459Szrj       thisplace = (max_count + min) / 2;
891*a9fa9459Szrj       sym = sorted_syms[thisplace];
892*a9fa9459Szrj 
893*a9fa9459Szrj       if (bfd_asymbol_value (sym) > vma)
894*a9fa9459Szrj 	max_count = thisplace;
895*a9fa9459Szrj       else if (bfd_asymbol_value (sym) < vma)
896*a9fa9459Szrj 	min = thisplace;
897*a9fa9459Szrj       else
898*a9fa9459Szrj 	{
899*a9fa9459Szrj 	  min = thisplace;
900*a9fa9459Szrj 	  break;
901*a9fa9459Szrj 	}
902*a9fa9459Szrj     }
903*a9fa9459Szrj 
904*a9fa9459Szrj   /* The symbol we want is now in min, the low end of the range we
905*a9fa9459Szrj      were searching.  If there are several symbols with the same
906*a9fa9459Szrj      value, we want the first one.  */
907*a9fa9459Szrj   thisplace = min;
908*a9fa9459Szrj   while (thisplace > 0
909*a9fa9459Szrj 	 && (bfd_asymbol_value (sorted_syms[thisplace])
910*a9fa9459Szrj 	     == bfd_asymbol_value (sorted_syms[thisplace - 1])))
911*a9fa9459Szrj     --thisplace;
912*a9fa9459Szrj 
913*a9fa9459Szrj   /* Prefer a symbol in the current section if we have multple symbols
914*a9fa9459Szrj      with the same value, as can occur with overlays or zero size
915*a9fa9459Szrj      sections.  */
916*a9fa9459Szrj   min = thisplace;
917*a9fa9459Szrj   while (min < max_count
918*a9fa9459Szrj 	 && (bfd_asymbol_value (sorted_syms[min])
919*a9fa9459Szrj 	     == bfd_asymbol_value (sorted_syms[thisplace])))
920*a9fa9459Szrj     {
921*a9fa9459Szrj       if (sorted_syms[min]->section == sec
922*a9fa9459Szrj 	  && inf->symbol_is_valid (sorted_syms[min], inf))
923*a9fa9459Szrj 	{
924*a9fa9459Szrj 	  thisplace = min;
925*a9fa9459Szrj 
926*a9fa9459Szrj 	  if (place != NULL)
927*a9fa9459Szrj 	    *place = thisplace;
928*a9fa9459Szrj 
929*a9fa9459Szrj 	  return sorted_syms[thisplace];
930*a9fa9459Szrj 	}
931*a9fa9459Szrj       ++min;
932*a9fa9459Szrj     }
933*a9fa9459Szrj 
934*a9fa9459Szrj   /* If the file is relocatable, and the symbol could be from this
935*a9fa9459Szrj      section, prefer a symbol from this section over symbols from
936*a9fa9459Szrj      others, even if the other symbol's value might be closer.
937*a9fa9459Szrj 
938*a9fa9459Szrj      Note that this may be wrong for some symbol references if the
939*a9fa9459Szrj      sections have overlapping memory ranges, but in that case there's
940*a9fa9459Szrj      no way to tell what's desired without looking at the relocation
941*a9fa9459Szrj      table.
942*a9fa9459Szrj 
943*a9fa9459Szrj      Also give the target a chance to reject symbols.  */
944*a9fa9459Szrj   want_section = (aux->require_sec
945*a9fa9459Szrj 		  || ((abfd->flags & HAS_RELOC) != 0
946*a9fa9459Szrj 		      && vma >= bfd_get_section_vma (abfd, sec)
947*a9fa9459Szrj 		      && vma < (bfd_get_section_vma (abfd, sec)
948*a9fa9459Szrj 				+ bfd_section_size (abfd, sec) / opb)));
949*a9fa9459Szrj   if ((sorted_syms[thisplace]->section != sec && want_section)
950*a9fa9459Szrj       || ! inf->symbol_is_valid (sorted_syms[thisplace], inf))
951*a9fa9459Szrj     {
952*a9fa9459Szrj       long i;
953*a9fa9459Szrj       long newplace = sorted_symcount;
954*a9fa9459Szrj 
955*a9fa9459Szrj       for (i = min - 1; i >= 0; i--)
956*a9fa9459Szrj 	{
957*a9fa9459Szrj 	  if ((sorted_syms[i]->section == sec || !want_section)
958*a9fa9459Szrj 	      && inf->symbol_is_valid (sorted_syms[i], inf))
959*a9fa9459Szrj 	    {
960*a9fa9459Szrj 	      if (newplace == sorted_symcount)
961*a9fa9459Szrj 		newplace = i;
962*a9fa9459Szrj 
963*a9fa9459Szrj 	      if (bfd_asymbol_value (sorted_syms[i])
964*a9fa9459Szrj 		  != bfd_asymbol_value (sorted_syms[newplace]))
965*a9fa9459Szrj 		break;
966*a9fa9459Szrj 
967*a9fa9459Szrj 	      /* Remember this symbol and keep searching until we reach
968*a9fa9459Szrj 		 an earlier address.  */
969*a9fa9459Szrj 	      newplace = i;
970*a9fa9459Szrj 	    }
971*a9fa9459Szrj 	}
972*a9fa9459Szrj 
973*a9fa9459Szrj       if (newplace != sorted_symcount)
974*a9fa9459Szrj 	thisplace = newplace;
975*a9fa9459Szrj       else
976*a9fa9459Szrj 	{
977*a9fa9459Szrj 	  /* We didn't find a good symbol with a smaller value.
978*a9fa9459Szrj 	     Look for one with a larger value.  */
979*a9fa9459Szrj 	  for (i = thisplace + 1; i < sorted_symcount; i++)
980*a9fa9459Szrj 	    {
981*a9fa9459Szrj 	      if ((sorted_syms[i]->section == sec || !want_section)
982*a9fa9459Szrj 		  && inf->symbol_is_valid (sorted_syms[i], inf))
983*a9fa9459Szrj 		{
984*a9fa9459Szrj 		  thisplace = i;
985*a9fa9459Szrj 		  break;
986*a9fa9459Szrj 		}
987*a9fa9459Szrj 	    }
988*a9fa9459Szrj 	}
989*a9fa9459Szrj 
990*a9fa9459Szrj       if ((sorted_syms[thisplace]->section != sec && want_section)
991*a9fa9459Szrj 	  || ! inf->symbol_is_valid (sorted_syms[thisplace], inf))
992*a9fa9459Szrj 	/* There is no suitable symbol.  */
993*a9fa9459Szrj 	return NULL;
994*a9fa9459Szrj     }
995*a9fa9459Szrj 
996*a9fa9459Szrj   if (place != NULL)
997*a9fa9459Szrj     *place = thisplace;
998*a9fa9459Szrj 
999*a9fa9459Szrj   return sorted_syms[thisplace];
1000*a9fa9459Szrj }
1001*a9fa9459Szrj 
1002*a9fa9459Szrj /* Print an address and the offset to the nearest symbol.  */
1003*a9fa9459Szrj 
1004*a9fa9459Szrj static void
objdump_print_addr_with_sym(bfd * abfd,asection * sec,asymbol * sym,bfd_vma vma,struct disassemble_info * inf,bfd_boolean skip_zeroes)1005*a9fa9459Szrj objdump_print_addr_with_sym (bfd *abfd, asection *sec, asymbol *sym,
1006*a9fa9459Szrj 			     bfd_vma vma, struct disassemble_info *inf,
1007*a9fa9459Szrj 			     bfd_boolean skip_zeroes)
1008*a9fa9459Szrj {
1009*a9fa9459Szrj   objdump_print_value (vma, inf, skip_zeroes);
1010*a9fa9459Szrj 
1011*a9fa9459Szrj   if (sym == NULL)
1012*a9fa9459Szrj     {
1013*a9fa9459Szrj       bfd_vma secaddr;
1014*a9fa9459Szrj 
1015*a9fa9459Szrj       (*inf->fprintf_func) (inf->stream, " <%s",
1016*a9fa9459Szrj 			    bfd_get_section_name (abfd, sec));
1017*a9fa9459Szrj       secaddr = bfd_get_section_vma (abfd, sec);
1018*a9fa9459Szrj       if (vma < secaddr)
1019*a9fa9459Szrj 	{
1020*a9fa9459Szrj 	  (*inf->fprintf_func) (inf->stream, "-0x");
1021*a9fa9459Szrj 	  objdump_print_value (secaddr - vma, inf, TRUE);
1022*a9fa9459Szrj 	}
1023*a9fa9459Szrj       else if (vma > secaddr)
1024*a9fa9459Szrj 	{
1025*a9fa9459Szrj 	  (*inf->fprintf_func) (inf->stream, "+0x");
1026*a9fa9459Szrj 	  objdump_print_value (vma - secaddr, inf, TRUE);
1027*a9fa9459Szrj 	}
1028*a9fa9459Szrj       (*inf->fprintf_func) (inf->stream, ">");
1029*a9fa9459Szrj     }
1030*a9fa9459Szrj   else
1031*a9fa9459Szrj     {
1032*a9fa9459Szrj       (*inf->fprintf_func) (inf->stream, " <");
1033*a9fa9459Szrj       objdump_print_symname (abfd, inf, sym);
1034*a9fa9459Szrj       if (bfd_asymbol_value (sym) > vma)
1035*a9fa9459Szrj 	{
1036*a9fa9459Szrj 	  (*inf->fprintf_func) (inf->stream, "-0x");
1037*a9fa9459Szrj 	  objdump_print_value (bfd_asymbol_value (sym) - vma, inf, TRUE);
1038*a9fa9459Szrj 	}
1039*a9fa9459Szrj       else if (vma > bfd_asymbol_value (sym))
1040*a9fa9459Szrj 	{
1041*a9fa9459Szrj 	  (*inf->fprintf_func) (inf->stream, "+0x");
1042*a9fa9459Szrj 	  objdump_print_value (vma - bfd_asymbol_value (sym), inf, TRUE);
1043*a9fa9459Szrj 	}
1044*a9fa9459Szrj       (*inf->fprintf_func) (inf->stream, ">");
1045*a9fa9459Szrj     }
1046*a9fa9459Szrj 
1047*a9fa9459Szrj   if (display_file_offsets)
1048*a9fa9459Szrj     inf->fprintf_func (inf->stream, _(" (File Offset: 0x%lx)"),
1049*a9fa9459Szrj 			(long int)(sec->filepos + (vma - sec->vma)));
1050*a9fa9459Szrj }
1051*a9fa9459Szrj 
1052*a9fa9459Szrj /* Print an address (VMA), symbolically if possible.
1053*a9fa9459Szrj    If SKIP_ZEROES is TRUE, don't output leading zeroes.  */
1054*a9fa9459Szrj 
1055*a9fa9459Szrj static void
objdump_print_addr(bfd_vma vma,struct disassemble_info * inf,bfd_boolean skip_zeroes)1056*a9fa9459Szrj objdump_print_addr (bfd_vma vma,
1057*a9fa9459Szrj 		    struct disassemble_info *inf,
1058*a9fa9459Szrj 		    bfd_boolean skip_zeroes)
1059*a9fa9459Szrj {
1060*a9fa9459Szrj   struct objdump_disasm_info *aux;
1061*a9fa9459Szrj   asymbol *sym = NULL;
1062*a9fa9459Szrj   bfd_boolean skip_find = FALSE;
1063*a9fa9459Szrj 
1064*a9fa9459Szrj   aux = (struct objdump_disasm_info *) inf->application_data;
1065*a9fa9459Szrj 
1066*a9fa9459Szrj   if (sorted_symcount < 1)
1067*a9fa9459Szrj     {
1068*a9fa9459Szrj       (*inf->fprintf_func) (inf->stream, "0x");
1069*a9fa9459Szrj       objdump_print_value (vma, inf, skip_zeroes);
1070*a9fa9459Szrj 
1071*a9fa9459Szrj       if (display_file_offsets)
1072*a9fa9459Szrj 	inf->fprintf_func (inf->stream, _(" (File Offset: 0x%lx)"),
1073*a9fa9459Szrj 			   (long int)(aux->sec->filepos + (vma - aux->sec->vma)));
1074*a9fa9459Szrj       return;
1075*a9fa9459Szrj     }
1076*a9fa9459Szrj 
1077*a9fa9459Szrj   if (aux->reloc != NULL
1078*a9fa9459Szrj       && aux->reloc->sym_ptr_ptr != NULL
1079*a9fa9459Szrj       && * aux->reloc->sym_ptr_ptr != NULL)
1080*a9fa9459Szrj     {
1081*a9fa9459Szrj       sym = * aux->reloc->sym_ptr_ptr;
1082*a9fa9459Szrj 
1083*a9fa9459Szrj       /* Adjust the vma to the reloc.  */
1084*a9fa9459Szrj       vma += bfd_asymbol_value (sym);
1085*a9fa9459Szrj 
1086*a9fa9459Szrj       if (bfd_is_und_section (bfd_get_section (sym)))
1087*a9fa9459Szrj 	skip_find = TRUE;
1088*a9fa9459Szrj     }
1089*a9fa9459Szrj 
1090*a9fa9459Szrj   if (!skip_find)
1091*a9fa9459Szrj     sym = find_symbol_for_address (vma, inf, NULL);
1092*a9fa9459Szrj 
1093*a9fa9459Szrj   objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, inf,
1094*a9fa9459Szrj 			       skip_zeroes);
1095*a9fa9459Szrj }
1096*a9fa9459Szrj 
1097*a9fa9459Szrj /* Print VMA to INFO.  This function is passed to the disassembler
1098*a9fa9459Szrj    routine.  */
1099*a9fa9459Szrj 
1100*a9fa9459Szrj static void
objdump_print_address(bfd_vma vma,struct disassemble_info * inf)1101*a9fa9459Szrj objdump_print_address (bfd_vma vma, struct disassemble_info *inf)
1102*a9fa9459Szrj {
1103*a9fa9459Szrj   objdump_print_addr (vma, inf, ! prefix_addresses);
1104*a9fa9459Szrj }
1105*a9fa9459Szrj 
1106*a9fa9459Szrj /* Determine if the given address has a symbol associated with it.  */
1107*a9fa9459Szrj 
1108*a9fa9459Szrj static int
objdump_symbol_at_address(bfd_vma vma,struct disassemble_info * inf)1109*a9fa9459Szrj objdump_symbol_at_address (bfd_vma vma, struct disassemble_info * inf)
1110*a9fa9459Szrj {
1111*a9fa9459Szrj   asymbol * sym;
1112*a9fa9459Szrj 
1113*a9fa9459Szrj   sym = find_symbol_for_address (vma, inf, NULL);
1114*a9fa9459Szrj 
1115*a9fa9459Szrj   return (sym != NULL && (bfd_asymbol_value (sym) == vma));
1116*a9fa9459Szrj }
1117*a9fa9459Szrj 
1118*a9fa9459Szrj /* Hold the last function name and the last line number we displayed
1119*a9fa9459Szrj    in a disassembly.  */
1120*a9fa9459Szrj 
1121*a9fa9459Szrj static char *prev_functionname;
1122*a9fa9459Szrj static unsigned int prev_line;
1123*a9fa9459Szrj static unsigned int prev_discriminator;
1124*a9fa9459Szrj 
1125*a9fa9459Szrj /* We keep a list of all files that we have seen when doing a
1126*a9fa9459Szrj    disassembly with source, so that we know how much of the file to
1127*a9fa9459Szrj    display.  This can be important for inlined functions.  */
1128*a9fa9459Szrj 
1129*a9fa9459Szrj struct print_file_list
1130*a9fa9459Szrj {
1131*a9fa9459Szrj   struct print_file_list *next;
1132*a9fa9459Szrj   const char *filename;
1133*a9fa9459Szrj   const char *modname;
1134*a9fa9459Szrj   const char *map;
1135*a9fa9459Szrj   size_t mapsize;
1136*a9fa9459Szrj   const char **linemap;
1137*a9fa9459Szrj   unsigned maxline;
1138*a9fa9459Szrj   unsigned last_line;
1139*a9fa9459Szrj   unsigned max_printed;
1140*a9fa9459Szrj   int first;
1141*a9fa9459Szrj };
1142*a9fa9459Szrj 
1143*a9fa9459Szrj static struct print_file_list *print_files;
1144*a9fa9459Szrj 
1145*a9fa9459Szrj /* The number of preceding context lines to show when we start
1146*a9fa9459Szrj    displaying a file for the first time.  */
1147*a9fa9459Szrj 
1148*a9fa9459Szrj #define SHOW_PRECEDING_CONTEXT_LINES (5)
1149*a9fa9459Szrj 
1150*a9fa9459Szrj /* Read a complete file into memory.  */
1151*a9fa9459Szrj 
1152*a9fa9459Szrj static const char *
slurp_file(const char * fn,size_t * size)1153*a9fa9459Szrj slurp_file (const char *fn, size_t *size)
1154*a9fa9459Szrj {
1155*a9fa9459Szrj #ifdef HAVE_MMAP
1156*a9fa9459Szrj   int ps = getpagesize ();
1157*a9fa9459Szrj   size_t msize;
1158*a9fa9459Szrj #endif
1159*a9fa9459Szrj   const char *map;
1160*a9fa9459Szrj   struct stat st;
1161*a9fa9459Szrj   int fd = open (fn, O_RDONLY | O_BINARY);
1162*a9fa9459Szrj 
1163*a9fa9459Szrj   if (fd < 0)
1164*a9fa9459Szrj     return NULL;
1165*a9fa9459Szrj   if (fstat (fd, &st) < 0)
1166*a9fa9459Szrj     {
1167*a9fa9459Szrj       close (fd);
1168*a9fa9459Szrj       return NULL;
1169*a9fa9459Szrj     }
1170*a9fa9459Szrj   *size = st.st_size;
1171*a9fa9459Szrj #ifdef HAVE_MMAP
1172*a9fa9459Szrj   msize = (*size + ps - 1) & ~(ps - 1);
1173*a9fa9459Szrj   map = mmap (NULL, msize, PROT_READ, MAP_SHARED, fd, 0);
1174*a9fa9459Szrj   if (map != (char *) -1L)
1175*a9fa9459Szrj     {
1176*a9fa9459Szrj       close (fd);
1177*a9fa9459Szrj       return map;
1178*a9fa9459Szrj     }
1179*a9fa9459Szrj #endif
1180*a9fa9459Szrj   map = (const char *) malloc (*size);
1181*a9fa9459Szrj   if (!map || (size_t) read (fd, (char *) map, *size) != *size)
1182*a9fa9459Szrj     {
1183*a9fa9459Szrj       free ((void *) map);
1184*a9fa9459Szrj       map = NULL;
1185*a9fa9459Szrj     }
1186*a9fa9459Szrj   close (fd);
1187*a9fa9459Szrj   return map;
1188*a9fa9459Szrj }
1189*a9fa9459Szrj 
1190*a9fa9459Szrj #define line_map_decrease 5
1191*a9fa9459Szrj 
1192*a9fa9459Szrj /* Precompute array of lines for a mapped file. */
1193*a9fa9459Szrj 
1194*a9fa9459Szrj static const char **
index_file(const char * map,size_t size,unsigned int * maxline)1195*a9fa9459Szrj index_file (const char *map, size_t size, unsigned int *maxline)
1196*a9fa9459Szrj {
1197*a9fa9459Szrj   const char *p, *lstart, *end;
1198*a9fa9459Szrj   int chars_per_line = 45; /* First iteration will use 40.  */
1199*a9fa9459Szrj   unsigned int lineno;
1200*a9fa9459Szrj   const char **linemap = NULL;
1201*a9fa9459Szrj   unsigned long line_map_size = 0;
1202*a9fa9459Szrj 
1203*a9fa9459Szrj   lineno = 0;
1204*a9fa9459Szrj   lstart = map;
1205*a9fa9459Szrj   end = map + size;
1206*a9fa9459Szrj 
1207*a9fa9459Szrj   for (p = map; p < end; p++)
1208*a9fa9459Szrj     {
1209*a9fa9459Szrj       if (*p == '\n')
1210*a9fa9459Szrj 	{
1211*a9fa9459Szrj 	  if (p + 1 < end && p[1] == '\r')
1212*a9fa9459Szrj 	    p++;
1213*a9fa9459Szrj 	}
1214*a9fa9459Szrj       else if (*p == '\r')
1215*a9fa9459Szrj 	{
1216*a9fa9459Szrj 	  if (p + 1 < end && p[1] == '\n')
1217*a9fa9459Szrj 	    p++;
1218*a9fa9459Szrj 	}
1219*a9fa9459Szrj       else
1220*a9fa9459Szrj 	continue;
1221*a9fa9459Szrj 
1222*a9fa9459Szrj       /* End of line found.  */
1223*a9fa9459Szrj 
1224*a9fa9459Szrj       if (linemap == NULL || line_map_size < lineno + 1)
1225*a9fa9459Szrj 	{
1226*a9fa9459Szrj 	  unsigned long newsize;
1227*a9fa9459Szrj 
1228*a9fa9459Szrj 	  chars_per_line -= line_map_decrease;
1229*a9fa9459Szrj 	  if (chars_per_line <= 1)
1230*a9fa9459Szrj 	    chars_per_line = 1;
1231*a9fa9459Szrj 	  line_map_size = size / chars_per_line + 1;
1232*a9fa9459Szrj 	  if (line_map_size < lineno + 1)
1233*a9fa9459Szrj 	    line_map_size = lineno + 1;
1234*a9fa9459Szrj 	  newsize = line_map_size * sizeof (char *);
1235*a9fa9459Szrj 	  linemap = (const char **) xrealloc (linemap, newsize);
1236*a9fa9459Szrj 	}
1237*a9fa9459Szrj 
1238*a9fa9459Szrj       linemap[lineno++] = lstart;
1239*a9fa9459Szrj       lstart = p + 1;
1240*a9fa9459Szrj     }
1241*a9fa9459Szrj 
1242*a9fa9459Szrj   *maxline = lineno;
1243*a9fa9459Szrj   return linemap;
1244*a9fa9459Szrj }
1245*a9fa9459Szrj 
1246*a9fa9459Szrj /* Tries to open MODNAME, and if successful adds a node to print_files
1247*a9fa9459Szrj    linked list and returns that node.  Returns NULL on failure.  */
1248*a9fa9459Szrj 
1249*a9fa9459Szrj static struct print_file_list *
try_print_file_open(const char * origname,const char * modname)1250*a9fa9459Szrj try_print_file_open (const char *origname, const char *modname)
1251*a9fa9459Szrj {
1252*a9fa9459Szrj   struct print_file_list *p;
1253*a9fa9459Szrj 
1254*a9fa9459Szrj   p = (struct print_file_list *) xmalloc (sizeof (struct print_file_list));
1255*a9fa9459Szrj 
1256*a9fa9459Szrj   p->map = slurp_file (modname, &p->mapsize);
1257*a9fa9459Szrj   if (p->map == NULL)
1258*a9fa9459Szrj     {
1259*a9fa9459Szrj       free (p);
1260*a9fa9459Szrj       return NULL;
1261*a9fa9459Szrj     }
1262*a9fa9459Szrj 
1263*a9fa9459Szrj   p->linemap = index_file (p->map, p->mapsize, &p->maxline);
1264*a9fa9459Szrj   p->last_line = 0;
1265*a9fa9459Szrj   p->max_printed = 0;
1266*a9fa9459Szrj   p->filename = origname;
1267*a9fa9459Szrj   p->modname = modname;
1268*a9fa9459Szrj   p->next = print_files;
1269*a9fa9459Szrj   p->first = 1;
1270*a9fa9459Szrj   print_files = p;
1271*a9fa9459Szrj   return p;
1272*a9fa9459Szrj }
1273*a9fa9459Szrj 
1274*a9fa9459Szrj /* If the source file, as described in the symtab, is not found
1275*a9fa9459Szrj    try to locate it in one of the paths specified with -I
1276*a9fa9459Szrj    If found, add location to print_files linked list.  */
1277*a9fa9459Szrj 
1278*a9fa9459Szrj static struct print_file_list *
update_source_path(const char * filename)1279*a9fa9459Szrj update_source_path (const char *filename)
1280*a9fa9459Szrj {
1281*a9fa9459Szrj   struct print_file_list *p;
1282*a9fa9459Szrj   const char *fname;
1283*a9fa9459Szrj   int i;
1284*a9fa9459Szrj 
1285*a9fa9459Szrj   p = try_print_file_open (filename, filename);
1286*a9fa9459Szrj   if (p != NULL)
1287*a9fa9459Szrj     return p;
1288*a9fa9459Szrj 
1289*a9fa9459Szrj   if (include_path_count == 0)
1290*a9fa9459Szrj     return NULL;
1291*a9fa9459Szrj 
1292*a9fa9459Szrj   /* Get the name of the file.  */
1293*a9fa9459Szrj   fname = lbasename (filename);
1294*a9fa9459Szrj 
1295*a9fa9459Szrj   /* If file exists under a new path, we need to add it to the list
1296*a9fa9459Szrj      so that show_line knows about it.  */
1297*a9fa9459Szrj   for (i = 0; i < include_path_count; i++)
1298*a9fa9459Szrj     {
1299*a9fa9459Szrj       char *modname = concat (include_paths[i], "/", fname, (const char *) 0);
1300*a9fa9459Szrj 
1301*a9fa9459Szrj       p = try_print_file_open (filename, modname);
1302*a9fa9459Szrj       if (p)
1303*a9fa9459Szrj 	return p;
1304*a9fa9459Szrj 
1305*a9fa9459Szrj       free (modname);
1306*a9fa9459Szrj     }
1307*a9fa9459Szrj 
1308*a9fa9459Szrj   return NULL;
1309*a9fa9459Szrj }
1310*a9fa9459Szrj 
1311*a9fa9459Szrj /* Print a source file line.  */
1312*a9fa9459Szrj 
1313*a9fa9459Szrj static void
print_line(struct print_file_list * p,unsigned int linenum)1314*a9fa9459Szrj print_line (struct print_file_list *p, unsigned int linenum)
1315*a9fa9459Szrj {
1316*a9fa9459Szrj   const char *l;
1317*a9fa9459Szrj   size_t len;
1318*a9fa9459Szrj 
1319*a9fa9459Szrj   --linenum;
1320*a9fa9459Szrj   if (linenum >= p->maxline)
1321*a9fa9459Szrj     return;
1322*a9fa9459Szrj   l = p->linemap [linenum];
1323*a9fa9459Szrj   /* Test fwrite return value to quiet glibc warning.  */
1324*a9fa9459Szrj   len = strcspn (l, "\n\r");
1325*a9fa9459Szrj   if (len == 0 || fwrite (l, len, 1, stdout) == 1)
1326*a9fa9459Szrj     putchar ('\n');
1327*a9fa9459Szrj }
1328*a9fa9459Szrj 
1329*a9fa9459Szrj /* Print a range of source code lines. */
1330*a9fa9459Szrj 
1331*a9fa9459Szrj static void
dump_lines(struct print_file_list * p,unsigned int start,unsigned int end)1332*a9fa9459Szrj dump_lines (struct print_file_list *p, unsigned int start, unsigned int end)
1333*a9fa9459Szrj {
1334*a9fa9459Szrj   if (p->map == NULL)
1335*a9fa9459Szrj     return;
1336*a9fa9459Szrj   while (start <= end)
1337*a9fa9459Szrj     {
1338*a9fa9459Szrj       print_line (p, start);
1339*a9fa9459Szrj       start++;
1340*a9fa9459Szrj     }
1341*a9fa9459Szrj }
1342*a9fa9459Szrj 
1343*a9fa9459Szrj /* Show the line number, or the source line, in a disassembly
1344*a9fa9459Szrj    listing.  */
1345*a9fa9459Szrj 
1346*a9fa9459Szrj static void
show_line(bfd * abfd,asection * section,bfd_vma addr_offset)1347*a9fa9459Szrj show_line (bfd *abfd, asection *section, bfd_vma addr_offset)
1348*a9fa9459Szrj {
1349*a9fa9459Szrj   const char *filename;
1350*a9fa9459Szrj   const char *functionname;
1351*a9fa9459Szrj   unsigned int linenumber;
1352*a9fa9459Szrj   unsigned int discriminator;
1353*a9fa9459Szrj   bfd_boolean reloc;
1354*a9fa9459Szrj   char *path = NULL;
1355*a9fa9459Szrj 
1356*a9fa9459Szrj   if (! with_line_numbers && ! with_source_code)
1357*a9fa9459Szrj     return;
1358*a9fa9459Szrj 
1359*a9fa9459Szrj   if (! bfd_find_nearest_line_discriminator (abfd, section, syms, addr_offset,
1360*a9fa9459Szrj                                              &filename, &functionname,
1361*a9fa9459Szrj                                              &linenumber, &discriminator))
1362*a9fa9459Szrj     return;
1363*a9fa9459Szrj 
1364*a9fa9459Szrj   if (filename != NULL && *filename == '\0')
1365*a9fa9459Szrj     filename = NULL;
1366*a9fa9459Szrj   if (functionname != NULL && *functionname == '\0')
1367*a9fa9459Szrj     functionname = NULL;
1368*a9fa9459Szrj 
1369*a9fa9459Szrj   if (filename
1370*a9fa9459Szrj       && IS_ABSOLUTE_PATH (filename)
1371*a9fa9459Szrj       && prefix)
1372*a9fa9459Szrj     {
1373*a9fa9459Szrj       char *path_up;
1374*a9fa9459Szrj       const char *fname = filename;
1375*a9fa9459Szrj 
1376*a9fa9459Szrj       path = xmalloc (prefix_length + PATH_MAX + 1);
1377*a9fa9459Szrj 
1378*a9fa9459Szrj       if (prefix_length)
1379*a9fa9459Szrj 	memcpy (path, prefix, prefix_length);
1380*a9fa9459Szrj       path_up = path + prefix_length;
1381*a9fa9459Szrj 
1382*a9fa9459Szrj       /* Build relocated filename, stripping off leading directories
1383*a9fa9459Szrj 	 from the initial filename if requested.  */
1384*a9fa9459Szrj       if (prefix_strip > 0)
1385*a9fa9459Szrj 	{
1386*a9fa9459Szrj 	  int level = 0;
1387*a9fa9459Szrj 	  const char *s;
1388*a9fa9459Szrj 
1389*a9fa9459Szrj 	  /* Skip selected directory levels.  */
1390*a9fa9459Szrj 	  for (s = fname + 1; *s != '\0' && level < prefix_strip; s++)
1391*a9fa9459Szrj 	    if (IS_DIR_SEPARATOR(*s))
1392*a9fa9459Szrj 	      {
1393*a9fa9459Szrj 		fname = s;
1394*a9fa9459Szrj 		level++;
1395*a9fa9459Szrj 	      }
1396*a9fa9459Szrj 	}
1397*a9fa9459Szrj 
1398*a9fa9459Szrj       /* Update complete filename.  */
1399*a9fa9459Szrj       strncpy (path_up, fname, PATH_MAX);
1400*a9fa9459Szrj       path_up[PATH_MAX] = '\0';
1401*a9fa9459Szrj 
1402*a9fa9459Szrj       filename = path;
1403*a9fa9459Szrj       reloc = TRUE;
1404*a9fa9459Szrj     }
1405*a9fa9459Szrj   else
1406*a9fa9459Szrj     reloc = FALSE;
1407*a9fa9459Szrj 
1408*a9fa9459Szrj   if (with_line_numbers)
1409*a9fa9459Szrj     {
1410*a9fa9459Szrj       if (functionname != NULL
1411*a9fa9459Szrj 	  && (prev_functionname == NULL
1412*a9fa9459Szrj 	      || strcmp (functionname, prev_functionname) != 0))
1413*a9fa9459Szrj 	printf ("%s():\n", functionname);
1414*a9fa9459Szrj       if (linenumber > 0 && (linenumber != prev_line ||
1415*a9fa9459Szrj                              (discriminator != prev_discriminator)))
1416*a9fa9459Szrj         {
1417*a9fa9459Szrj           if (discriminator > 0)
1418*a9fa9459Szrj             printf ("%s:%u (discriminator %u)\n", filename == NULL ? "???" : filename,
1419*a9fa9459Szrj                     linenumber, discriminator);
1420*a9fa9459Szrj           else
1421*a9fa9459Szrj             printf ("%s:%u\n", filename == NULL ? "???" : filename, linenumber);
1422*a9fa9459Szrj         }
1423*a9fa9459Szrj     }
1424*a9fa9459Szrj 
1425*a9fa9459Szrj   if (with_source_code
1426*a9fa9459Szrj       && filename != NULL
1427*a9fa9459Szrj       && linenumber > 0)
1428*a9fa9459Szrj     {
1429*a9fa9459Szrj       struct print_file_list **pp, *p;
1430*a9fa9459Szrj       unsigned l;
1431*a9fa9459Szrj 
1432*a9fa9459Szrj       for (pp = &print_files; *pp != NULL; pp = &(*pp)->next)
1433*a9fa9459Szrj 	if (filename_cmp ((*pp)->filename, filename) == 0)
1434*a9fa9459Szrj 	  break;
1435*a9fa9459Szrj       p = *pp;
1436*a9fa9459Szrj 
1437*a9fa9459Szrj       if (p == NULL)
1438*a9fa9459Szrj 	{
1439*a9fa9459Szrj 	  if (reloc)
1440*a9fa9459Szrj 	    filename = xstrdup (filename);
1441*a9fa9459Szrj 	  p = update_source_path (filename);
1442*a9fa9459Szrj 	}
1443*a9fa9459Szrj 
1444*a9fa9459Szrj       if (p != NULL && linenumber != p->last_line)
1445*a9fa9459Szrj 	{
1446*a9fa9459Szrj 	  if (file_start_context && p->first)
1447*a9fa9459Szrj 	    l = 1;
1448*a9fa9459Szrj 	  else
1449*a9fa9459Szrj 	    {
1450*a9fa9459Szrj 	      l = linenumber - SHOW_PRECEDING_CONTEXT_LINES;
1451*a9fa9459Szrj 	      if (l >= linenumber)
1452*a9fa9459Szrj 		l = 1;
1453*a9fa9459Szrj 	      if (p->max_printed >= l)
1454*a9fa9459Szrj 		{
1455*a9fa9459Szrj 		  if (p->max_printed < linenumber)
1456*a9fa9459Szrj 		    l = p->max_printed + 1;
1457*a9fa9459Szrj 		  else
1458*a9fa9459Szrj 		    l = linenumber;
1459*a9fa9459Szrj 		}
1460*a9fa9459Szrj 	    }
1461*a9fa9459Szrj 	  dump_lines (p, l, linenumber);
1462*a9fa9459Szrj 	  if (p->max_printed < linenumber)
1463*a9fa9459Szrj 	    p->max_printed = linenumber;
1464*a9fa9459Szrj 	  p->last_line = linenumber;
1465*a9fa9459Szrj 	  p->first = 0;
1466*a9fa9459Szrj 	}
1467*a9fa9459Szrj     }
1468*a9fa9459Szrj 
1469*a9fa9459Szrj   if (functionname != NULL
1470*a9fa9459Szrj       && (prev_functionname == NULL
1471*a9fa9459Szrj 	  || strcmp (functionname, prev_functionname) != 0))
1472*a9fa9459Szrj     {
1473*a9fa9459Szrj       if (prev_functionname != NULL)
1474*a9fa9459Szrj 	free (prev_functionname);
1475*a9fa9459Szrj       prev_functionname = (char *) xmalloc (strlen (functionname) + 1);
1476*a9fa9459Szrj       strcpy (prev_functionname, functionname);
1477*a9fa9459Szrj     }
1478*a9fa9459Szrj 
1479*a9fa9459Szrj   if (linenumber > 0 && linenumber != prev_line)
1480*a9fa9459Szrj     prev_line = linenumber;
1481*a9fa9459Szrj 
1482*a9fa9459Szrj   if (discriminator != prev_discriminator)
1483*a9fa9459Szrj     prev_discriminator = discriminator;
1484*a9fa9459Szrj 
1485*a9fa9459Szrj   if (path)
1486*a9fa9459Szrj     free (path);
1487*a9fa9459Szrj }
1488*a9fa9459Szrj 
1489*a9fa9459Szrj /* Pseudo FILE object for strings.  */
1490*a9fa9459Szrj typedef struct
1491*a9fa9459Szrj {
1492*a9fa9459Szrj   char *buffer;
1493*a9fa9459Szrj   size_t pos;
1494*a9fa9459Szrj   size_t alloc;
1495*a9fa9459Szrj } SFILE;
1496*a9fa9459Szrj 
1497*a9fa9459Szrj /* sprintf to a "stream".  */
1498*a9fa9459Szrj 
1499*a9fa9459Szrj static int ATTRIBUTE_PRINTF_2
objdump_sprintf(SFILE * f,const char * format,...)1500*a9fa9459Szrj objdump_sprintf (SFILE *f, const char *format, ...)
1501*a9fa9459Szrj {
1502*a9fa9459Szrj   size_t n;
1503*a9fa9459Szrj   va_list args;
1504*a9fa9459Szrj 
1505*a9fa9459Szrj   while (1)
1506*a9fa9459Szrj     {
1507*a9fa9459Szrj       size_t space = f->alloc - f->pos;
1508*a9fa9459Szrj 
1509*a9fa9459Szrj       va_start (args, format);
1510*a9fa9459Szrj       n = vsnprintf (f->buffer + f->pos, space, format, args);
1511*a9fa9459Szrj       va_end (args);
1512*a9fa9459Szrj 
1513*a9fa9459Szrj       if (space > n)
1514*a9fa9459Szrj 	break;
1515*a9fa9459Szrj 
1516*a9fa9459Szrj       f->alloc = (f->alloc + n) * 2;
1517*a9fa9459Szrj       f->buffer = (char *) xrealloc (f->buffer, f->alloc);
1518*a9fa9459Szrj     }
1519*a9fa9459Szrj   f->pos += n;
1520*a9fa9459Szrj 
1521*a9fa9459Szrj   return n;
1522*a9fa9459Szrj }
1523*a9fa9459Szrj 
1524*a9fa9459Szrj /* The number of zeroes we want to see before we start skipping them.
1525*a9fa9459Szrj    The number is arbitrarily chosen.  */
1526*a9fa9459Szrj 
1527*a9fa9459Szrj #define DEFAULT_SKIP_ZEROES 8
1528*a9fa9459Szrj 
1529*a9fa9459Szrj /* The number of zeroes to skip at the end of a section.  If the
1530*a9fa9459Szrj    number of zeroes at the end is between SKIP_ZEROES_AT_END and
1531*a9fa9459Szrj    SKIP_ZEROES, they will be disassembled.  If there are fewer than
1532*a9fa9459Szrj    SKIP_ZEROES_AT_END, they will be skipped.  This is a heuristic
1533*a9fa9459Szrj    attempt to avoid disassembling zeroes inserted by section
1534*a9fa9459Szrj    alignment.  */
1535*a9fa9459Szrj 
1536*a9fa9459Szrj #define DEFAULT_SKIP_ZEROES_AT_END 3
1537*a9fa9459Szrj 
1538*a9fa9459Szrj /* Disassemble some data in memory between given values.  */
1539*a9fa9459Szrj 
1540*a9fa9459Szrj static void
disassemble_bytes(struct disassemble_info * inf,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)1541*a9fa9459Szrj disassemble_bytes (struct disassemble_info * inf,
1542*a9fa9459Szrj 		   disassembler_ftype        disassemble_fn,
1543*a9fa9459Szrj 		   bfd_boolean               insns,
1544*a9fa9459Szrj 		   bfd_byte *                data,
1545*a9fa9459Szrj 		   bfd_vma                   start_offset,
1546*a9fa9459Szrj 		   bfd_vma                   stop_offset,
1547*a9fa9459Szrj 		   bfd_vma		     rel_offset,
1548*a9fa9459Szrj 		   arelent ***               relppp,
1549*a9fa9459Szrj 		   arelent **                relppend)
1550*a9fa9459Szrj {
1551*a9fa9459Szrj   struct objdump_disasm_info *aux;
1552*a9fa9459Szrj   asection *section;
1553*a9fa9459Szrj   int octets_per_line;
1554*a9fa9459Szrj   int skip_addr_chars;
1555*a9fa9459Szrj   bfd_vma addr_offset;
1556*a9fa9459Szrj   unsigned int opb = inf->octets_per_byte;
1557*a9fa9459Szrj   unsigned int skip_zeroes = inf->skip_zeroes;
1558*a9fa9459Szrj   unsigned int skip_zeroes_at_end = inf->skip_zeroes_at_end;
1559*a9fa9459Szrj   int octets = opb;
1560*a9fa9459Szrj   SFILE sfile;
1561*a9fa9459Szrj 
1562*a9fa9459Szrj   aux = (struct objdump_disasm_info *) inf->application_data;
1563*a9fa9459Szrj   section = aux->sec;
1564*a9fa9459Szrj 
1565*a9fa9459Szrj   sfile.alloc = 120;
1566*a9fa9459Szrj   sfile.buffer = (char *) xmalloc (sfile.alloc);
1567*a9fa9459Szrj   sfile.pos = 0;
1568*a9fa9459Szrj 
1569*a9fa9459Szrj   if (insn_width)
1570*a9fa9459Szrj     octets_per_line = insn_width;
1571*a9fa9459Szrj   else if (insns)
1572*a9fa9459Szrj     octets_per_line = 4;
1573*a9fa9459Szrj   else
1574*a9fa9459Szrj     octets_per_line = 16;
1575*a9fa9459Szrj 
1576*a9fa9459Szrj   /* Figure out how many characters to skip at the start of an
1577*a9fa9459Szrj      address, to make the disassembly look nicer.  We discard leading
1578*a9fa9459Szrj      zeroes in chunks of 4, ensuring that there is always a leading
1579*a9fa9459Szrj      zero remaining.  */
1580*a9fa9459Szrj   skip_addr_chars = 0;
1581*a9fa9459Szrj   if (! prefix_addresses)
1582*a9fa9459Szrj     {
1583*a9fa9459Szrj       char buf[30];
1584*a9fa9459Szrj 
1585*a9fa9459Szrj       bfd_sprintf_vma (aux->abfd, buf, section->vma + section->size / opb);
1586*a9fa9459Szrj 
1587*a9fa9459Szrj       while (buf[skip_addr_chars] == '0')
1588*a9fa9459Szrj 	++skip_addr_chars;
1589*a9fa9459Szrj 
1590*a9fa9459Szrj       /* Don't discard zeros on overflow.  */
1591*a9fa9459Szrj       if (buf[skip_addr_chars] == '\0' && section->vma != 0)
1592*a9fa9459Szrj 	skip_addr_chars = 0;
1593*a9fa9459Szrj 
1594*a9fa9459Szrj       if (skip_addr_chars != 0)
1595*a9fa9459Szrj 	skip_addr_chars = (skip_addr_chars - 1) & -4;
1596*a9fa9459Szrj     }
1597*a9fa9459Szrj 
1598*a9fa9459Szrj   inf->insn_info_valid = 0;
1599*a9fa9459Szrj 
1600*a9fa9459Szrj   addr_offset = start_offset;
1601*a9fa9459Szrj   while (addr_offset < stop_offset)
1602*a9fa9459Szrj     {
1603*a9fa9459Szrj       bfd_vma z;
1604*a9fa9459Szrj       bfd_boolean need_nl = FALSE;
1605*a9fa9459Szrj       int previous_octets;
1606*a9fa9459Szrj 
1607*a9fa9459Szrj       /* Remember the length of the previous instruction.  */
1608*a9fa9459Szrj       previous_octets = octets;
1609*a9fa9459Szrj       octets = 0;
1610*a9fa9459Szrj 
1611*a9fa9459Szrj       /* Make sure we don't use relocs from previous instructions.  */
1612*a9fa9459Szrj       aux->reloc = NULL;
1613*a9fa9459Szrj 
1614*a9fa9459Szrj       /* If we see more than SKIP_ZEROES octets of zeroes, we just
1615*a9fa9459Szrj 	 print `...'.  */
1616*a9fa9459Szrj       for (z = addr_offset * opb; z < stop_offset * opb; z++)
1617*a9fa9459Szrj 	if (data[z] != 0)
1618*a9fa9459Szrj 	  break;
1619*a9fa9459Szrj       if (! disassemble_zeroes
1620*a9fa9459Szrj 	  && (inf->insn_info_valid == 0
1621*a9fa9459Szrj 	      || inf->branch_delay_insns == 0)
1622*a9fa9459Szrj 	  && (z - addr_offset * opb >= skip_zeroes
1623*a9fa9459Szrj 	      || (z == stop_offset * opb &&
1624*a9fa9459Szrj 		  z - addr_offset * opb < skip_zeroes_at_end)))
1625*a9fa9459Szrj 	{
1626*a9fa9459Szrj 	  /* If there are more nonzero octets to follow, we only skip
1627*a9fa9459Szrj 	     zeroes in multiples of 4, to try to avoid running over
1628*a9fa9459Szrj 	     the start of an instruction which happens to start with
1629*a9fa9459Szrj 	     zero.  */
1630*a9fa9459Szrj 	  if (z != stop_offset * opb)
1631*a9fa9459Szrj 	    z = addr_offset * opb + ((z - addr_offset * opb) &~ 3);
1632*a9fa9459Szrj 
1633*a9fa9459Szrj 	  octets = z - addr_offset * opb;
1634*a9fa9459Szrj 
1635*a9fa9459Szrj 	  /* If we are going to display more data, and we are displaying
1636*a9fa9459Szrj 	     file offsets, then tell the user how many zeroes we skip
1637*a9fa9459Szrj 	     and the file offset from where we resume dumping.  */
1638*a9fa9459Szrj 	  if (display_file_offsets && ((addr_offset + (octets / opb)) < stop_offset))
1639*a9fa9459Szrj 	    printf ("\t... (skipping %d zeroes, resuming at file offset: 0x%lx)\n",
1640*a9fa9459Szrj 		    octets / opb,
1641*a9fa9459Szrj 		    (unsigned long) (section->filepos
1642*a9fa9459Szrj 				     + (addr_offset + (octets / opb))));
1643*a9fa9459Szrj 	  else
1644*a9fa9459Szrj 	    printf ("\t...\n");
1645*a9fa9459Szrj 	}
1646*a9fa9459Szrj       else
1647*a9fa9459Szrj 	{
1648*a9fa9459Szrj 	  char buf[50];
1649*a9fa9459Szrj 	  int bpc = 0;
1650*a9fa9459Szrj 	  int pb = 0;
1651*a9fa9459Szrj 
1652*a9fa9459Szrj 	  if (with_line_numbers || with_source_code)
1653*a9fa9459Szrj 	    show_line (aux->abfd, section, addr_offset);
1654*a9fa9459Szrj 
1655*a9fa9459Szrj 	  if (! prefix_addresses)
1656*a9fa9459Szrj 	    {
1657*a9fa9459Szrj 	      char *s;
1658*a9fa9459Szrj 
1659*a9fa9459Szrj 	      bfd_sprintf_vma (aux->abfd, buf, section->vma + addr_offset);
1660*a9fa9459Szrj 	      for (s = buf + skip_addr_chars; *s == '0'; s++)
1661*a9fa9459Szrj 		*s = ' ';
1662*a9fa9459Szrj 	      if (*s == '\0')
1663*a9fa9459Szrj 		*--s = '0';
1664*a9fa9459Szrj 	      printf ("%s:\t", buf + skip_addr_chars);
1665*a9fa9459Szrj 	    }
1666*a9fa9459Szrj 	  else
1667*a9fa9459Szrj 	    {
1668*a9fa9459Szrj 	      aux->require_sec = TRUE;
1669*a9fa9459Szrj 	      objdump_print_address (section->vma + addr_offset, inf);
1670*a9fa9459Szrj 	      aux->require_sec = FALSE;
1671*a9fa9459Szrj 	      putchar (' ');
1672*a9fa9459Szrj 	    }
1673*a9fa9459Szrj 
1674*a9fa9459Szrj 	  if (insns)
1675*a9fa9459Szrj 	    {
1676*a9fa9459Szrj 	      sfile.pos = 0;
1677*a9fa9459Szrj 	      inf->fprintf_func = (fprintf_ftype) objdump_sprintf;
1678*a9fa9459Szrj 	      inf->stream = &sfile;
1679*a9fa9459Szrj 	      inf->bytes_per_line = 0;
1680*a9fa9459Szrj 	      inf->bytes_per_chunk = 0;
1681*a9fa9459Szrj 	      inf->flags = disassemble_all ? DISASSEMBLE_DATA : 0;
1682*a9fa9459Szrj 	      if (machine)
1683*a9fa9459Szrj 		inf->flags |= USER_SPECIFIED_MACHINE_TYPE;
1684*a9fa9459Szrj 
1685*a9fa9459Szrj 	      if (inf->disassembler_needs_relocs
1686*a9fa9459Szrj 		  && (bfd_get_file_flags (aux->abfd) & EXEC_P) == 0
1687*a9fa9459Szrj 		  && (bfd_get_file_flags (aux->abfd) & DYNAMIC) == 0
1688*a9fa9459Szrj 		  && *relppp < relppend)
1689*a9fa9459Szrj 		{
1690*a9fa9459Szrj 		  bfd_signed_vma distance_to_rel;
1691*a9fa9459Szrj 
1692*a9fa9459Szrj 		  distance_to_rel = (**relppp)->address
1693*a9fa9459Szrj 		    - (rel_offset + addr_offset);
1694*a9fa9459Szrj 
1695*a9fa9459Szrj 		  /* Check to see if the current reloc is associated with
1696*a9fa9459Szrj 		     the instruction that we are about to disassemble.  */
1697*a9fa9459Szrj 		  if (distance_to_rel == 0
1698*a9fa9459Szrj 		      /* FIXME: This is wrong.  We are trying to catch
1699*a9fa9459Szrj 			 relocs that are addressed part way through the
1700*a9fa9459Szrj 			 current instruction, as might happen with a packed
1701*a9fa9459Szrj 			 VLIW instruction.  Unfortunately we do not know the
1702*a9fa9459Szrj 			 length of the current instruction since we have not
1703*a9fa9459Szrj 			 disassembled it yet.  Instead we take a guess based
1704*a9fa9459Szrj 			 upon the length of the previous instruction.  The
1705*a9fa9459Szrj 			 proper solution is to have a new target-specific
1706*a9fa9459Szrj 			 disassembler function which just returns the length
1707*a9fa9459Szrj 			 of an instruction at a given address without trying
1708*a9fa9459Szrj 			 to display its disassembly. */
1709*a9fa9459Szrj 		      || (distance_to_rel > 0
1710*a9fa9459Szrj 			  && distance_to_rel < (bfd_signed_vma) (previous_octets/ opb)))
1711*a9fa9459Szrj 		    {
1712*a9fa9459Szrj 		      inf->flags |= INSN_HAS_RELOC;
1713*a9fa9459Szrj 		      aux->reloc = **relppp;
1714*a9fa9459Szrj 		    }
1715*a9fa9459Szrj 		}
1716*a9fa9459Szrj 
1717*a9fa9459Szrj 	      if (! disassemble_all
1718*a9fa9459Szrj 		  && (section->flags & (SEC_CODE | SEC_HAS_CONTENTS))
1719*a9fa9459Szrj 		  == (SEC_CODE | SEC_HAS_CONTENTS))
1720*a9fa9459Szrj 		/* Set a stop_vma so that the disassembler will not read
1721*a9fa9459Szrj 		   beyond the next symbol.  We assume that symbols appear on
1722*a9fa9459Szrj 		   the boundaries between instructions.  We only do this when
1723*a9fa9459Szrj 		   disassembling code of course, and when -D is in effect.  */
1724*a9fa9459Szrj 		inf->stop_vma = section->vma + stop_offset;
1725*a9fa9459Szrj 
1726*a9fa9459Szrj 	      octets = (*disassemble_fn) (section->vma + addr_offset, inf);
1727*a9fa9459Szrj 
1728*a9fa9459Szrj 	      inf->stop_vma = 0;
1729*a9fa9459Szrj 	      inf->fprintf_func = (fprintf_ftype) fprintf;
1730*a9fa9459Szrj 	      inf->stream = stdout;
1731*a9fa9459Szrj 	      if (insn_width == 0 && inf->bytes_per_line != 0)
1732*a9fa9459Szrj 		octets_per_line = inf->bytes_per_line;
1733*a9fa9459Szrj 	      if (octets < (int) opb)
1734*a9fa9459Szrj 		{
1735*a9fa9459Szrj 		  if (sfile.pos)
1736*a9fa9459Szrj 		    printf ("%s\n", sfile.buffer);
1737*a9fa9459Szrj 		  if (octets >= 0)
1738*a9fa9459Szrj 		    {
1739*a9fa9459Szrj 		      non_fatal (_("disassemble_fn returned length %d"),
1740*a9fa9459Szrj 				 octets);
1741*a9fa9459Szrj 		      exit_status = 1;
1742*a9fa9459Szrj 		    }
1743*a9fa9459Szrj 		  break;
1744*a9fa9459Szrj 		}
1745*a9fa9459Szrj 	    }
1746*a9fa9459Szrj 	  else
1747*a9fa9459Szrj 	    {
1748*a9fa9459Szrj 	      bfd_vma j;
1749*a9fa9459Szrj 
1750*a9fa9459Szrj 	      octets = octets_per_line;
1751*a9fa9459Szrj 	      if (addr_offset + octets / opb > stop_offset)
1752*a9fa9459Szrj 		octets = (stop_offset - addr_offset) * opb;
1753*a9fa9459Szrj 
1754*a9fa9459Szrj 	      for (j = addr_offset * opb; j < addr_offset * opb + octets; ++j)
1755*a9fa9459Szrj 		{
1756*a9fa9459Szrj 		  if (ISPRINT (data[j]))
1757*a9fa9459Szrj 		    buf[j - addr_offset * opb] = data[j];
1758*a9fa9459Szrj 		  else
1759*a9fa9459Szrj 		    buf[j - addr_offset * opb] = '.';
1760*a9fa9459Szrj 		}
1761*a9fa9459Szrj 	      buf[j - addr_offset * opb] = '\0';
1762*a9fa9459Szrj 	    }
1763*a9fa9459Szrj 
1764*a9fa9459Szrj 	  if (prefix_addresses
1765*a9fa9459Szrj 	      ? show_raw_insn > 0
1766*a9fa9459Szrj 	      : show_raw_insn >= 0)
1767*a9fa9459Szrj 	    {
1768*a9fa9459Szrj 	      bfd_vma j;
1769*a9fa9459Szrj 
1770*a9fa9459Szrj 	      /* If ! prefix_addresses and ! wide_output, we print
1771*a9fa9459Szrj 		 octets_per_line octets per line.  */
1772*a9fa9459Szrj 	      pb = octets;
1773*a9fa9459Szrj 	      if (pb > octets_per_line && ! prefix_addresses && ! wide_output)
1774*a9fa9459Szrj 		pb = octets_per_line;
1775*a9fa9459Szrj 
1776*a9fa9459Szrj 	      if (inf->bytes_per_chunk)
1777*a9fa9459Szrj 		bpc = inf->bytes_per_chunk;
1778*a9fa9459Szrj 	      else
1779*a9fa9459Szrj 		bpc = 1;
1780*a9fa9459Szrj 
1781*a9fa9459Szrj 	      for (j = addr_offset * opb; j < addr_offset * opb + pb; j += bpc)
1782*a9fa9459Szrj 		{
1783*a9fa9459Szrj 		  int k;
1784*a9fa9459Szrj 
1785*a9fa9459Szrj 		  if (bpc > 1 && inf->display_endian == BFD_ENDIAN_LITTLE)
1786*a9fa9459Szrj 		    {
1787*a9fa9459Szrj 		      for (k = bpc - 1; k >= 0; k--)
1788*a9fa9459Szrj 			printf ("%02x", (unsigned) data[j + k]);
1789*a9fa9459Szrj 		      putchar (' ');
1790*a9fa9459Szrj 		    }
1791*a9fa9459Szrj 		  else
1792*a9fa9459Szrj 		    {
1793*a9fa9459Szrj 		      for (k = 0; k < bpc; k++)
1794*a9fa9459Szrj 			printf ("%02x", (unsigned) data[j + k]);
1795*a9fa9459Szrj 		      putchar (' ');
1796*a9fa9459Szrj 		    }
1797*a9fa9459Szrj 		}
1798*a9fa9459Szrj 
1799*a9fa9459Szrj 	      for (; pb < octets_per_line; pb += bpc)
1800*a9fa9459Szrj 		{
1801*a9fa9459Szrj 		  int k;
1802*a9fa9459Szrj 
1803*a9fa9459Szrj 		  for (k = 0; k < bpc; k++)
1804*a9fa9459Szrj 		    printf ("  ");
1805*a9fa9459Szrj 		  putchar (' ');
1806*a9fa9459Szrj 		}
1807*a9fa9459Szrj 
1808*a9fa9459Szrj 	      /* Separate raw data from instruction by extra space.  */
1809*a9fa9459Szrj 	      if (insns)
1810*a9fa9459Szrj 		putchar ('\t');
1811*a9fa9459Szrj 	      else
1812*a9fa9459Szrj 		printf ("    ");
1813*a9fa9459Szrj 	    }
1814*a9fa9459Szrj 
1815*a9fa9459Szrj 	  if (! insns)
1816*a9fa9459Szrj 	    printf ("%s", buf);
1817*a9fa9459Szrj 	  else if (sfile.pos)
1818*a9fa9459Szrj 	    printf ("%s", sfile.buffer);
1819*a9fa9459Szrj 
1820*a9fa9459Szrj 	  if (prefix_addresses
1821*a9fa9459Szrj 	      ? show_raw_insn > 0
1822*a9fa9459Szrj 	      : show_raw_insn >= 0)
1823*a9fa9459Szrj 	    {
1824*a9fa9459Szrj 	      while (pb < octets)
1825*a9fa9459Szrj 		{
1826*a9fa9459Szrj 		  bfd_vma j;
1827*a9fa9459Szrj 		  char *s;
1828*a9fa9459Szrj 
1829*a9fa9459Szrj 		  putchar ('\n');
1830*a9fa9459Szrj 		  j = addr_offset * opb + pb;
1831*a9fa9459Szrj 
1832*a9fa9459Szrj 		  bfd_sprintf_vma (aux->abfd, buf, section->vma + j / opb);
1833*a9fa9459Szrj 		  for (s = buf + skip_addr_chars; *s == '0'; s++)
1834*a9fa9459Szrj 		    *s = ' ';
1835*a9fa9459Szrj 		  if (*s == '\0')
1836*a9fa9459Szrj 		    *--s = '0';
1837*a9fa9459Szrj 		  printf ("%s:\t", buf + skip_addr_chars);
1838*a9fa9459Szrj 
1839*a9fa9459Szrj 		  pb += octets_per_line;
1840*a9fa9459Szrj 		  if (pb > octets)
1841*a9fa9459Szrj 		    pb = octets;
1842*a9fa9459Szrj 		  for (; j < addr_offset * opb + pb; j += bpc)
1843*a9fa9459Szrj 		    {
1844*a9fa9459Szrj 		      int k;
1845*a9fa9459Szrj 
1846*a9fa9459Szrj 		      if (bpc > 1 && inf->display_endian == BFD_ENDIAN_LITTLE)
1847*a9fa9459Szrj 			{
1848*a9fa9459Szrj 			  for (k = bpc - 1; k >= 0; k--)
1849*a9fa9459Szrj 			    printf ("%02x", (unsigned) data[j + k]);
1850*a9fa9459Szrj 			  putchar (' ');
1851*a9fa9459Szrj 			}
1852*a9fa9459Szrj 		      else
1853*a9fa9459Szrj 			{
1854*a9fa9459Szrj 			  for (k = 0; k < bpc; k++)
1855*a9fa9459Szrj 			    printf ("%02x", (unsigned) data[j + k]);
1856*a9fa9459Szrj 			  putchar (' ');
1857*a9fa9459Szrj 			}
1858*a9fa9459Szrj 		    }
1859*a9fa9459Szrj 		}
1860*a9fa9459Szrj 	    }
1861*a9fa9459Szrj 
1862*a9fa9459Szrj 	  if (!wide_output)
1863*a9fa9459Szrj 	    putchar ('\n');
1864*a9fa9459Szrj 	  else
1865*a9fa9459Szrj 	    need_nl = TRUE;
1866*a9fa9459Szrj 	}
1867*a9fa9459Szrj 
1868*a9fa9459Szrj       while ((*relppp) < relppend
1869*a9fa9459Szrj 	     && (**relppp)->address < rel_offset + addr_offset + octets / opb)
1870*a9fa9459Szrj 	{
1871*a9fa9459Szrj 	  if (dump_reloc_info || dump_dynamic_reloc_info)
1872*a9fa9459Szrj 	    {
1873*a9fa9459Szrj 	      arelent *q;
1874*a9fa9459Szrj 
1875*a9fa9459Szrj 	      q = **relppp;
1876*a9fa9459Szrj 
1877*a9fa9459Szrj 	      if (wide_output)
1878*a9fa9459Szrj 		putchar ('\t');
1879*a9fa9459Szrj 	      else
1880*a9fa9459Szrj 		printf ("\t\t\t");
1881*a9fa9459Szrj 
1882*a9fa9459Szrj 	      objdump_print_value (section->vma - rel_offset + q->address,
1883*a9fa9459Szrj 				   inf, TRUE);
1884*a9fa9459Szrj 
1885*a9fa9459Szrj 	      if (q->howto == NULL)
1886*a9fa9459Szrj 		printf (": *unknown*\t");
1887*a9fa9459Szrj 	      else if (q->howto->name)
1888*a9fa9459Szrj 		printf (": %s\t", q->howto->name);
1889*a9fa9459Szrj 	      else
1890*a9fa9459Szrj 		printf (": %d\t", q->howto->type);
1891*a9fa9459Szrj 
1892*a9fa9459Szrj 	      if (q->sym_ptr_ptr == NULL || *q->sym_ptr_ptr == NULL)
1893*a9fa9459Szrj 		printf ("*unknown*");
1894*a9fa9459Szrj 	      else
1895*a9fa9459Szrj 		{
1896*a9fa9459Szrj 		  const char *sym_name;
1897*a9fa9459Szrj 
1898*a9fa9459Szrj 		  sym_name = bfd_asymbol_name (*q->sym_ptr_ptr);
1899*a9fa9459Szrj 		  if (sym_name != NULL && *sym_name != '\0')
1900*a9fa9459Szrj 		    objdump_print_symname (aux->abfd, inf, *q->sym_ptr_ptr);
1901*a9fa9459Szrj 		  else
1902*a9fa9459Szrj 		    {
1903*a9fa9459Szrj 		      asection *sym_sec;
1904*a9fa9459Szrj 
1905*a9fa9459Szrj 		      sym_sec = bfd_get_section (*q->sym_ptr_ptr);
1906*a9fa9459Szrj 		      sym_name = bfd_get_section_name (aux->abfd, sym_sec);
1907*a9fa9459Szrj 		      if (sym_name == NULL || *sym_name == '\0')
1908*a9fa9459Szrj 			sym_name = "*unknown*";
1909*a9fa9459Szrj 		      printf ("%s", sym_name);
1910*a9fa9459Szrj 		    }
1911*a9fa9459Szrj 		}
1912*a9fa9459Szrj 
1913*a9fa9459Szrj 	      if (q->addend)
1914*a9fa9459Szrj 		{
1915*a9fa9459Szrj 		  bfd_signed_vma addend = q->addend;
1916*a9fa9459Szrj 		  if (addend < 0)
1917*a9fa9459Szrj 		    {
1918*a9fa9459Szrj 		      printf ("-0x");
1919*a9fa9459Szrj 		      addend = -addend;
1920*a9fa9459Szrj 		    }
1921*a9fa9459Szrj 		  else
1922*a9fa9459Szrj 		    printf ("+0x");
1923*a9fa9459Szrj 		  objdump_print_value (addend, inf, TRUE);
1924*a9fa9459Szrj 		}
1925*a9fa9459Szrj 
1926*a9fa9459Szrj 	      printf ("\n");
1927*a9fa9459Szrj 	      need_nl = FALSE;
1928*a9fa9459Szrj 	    }
1929*a9fa9459Szrj 	  ++(*relppp);
1930*a9fa9459Szrj 	}
1931*a9fa9459Szrj 
1932*a9fa9459Szrj       if (need_nl)
1933*a9fa9459Szrj 	printf ("\n");
1934*a9fa9459Szrj 
1935*a9fa9459Szrj       addr_offset += octets / opb;
1936*a9fa9459Szrj     }
1937*a9fa9459Szrj 
1938*a9fa9459Szrj   free (sfile.buffer);
1939*a9fa9459Szrj }
1940*a9fa9459Szrj 
1941*a9fa9459Szrj static void
disassemble_section(bfd * abfd,asection * section,void * inf)1942*a9fa9459Szrj disassemble_section (bfd *abfd, asection *section, void *inf)
1943*a9fa9459Szrj {
1944*a9fa9459Szrj   const struct elf_backend_data * bed;
1945*a9fa9459Szrj   bfd_vma                      sign_adjust = 0;
1946*a9fa9459Szrj   struct disassemble_info *    pinfo = (struct disassemble_info *) inf;
1947*a9fa9459Szrj   struct objdump_disasm_info * paux;
1948*a9fa9459Szrj   unsigned int                 opb = pinfo->octets_per_byte;
1949*a9fa9459Szrj   bfd_byte *                   data = NULL;
1950*a9fa9459Szrj   bfd_size_type                datasize = 0;
1951*a9fa9459Szrj   arelent **                   rel_pp = NULL;
1952*a9fa9459Szrj   arelent **                   rel_ppstart = NULL;
1953*a9fa9459Szrj   arelent **                   rel_ppend;
1954*a9fa9459Szrj   bfd_vma                      stop_offset;
1955*a9fa9459Szrj   asymbol *                    sym = NULL;
1956*a9fa9459Szrj   long                         place = 0;
1957*a9fa9459Szrj   long                         rel_count;
1958*a9fa9459Szrj   bfd_vma                      rel_offset;
1959*a9fa9459Szrj   unsigned long                addr_offset;
1960*a9fa9459Szrj 
1961*a9fa9459Szrj   /* Sections that do not contain machine
1962*a9fa9459Szrj      code are not normally disassembled.  */
1963*a9fa9459Szrj   if (! disassemble_all
1964*a9fa9459Szrj       && only_list == NULL
1965*a9fa9459Szrj       && ((section->flags & (SEC_CODE | SEC_HAS_CONTENTS))
1966*a9fa9459Szrj 	  != (SEC_CODE | SEC_HAS_CONTENTS)))
1967*a9fa9459Szrj     return;
1968*a9fa9459Szrj 
1969*a9fa9459Szrj   if (! process_section_p (section))
1970*a9fa9459Szrj     return;
1971*a9fa9459Szrj 
1972*a9fa9459Szrj   datasize = bfd_get_section_size (section);
1973*a9fa9459Szrj   if (datasize == 0)
1974*a9fa9459Szrj     return;
1975*a9fa9459Szrj 
1976*a9fa9459Szrj   if (start_address == (bfd_vma) -1
1977*a9fa9459Szrj       || start_address < section->vma)
1978*a9fa9459Szrj     addr_offset = 0;
1979*a9fa9459Szrj   else
1980*a9fa9459Szrj     addr_offset = start_address - section->vma;
1981*a9fa9459Szrj 
1982*a9fa9459Szrj   if (stop_address == (bfd_vma) -1)
1983*a9fa9459Szrj     stop_offset = datasize / opb;
1984*a9fa9459Szrj   else
1985*a9fa9459Szrj     {
1986*a9fa9459Szrj       if (stop_address < section->vma)
1987*a9fa9459Szrj 	stop_offset = 0;
1988*a9fa9459Szrj       else
1989*a9fa9459Szrj 	stop_offset = stop_address - section->vma;
1990*a9fa9459Szrj       if (stop_offset > datasize / opb)
1991*a9fa9459Szrj 	stop_offset = datasize / opb;
1992*a9fa9459Szrj     }
1993*a9fa9459Szrj 
1994*a9fa9459Szrj   if (addr_offset >= stop_offset)
1995*a9fa9459Szrj     return;
1996*a9fa9459Szrj 
1997*a9fa9459Szrj   /* Decide which set of relocs to use.  Load them if necessary.  */
1998*a9fa9459Szrj   paux = (struct objdump_disasm_info *) pinfo->application_data;
1999*a9fa9459Szrj   if (paux->dynrelbuf)
2000*a9fa9459Szrj     {
2001*a9fa9459Szrj       rel_pp = paux->dynrelbuf;
2002*a9fa9459Szrj       rel_count = paux->dynrelcount;
2003*a9fa9459Szrj       /* Dynamic reloc addresses are absolute, non-dynamic are section
2004*a9fa9459Szrj 	 relative.  REL_OFFSET specifies the reloc address corresponding
2005*a9fa9459Szrj 	 to the start of this section.  */
2006*a9fa9459Szrj       rel_offset = section->vma;
2007*a9fa9459Szrj     }
2008*a9fa9459Szrj   else
2009*a9fa9459Szrj     {
2010*a9fa9459Szrj       rel_count = 0;
2011*a9fa9459Szrj       rel_pp = NULL;
2012*a9fa9459Szrj       rel_offset = 0;
2013*a9fa9459Szrj 
2014*a9fa9459Szrj       if ((section->flags & SEC_RELOC) != 0
2015*a9fa9459Szrj 	  && (dump_reloc_info || pinfo->disassembler_needs_relocs))
2016*a9fa9459Szrj 	{
2017*a9fa9459Szrj 	  long relsize;
2018*a9fa9459Szrj 
2019*a9fa9459Szrj 	  relsize = bfd_get_reloc_upper_bound (abfd, section);
2020*a9fa9459Szrj 	  if (relsize < 0)
2021*a9fa9459Szrj 	    bfd_fatal (bfd_get_filename (abfd));
2022*a9fa9459Szrj 
2023*a9fa9459Szrj 	  if (relsize > 0)
2024*a9fa9459Szrj 	    {
2025*a9fa9459Szrj 	      rel_ppstart = rel_pp = (arelent **) xmalloc (relsize);
2026*a9fa9459Szrj 	      rel_count = bfd_canonicalize_reloc (abfd, section, rel_pp, syms);
2027*a9fa9459Szrj 	      if (rel_count < 0)
2028*a9fa9459Szrj 		bfd_fatal (bfd_get_filename (abfd));
2029*a9fa9459Szrj 
2030*a9fa9459Szrj 	      /* Sort the relocs by address.  */
2031*a9fa9459Szrj 	      qsort (rel_pp, rel_count, sizeof (arelent *), compare_relocs);
2032*a9fa9459Szrj 	    }
2033*a9fa9459Szrj 	}
2034*a9fa9459Szrj     }
2035*a9fa9459Szrj   rel_ppend = rel_pp + rel_count;
2036*a9fa9459Szrj 
2037*a9fa9459Szrj   data = (bfd_byte *) xmalloc (datasize);
2038*a9fa9459Szrj 
2039*a9fa9459Szrj   bfd_get_section_contents (abfd, section, data, 0, datasize);
2040*a9fa9459Szrj 
2041*a9fa9459Szrj   paux->sec = section;
2042*a9fa9459Szrj   pinfo->buffer = data;
2043*a9fa9459Szrj   pinfo->buffer_vma = section->vma;
2044*a9fa9459Szrj   pinfo->buffer_length = datasize;
2045*a9fa9459Szrj   pinfo->section = section;
2046*a9fa9459Szrj 
2047*a9fa9459Szrj   /* Skip over the relocs belonging to addresses below the
2048*a9fa9459Szrj      start address.  */
2049*a9fa9459Szrj   while (rel_pp < rel_ppend
2050*a9fa9459Szrj 	 && (*rel_pp)->address < rel_offset + addr_offset)
2051*a9fa9459Szrj     ++rel_pp;
2052*a9fa9459Szrj 
2053*a9fa9459Szrj   printf (_("\nDisassembly of section %s:\n"), section->name);
2054*a9fa9459Szrj 
2055*a9fa9459Szrj   /* Find the nearest symbol forwards from our current position.  */
2056*a9fa9459Szrj   paux->require_sec = TRUE;
2057*a9fa9459Szrj   sym = (asymbol *) find_symbol_for_address (section->vma + addr_offset,
2058*a9fa9459Szrj                                              (struct disassemble_info *) inf,
2059*a9fa9459Szrj                                              &place);
2060*a9fa9459Szrj   paux->require_sec = FALSE;
2061*a9fa9459Szrj 
2062*a9fa9459Szrj   /* PR 9774: If the target used signed addresses then we must make
2063*a9fa9459Szrj      sure that we sign extend the value that we calculate for 'addr'
2064*a9fa9459Szrj      in the loop below.  */
2065*a9fa9459Szrj   if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
2066*a9fa9459Szrj       && (bed = get_elf_backend_data (abfd)) != NULL
2067*a9fa9459Szrj       && bed->sign_extend_vma)
2068*a9fa9459Szrj     sign_adjust = (bfd_vma) 1 << (bed->s->arch_size - 1);
2069*a9fa9459Szrj 
2070*a9fa9459Szrj   /* Disassemble a block of instructions up to the address associated with
2071*a9fa9459Szrj      the symbol we have just found.  Then print the symbol and find the
2072*a9fa9459Szrj      next symbol on.  Repeat until we have disassembled the entire section
2073*a9fa9459Szrj      or we have reached the end of the address range we are interested in.  */
2074*a9fa9459Szrj   while (addr_offset < stop_offset)
2075*a9fa9459Szrj     {
2076*a9fa9459Szrj       bfd_vma addr;
2077*a9fa9459Szrj       asymbol *nextsym;
2078*a9fa9459Szrj       bfd_vma nextstop_offset;
2079*a9fa9459Szrj       bfd_boolean insns;
2080*a9fa9459Szrj 
2081*a9fa9459Szrj       addr = section->vma + addr_offset;
2082*a9fa9459Szrj       addr = ((addr & ((sign_adjust << 1) - 1)) ^ sign_adjust) - sign_adjust;
2083*a9fa9459Szrj 
2084*a9fa9459Szrj       if (sym != NULL && bfd_asymbol_value (sym) <= addr)
2085*a9fa9459Szrj 	{
2086*a9fa9459Szrj 	  int x;
2087*a9fa9459Szrj 
2088*a9fa9459Szrj 	  for (x = place;
2089*a9fa9459Szrj 	       (x < sorted_symcount
2090*a9fa9459Szrj 		&& (bfd_asymbol_value (sorted_syms[x]) <= addr));
2091*a9fa9459Szrj 	       ++x)
2092*a9fa9459Szrj 	    continue;
2093*a9fa9459Szrj 
2094*a9fa9459Szrj 	  pinfo->symbols = sorted_syms + place;
2095*a9fa9459Szrj 	  pinfo->num_symbols = x - place;
2096*a9fa9459Szrj 	  pinfo->symtab_pos = place;
2097*a9fa9459Szrj 	}
2098*a9fa9459Szrj       else
2099*a9fa9459Szrj 	{
2100*a9fa9459Szrj 	  pinfo->symbols = NULL;
2101*a9fa9459Szrj 	  pinfo->num_symbols = 0;
2102*a9fa9459Szrj 	  pinfo->symtab_pos = -1;
2103*a9fa9459Szrj 	}
2104*a9fa9459Szrj 
2105*a9fa9459Szrj       if (! prefix_addresses)
2106*a9fa9459Szrj 	{
2107*a9fa9459Szrj 	  pinfo->fprintf_func (pinfo->stream, "\n");
2108*a9fa9459Szrj 	  objdump_print_addr_with_sym (abfd, section, sym, addr,
2109*a9fa9459Szrj 				       pinfo, FALSE);
2110*a9fa9459Szrj 	  pinfo->fprintf_func (pinfo->stream, ":\n");
2111*a9fa9459Szrj 	}
2112*a9fa9459Szrj 
2113*a9fa9459Szrj       if (sym != NULL && bfd_asymbol_value (sym) > addr)
2114*a9fa9459Szrj 	nextsym = sym;
2115*a9fa9459Szrj       else if (sym == NULL)
2116*a9fa9459Szrj 	nextsym = NULL;
2117*a9fa9459Szrj       else
2118*a9fa9459Szrj 	{
2119*a9fa9459Szrj #define is_valid_next_sym(SYM) \
2120*a9fa9459Szrj   ((SYM)->section == section \
2121*a9fa9459Szrj    && (bfd_asymbol_value (SYM) > bfd_asymbol_value (sym)) \
2122*a9fa9459Szrj    && pinfo->symbol_is_valid (SYM, pinfo))
2123*a9fa9459Szrj 
2124*a9fa9459Szrj 	  /* Search forward for the next appropriate symbol in
2125*a9fa9459Szrj 	     SECTION.  Note that all the symbols are sorted
2126*a9fa9459Szrj 	     together into one big array, and that some sections
2127*a9fa9459Szrj 	     may have overlapping addresses.  */
2128*a9fa9459Szrj 	  while (place < sorted_symcount
2129*a9fa9459Szrj 		 && ! is_valid_next_sym (sorted_syms [place]))
2130*a9fa9459Szrj 	    ++place;
2131*a9fa9459Szrj 
2132*a9fa9459Szrj 	  if (place >= sorted_symcount)
2133*a9fa9459Szrj 	    nextsym = NULL;
2134*a9fa9459Szrj 	  else
2135*a9fa9459Szrj 	    nextsym = sorted_syms[place];
2136*a9fa9459Szrj 	}
2137*a9fa9459Szrj 
2138*a9fa9459Szrj       if (sym != NULL && bfd_asymbol_value (sym) > addr)
2139*a9fa9459Szrj 	nextstop_offset = bfd_asymbol_value (sym) - section->vma;
2140*a9fa9459Szrj       else if (nextsym == NULL)
2141*a9fa9459Szrj 	nextstop_offset = stop_offset;
2142*a9fa9459Szrj       else
2143*a9fa9459Szrj 	nextstop_offset = bfd_asymbol_value (nextsym) - section->vma;
2144*a9fa9459Szrj 
2145*a9fa9459Szrj       if (nextstop_offset > stop_offset
2146*a9fa9459Szrj 	  || nextstop_offset <= addr_offset)
2147*a9fa9459Szrj 	nextstop_offset = stop_offset;
2148*a9fa9459Szrj 
2149*a9fa9459Szrj       /* If a symbol is explicitly marked as being an object
2150*a9fa9459Szrj 	 rather than a function, just dump the bytes without
2151*a9fa9459Szrj 	 disassembling them.  */
2152*a9fa9459Szrj       if (disassemble_all
2153*a9fa9459Szrj 	  || sym == NULL
2154*a9fa9459Szrj 	  || sym->section != section
2155*a9fa9459Szrj 	  || bfd_asymbol_value (sym) > addr
2156*a9fa9459Szrj 	  || ((sym->flags & BSF_OBJECT) == 0
2157*a9fa9459Szrj 	      && (strstr (bfd_asymbol_name (sym), "gnu_compiled")
2158*a9fa9459Szrj 		  == NULL)
2159*a9fa9459Szrj 	      && (strstr (bfd_asymbol_name (sym), "gcc2_compiled")
2160*a9fa9459Szrj 		  == NULL))
2161*a9fa9459Szrj 	  || (sym->flags & BSF_FUNCTION) != 0)
2162*a9fa9459Szrj 	insns = TRUE;
2163*a9fa9459Szrj       else
2164*a9fa9459Szrj 	insns = FALSE;
2165*a9fa9459Szrj 
2166*a9fa9459Szrj       disassemble_bytes (pinfo, paux->disassemble_fn, insns, data,
2167*a9fa9459Szrj 			 addr_offset, nextstop_offset,
2168*a9fa9459Szrj 			 rel_offset, &rel_pp, rel_ppend);
2169*a9fa9459Szrj 
2170*a9fa9459Szrj       addr_offset = nextstop_offset;
2171*a9fa9459Szrj       sym = nextsym;
2172*a9fa9459Szrj     }
2173*a9fa9459Szrj 
2174*a9fa9459Szrj   free (data);
2175*a9fa9459Szrj 
2176*a9fa9459Szrj   if (rel_ppstart != NULL)
2177*a9fa9459Szrj     free (rel_ppstart);
2178*a9fa9459Szrj }
2179*a9fa9459Szrj 
2180*a9fa9459Szrj /* Disassemble the contents of an object file.  */
2181*a9fa9459Szrj 
2182*a9fa9459Szrj static void
disassemble_data(bfd * abfd)2183*a9fa9459Szrj disassemble_data (bfd *abfd)
2184*a9fa9459Szrj {
2185*a9fa9459Szrj   struct disassemble_info disasm_info;
2186*a9fa9459Szrj   struct objdump_disasm_info aux;
2187*a9fa9459Szrj   long i;
2188*a9fa9459Szrj 
2189*a9fa9459Szrj   print_files = NULL;
2190*a9fa9459Szrj   prev_functionname = NULL;
2191*a9fa9459Szrj   prev_line = -1;
2192*a9fa9459Szrj   prev_discriminator = 0;
2193*a9fa9459Szrj 
2194*a9fa9459Szrj   /* We make a copy of syms to sort.  We don't want to sort syms
2195*a9fa9459Szrj      because that will screw up the relocs.  */
2196*a9fa9459Szrj   sorted_symcount = symcount ? symcount : dynsymcount;
2197*a9fa9459Szrj   sorted_syms = (asymbol **) xmalloc ((sorted_symcount + synthcount)
2198*a9fa9459Szrj                                       * sizeof (asymbol *));
2199*a9fa9459Szrj   memcpy (sorted_syms, symcount ? syms : dynsyms,
2200*a9fa9459Szrj 	  sorted_symcount * sizeof (asymbol *));
2201*a9fa9459Szrj 
2202*a9fa9459Szrj   sorted_symcount = remove_useless_symbols (sorted_syms, sorted_symcount);
2203*a9fa9459Szrj 
2204*a9fa9459Szrj   for (i = 0; i < synthcount; ++i)
2205*a9fa9459Szrj     {
2206*a9fa9459Szrj       sorted_syms[sorted_symcount] = synthsyms + i;
2207*a9fa9459Szrj       ++sorted_symcount;
2208*a9fa9459Szrj     }
2209*a9fa9459Szrj 
2210*a9fa9459Szrj   /* Sort the symbols into section and symbol order.  */
2211*a9fa9459Szrj   qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
2212*a9fa9459Szrj 
2213*a9fa9459Szrj   init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf);
2214*a9fa9459Szrj 
2215*a9fa9459Szrj   disasm_info.application_data = (void *) &aux;
2216*a9fa9459Szrj   aux.abfd = abfd;
2217*a9fa9459Szrj   aux.require_sec = FALSE;
2218*a9fa9459Szrj   aux.dynrelbuf = NULL;
2219*a9fa9459Szrj   aux.dynrelcount = 0;
2220*a9fa9459Szrj   aux.reloc = NULL;
2221*a9fa9459Szrj 
2222*a9fa9459Szrj   disasm_info.print_address_func = objdump_print_address;
2223*a9fa9459Szrj   disasm_info.symbol_at_address_func = objdump_symbol_at_address;
2224*a9fa9459Szrj 
2225*a9fa9459Szrj   if (machine != NULL)
2226*a9fa9459Szrj     {
2227*a9fa9459Szrj       const bfd_arch_info_type *inf = bfd_scan_arch (machine);
2228*a9fa9459Szrj 
2229*a9fa9459Szrj       if (inf == NULL)
2230*a9fa9459Szrj 	fatal (_("can't use supplied machine %s"), machine);
2231*a9fa9459Szrj 
2232*a9fa9459Szrj       abfd->arch_info = inf;
2233*a9fa9459Szrj     }
2234*a9fa9459Szrj 
2235*a9fa9459Szrj   if (endian != BFD_ENDIAN_UNKNOWN)
2236*a9fa9459Szrj     {
2237*a9fa9459Szrj       struct bfd_target *xvec;
2238*a9fa9459Szrj 
2239*a9fa9459Szrj       xvec = (struct bfd_target *) xmalloc (sizeof (struct bfd_target));
2240*a9fa9459Szrj       memcpy (xvec, abfd->xvec, sizeof (struct bfd_target));
2241*a9fa9459Szrj       xvec->byteorder = endian;
2242*a9fa9459Szrj       abfd->xvec = xvec;
2243*a9fa9459Szrj     }
2244*a9fa9459Szrj 
2245*a9fa9459Szrj   /* Use libopcodes to locate a suitable disassembler.  */
2246*a9fa9459Szrj   aux.disassemble_fn = disassembler (abfd);
2247*a9fa9459Szrj   if (!aux.disassemble_fn)
2248*a9fa9459Szrj     {
2249*a9fa9459Szrj       non_fatal (_("can't disassemble for architecture %s\n"),
2250*a9fa9459Szrj 		 bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
2251*a9fa9459Szrj       exit_status = 1;
2252*a9fa9459Szrj       return;
2253*a9fa9459Szrj     }
2254*a9fa9459Szrj 
2255*a9fa9459Szrj   disasm_info.flavour = bfd_get_flavour (abfd);
2256*a9fa9459Szrj   disasm_info.arch = bfd_get_arch (abfd);
2257*a9fa9459Szrj   disasm_info.mach = bfd_get_mach (abfd);
2258*a9fa9459Szrj   disasm_info.disassembler_options = disassembler_options;
2259*a9fa9459Szrj   disasm_info.octets_per_byte = bfd_octets_per_byte (abfd);
2260*a9fa9459Szrj   disasm_info.skip_zeroes = DEFAULT_SKIP_ZEROES;
2261*a9fa9459Szrj   disasm_info.skip_zeroes_at_end = DEFAULT_SKIP_ZEROES_AT_END;
2262*a9fa9459Szrj   disasm_info.disassembler_needs_relocs = FALSE;
2263*a9fa9459Szrj 
2264*a9fa9459Szrj   if (bfd_big_endian (abfd))
2265*a9fa9459Szrj     disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_BIG;
2266*a9fa9459Szrj   else if (bfd_little_endian (abfd))
2267*a9fa9459Szrj     disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE;
2268*a9fa9459Szrj   else
2269*a9fa9459Szrj     /* ??? Aborting here seems too drastic.  We could default to big or little
2270*a9fa9459Szrj        instead.  */
2271*a9fa9459Szrj     disasm_info.endian = BFD_ENDIAN_UNKNOWN;
2272*a9fa9459Szrj 
2273*a9fa9459Szrj   /* Allow the target to customize the info structure.  */
2274*a9fa9459Szrj   disassemble_init_for_target (& disasm_info);
2275*a9fa9459Szrj 
2276*a9fa9459Szrj   /* Pre-load the dynamic relocs if we are going
2277*a9fa9459Szrj      to be dumping them along with the disassembly.  */
2278*a9fa9459Szrj   if (dump_dynamic_reloc_info)
2279*a9fa9459Szrj     {
2280*a9fa9459Szrj       long relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
2281*a9fa9459Szrj 
2282*a9fa9459Szrj       if (relsize < 0)
2283*a9fa9459Szrj 	bfd_fatal (bfd_get_filename (abfd));
2284*a9fa9459Szrj 
2285*a9fa9459Szrj       if (relsize > 0)
2286*a9fa9459Szrj 	{
2287*a9fa9459Szrj 	  aux.dynrelbuf = (arelent **) xmalloc (relsize);
2288*a9fa9459Szrj 	  aux.dynrelcount = bfd_canonicalize_dynamic_reloc (abfd,
2289*a9fa9459Szrj 							    aux.dynrelbuf,
2290*a9fa9459Szrj 							    dynsyms);
2291*a9fa9459Szrj 	  if (aux.dynrelcount < 0)
2292*a9fa9459Szrj 	    bfd_fatal (bfd_get_filename (abfd));
2293*a9fa9459Szrj 
2294*a9fa9459Szrj 	  /* Sort the relocs by address.  */
2295*a9fa9459Szrj 	  qsort (aux.dynrelbuf, aux.dynrelcount, sizeof (arelent *),
2296*a9fa9459Szrj 		 compare_relocs);
2297*a9fa9459Szrj 	}
2298*a9fa9459Szrj     }
2299*a9fa9459Szrj   disasm_info.symtab = sorted_syms;
2300*a9fa9459Szrj   disasm_info.symtab_size = sorted_symcount;
2301*a9fa9459Szrj 
2302*a9fa9459Szrj   bfd_map_over_sections (abfd, disassemble_section, & disasm_info);
2303*a9fa9459Szrj 
2304*a9fa9459Szrj   if (aux.dynrelbuf != NULL)
2305*a9fa9459Szrj     free (aux.dynrelbuf);
2306*a9fa9459Szrj   free (sorted_syms);
2307*a9fa9459Szrj }
2308*a9fa9459Szrj 
2309*a9fa9459Szrj static int
load_specific_debug_section(enum dwarf_section_display_enum debug,asection * sec,void * file)2310*a9fa9459Szrj load_specific_debug_section (enum dwarf_section_display_enum debug,
2311*a9fa9459Szrj 			     asection *sec, void *file)
2312*a9fa9459Szrj {
2313*a9fa9459Szrj   struct dwarf_section *section = &debug_displays [debug].section;
2314*a9fa9459Szrj   bfd *abfd = (bfd *) file;
2315*a9fa9459Szrj   bfd_boolean ret;
2316*a9fa9459Szrj 
2317*a9fa9459Szrj   /* If it is already loaded, do nothing.  */
2318*a9fa9459Szrj   if (section->start != NULL)
2319*a9fa9459Szrj     return 1;
2320*a9fa9459Szrj 
2321*a9fa9459Szrj   section->reloc_info = NULL;
2322*a9fa9459Szrj   section->num_relocs = 0;
2323*a9fa9459Szrj   section->address = bfd_get_section_vma (abfd, sec);
2324*a9fa9459Szrj   section->size = bfd_get_section_size (sec);
2325*a9fa9459Szrj   section->start = NULL;
2326*a9fa9459Szrj   section->user_data = sec;
2327*a9fa9459Szrj   ret = bfd_get_full_section_contents (abfd, sec, &section->start);
2328*a9fa9459Szrj 
2329*a9fa9459Szrj   if (! ret)
2330*a9fa9459Szrj     {
2331*a9fa9459Szrj       free_debug_section (debug);
2332*a9fa9459Szrj       printf (_("\nCan't get contents for section '%s'.\n"),
2333*a9fa9459Szrj 	      section->name);
2334*a9fa9459Szrj       return 0;
2335*a9fa9459Szrj     }
2336*a9fa9459Szrj 
2337*a9fa9459Szrj   if (is_relocatable && debug_displays [debug].relocate)
2338*a9fa9459Szrj     {
2339*a9fa9459Szrj       bfd_cache_section_contents (sec, section->start);
2340*a9fa9459Szrj 
2341*a9fa9459Szrj       ret = bfd_simple_get_relocated_section_contents (abfd,
2342*a9fa9459Szrj 						       sec,
2343*a9fa9459Szrj 						       section->start,
2344*a9fa9459Szrj 						       syms) != NULL;
2345*a9fa9459Szrj 
2346*a9fa9459Szrj       if (! ret)
2347*a9fa9459Szrj         {
2348*a9fa9459Szrj           free_debug_section (debug);
2349*a9fa9459Szrj           printf (_("\nCan't get contents for section '%s'.\n"),
2350*a9fa9459Szrj 	          section->name);
2351*a9fa9459Szrj           return 0;
2352*a9fa9459Szrj         }
2353*a9fa9459Szrj 
2354*a9fa9459Szrj       long reloc_size;
2355*a9fa9459Szrj 
2356*a9fa9459Szrj       reloc_size = bfd_get_reloc_upper_bound (abfd, sec);
2357*a9fa9459Szrj       if (reloc_size > 0)
2358*a9fa9459Szrj 	{
2359*a9fa9459Szrj 	  unsigned long reloc_count;
2360*a9fa9459Szrj 	  arelent **relocs;
2361*a9fa9459Szrj 
2362*a9fa9459Szrj 	  relocs = (arelent **) xmalloc (reloc_size);
2363*a9fa9459Szrj 
2364*a9fa9459Szrj 	  reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, NULL);
2365*a9fa9459Szrj 	  if (reloc_count == 0)
2366*a9fa9459Szrj 	    free (relocs);
2367*a9fa9459Szrj 	  else
2368*a9fa9459Szrj 	    {
2369*a9fa9459Szrj 	      section->reloc_info = relocs;
2370*a9fa9459Szrj 	      section->num_relocs = reloc_count;
2371*a9fa9459Szrj 	    }
2372*a9fa9459Szrj 	}
2373*a9fa9459Szrj     }
2374*a9fa9459Szrj 
2375*a9fa9459Szrj   return 1;
2376*a9fa9459Szrj }
2377*a9fa9459Szrj 
2378*a9fa9459Szrj bfd_boolean
reloc_at(struct dwarf_section * dsec,dwarf_vma offset)2379*a9fa9459Szrj reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
2380*a9fa9459Szrj {
2381*a9fa9459Szrj   arelent ** relocs;
2382*a9fa9459Szrj   arelent * rp;
2383*a9fa9459Szrj 
2384*a9fa9459Szrj   if (dsec == NULL || dsec->reloc_info == NULL)
2385*a9fa9459Szrj     return FALSE;
2386*a9fa9459Szrj 
2387*a9fa9459Szrj   relocs = (arelent **) dsec->reloc_info;
2388*a9fa9459Szrj 
2389*a9fa9459Szrj   for (; (rp = * relocs) != NULL; ++ relocs)
2390*a9fa9459Szrj     if (rp->address == offset)
2391*a9fa9459Szrj       return TRUE;
2392*a9fa9459Szrj 
2393*a9fa9459Szrj   return FALSE;
2394*a9fa9459Szrj }
2395*a9fa9459Szrj 
2396*a9fa9459Szrj int
load_debug_section(enum dwarf_section_display_enum debug,void * file)2397*a9fa9459Szrj load_debug_section (enum dwarf_section_display_enum debug, void *file)
2398*a9fa9459Szrj {
2399*a9fa9459Szrj   struct dwarf_section *section = &debug_displays [debug].section;
2400*a9fa9459Szrj   bfd *abfd = (bfd *) file;
2401*a9fa9459Szrj   asection *sec;
2402*a9fa9459Szrj 
2403*a9fa9459Szrj   /* If it is already loaded, do nothing.  */
2404*a9fa9459Szrj   if (section->start != NULL)
2405*a9fa9459Szrj     return 1;
2406*a9fa9459Szrj 
2407*a9fa9459Szrj   /* Locate the debug section.  */
2408*a9fa9459Szrj   sec = bfd_get_section_by_name (abfd, section->uncompressed_name);
2409*a9fa9459Szrj   if (sec != NULL)
2410*a9fa9459Szrj     section->name = section->uncompressed_name;
2411*a9fa9459Szrj   else
2412*a9fa9459Szrj     {
2413*a9fa9459Szrj       sec = bfd_get_section_by_name (abfd, section->compressed_name);
2414*a9fa9459Szrj       if (sec != NULL)
2415*a9fa9459Szrj         section->name = section->compressed_name;
2416*a9fa9459Szrj     }
2417*a9fa9459Szrj   if (sec == NULL)
2418*a9fa9459Szrj     return 0;
2419*a9fa9459Szrj 
2420*a9fa9459Szrj   return load_specific_debug_section (debug, sec, file);
2421*a9fa9459Szrj }
2422*a9fa9459Szrj 
2423*a9fa9459Szrj void
free_debug_section(enum dwarf_section_display_enum debug)2424*a9fa9459Szrj free_debug_section (enum dwarf_section_display_enum debug)
2425*a9fa9459Szrj {
2426*a9fa9459Szrj   struct dwarf_section *section = &debug_displays [debug].section;
2427*a9fa9459Szrj 
2428*a9fa9459Szrj   if (section->start == NULL)
2429*a9fa9459Szrj     return;
2430*a9fa9459Szrj 
2431*a9fa9459Szrj   /* PR 17512: file: 0f67f69d.  */
2432*a9fa9459Szrj   if (section->user_data != NULL)
2433*a9fa9459Szrj     {
2434*a9fa9459Szrj       asection * sec = (asection *) section->user_data;
2435*a9fa9459Szrj 
2436*a9fa9459Szrj       /* If we are freeing contents that are also pointed to by the BFD
2437*a9fa9459Szrj 	 library's section structure then make sure to update those pointers
2438*a9fa9459Szrj 	 too.  Otherwise, the next time we try to load data for this section
2439*a9fa9459Szrj 	 we can end up using a stale pointer.  */
2440*a9fa9459Szrj       if (section->start == sec->contents)
2441*a9fa9459Szrj 	{
2442*a9fa9459Szrj 	  sec->contents = NULL;
2443*a9fa9459Szrj 	  sec->flags &= ~ SEC_IN_MEMORY;
2444*a9fa9459Szrj 	  sec->compress_status = COMPRESS_SECTION_NONE;
2445*a9fa9459Szrj 	}
2446*a9fa9459Szrj     }
2447*a9fa9459Szrj 
2448*a9fa9459Szrj   free ((char *) section->start);
2449*a9fa9459Szrj   section->start = NULL;
2450*a9fa9459Szrj   section->address = 0;
2451*a9fa9459Szrj   section->size = 0;
2452*a9fa9459Szrj }
2453*a9fa9459Szrj 
2454*a9fa9459Szrj static void
dump_dwarf_section(bfd * abfd,asection * section,void * arg ATTRIBUTE_UNUSED)2455*a9fa9459Szrj dump_dwarf_section (bfd *abfd, asection *section,
2456*a9fa9459Szrj 		    void *arg ATTRIBUTE_UNUSED)
2457*a9fa9459Szrj {
2458*a9fa9459Szrj   const char *name = bfd_get_section_name (abfd, section);
2459*a9fa9459Szrj   const char *match;
2460*a9fa9459Szrj   int i;
2461*a9fa9459Szrj 
2462*a9fa9459Szrj   if (CONST_STRNEQ (name, ".gnu.linkonce.wi."))
2463*a9fa9459Szrj     match = ".debug_info";
2464*a9fa9459Szrj   else
2465*a9fa9459Szrj     match = name;
2466*a9fa9459Szrj 
2467*a9fa9459Szrj   for (i = 0; i < max; i++)
2468*a9fa9459Szrj     if ((strcmp (debug_displays [i].section.uncompressed_name, match) == 0
2469*a9fa9459Szrj 	 || strcmp (debug_displays [i].section.compressed_name, match) == 0)
2470*a9fa9459Szrj 	&& debug_displays [i].enabled != NULL
2471*a9fa9459Szrj 	&& *debug_displays [i].enabled)
2472*a9fa9459Szrj       {
2473*a9fa9459Szrj 	struct dwarf_section *sec = &debug_displays [i].section;
2474*a9fa9459Szrj 
2475*a9fa9459Szrj 	if (strcmp (sec->uncompressed_name, match) == 0)
2476*a9fa9459Szrj 	  sec->name = sec->uncompressed_name;
2477*a9fa9459Szrj 	else
2478*a9fa9459Szrj 	  sec->name = sec->compressed_name;
2479*a9fa9459Szrj 	if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
2480*a9fa9459Szrj                                          section, abfd))
2481*a9fa9459Szrj 	  {
2482*a9fa9459Szrj 	    debug_displays [i].display (sec, abfd);
2483*a9fa9459Szrj 
2484*a9fa9459Szrj 	    if (i != info && i != abbrev)
2485*a9fa9459Szrj 	      free_debug_section ((enum dwarf_section_display_enum) i);
2486*a9fa9459Szrj 	  }
2487*a9fa9459Szrj 	break;
2488*a9fa9459Szrj       }
2489*a9fa9459Szrj }
2490*a9fa9459Szrj 
2491*a9fa9459Szrj /* Dump the dwarf debugging information.  */
2492*a9fa9459Szrj 
2493*a9fa9459Szrj static void
dump_dwarf(bfd * abfd)2494*a9fa9459Szrj dump_dwarf (bfd *abfd)
2495*a9fa9459Szrj {
2496*a9fa9459Szrj   is_relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0;
2497*a9fa9459Szrj 
2498*a9fa9459Szrj   eh_addr_size = bfd_arch_bits_per_address (abfd) / 8;
2499*a9fa9459Szrj 
2500*a9fa9459Szrj   if (bfd_big_endian (abfd))
2501*a9fa9459Szrj     byte_get = byte_get_big_endian;
2502*a9fa9459Szrj   else if (bfd_little_endian (abfd))
2503*a9fa9459Szrj     byte_get = byte_get_little_endian;
2504*a9fa9459Szrj   else
2505*a9fa9459Szrj     /* PR 17512: file: objdump-s-endless-loop.tekhex.  */
2506*a9fa9459Szrj     {
2507*a9fa9459Szrj       warn (_("File %s does not contain any dwarf debug information\n"),
2508*a9fa9459Szrj 	    bfd_get_filename (abfd));
2509*a9fa9459Szrj       return;
2510*a9fa9459Szrj     }
2511*a9fa9459Szrj 
2512*a9fa9459Szrj   switch (bfd_get_arch (abfd))
2513*a9fa9459Szrj     {
2514*a9fa9459Szrj     case bfd_arch_i386:
2515*a9fa9459Szrj       switch (bfd_get_mach (abfd))
2516*a9fa9459Szrj 	{
2517*a9fa9459Szrj 	case bfd_mach_x86_64:
2518*a9fa9459Szrj 	case bfd_mach_x86_64_intel_syntax:
2519*a9fa9459Szrj 	case bfd_mach_x86_64_nacl:
2520*a9fa9459Szrj 	case bfd_mach_x64_32:
2521*a9fa9459Szrj 	case bfd_mach_x64_32_intel_syntax:
2522*a9fa9459Szrj 	case bfd_mach_x64_32_nacl:
2523*a9fa9459Szrj 	  init_dwarf_regnames_x86_64 ();
2524*a9fa9459Szrj 	  break;
2525*a9fa9459Szrj 
2526*a9fa9459Szrj 	default:
2527*a9fa9459Szrj 	  init_dwarf_regnames_i386 ();
2528*a9fa9459Szrj 	  break;
2529*a9fa9459Szrj 	}
2530*a9fa9459Szrj       break;
2531*a9fa9459Szrj 
2532*a9fa9459Szrj     case bfd_arch_iamcu:
2533*a9fa9459Szrj       init_dwarf_regnames_iamcu ();
2534*a9fa9459Szrj       break;
2535*a9fa9459Szrj 
2536*a9fa9459Szrj     case bfd_arch_aarch64:
2537*a9fa9459Szrj       init_dwarf_regnames_aarch64();
2538*a9fa9459Szrj       break;
2539*a9fa9459Szrj 
2540*a9fa9459Szrj     case bfd_arch_s390:
2541*a9fa9459Szrj       init_dwarf_regnames_s390 ();
2542*a9fa9459Szrj       break;
2543*a9fa9459Szrj 
2544*a9fa9459Szrj     default:
2545*a9fa9459Szrj       break;
2546*a9fa9459Szrj     }
2547*a9fa9459Szrj 
2548*a9fa9459Szrj   bfd_map_over_sections (abfd, dump_dwarf_section, NULL);
2549*a9fa9459Szrj 
2550*a9fa9459Szrj   free_debug_memory ();
2551*a9fa9459Szrj }
2552*a9fa9459Szrj 
2553*a9fa9459Szrj /* Read ABFD's stabs section STABSECT_NAME, and return a pointer to
2554*a9fa9459Szrj    it.  Return NULL on failure.   */
2555*a9fa9459Szrj 
2556*a9fa9459Szrj static char *
read_section_stabs(bfd * abfd,const char * sect_name,bfd_size_type * size_ptr)2557*a9fa9459Szrj read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr)
2558*a9fa9459Szrj {
2559*a9fa9459Szrj   asection *stabsect;
2560*a9fa9459Szrj   bfd_size_type size;
2561*a9fa9459Szrj   char *contents;
2562*a9fa9459Szrj 
2563*a9fa9459Szrj   stabsect = bfd_get_section_by_name (abfd, sect_name);
2564*a9fa9459Szrj   if (stabsect == NULL)
2565*a9fa9459Szrj     {
2566*a9fa9459Szrj       printf (_("No %s section present\n\n"), sect_name);
2567*a9fa9459Szrj       return FALSE;
2568*a9fa9459Szrj     }
2569*a9fa9459Szrj 
2570*a9fa9459Szrj   size = bfd_section_size (abfd, stabsect);
2571*a9fa9459Szrj   contents  = (char *) xmalloc (size);
2572*a9fa9459Szrj 
2573*a9fa9459Szrj   if (! bfd_get_section_contents (abfd, stabsect, contents, 0, size))
2574*a9fa9459Szrj     {
2575*a9fa9459Szrj       non_fatal (_("reading %s section of %s failed: %s"),
2576*a9fa9459Szrj 		 sect_name, bfd_get_filename (abfd),
2577*a9fa9459Szrj 		 bfd_errmsg (bfd_get_error ()));
2578*a9fa9459Szrj       exit_status = 1;
2579*a9fa9459Szrj       free (contents);
2580*a9fa9459Szrj       return NULL;
2581*a9fa9459Szrj     }
2582*a9fa9459Szrj 
2583*a9fa9459Szrj   *size_ptr = size;
2584*a9fa9459Szrj 
2585*a9fa9459Szrj   return contents;
2586*a9fa9459Szrj }
2587*a9fa9459Szrj 
2588*a9fa9459Szrj /* Stabs entries use a 12 byte format:
2589*a9fa9459Szrj      4 byte string table index
2590*a9fa9459Szrj      1 byte stab type
2591*a9fa9459Szrj      1 byte stab other field
2592*a9fa9459Szrj      2 byte stab desc field
2593*a9fa9459Szrj      4 byte stab value
2594*a9fa9459Szrj    FIXME: This will have to change for a 64 bit object format.  */
2595*a9fa9459Szrj 
2596*a9fa9459Szrj #define STRDXOFF  (0)
2597*a9fa9459Szrj #define TYPEOFF   (4)
2598*a9fa9459Szrj #define OTHEROFF  (5)
2599*a9fa9459Szrj #define DESCOFF   (6)
2600*a9fa9459Szrj #define VALOFF    (8)
2601*a9fa9459Szrj #define STABSIZE (12)
2602*a9fa9459Szrj 
2603*a9fa9459Szrj /* Print ABFD's stabs section STABSECT_NAME (in `stabs'),
2604*a9fa9459Szrj    using string table section STRSECT_NAME (in `strtab').  */
2605*a9fa9459Szrj 
2606*a9fa9459Szrj static void
print_section_stabs(bfd * abfd,const char * stabsect_name,unsigned * string_offset_ptr)2607*a9fa9459Szrj print_section_stabs (bfd *abfd,
2608*a9fa9459Szrj 		     const char *stabsect_name,
2609*a9fa9459Szrj 		     unsigned *string_offset_ptr)
2610*a9fa9459Szrj {
2611*a9fa9459Szrj   int i;
2612*a9fa9459Szrj   unsigned file_string_table_offset = 0;
2613*a9fa9459Szrj   unsigned next_file_string_table_offset = *string_offset_ptr;
2614*a9fa9459Szrj   bfd_byte *stabp, *stabs_end;
2615*a9fa9459Szrj 
2616*a9fa9459Szrj   stabp = stabs;
2617*a9fa9459Szrj   stabs_end = stabp + stab_size;
2618*a9fa9459Szrj 
2619*a9fa9459Szrj   printf (_("Contents of %s section:\n\n"), stabsect_name);
2620*a9fa9459Szrj   printf ("Symnum n_type n_othr n_desc n_value  n_strx String\n");
2621*a9fa9459Szrj 
2622*a9fa9459Szrj   /* Loop through all symbols and print them.
2623*a9fa9459Szrj 
2624*a9fa9459Szrj      We start the index at -1 because there is a dummy symbol on
2625*a9fa9459Szrj      the front of stabs-in-{coff,elf} sections that supplies sizes.  */
2626*a9fa9459Szrj   for (i = -1; stabp <= stabs_end - STABSIZE; stabp += STABSIZE, i++)
2627*a9fa9459Szrj     {
2628*a9fa9459Szrj       const char *name;
2629*a9fa9459Szrj       unsigned long strx;
2630*a9fa9459Szrj       unsigned char type, other;
2631*a9fa9459Szrj       unsigned short desc;
2632*a9fa9459Szrj       bfd_vma value;
2633*a9fa9459Szrj 
2634*a9fa9459Szrj       strx = bfd_h_get_32 (abfd, stabp + STRDXOFF);
2635*a9fa9459Szrj       type = bfd_h_get_8 (abfd, stabp + TYPEOFF);
2636*a9fa9459Szrj       other = bfd_h_get_8 (abfd, stabp + OTHEROFF);
2637*a9fa9459Szrj       desc = bfd_h_get_16 (abfd, stabp + DESCOFF);
2638*a9fa9459Szrj       value = bfd_h_get_32 (abfd, stabp + VALOFF);
2639*a9fa9459Szrj 
2640*a9fa9459Szrj       printf ("\n%-6d ", i);
2641*a9fa9459Szrj       /* Either print the stab name, or, if unnamed, print its number
2642*a9fa9459Szrj 	 again (makes consistent formatting for tools like awk).  */
2643*a9fa9459Szrj       name = bfd_get_stab_name (type);
2644*a9fa9459Szrj       if (name != NULL)
2645*a9fa9459Szrj 	printf ("%-6s", name);
2646*a9fa9459Szrj       else if (type == N_UNDF)
2647*a9fa9459Szrj 	printf ("HdrSym");
2648*a9fa9459Szrj       else
2649*a9fa9459Szrj 	printf ("%-6d", type);
2650*a9fa9459Szrj       printf (" %-6d %-6d ", other, desc);
2651*a9fa9459Szrj       bfd_printf_vma (abfd, value);
2652*a9fa9459Szrj       printf (" %-6lu", strx);
2653*a9fa9459Szrj 
2654*a9fa9459Szrj       /* Symbols with type == 0 (N_UNDF) specify the length of the
2655*a9fa9459Szrj 	 string table associated with this file.  We use that info
2656*a9fa9459Szrj 	 to know how to relocate the *next* file's string table indices.  */
2657*a9fa9459Szrj       if (type == N_UNDF)
2658*a9fa9459Szrj 	{
2659*a9fa9459Szrj 	  file_string_table_offset = next_file_string_table_offset;
2660*a9fa9459Szrj 	  next_file_string_table_offset += value;
2661*a9fa9459Szrj 	}
2662*a9fa9459Szrj       else
2663*a9fa9459Szrj 	{
2664*a9fa9459Szrj 	  bfd_size_type amt = strx + file_string_table_offset;
2665*a9fa9459Szrj 
2666*a9fa9459Szrj 	  /* Using the (possibly updated) string table offset, print the
2667*a9fa9459Szrj 	     string (if any) associated with this symbol.  */
2668*a9fa9459Szrj 	  if (amt < stabstr_size)
2669*a9fa9459Szrj 	    /* PR 17512: file: 079-79389-0.001:0.1.  */
2670*a9fa9459Szrj 	    printf (" %.*s", (int)(stabstr_size - amt), strtab + amt);
2671*a9fa9459Szrj 	  else
2672*a9fa9459Szrj 	    printf (" *");
2673*a9fa9459Szrj 	}
2674*a9fa9459Szrj     }
2675*a9fa9459Szrj   printf ("\n\n");
2676*a9fa9459Szrj   *string_offset_ptr = next_file_string_table_offset;
2677*a9fa9459Szrj }
2678*a9fa9459Szrj 
2679*a9fa9459Szrj typedef struct
2680*a9fa9459Szrj {
2681*a9fa9459Szrj   const char * section_name;
2682*a9fa9459Szrj   const char * string_section_name;
2683*a9fa9459Szrj   unsigned string_offset;
2684*a9fa9459Szrj }
2685*a9fa9459Szrj stab_section_names;
2686*a9fa9459Szrj 
2687*a9fa9459Szrj static void
find_stabs_section(bfd * abfd,asection * section,void * names)2688*a9fa9459Szrj find_stabs_section (bfd *abfd, asection *section, void *names)
2689*a9fa9459Szrj {
2690*a9fa9459Szrj   int len;
2691*a9fa9459Szrj   stab_section_names * sought = (stab_section_names *) names;
2692*a9fa9459Szrj 
2693*a9fa9459Szrj   /* Check for section names for which stabsect_name is a prefix, to
2694*a9fa9459Szrj      handle .stab.N, etc.  */
2695*a9fa9459Szrj   len = strlen (sought->section_name);
2696*a9fa9459Szrj 
2697*a9fa9459Szrj   /* If the prefix matches, and the files section name ends with a
2698*a9fa9459Szrj      nul or a digit, then we match.  I.e., we want either an exact
2699*a9fa9459Szrj      match or a section followed by a number.  */
2700*a9fa9459Szrj   if (strncmp (sought->section_name, section->name, len) == 0
2701*a9fa9459Szrj       && (section->name[len] == 0
2702*a9fa9459Szrj 	  || (section->name[len] == '.' && ISDIGIT (section->name[len + 1]))))
2703*a9fa9459Szrj     {
2704*a9fa9459Szrj       if (strtab == NULL)
2705*a9fa9459Szrj 	strtab = read_section_stabs (abfd, sought->string_section_name,
2706*a9fa9459Szrj 				     &stabstr_size);
2707*a9fa9459Szrj 
2708*a9fa9459Szrj       if (strtab)
2709*a9fa9459Szrj 	{
2710*a9fa9459Szrj 	  stabs = (bfd_byte *) read_section_stabs (abfd, section->name,
2711*a9fa9459Szrj 						   &stab_size);
2712*a9fa9459Szrj 	  if (stabs)
2713*a9fa9459Szrj 	    print_section_stabs (abfd, section->name, &sought->string_offset);
2714*a9fa9459Szrj 	}
2715*a9fa9459Szrj     }
2716*a9fa9459Szrj }
2717*a9fa9459Szrj 
2718*a9fa9459Szrj static void
dump_stabs_section(bfd * abfd,char * stabsect_name,char * strsect_name)2719*a9fa9459Szrj dump_stabs_section (bfd *abfd, char *stabsect_name, char *strsect_name)
2720*a9fa9459Szrj {
2721*a9fa9459Szrj   stab_section_names s;
2722*a9fa9459Szrj 
2723*a9fa9459Szrj   s.section_name = stabsect_name;
2724*a9fa9459Szrj   s.string_section_name = strsect_name;
2725*a9fa9459Szrj   s.string_offset = 0;
2726*a9fa9459Szrj 
2727*a9fa9459Szrj   bfd_map_over_sections (abfd, find_stabs_section, & s);
2728*a9fa9459Szrj 
2729*a9fa9459Szrj   free (strtab);
2730*a9fa9459Szrj   strtab = NULL;
2731*a9fa9459Szrj }
2732*a9fa9459Szrj 
2733*a9fa9459Szrj /* Dump the any sections containing stabs debugging information.  */
2734*a9fa9459Szrj 
2735*a9fa9459Szrj static void
dump_stabs(bfd * abfd)2736*a9fa9459Szrj dump_stabs (bfd *abfd)
2737*a9fa9459Szrj {
2738*a9fa9459Szrj   dump_stabs_section (abfd, ".stab", ".stabstr");
2739*a9fa9459Szrj   dump_stabs_section (abfd, ".stab.excl", ".stab.exclstr");
2740*a9fa9459Szrj   dump_stabs_section (abfd, ".stab.index", ".stab.indexstr");
2741*a9fa9459Szrj 
2742*a9fa9459Szrj   /* For Darwin.  */
2743*a9fa9459Szrj   dump_stabs_section (abfd, "LC_SYMTAB.stabs", "LC_SYMTAB.stabstr");
2744*a9fa9459Szrj 
2745*a9fa9459Szrj   dump_stabs_section (abfd, "$GDB_SYMBOLS$", "$GDB_STRINGS$");
2746*a9fa9459Szrj }
2747*a9fa9459Szrj 
2748*a9fa9459Szrj static void
dump_bfd_header(bfd * abfd)2749*a9fa9459Szrj dump_bfd_header (bfd *abfd)
2750*a9fa9459Szrj {
2751*a9fa9459Szrj   char *comma = "";
2752*a9fa9459Szrj 
2753*a9fa9459Szrj   printf (_("architecture: %s, "),
2754*a9fa9459Szrj 	  bfd_printable_arch_mach (bfd_get_arch (abfd),
2755*a9fa9459Szrj 				   bfd_get_mach (abfd)));
2756*a9fa9459Szrj   printf (_("flags 0x%08x:\n"), abfd->flags & ~BFD_FLAGS_FOR_BFD_USE_MASK);
2757*a9fa9459Szrj 
2758*a9fa9459Szrj #define PF(x, y)    if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
2759*a9fa9459Szrj   PF (HAS_RELOC, "HAS_RELOC");
2760*a9fa9459Szrj   PF (EXEC_P, "EXEC_P");
2761*a9fa9459Szrj   PF (HAS_LINENO, "HAS_LINENO");
2762*a9fa9459Szrj   PF (HAS_DEBUG, "HAS_DEBUG");
2763*a9fa9459Szrj   PF (HAS_SYMS, "HAS_SYMS");
2764*a9fa9459Szrj   PF (HAS_LOCALS, "HAS_LOCALS");
2765*a9fa9459Szrj   PF (DYNAMIC, "DYNAMIC");
2766*a9fa9459Szrj   PF (WP_TEXT, "WP_TEXT");
2767*a9fa9459Szrj   PF (D_PAGED, "D_PAGED");
2768*a9fa9459Szrj   PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
2769*a9fa9459Szrj   printf (_("\nstart address 0x"));
2770*a9fa9459Szrj   bfd_printf_vma (abfd, abfd->start_address);
2771*a9fa9459Szrj   printf ("\n");
2772*a9fa9459Szrj }
2773*a9fa9459Szrj 
2774*a9fa9459Szrj 
2775*a9fa9459Szrj static void
dump_bfd_private_header(bfd * abfd)2776*a9fa9459Szrj dump_bfd_private_header (bfd *abfd)
2777*a9fa9459Szrj {
2778*a9fa9459Szrj   bfd_print_private_bfd_data (abfd, stdout);
2779*a9fa9459Szrj }
2780*a9fa9459Szrj 
2781*a9fa9459Szrj static void
dump_target_specific(bfd * abfd)2782*a9fa9459Szrj dump_target_specific (bfd *abfd)
2783*a9fa9459Szrj {
2784*a9fa9459Szrj   const struct objdump_private_desc * const *desc;
2785*a9fa9459Szrj   struct objdump_private_option *opt;
2786*a9fa9459Szrj   char *e, *b;
2787*a9fa9459Szrj 
2788*a9fa9459Szrj   /* Find the desc.  */
2789*a9fa9459Szrj   for (desc = objdump_private_vectors; *desc != NULL; desc++)
2790*a9fa9459Szrj     if ((*desc)->filter (abfd))
2791*a9fa9459Szrj       break;
2792*a9fa9459Szrj 
2793*a9fa9459Szrj   if (*desc == NULL)
2794*a9fa9459Szrj     {
2795*a9fa9459Szrj       non_fatal (_("option -P/--private not supported by this file"));
2796*a9fa9459Szrj       return;
2797*a9fa9459Szrj     }
2798*a9fa9459Szrj 
2799*a9fa9459Szrj   /* Clear all options.  */
2800*a9fa9459Szrj   for (opt = (*desc)->options; opt->name; opt++)
2801*a9fa9459Szrj     opt->selected = FALSE;
2802*a9fa9459Szrj 
2803*a9fa9459Szrj   /* Decode options.  */
2804*a9fa9459Szrj   b = dump_private_options;
2805*a9fa9459Szrj   do
2806*a9fa9459Szrj     {
2807*a9fa9459Szrj       e = strchr (b, ',');
2808*a9fa9459Szrj 
2809*a9fa9459Szrj       if (e)
2810*a9fa9459Szrj         *e = 0;
2811*a9fa9459Szrj 
2812*a9fa9459Szrj       for (opt = (*desc)->options; opt->name; opt++)
2813*a9fa9459Szrj         if (strcmp (opt->name, b) == 0)
2814*a9fa9459Szrj           {
2815*a9fa9459Szrj             opt->selected = TRUE;
2816*a9fa9459Szrj             break;
2817*a9fa9459Szrj           }
2818*a9fa9459Szrj       if (opt->name == NULL)
2819*a9fa9459Szrj         non_fatal (_("target specific dump '%s' not supported"), b);
2820*a9fa9459Szrj 
2821*a9fa9459Szrj       if (e)
2822*a9fa9459Szrj         {
2823*a9fa9459Szrj           *e = ',';
2824*a9fa9459Szrj           b = e + 1;
2825*a9fa9459Szrj         }
2826*a9fa9459Szrj     }
2827*a9fa9459Szrj   while (e != NULL);
2828*a9fa9459Szrj 
2829*a9fa9459Szrj   /* Dump.  */
2830*a9fa9459Szrj   (*desc)->dump (abfd);
2831*a9fa9459Szrj }
2832*a9fa9459Szrj 
2833*a9fa9459Szrj /* Display a section in hexadecimal format with associated characters.
2834*a9fa9459Szrj    Each line prefixed by the zero padded address.  */
2835*a9fa9459Szrj 
2836*a9fa9459Szrj static void
dump_section(bfd * abfd,asection * section,void * dummy ATTRIBUTE_UNUSED)2837*a9fa9459Szrj dump_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
2838*a9fa9459Szrj {
2839*a9fa9459Szrj   bfd_byte *data = 0;
2840*a9fa9459Szrj   bfd_size_type datasize;
2841*a9fa9459Szrj   bfd_vma addr_offset;
2842*a9fa9459Szrj   bfd_vma start_offset;
2843*a9fa9459Szrj   bfd_vma stop_offset;
2844*a9fa9459Szrj   unsigned int opb = bfd_octets_per_byte (abfd);
2845*a9fa9459Szrj   /* Bytes per line.  */
2846*a9fa9459Szrj   const int onaline = 16;
2847*a9fa9459Szrj   char buf[64];
2848*a9fa9459Szrj   int count;
2849*a9fa9459Szrj   int width;
2850*a9fa9459Szrj 
2851*a9fa9459Szrj   if ((section->flags & SEC_HAS_CONTENTS) == 0)
2852*a9fa9459Szrj     return;
2853*a9fa9459Szrj 
2854*a9fa9459Szrj   if (! process_section_p (section))
2855*a9fa9459Szrj     return;
2856*a9fa9459Szrj 
2857*a9fa9459Szrj   if ((datasize = bfd_section_size (abfd, section)) == 0)
2858*a9fa9459Szrj     return;
2859*a9fa9459Szrj 
2860*a9fa9459Szrj   /* Compute the address range to display.  */
2861*a9fa9459Szrj   if (start_address == (bfd_vma) -1
2862*a9fa9459Szrj       || start_address < section->vma)
2863*a9fa9459Szrj     start_offset = 0;
2864*a9fa9459Szrj   else
2865*a9fa9459Szrj     start_offset = start_address - section->vma;
2866*a9fa9459Szrj 
2867*a9fa9459Szrj   if (stop_address == (bfd_vma) -1)
2868*a9fa9459Szrj     stop_offset = datasize / opb;
2869*a9fa9459Szrj   else
2870*a9fa9459Szrj     {
2871*a9fa9459Szrj       if (stop_address < section->vma)
2872*a9fa9459Szrj 	stop_offset = 0;
2873*a9fa9459Szrj       else
2874*a9fa9459Szrj 	stop_offset = stop_address - section->vma;
2875*a9fa9459Szrj 
2876*a9fa9459Szrj       if (stop_offset > datasize / opb)
2877*a9fa9459Szrj 	stop_offset = datasize / opb;
2878*a9fa9459Szrj     }
2879*a9fa9459Szrj 
2880*a9fa9459Szrj   if (start_offset >= stop_offset)
2881*a9fa9459Szrj     return;
2882*a9fa9459Szrj 
2883*a9fa9459Szrj   printf (_("Contents of section %s:"), section->name);
2884*a9fa9459Szrj   if (display_file_offsets)
2885*a9fa9459Szrj     printf (_("  (Starting at file offset: 0x%lx)"),
2886*a9fa9459Szrj 	    (unsigned long) (section->filepos + start_offset));
2887*a9fa9459Szrj   printf ("\n");
2888*a9fa9459Szrj 
2889*a9fa9459Szrj   if (!bfd_get_full_section_contents (abfd, section, &data))
2890*a9fa9459Szrj     {
2891*a9fa9459Szrj       non_fatal (_("Reading section %s failed because: %s"),
2892*a9fa9459Szrj 		 section->name, bfd_errmsg (bfd_get_error ()));
2893*a9fa9459Szrj       return;
2894*a9fa9459Szrj     }
2895*a9fa9459Szrj 
2896*a9fa9459Szrj   width = 4;
2897*a9fa9459Szrj 
2898*a9fa9459Szrj   bfd_sprintf_vma (abfd, buf, start_offset + section->vma);
2899*a9fa9459Szrj   if (strlen (buf) >= sizeof (buf))
2900*a9fa9459Szrj     abort ();
2901*a9fa9459Szrj 
2902*a9fa9459Szrj   count = 0;
2903*a9fa9459Szrj   while (buf[count] == '0' && buf[count+1] != '\0')
2904*a9fa9459Szrj     count++;
2905*a9fa9459Szrj   count = strlen (buf) - count;
2906*a9fa9459Szrj   if (count > width)
2907*a9fa9459Szrj     width = count;
2908*a9fa9459Szrj 
2909*a9fa9459Szrj   bfd_sprintf_vma (abfd, buf, stop_offset + section->vma - 1);
2910*a9fa9459Szrj   if (strlen (buf) >= sizeof (buf))
2911*a9fa9459Szrj     abort ();
2912*a9fa9459Szrj 
2913*a9fa9459Szrj   count = 0;
2914*a9fa9459Szrj   while (buf[count] == '0' && buf[count+1] != '\0')
2915*a9fa9459Szrj     count++;
2916*a9fa9459Szrj   count = strlen (buf) - count;
2917*a9fa9459Szrj   if (count > width)
2918*a9fa9459Szrj     width = count;
2919*a9fa9459Szrj 
2920*a9fa9459Szrj   for (addr_offset = start_offset;
2921*a9fa9459Szrj        addr_offset < stop_offset; addr_offset += onaline / opb)
2922*a9fa9459Szrj     {
2923*a9fa9459Szrj       bfd_size_type j;
2924*a9fa9459Szrj 
2925*a9fa9459Szrj       bfd_sprintf_vma (abfd, buf, (addr_offset + section->vma));
2926*a9fa9459Szrj       count = strlen (buf);
2927*a9fa9459Szrj       if ((size_t) count >= sizeof (buf))
2928*a9fa9459Szrj 	abort ();
2929*a9fa9459Szrj 
2930*a9fa9459Szrj       putchar (' ');
2931*a9fa9459Szrj       while (count < width)
2932*a9fa9459Szrj 	{
2933*a9fa9459Szrj 	  putchar ('0');
2934*a9fa9459Szrj 	  count++;
2935*a9fa9459Szrj 	}
2936*a9fa9459Szrj       fputs (buf + count - width, stdout);
2937*a9fa9459Szrj       putchar (' ');
2938*a9fa9459Szrj 
2939*a9fa9459Szrj       for (j = addr_offset * opb;
2940*a9fa9459Szrj 	   j < addr_offset * opb + onaline; j++)
2941*a9fa9459Szrj 	{
2942*a9fa9459Szrj 	  if (j < stop_offset * opb)
2943*a9fa9459Szrj 	    printf ("%02x", (unsigned) (data[j]));
2944*a9fa9459Szrj 	  else
2945*a9fa9459Szrj 	    printf ("  ");
2946*a9fa9459Szrj 	  if ((j & 3) == 3)
2947*a9fa9459Szrj 	    printf (" ");
2948*a9fa9459Szrj 	}
2949*a9fa9459Szrj 
2950*a9fa9459Szrj       printf (" ");
2951*a9fa9459Szrj       for (j = addr_offset * opb;
2952*a9fa9459Szrj 	   j < addr_offset * opb + onaline; j++)
2953*a9fa9459Szrj 	{
2954*a9fa9459Szrj 	  if (j >= stop_offset * opb)
2955*a9fa9459Szrj 	    printf (" ");
2956*a9fa9459Szrj 	  else
2957*a9fa9459Szrj 	    printf ("%c", ISPRINT (data[j]) ? data[j] : '.');
2958*a9fa9459Szrj 	}
2959*a9fa9459Szrj       putchar ('\n');
2960*a9fa9459Szrj     }
2961*a9fa9459Szrj   free (data);
2962*a9fa9459Szrj }
2963*a9fa9459Szrj 
2964*a9fa9459Szrj /* Actually display the various requested regions.  */
2965*a9fa9459Szrj 
2966*a9fa9459Szrj static void
dump_data(bfd * abfd)2967*a9fa9459Szrj dump_data (bfd *abfd)
2968*a9fa9459Szrj {
2969*a9fa9459Szrj   bfd_map_over_sections (abfd, dump_section, NULL);
2970*a9fa9459Szrj }
2971*a9fa9459Szrj 
2972*a9fa9459Szrj /* Should perhaps share code and display with nm?  */
2973*a9fa9459Szrj 
2974*a9fa9459Szrj static void
dump_symbols(bfd * abfd ATTRIBUTE_UNUSED,bfd_boolean dynamic)2975*a9fa9459Szrj dump_symbols (bfd *abfd ATTRIBUTE_UNUSED, bfd_boolean dynamic)
2976*a9fa9459Szrj {
2977*a9fa9459Szrj   asymbol **current;
2978*a9fa9459Szrj   long max_count;
2979*a9fa9459Szrj   long count;
2980*a9fa9459Szrj 
2981*a9fa9459Szrj   if (dynamic)
2982*a9fa9459Szrj     {
2983*a9fa9459Szrj       current = dynsyms;
2984*a9fa9459Szrj       max_count = dynsymcount;
2985*a9fa9459Szrj       printf ("DYNAMIC SYMBOL TABLE:\n");
2986*a9fa9459Szrj     }
2987*a9fa9459Szrj   else
2988*a9fa9459Szrj     {
2989*a9fa9459Szrj       current = syms;
2990*a9fa9459Szrj       max_count = symcount;
2991*a9fa9459Szrj       printf ("SYMBOL TABLE:\n");
2992*a9fa9459Szrj     }
2993*a9fa9459Szrj 
2994*a9fa9459Szrj   if (max_count == 0)
2995*a9fa9459Szrj     printf (_("no symbols\n"));
2996*a9fa9459Szrj 
2997*a9fa9459Szrj   for (count = 0; count < max_count; count++)
2998*a9fa9459Szrj     {
2999*a9fa9459Szrj       bfd *cur_bfd;
3000*a9fa9459Szrj 
3001*a9fa9459Szrj       if (*current == NULL)
3002*a9fa9459Szrj 	printf (_("no information for symbol number %ld\n"), count);
3003*a9fa9459Szrj 
3004*a9fa9459Szrj       else if ((cur_bfd = bfd_asymbol_bfd (*current)) == NULL)
3005*a9fa9459Szrj 	printf (_("could not determine the type of symbol number %ld\n"),
3006*a9fa9459Szrj 		count);
3007*a9fa9459Szrj 
3008*a9fa9459Szrj       else if (process_section_p ((* current)->section)
3009*a9fa9459Szrj 	       && (dump_special_syms
3010*a9fa9459Szrj 		   || !bfd_is_target_special_symbol (cur_bfd, *current)))
3011*a9fa9459Szrj 	{
3012*a9fa9459Szrj 	  const char *name = (*current)->name;
3013*a9fa9459Szrj 
3014*a9fa9459Szrj 	  if (do_demangle && name != NULL && *name != '\0')
3015*a9fa9459Szrj 	    {
3016*a9fa9459Szrj 	      char *alloc;
3017*a9fa9459Szrj 
3018*a9fa9459Szrj 	      /* If we want to demangle the name, we demangle it
3019*a9fa9459Szrj 		 here, and temporarily clobber it while calling
3020*a9fa9459Szrj 		 bfd_print_symbol.  FIXME: This is a gross hack.  */
3021*a9fa9459Szrj 	      alloc = bfd_demangle (cur_bfd, name, DMGL_ANSI | DMGL_PARAMS);
3022*a9fa9459Szrj 	      if (alloc != NULL)
3023*a9fa9459Szrj 		(*current)->name = alloc;
3024*a9fa9459Szrj 	      bfd_print_symbol (cur_bfd, stdout, *current,
3025*a9fa9459Szrj 				bfd_print_symbol_all);
3026*a9fa9459Szrj 	      if (alloc != NULL)
3027*a9fa9459Szrj 		{
3028*a9fa9459Szrj 		  (*current)->name = name;
3029*a9fa9459Szrj 		  free (alloc);
3030*a9fa9459Szrj 		}
3031*a9fa9459Szrj 	    }
3032*a9fa9459Szrj 	  else
3033*a9fa9459Szrj 	    bfd_print_symbol (cur_bfd, stdout, *current,
3034*a9fa9459Szrj 			      bfd_print_symbol_all);
3035*a9fa9459Szrj 	  printf ("\n");
3036*a9fa9459Szrj 	}
3037*a9fa9459Szrj 
3038*a9fa9459Szrj       current++;
3039*a9fa9459Szrj     }
3040*a9fa9459Szrj   printf ("\n\n");
3041*a9fa9459Szrj }
3042*a9fa9459Szrj 
3043*a9fa9459Szrj static void
dump_reloc_set(bfd * abfd,asection * sec,arelent ** relpp,long relcount)3044*a9fa9459Szrj dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount)
3045*a9fa9459Szrj {
3046*a9fa9459Szrj   arelent **p;
3047*a9fa9459Szrj   char *last_filename, *last_functionname;
3048*a9fa9459Szrj   unsigned int last_line;
3049*a9fa9459Szrj   unsigned int last_discriminator;
3050*a9fa9459Szrj 
3051*a9fa9459Szrj   /* Get column headers lined up reasonably.  */
3052*a9fa9459Szrj   {
3053*a9fa9459Szrj     static int width;
3054*a9fa9459Szrj 
3055*a9fa9459Szrj     if (width == 0)
3056*a9fa9459Szrj       {
3057*a9fa9459Szrj 	char buf[30];
3058*a9fa9459Szrj 
3059*a9fa9459Szrj 	bfd_sprintf_vma (abfd, buf, (bfd_vma) -1);
3060*a9fa9459Szrj 	width = strlen (buf) - 7;
3061*a9fa9459Szrj       }
3062*a9fa9459Szrj     printf ("OFFSET %*s TYPE %*s VALUE \n", width, "", 12, "");
3063*a9fa9459Szrj   }
3064*a9fa9459Szrj 
3065*a9fa9459Szrj   last_filename = NULL;
3066*a9fa9459Szrj   last_functionname = NULL;
3067*a9fa9459Szrj   last_line = 0;
3068*a9fa9459Szrj   last_discriminator = 0;
3069*a9fa9459Szrj 
3070*a9fa9459Szrj   for (p = relpp; relcount && *p != NULL; p++, relcount--)
3071*a9fa9459Szrj     {
3072*a9fa9459Szrj       arelent *q = *p;
3073*a9fa9459Szrj       const char *filename, *functionname;
3074*a9fa9459Szrj       unsigned int linenumber;
3075*a9fa9459Szrj       unsigned int discriminator;
3076*a9fa9459Szrj       const char *sym_name;
3077*a9fa9459Szrj       const char *section_name;
3078*a9fa9459Szrj       bfd_vma addend2 = 0;
3079*a9fa9459Szrj 
3080*a9fa9459Szrj       if (start_address != (bfd_vma) -1
3081*a9fa9459Szrj 	  && q->address < start_address)
3082*a9fa9459Szrj 	continue;
3083*a9fa9459Szrj       if (stop_address != (bfd_vma) -1
3084*a9fa9459Szrj 	  && q->address > stop_address)
3085*a9fa9459Szrj 	continue;
3086*a9fa9459Szrj 
3087*a9fa9459Szrj       if (with_line_numbers
3088*a9fa9459Szrj 	  && sec != NULL
3089*a9fa9459Szrj 	  && bfd_find_nearest_line_discriminator (abfd, sec, syms, q->address,
3090*a9fa9459Szrj                                                   &filename, &functionname,
3091*a9fa9459Szrj                                                   &linenumber, &discriminator))
3092*a9fa9459Szrj 	{
3093*a9fa9459Szrj 	  if (functionname != NULL
3094*a9fa9459Szrj 	      && (last_functionname == NULL
3095*a9fa9459Szrj 		  || strcmp (functionname, last_functionname) != 0))
3096*a9fa9459Szrj 	    {
3097*a9fa9459Szrj 	      printf ("%s():\n", functionname);
3098*a9fa9459Szrj 	      if (last_functionname != NULL)
3099*a9fa9459Szrj 		free (last_functionname);
3100*a9fa9459Szrj 	      last_functionname = xstrdup (functionname);
3101*a9fa9459Szrj 	    }
3102*a9fa9459Szrj 
3103*a9fa9459Szrj 	  if (linenumber > 0
3104*a9fa9459Szrj 	      && (linenumber != last_line
3105*a9fa9459Szrj 		  || (filename != NULL
3106*a9fa9459Szrj 		      && last_filename != NULL
3107*a9fa9459Szrj 		      && filename_cmp (filename, last_filename) != 0)
3108*a9fa9459Szrj                   || (discriminator != last_discriminator)))
3109*a9fa9459Szrj 	    {
3110*a9fa9459Szrj               if (discriminator > 0)
3111*a9fa9459Szrj                 printf ("%s:%u\n", filename == NULL ? "???" : filename, linenumber);
3112*a9fa9459Szrj               else
3113*a9fa9459Szrj                 printf ("%s:%u (discriminator %u)\n", filename == NULL ? "???" : filename,
3114*a9fa9459Szrj                         linenumber, discriminator);
3115*a9fa9459Szrj 	      last_line = linenumber;
3116*a9fa9459Szrj 	      last_discriminator = discriminator;
3117*a9fa9459Szrj 	      if (last_filename != NULL)
3118*a9fa9459Szrj 		free (last_filename);
3119*a9fa9459Szrj 	      if (filename == NULL)
3120*a9fa9459Szrj 		last_filename = NULL;
3121*a9fa9459Szrj 	      else
3122*a9fa9459Szrj 		last_filename = xstrdup (filename);
3123*a9fa9459Szrj 	    }
3124*a9fa9459Szrj 	}
3125*a9fa9459Szrj 
3126*a9fa9459Szrj       if (q->sym_ptr_ptr && *q->sym_ptr_ptr)
3127*a9fa9459Szrj 	{
3128*a9fa9459Szrj 	  sym_name = (*(q->sym_ptr_ptr))->name;
3129*a9fa9459Szrj 	  section_name = (*(q->sym_ptr_ptr))->section->name;
3130*a9fa9459Szrj 	}
3131*a9fa9459Szrj       else
3132*a9fa9459Szrj 	{
3133*a9fa9459Szrj 	  sym_name = NULL;
3134*a9fa9459Szrj 	  section_name = NULL;
3135*a9fa9459Szrj 	}
3136*a9fa9459Szrj 
3137*a9fa9459Szrj       bfd_printf_vma (abfd, q->address);
3138*a9fa9459Szrj       if (q->howto == NULL)
3139*a9fa9459Szrj 	printf (" *unknown*         ");
3140*a9fa9459Szrj       else if (q->howto->name)
3141*a9fa9459Szrj 	{
3142*a9fa9459Szrj 	  const char *name = q->howto->name;
3143*a9fa9459Szrj 
3144*a9fa9459Szrj 	  /* R_SPARC_OLO10 relocations contain two addends.
3145*a9fa9459Szrj 	     But because 'arelent' lacks enough storage to
3146*a9fa9459Szrj 	     store them both, the 64-bit ELF Sparc backend
3147*a9fa9459Szrj 	     records this as two relocations.  One R_SPARC_LO10
3148*a9fa9459Szrj 	     and one R_SPARC_13, both pointing to the same
3149*a9fa9459Szrj 	     address.  This is merely so that we have some
3150*a9fa9459Szrj 	     place to store both addend fields.
3151*a9fa9459Szrj 
3152*a9fa9459Szrj 	     Undo this transformation, otherwise the output
3153*a9fa9459Szrj 	     will be confusing.  */
3154*a9fa9459Szrj 	  if (abfd->xvec->flavour == bfd_target_elf_flavour
3155*a9fa9459Szrj 	      && elf_tdata(abfd)->elf_header->e_machine == EM_SPARCV9
3156*a9fa9459Szrj 	      && relcount > 1
3157*a9fa9459Szrj 	      && !strcmp (q->howto->name, "R_SPARC_LO10"))
3158*a9fa9459Szrj 	    {
3159*a9fa9459Szrj 	      arelent *q2 = *(p + 1);
3160*a9fa9459Szrj 	      if (q2 != NULL
3161*a9fa9459Szrj 		  && q2->howto
3162*a9fa9459Szrj 		  && q->address == q2->address
3163*a9fa9459Szrj 		  && !strcmp (q2->howto->name, "R_SPARC_13"))
3164*a9fa9459Szrj 		{
3165*a9fa9459Szrj 		  name = "R_SPARC_OLO10";
3166*a9fa9459Szrj 		  addend2 = q2->addend;
3167*a9fa9459Szrj 		  p++;
3168*a9fa9459Szrj 		}
3169*a9fa9459Szrj 	    }
3170*a9fa9459Szrj 	  printf (" %-16s  ", name);
3171*a9fa9459Szrj 	}
3172*a9fa9459Szrj       else
3173*a9fa9459Szrj 	printf (" %-16d  ", q->howto->type);
3174*a9fa9459Szrj 
3175*a9fa9459Szrj       if (sym_name)
3176*a9fa9459Szrj 	{
3177*a9fa9459Szrj 	  objdump_print_symname (abfd, NULL, *q->sym_ptr_ptr);
3178*a9fa9459Szrj 	}
3179*a9fa9459Szrj       else
3180*a9fa9459Szrj 	{
3181*a9fa9459Szrj 	  if (section_name == NULL)
3182*a9fa9459Szrj 	    section_name = "*unknown*";
3183*a9fa9459Szrj 	  printf ("[%s]", section_name);
3184*a9fa9459Szrj 	}
3185*a9fa9459Szrj 
3186*a9fa9459Szrj       if (q->addend)
3187*a9fa9459Szrj 	{
3188*a9fa9459Szrj 	  bfd_signed_vma addend = q->addend;
3189*a9fa9459Szrj 	  if (addend < 0)
3190*a9fa9459Szrj 	    {
3191*a9fa9459Szrj 	      printf ("-0x");
3192*a9fa9459Szrj 	      addend = -addend;
3193*a9fa9459Szrj 	    }
3194*a9fa9459Szrj 	  else
3195*a9fa9459Szrj 	    printf ("+0x");
3196*a9fa9459Szrj 	  bfd_printf_vma (abfd, addend);
3197*a9fa9459Szrj 	}
3198*a9fa9459Szrj       if (addend2)
3199*a9fa9459Szrj 	{
3200*a9fa9459Szrj 	  printf ("+0x");
3201*a9fa9459Szrj 	  bfd_printf_vma (abfd, addend2);
3202*a9fa9459Szrj 	}
3203*a9fa9459Szrj 
3204*a9fa9459Szrj       printf ("\n");
3205*a9fa9459Szrj     }
3206*a9fa9459Szrj 
3207*a9fa9459Szrj   if (last_filename != NULL)
3208*a9fa9459Szrj     free (last_filename);
3209*a9fa9459Szrj   if (last_functionname != NULL)
3210*a9fa9459Szrj     free (last_functionname);
3211*a9fa9459Szrj }
3212*a9fa9459Szrj 
3213*a9fa9459Szrj static void
dump_relocs_in_section(bfd * abfd,asection * section,void * dummy ATTRIBUTE_UNUSED)3214*a9fa9459Szrj dump_relocs_in_section (bfd *abfd,
3215*a9fa9459Szrj 			asection *section,
3216*a9fa9459Szrj 			void *dummy ATTRIBUTE_UNUSED)
3217*a9fa9459Szrj {
3218*a9fa9459Szrj   arelent **relpp;
3219*a9fa9459Szrj   long relcount;
3220*a9fa9459Szrj   long relsize;
3221*a9fa9459Szrj 
3222*a9fa9459Szrj   if (   bfd_is_abs_section (section)
3223*a9fa9459Szrj       || bfd_is_und_section (section)
3224*a9fa9459Szrj       || bfd_is_com_section (section)
3225*a9fa9459Szrj       || (! process_section_p (section))
3226*a9fa9459Szrj       || ((section->flags & SEC_RELOC) == 0))
3227*a9fa9459Szrj     return;
3228*a9fa9459Szrj 
3229*a9fa9459Szrj   relsize = bfd_get_reloc_upper_bound (abfd, section);
3230*a9fa9459Szrj   if (relsize < 0)
3231*a9fa9459Szrj     bfd_fatal (bfd_get_filename (abfd));
3232*a9fa9459Szrj 
3233*a9fa9459Szrj   printf ("RELOCATION RECORDS FOR [%s]:", section->name);
3234*a9fa9459Szrj 
3235*a9fa9459Szrj   if (relsize == 0)
3236*a9fa9459Szrj     {
3237*a9fa9459Szrj       printf (" (none)\n\n");
3238*a9fa9459Szrj       return;
3239*a9fa9459Szrj     }
3240*a9fa9459Szrj 
3241*a9fa9459Szrj   relpp = (arelent **) xmalloc (relsize);
3242*a9fa9459Szrj   relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);
3243*a9fa9459Szrj 
3244*a9fa9459Szrj   if (relcount < 0)
3245*a9fa9459Szrj     {
3246*a9fa9459Szrj       printf ("\n");
3247*a9fa9459Szrj       non_fatal (_("failed to read relocs in: %s"), bfd_get_filename (abfd));
3248*a9fa9459Szrj       bfd_fatal (_("error message was"));
3249*a9fa9459Szrj     }
3250*a9fa9459Szrj   else if (relcount == 0)
3251*a9fa9459Szrj     printf (" (none)\n\n");
3252*a9fa9459Szrj   else
3253*a9fa9459Szrj     {
3254*a9fa9459Szrj       printf ("\n");
3255*a9fa9459Szrj       dump_reloc_set (abfd, section, relpp, relcount);
3256*a9fa9459Szrj       printf ("\n\n");
3257*a9fa9459Szrj     }
3258*a9fa9459Szrj   free (relpp);
3259*a9fa9459Szrj }
3260*a9fa9459Szrj 
3261*a9fa9459Szrj static void
dump_relocs(bfd * abfd)3262*a9fa9459Szrj dump_relocs (bfd *abfd)
3263*a9fa9459Szrj {
3264*a9fa9459Szrj   bfd_map_over_sections (abfd, dump_relocs_in_section, NULL);
3265*a9fa9459Szrj }
3266*a9fa9459Szrj 
3267*a9fa9459Szrj static void
dump_dynamic_relocs(bfd * abfd)3268*a9fa9459Szrj dump_dynamic_relocs (bfd *abfd)
3269*a9fa9459Szrj {
3270*a9fa9459Szrj   long relsize;
3271*a9fa9459Szrj   arelent **relpp;
3272*a9fa9459Szrj   long relcount;
3273*a9fa9459Szrj 
3274*a9fa9459Szrj   relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
3275*a9fa9459Szrj   if (relsize < 0)
3276*a9fa9459Szrj     bfd_fatal (bfd_get_filename (abfd));
3277*a9fa9459Szrj 
3278*a9fa9459Szrj   printf ("DYNAMIC RELOCATION RECORDS");
3279*a9fa9459Szrj 
3280*a9fa9459Szrj   if (relsize == 0)
3281*a9fa9459Szrj     printf (" (none)\n\n");
3282*a9fa9459Szrj   else
3283*a9fa9459Szrj     {
3284*a9fa9459Szrj       relpp = (arelent **) xmalloc (relsize);
3285*a9fa9459Szrj       relcount = bfd_canonicalize_dynamic_reloc (abfd, relpp, dynsyms);
3286*a9fa9459Szrj 
3287*a9fa9459Szrj       if (relcount < 0)
3288*a9fa9459Szrj 	bfd_fatal (bfd_get_filename (abfd));
3289*a9fa9459Szrj       else if (relcount == 0)
3290*a9fa9459Szrj 	printf (" (none)\n\n");
3291*a9fa9459Szrj       else
3292*a9fa9459Szrj 	{
3293*a9fa9459Szrj 	  printf ("\n");
3294*a9fa9459Szrj 	  dump_reloc_set (abfd, NULL, relpp, relcount);
3295*a9fa9459Szrj 	  printf ("\n\n");
3296*a9fa9459Szrj 	}
3297*a9fa9459Szrj       free (relpp);
3298*a9fa9459Szrj     }
3299*a9fa9459Szrj }
3300*a9fa9459Szrj 
3301*a9fa9459Szrj /* Creates a table of paths, to search for source files.  */
3302*a9fa9459Szrj 
3303*a9fa9459Szrj static void
add_include_path(const char * path)3304*a9fa9459Szrj add_include_path (const char *path)
3305*a9fa9459Szrj {
3306*a9fa9459Szrj   if (path[0] == 0)
3307*a9fa9459Szrj     return;
3308*a9fa9459Szrj   include_path_count++;
3309*a9fa9459Szrj   include_paths = (const char **)
3310*a9fa9459Szrj       xrealloc (include_paths, include_path_count * sizeof (*include_paths));
3311*a9fa9459Szrj #ifdef HAVE_DOS_BASED_FILE_SYSTEM
3312*a9fa9459Szrj   if (path[1] == ':' && path[2] == 0)
3313*a9fa9459Szrj     path = concat (path, ".", (const char *) 0);
3314*a9fa9459Szrj #endif
3315*a9fa9459Szrj   include_paths[include_path_count - 1] = path;
3316*a9fa9459Szrj }
3317*a9fa9459Szrj 
3318*a9fa9459Szrj static void
adjust_addresses(bfd * abfd ATTRIBUTE_UNUSED,asection * section,void * arg)3319*a9fa9459Szrj adjust_addresses (bfd *abfd ATTRIBUTE_UNUSED,
3320*a9fa9459Szrj 		  asection *section,
3321*a9fa9459Szrj 		  void *arg)
3322*a9fa9459Szrj {
3323*a9fa9459Szrj   if ((section->flags & SEC_DEBUGGING) == 0)
3324*a9fa9459Szrj     {
3325*a9fa9459Szrj       bfd_boolean *has_reloc_p = (bfd_boolean *) arg;
3326*a9fa9459Szrj       section->vma += adjust_section_vma;
3327*a9fa9459Szrj       if (*has_reloc_p)
3328*a9fa9459Szrj 	section->lma += adjust_section_vma;
3329*a9fa9459Szrj     }
3330*a9fa9459Szrj }
3331*a9fa9459Szrj 
3332*a9fa9459Szrj /* Dump selected contents of ABFD.  */
3333*a9fa9459Szrj 
3334*a9fa9459Szrj static void
dump_bfd(bfd * abfd)3335*a9fa9459Szrj dump_bfd (bfd *abfd)
3336*a9fa9459Szrj {
3337*a9fa9459Szrj   /* If we are adjusting section VMA's, change them all now.  Changing
3338*a9fa9459Szrj      the BFD information is a hack.  However, we must do it, or
3339*a9fa9459Szrj      bfd_find_nearest_line will not do the right thing.  */
3340*a9fa9459Szrj   if (adjust_section_vma != 0)
3341*a9fa9459Szrj     {
3342*a9fa9459Szrj       bfd_boolean has_reloc = (abfd->flags & HAS_RELOC);
3343*a9fa9459Szrj       bfd_map_over_sections (abfd, adjust_addresses, &has_reloc);
3344*a9fa9459Szrj     }
3345*a9fa9459Szrj 
3346*a9fa9459Szrj   if (! dump_debugging_tags && ! suppress_bfd_header)
3347*a9fa9459Szrj     printf (_("\n%s:     file format %s\n"), bfd_get_filename (abfd),
3348*a9fa9459Szrj 	    abfd->xvec->name);
3349*a9fa9459Szrj   if (dump_ar_hdrs)
3350*a9fa9459Szrj     print_arelt_descr (stdout, abfd, TRUE);
3351*a9fa9459Szrj   if (dump_file_header)
3352*a9fa9459Szrj     dump_bfd_header (abfd);
3353*a9fa9459Szrj   if (dump_private_headers)
3354*a9fa9459Szrj     dump_bfd_private_header (abfd);
3355*a9fa9459Szrj   if (dump_private_options != NULL)
3356*a9fa9459Szrj     dump_target_specific (abfd);
3357*a9fa9459Szrj   if (! dump_debugging_tags && ! suppress_bfd_header)
3358*a9fa9459Szrj     putchar ('\n');
3359*a9fa9459Szrj 
3360*a9fa9459Szrj   if (dump_symtab
3361*a9fa9459Szrj       || dump_reloc_info
3362*a9fa9459Szrj       || disassemble
3363*a9fa9459Szrj       || dump_debugging
3364*a9fa9459Szrj       || dump_dwarf_section_info)
3365*a9fa9459Szrj     syms = slurp_symtab (abfd);
3366*a9fa9459Szrj 
3367*a9fa9459Szrj   if (dump_section_headers)
3368*a9fa9459Szrj     dump_headers (abfd);
3369*a9fa9459Szrj 
3370*a9fa9459Szrj   if (dump_dynamic_symtab || dump_dynamic_reloc_info
3371*a9fa9459Szrj       || (disassemble && bfd_get_dynamic_symtab_upper_bound (abfd) > 0))
3372*a9fa9459Szrj     dynsyms = slurp_dynamic_symtab (abfd);
3373*a9fa9459Szrj   if (disassemble)
3374*a9fa9459Szrj     {
3375*a9fa9459Szrj       synthcount = bfd_get_synthetic_symtab (abfd, symcount, syms,
3376*a9fa9459Szrj 					     dynsymcount, dynsyms, &synthsyms);
3377*a9fa9459Szrj       if (synthcount < 0)
3378*a9fa9459Szrj 	synthcount = 0;
3379*a9fa9459Szrj     }
3380*a9fa9459Szrj 
3381*a9fa9459Szrj   if (dump_symtab)
3382*a9fa9459Szrj     dump_symbols (abfd, FALSE);
3383*a9fa9459Szrj   if (dump_dynamic_symtab)
3384*a9fa9459Szrj     dump_symbols (abfd, TRUE);
3385*a9fa9459Szrj   if (dump_dwarf_section_info)
3386*a9fa9459Szrj     dump_dwarf (abfd);
3387*a9fa9459Szrj   if (dump_stab_section_info)
3388*a9fa9459Szrj     dump_stabs (abfd);
3389*a9fa9459Szrj   if (dump_reloc_info && ! disassemble)
3390*a9fa9459Szrj     dump_relocs (abfd);
3391*a9fa9459Szrj   if (dump_dynamic_reloc_info && ! disassemble)
3392*a9fa9459Szrj     dump_dynamic_relocs (abfd);
3393*a9fa9459Szrj   if (dump_section_contents)
3394*a9fa9459Szrj     dump_data (abfd);
3395*a9fa9459Szrj   if (disassemble)
3396*a9fa9459Szrj     disassemble_data (abfd);
3397*a9fa9459Szrj 
3398*a9fa9459Szrj   if (dump_debugging)
3399*a9fa9459Szrj     {
3400*a9fa9459Szrj       void *dhandle;
3401*a9fa9459Szrj 
3402*a9fa9459Szrj       dhandle = read_debugging_info (abfd, syms, symcount, TRUE);
3403*a9fa9459Szrj       if (dhandle != NULL)
3404*a9fa9459Szrj 	{
3405*a9fa9459Szrj 	  if (!print_debugging_info (stdout, dhandle, abfd, syms,
3406*a9fa9459Szrj 				     bfd_demangle,
3407*a9fa9459Szrj 				     dump_debugging_tags ? TRUE : FALSE))
3408*a9fa9459Szrj 	    {
3409*a9fa9459Szrj 	      non_fatal (_("%s: printing debugging information failed"),
3410*a9fa9459Szrj 			 bfd_get_filename (abfd));
3411*a9fa9459Szrj 	      exit_status = 1;
3412*a9fa9459Szrj 	    }
3413*a9fa9459Szrj 	}
3414*a9fa9459Szrj       /* PR 6483: If there was no STABS or IEEE debug
3415*a9fa9459Szrj 	 info in the file, try DWARF instead.  */
3416*a9fa9459Szrj       else if (! dump_dwarf_section_info)
3417*a9fa9459Szrj 	{
3418*a9fa9459Szrj 	  dwarf_select_sections_all ();
3419*a9fa9459Szrj 	  dump_dwarf (abfd);
3420*a9fa9459Szrj 	}
3421*a9fa9459Szrj     }
3422*a9fa9459Szrj 
3423*a9fa9459Szrj   if (syms)
3424*a9fa9459Szrj     {
3425*a9fa9459Szrj       free (syms);
3426*a9fa9459Szrj       syms = NULL;
3427*a9fa9459Szrj     }
3428*a9fa9459Szrj 
3429*a9fa9459Szrj   if (dynsyms)
3430*a9fa9459Szrj     {
3431*a9fa9459Szrj       free (dynsyms);
3432*a9fa9459Szrj       dynsyms = NULL;
3433*a9fa9459Szrj     }
3434*a9fa9459Szrj 
3435*a9fa9459Szrj   if (synthsyms)
3436*a9fa9459Szrj     {
3437*a9fa9459Szrj       free (synthsyms);
3438*a9fa9459Szrj       synthsyms = NULL;
3439*a9fa9459Szrj     }
3440*a9fa9459Szrj 
3441*a9fa9459Szrj   symcount = 0;
3442*a9fa9459Szrj   dynsymcount = 0;
3443*a9fa9459Szrj   synthcount = 0;
3444*a9fa9459Szrj }
3445*a9fa9459Szrj 
3446*a9fa9459Szrj static void
display_object_bfd(bfd * abfd)3447*a9fa9459Szrj display_object_bfd (bfd *abfd)
3448*a9fa9459Szrj {
3449*a9fa9459Szrj   char **matching;
3450*a9fa9459Szrj 
3451*a9fa9459Szrj   if (bfd_check_format_matches (abfd, bfd_object, &matching))
3452*a9fa9459Szrj     {
3453*a9fa9459Szrj       dump_bfd (abfd);
3454*a9fa9459Szrj       return;
3455*a9fa9459Szrj     }
3456*a9fa9459Szrj 
3457*a9fa9459Szrj   if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
3458*a9fa9459Szrj     {
3459*a9fa9459Szrj       nonfatal (bfd_get_filename (abfd));
3460*a9fa9459Szrj       list_matching_formats (matching);
3461*a9fa9459Szrj       free (matching);
3462*a9fa9459Szrj       return;
3463*a9fa9459Szrj     }
3464*a9fa9459Szrj 
3465*a9fa9459Szrj   if (bfd_get_error () != bfd_error_file_not_recognized)
3466*a9fa9459Szrj     {
3467*a9fa9459Szrj       nonfatal (bfd_get_filename (abfd));
3468*a9fa9459Szrj       return;
3469*a9fa9459Szrj     }
3470*a9fa9459Szrj 
3471*a9fa9459Szrj   if (bfd_check_format_matches (abfd, bfd_core, &matching))
3472*a9fa9459Szrj     {
3473*a9fa9459Szrj       dump_bfd (abfd);
3474*a9fa9459Szrj       return;
3475*a9fa9459Szrj     }
3476*a9fa9459Szrj 
3477*a9fa9459Szrj   nonfatal (bfd_get_filename (abfd));
3478*a9fa9459Szrj 
3479*a9fa9459Szrj   if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
3480*a9fa9459Szrj     {
3481*a9fa9459Szrj       list_matching_formats (matching);
3482*a9fa9459Szrj       free (matching);
3483*a9fa9459Szrj     }
3484*a9fa9459Szrj }
3485*a9fa9459Szrj 
3486*a9fa9459Szrj static void
display_any_bfd(bfd * file,int level)3487*a9fa9459Szrj display_any_bfd (bfd *file, int level)
3488*a9fa9459Szrj {
3489*a9fa9459Szrj   /* Decompress sections unless dumping the section contents.  */
3490*a9fa9459Szrj   if (!dump_section_contents)
3491*a9fa9459Szrj     file->flags |= BFD_DECOMPRESS;
3492*a9fa9459Szrj 
3493*a9fa9459Szrj   /* If the file is an archive, process all of its elements.  */
3494*a9fa9459Szrj   if (bfd_check_format (file, bfd_archive))
3495*a9fa9459Szrj     {
3496*a9fa9459Szrj       bfd *arfile = NULL;
3497*a9fa9459Szrj       bfd *last_arfile = NULL;
3498*a9fa9459Szrj 
3499*a9fa9459Szrj       if (level == 0)
3500*a9fa9459Szrj         printf (_("In archive %s:\n"), bfd_get_filename (file));
3501*a9fa9459Szrj       else if (level > 100)
3502*a9fa9459Szrj 	{
3503*a9fa9459Szrj 	  /* Prevent corrupted files from spinning us into an
3504*a9fa9459Szrj 	     infinite loop.  100 is an arbitrary heuristic.  */
3505*a9fa9459Szrj 	  fatal (_("Archive nesting is too deep"));
3506*a9fa9459Szrj 	  return;
3507*a9fa9459Szrj 	}
3508*a9fa9459Szrj       else
3509*a9fa9459Szrj         printf (_("In nested archive %s:\n"), bfd_get_filename (file));
3510*a9fa9459Szrj 
3511*a9fa9459Szrj       for (;;)
3512*a9fa9459Szrj 	{
3513*a9fa9459Szrj 	  bfd_set_error (bfd_error_no_error);
3514*a9fa9459Szrj 
3515*a9fa9459Szrj 	  arfile = bfd_openr_next_archived_file (file, arfile);
3516*a9fa9459Szrj 	  if (arfile == NULL)
3517*a9fa9459Szrj 	    {
3518*a9fa9459Szrj 	      if (bfd_get_error () != bfd_error_no_more_archived_files)
3519*a9fa9459Szrj 		nonfatal (bfd_get_filename (file));
3520*a9fa9459Szrj 	      break;
3521*a9fa9459Szrj 	    }
3522*a9fa9459Szrj 
3523*a9fa9459Szrj 	  display_any_bfd (arfile, level + 1);
3524*a9fa9459Szrj 
3525*a9fa9459Szrj 	  if (last_arfile != NULL)
3526*a9fa9459Szrj 	    {
3527*a9fa9459Szrj 	      bfd_close (last_arfile);
3528*a9fa9459Szrj 	      /* PR 17512: file: ac585d01.  */
3529*a9fa9459Szrj 	      if (arfile == last_arfile)
3530*a9fa9459Szrj 		{
3531*a9fa9459Szrj 		  last_arfile = NULL;
3532*a9fa9459Szrj 		  break;
3533*a9fa9459Szrj 		}
3534*a9fa9459Szrj 	    }
3535*a9fa9459Szrj 	  last_arfile = arfile;
3536*a9fa9459Szrj 	}
3537*a9fa9459Szrj 
3538*a9fa9459Szrj       if (last_arfile != NULL)
3539*a9fa9459Szrj 	bfd_close (last_arfile);
3540*a9fa9459Szrj     }
3541*a9fa9459Szrj   else
3542*a9fa9459Szrj     display_object_bfd (file);
3543*a9fa9459Szrj }
3544*a9fa9459Szrj 
3545*a9fa9459Szrj static void
display_file(char * filename,char * target)3546*a9fa9459Szrj display_file (char *filename, char *target)
3547*a9fa9459Szrj {
3548*a9fa9459Szrj   bfd *file;
3549*a9fa9459Szrj 
3550*a9fa9459Szrj   if (get_file_size (filename) < 1)
3551*a9fa9459Szrj     {
3552*a9fa9459Szrj       exit_status = 1;
3553*a9fa9459Szrj       return;
3554*a9fa9459Szrj     }
3555*a9fa9459Szrj 
3556*a9fa9459Szrj   file = bfd_openr (filename, target);
3557*a9fa9459Szrj   if (file == NULL)
3558*a9fa9459Szrj     {
3559*a9fa9459Szrj       nonfatal (filename);
3560*a9fa9459Szrj       return;
3561*a9fa9459Szrj     }
3562*a9fa9459Szrj 
3563*a9fa9459Szrj   display_any_bfd (file, 0);
3564*a9fa9459Szrj 
3565*a9fa9459Szrj   bfd_close (file);
3566*a9fa9459Szrj }
3567*a9fa9459Szrj 
3568*a9fa9459Szrj int
main(int argc,char ** argv)3569*a9fa9459Szrj main (int argc, char **argv)
3570*a9fa9459Szrj {
3571*a9fa9459Szrj   int c;
3572*a9fa9459Szrj   char *target = default_target;
3573*a9fa9459Szrj   bfd_boolean seenflag = FALSE;
3574*a9fa9459Szrj 
3575*a9fa9459Szrj #if defined (HAVE_SETLOCALE)
3576*a9fa9459Szrj #if defined (HAVE_LC_MESSAGES)
3577*a9fa9459Szrj   setlocale (LC_MESSAGES, "");
3578*a9fa9459Szrj #endif
3579*a9fa9459Szrj   setlocale (LC_CTYPE, "");
3580*a9fa9459Szrj #endif
3581*a9fa9459Szrj 
3582*a9fa9459Szrj   bindtextdomain (PACKAGE, LOCALEDIR);
3583*a9fa9459Szrj   textdomain (PACKAGE);
3584*a9fa9459Szrj 
3585*a9fa9459Szrj   program_name = *argv;
3586*a9fa9459Szrj   xmalloc_set_program_name (program_name);
3587*a9fa9459Szrj   bfd_set_error_program_name (program_name);
3588*a9fa9459Szrj 
3589*a9fa9459Szrj   START_PROGRESS (program_name, 0);
3590*a9fa9459Szrj 
3591*a9fa9459Szrj   expandargv (&argc, &argv);
3592*a9fa9459Szrj 
3593*a9fa9459Szrj   bfd_init ();
3594*a9fa9459Szrj   set_default_bfd_target ();
3595*a9fa9459Szrj 
3596*a9fa9459Szrj   while ((c = getopt_long (argc, argv,
3597*a9fa9459Szrj 			   "pP:ib:m:M:VvCdDlfFaHhrRtTxsSI:j:wE:zgeGW::",
3598*a9fa9459Szrj 			   long_options, (int *) 0))
3599*a9fa9459Szrj 	 != EOF)
3600*a9fa9459Szrj     {
3601*a9fa9459Szrj       switch (c)
3602*a9fa9459Szrj 	{
3603*a9fa9459Szrj 	case 0:
3604*a9fa9459Szrj 	  break;		/* We've been given a long option.  */
3605*a9fa9459Szrj 	case 'm':
3606*a9fa9459Szrj 	  machine = optarg;
3607*a9fa9459Szrj 	  break;
3608*a9fa9459Szrj 	case 'M':
3609*a9fa9459Szrj 	  if (disassembler_options)
3610*a9fa9459Szrj 	    /* Ignore potential memory leak for now.  */
3611*a9fa9459Szrj 	    disassembler_options = concat (disassembler_options, ",",
3612*a9fa9459Szrj 					   optarg, (const char *) NULL);
3613*a9fa9459Szrj 	  else
3614*a9fa9459Szrj 	    disassembler_options = optarg;
3615*a9fa9459Szrj 	  break;
3616*a9fa9459Szrj 	case 'j':
3617*a9fa9459Szrj 	  add_only (optarg);
3618*a9fa9459Szrj 	  break;
3619*a9fa9459Szrj 	case 'F':
3620*a9fa9459Szrj 	  display_file_offsets = TRUE;
3621*a9fa9459Szrj 	  break;
3622*a9fa9459Szrj 	case 'l':
3623*a9fa9459Szrj 	  with_line_numbers = TRUE;
3624*a9fa9459Szrj 	  break;
3625*a9fa9459Szrj 	case 'b':
3626*a9fa9459Szrj 	  target = optarg;
3627*a9fa9459Szrj 	  break;
3628*a9fa9459Szrj 	case 'C':
3629*a9fa9459Szrj 	  do_demangle = TRUE;
3630*a9fa9459Szrj 	  if (optarg != NULL)
3631*a9fa9459Szrj 	    {
3632*a9fa9459Szrj 	      enum demangling_styles style;
3633*a9fa9459Szrj 
3634*a9fa9459Szrj 	      style = cplus_demangle_name_to_style (optarg);
3635*a9fa9459Szrj 	      if (style == unknown_demangling)
3636*a9fa9459Szrj 		fatal (_("unknown demangling style `%s'"),
3637*a9fa9459Szrj 		       optarg);
3638*a9fa9459Szrj 
3639*a9fa9459Szrj 	      cplus_demangle_set_style (style);
3640*a9fa9459Szrj 	    }
3641*a9fa9459Szrj 	  break;
3642*a9fa9459Szrj 	case 'w':
3643*a9fa9459Szrj 	  wide_output = TRUE;
3644*a9fa9459Szrj 	  break;
3645*a9fa9459Szrj 	case OPTION_ADJUST_VMA:
3646*a9fa9459Szrj 	  adjust_section_vma = parse_vma (optarg, "--adjust-vma");
3647*a9fa9459Szrj 	  break;
3648*a9fa9459Szrj 	case OPTION_START_ADDRESS:
3649*a9fa9459Szrj 	  start_address = parse_vma (optarg, "--start-address");
3650*a9fa9459Szrj 	  if ((stop_address != (bfd_vma) -1) && stop_address <= start_address)
3651*a9fa9459Szrj 	    fatal (_("error: the start address should be before the end address"));
3652*a9fa9459Szrj 	  break;
3653*a9fa9459Szrj 	case OPTION_STOP_ADDRESS:
3654*a9fa9459Szrj 	  stop_address = parse_vma (optarg, "--stop-address");
3655*a9fa9459Szrj 	  if ((start_address != (bfd_vma) -1) && stop_address <= start_address)
3656*a9fa9459Szrj 	    fatal (_("error: the stop address should be after the start address"));
3657*a9fa9459Szrj 	  break;
3658*a9fa9459Szrj 	case OPTION_PREFIX:
3659*a9fa9459Szrj 	  prefix = optarg;
3660*a9fa9459Szrj 	  prefix_length = strlen (prefix);
3661*a9fa9459Szrj 	  /* Remove an unnecessary trailing '/' */
3662*a9fa9459Szrj 	  while (IS_DIR_SEPARATOR (prefix[prefix_length - 1]))
3663*a9fa9459Szrj 	    prefix_length--;
3664*a9fa9459Szrj 	  break;
3665*a9fa9459Szrj 	case OPTION_PREFIX_STRIP:
3666*a9fa9459Szrj 	  prefix_strip = atoi (optarg);
3667*a9fa9459Szrj 	  if (prefix_strip < 0)
3668*a9fa9459Szrj 	    fatal (_("error: prefix strip must be non-negative"));
3669*a9fa9459Szrj 	  break;
3670*a9fa9459Szrj 	case OPTION_INSN_WIDTH:
3671*a9fa9459Szrj 	  insn_width = strtoul (optarg, NULL, 0);
3672*a9fa9459Szrj 	  if (insn_width <= 0)
3673*a9fa9459Szrj 	    fatal (_("error: instruction width must be positive"));
3674*a9fa9459Szrj 	  break;
3675*a9fa9459Szrj 	case 'E':
3676*a9fa9459Szrj 	  if (strcmp (optarg, "B") == 0)
3677*a9fa9459Szrj 	    endian = BFD_ENDIAN_BIG;
3678*a9fa9459Szrj 	  else if (strcmp (optarg, "L") == 0)
3679*a9fa9459Szrj 	    endian = BFD_ENDIAN_LITTLE;
3680*a9fa9459Szrj 	  else
3681*a9fa9459Szrj 	    {
3682*a9fa9459Szrj 	      nonfatal (_("unrecognized -E option"));
3683*a9fa9459Szrj 	      usage (stderr, 1);
3684*a9fa9459Szrj 	    }
3685*a9fa9459Szrj 	  break;
3686*a9fa9459Szrj 	case OPTION_ENDIAN:
3687*a9fa9459Szrj 	  if (strncmp (optarg, "big", strlen (optarg)) == 0)
3688*a9fa9459Szrj 	    endian = BFD_ENDIAN_BIG;
3689*a9fa9459Szrj 	  else if (strncmp (optarg, "little", strlen (optarg)) == 0)
3690*a9fa9459Szrj 	    endian = BFD_ENDIAN_LITTLE;
3691*a9fa9459Szrj 	  else
3692*a9fa9459Szrj 	    {
3693*a9fa9459Szrj 	      non_fatal (_("unrecognized --endian type `%s'"), optarg);
3694*a9fa9459Szrj 	      exit_status = 1;
3695*a9fa9459Szrj 	      usage (stderr, 1);
3696*a9fa9459Szrj 	    }
3697*a9fa9459Szrj 	  break;
3698*a9fa9459Szrj 
3699*a9fa9459Szrj 	case 'f':
3700*a9fa9459Szrj 	  dump_file_header = TRUE;
3701*a9fa9459Szrj 	  seenflag = TRUE;
3702*a9fa9459Szrj 	  break;
3703*a9fa9459Szrj 	case 'i':
3704*a9fa9459Szrj 	  formats_info = TRUE;
3705*a9fa9459Szrj 	  seenflag = TRUE;
3706*a9fa9459Szrj 	  break;
3707*a9fa9459Szrj 	case 'I':
3708*a9fa9459Szrj 	  add_include_path (optarg);
3709*a9fa9459Szrj 	  break;
3710*a9fa9459Szrj 	case 'p':
3711*a9fa9459Szrj 	  dump_private_headers = TRUE;
3712*a9fa9459Szrj 	  seenflag = TRUE;
3713*a9fa9459Szrj 	  break;
3714*a9fa9459Szrj 	case 'P':
3715*a9fa9459Szrj 	  dump_private_options = optarg;
3716*a9fa9459Szrj 	  seenflag = TRUE;
3717*a9fa9459Szrj 	  break;
3718*a9fa9459Szrj 	case 'x':
3719*a9fa9459Szrj 	  dump_private_headers = TRUE;
3720*a9fa9459Szrj 	  dump_symtab = TRUE;
3721*a9fa9459Szrj 	  dump_reloc_info = TRUE;
3722*a9fa9459Szrj 	  dump_file_header = TRUE;
3723*a9fa9459Szrj 	  dump_ar_hdrs = TRUE;
3724*a9fa9459Szrj 	  dump_section_headers = TRUE;
3725*a9fa9459Szrj 	  seenflag = TRUE;
3726*a9fa9459Szrj 	  break;
3727*a9fa9459Szrj 	case 't':
3728*a9fa9459Szrj 	  dump_symtab = TRUE;
3729*a9fa9459Szrj 	  seenflag = TRUE;
3730*a9fa9459Szrj 	  break;
3731*a9fa9459Szrj 	case 'T':
3732*a9fa9459Szrj 	  dump_dynamic_symtab = TRUE;
3733*a9fa9459Szrj 	  seenflag = TRUE;
3734*a9fa9459Szrj 	  break;
3735*a9fa9459Szrj 	case 'd':
3736*a9fa9459Szrj 	  disassemble = TRUE;
3737*a9fa9459Szrj 	  seenflag = TRUE;
3738*a9fa9459Szrj 	  break;
3739*a9fa9459Szrj 	case 'z':
3740*a9fa9459Szrj 	  disassemble_zeroes = TRUE;
3741*a9fa9459Szrj 	  break;
3742*a9fa9459Szrj 	case 'D':
3743*a9fa9459Szrj 	  disassemble = TRUE;
3744*a9fa9459Szrj 	  disassemble_all = TRUE;
3745*a9fa9459Szrj 	  seenflag = TRUE;
3746*a9fa9459Szrj 	  break;
3747*a9fa9459Szrj 	case 'S':
3748*a9fa9459Szrj 	  disassemble = TRUE;
3749*a9fa9459Szrj 	  with_source_code = TRUE;
3750*a9fa9459Szrj 	  seenflag = TRUE;
3751*a9fa9459Szrj 	  break;
3752*a9fa9459Szrj 	case 'g':
3753*a9fa9459Szrj 	  dump_debugging = 1;
3754*a9fa9459Szrj 	  seenflag = TRUE;
3755*a9fa9459Szrj 	  break;
3756*a9fa9459Szrj 	case 'e':
3757*a9fa9459Szrj 	  dump_debugging = 1;
3758*a9fa9459Szrj 	  dump_debugging_tags = 1;
3759*a9fa9459Szrj 	  do_demangle = TRUE;
3760*a9fa9459Szrj 	  seenflag = TRUE;
3761*a9fa9459Szrj 	  break;
3762*a9fa9459Szrj 	case 'W':
3763*a9fa9459Szrj 	  dump_dwarf_section_info = TRUE;
3764*a9fa9459Szrj 	  seenflag = TRUE;
3765*a9fa9459Szrj 	  if (optarg)
3766*a9fa9459Szrj 	    dwarf_select_sections_by_letters (optarg);
3767*a9fa9459Szrj 	  else
3768*a9fa9459Szrj 	    dwarf_select_sections_all ();
3769*a9fa9459Szrj 	  break;
3770*a9fa9459Szrj 	case OPTION_DWARF:
3771*a9fa9459Szrj 	  dump_dwarf_section_info = TRUE;
3772*a9fa9459Szrj 	  seenflag = TRUE;
3773*a9fa9459Szrj 	  if (optarg)
3774*a9fa9459Szrj 	    dwarf_select_sections_by_names (optarg);
3775*a9fa9459Szrj 	  else
3776*a9fa9459Szrj 	    dwarf_select_sections_all ();
3777*a9fa9459Szrj 	  break;
3778*a9fa9459Szrj 	case OPTION_DWARF_DEPTH:
3779*a9fa9459Szrj 	  {
3780*a9fa9459Szrj 	    char *cp;
3781*a9fa9459Szrj 	    dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3782*a9fa9459Szrj 	  }
3783*a9fa9459Szrj 	  break;
3784*a9fa9459Szrj 	case OPTION_DWARF_START:
3785*a9fa9459Szrj 	  {
3786*a9fa9459Szrj 	    char *cp;
3787*a9fa9459Szrj 	    dwarf_start_die = strtoul (optarg, & cp, 0);
3788*a9fa9459Szrj 	    suppress_bfd_header = 1;
3789*a9fa9459Szrj 	  }
3790*a9fa9459Szrj 	  break;
3791*a9fa9459Szrj 	case OPTION_DWARF_CHECK:
3792*a9fa9459Szrj 	  dwarf_check = TRUE;
3793*a9fa9459Szrj 	  break;
3794*a9fa9459Szrj 	case 'G':
3795*a9fa9459Szrj 	  dump_stab_section_info = TRUE;
3796*a9fa9459Szrj 	  seenflag = TRUE;
3797*a9fa9459Szrj 	  break;
3798*a9fa9459Szrj 	case 's':
3799*a9fa9459Szrj 	  dump_section_contents = TRUE;
3800*a9fa9459Szrj 	  seenflag = TRUE;
3801*a9fa9459Szrj 	  break;
3802*a9fa9459Szrj 	case 'r':
3803*a9fa9459Szrj 	  dump_reloc_info = TRUE;
3804*a9fa9459Szrj 	  seenflag = TRUE;
3805*a9fa9459Szrj 	  break;
3806*a9fa9459Szrj 	case 'R':
3807*a9fa9459Szrj 	  dump_dynamic_reloc_info = TRUE;
3808*a9fa9459Szrj 	  seenflag = TRUE;
3809*a9fa9459Szrj 	  break;
3810*a9fa9459Szrj 	case 'a':
3811*a9fa9459Szrj 	  dump_ar_hdrs = TRUE;
3812*a9fa9459Szrj 	  seenflag = TRUE;
3813*a9fa9459Szrj 	  break;
3814*a9fa9459Szrj 	case 'h':
3815*a9fa9459Szrj 	  dump_section_headers = TRUE;
3816*a9fa9459Szrj 	  seenflag = TRUE;
3817*a9fa9459Szrj 	  break;
3818*a9fa9459Szrj 	case 'v':
3819*a9fa9459Szrj 	case 'V':
3820*a9fa9459Szrj 	  show_version = TRUE;
3821*a9fa9459Szrj 	  seenflag = TRUE;
3822*a9fa9459Szrj 	  break;
3823*a9fa9459Szrj 
3824*a9fa9459Szrj 	case 'H':
3825*a9fa9459Szrj 	  usage (stdout, 0);
3826*a9fa9459Szrj 	  /* No need to set seenflag or to break - usage() does not return.  */
3827*a9fa9459Szrj 	default:
3828*a9fa9459Szrj 	  usage (stderr, 1);
3829*a9fa9459Szrj 	}
3830*a9fa9459Szrj     }
3831*a9fa9459Szrj 
3832*a9fa9459Szrj   if (show_version)
3833*a9fa9459Szrj     print_version ("objdump");
3834*a9fa9459Szrj 
3835*a9fa9459Szrj   if (!seenflag)
3836*a9fa9459Szrj     usage (stderr, 2);
3837*a9fa9459Szrj 
3838*a9fa9459Szrj   if (formats_info)
3839*a9fa9459Szrj     exit_status = display_info ();
3840*a9fa9459Szrj   else
3841*a9fa9459Szrj     {
3842*a9fa9459Szrj       if (optind == argc)
3843*a9fa9459Szrj 	display_file ("a.out", target);
3844*a9fa9459Szrj       else
3845*a9fa9459Szrj 	for (; optind < argc;)
3846*a9fa9459Szrj 	  display_file (argv[optind++], target);
3847*a9fa9459Szrj     }
3848*a9fa9459Szrj 
3849*a9fa9459Szrj   free_only_list ();
3850*a9fa9459Szrj 
3851*a9fa9459Szrj   END_PROGRESS (program_name);
3852*a9fa9459Szrj 
3853*a9fa9459Szrj   return exit_status;
3854*a9fa9459Szrj }
3855