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, §ion->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