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