]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/objdump.c
new file.
[thirdparty/binutils-gdb.git] / binutils / objdump.c
CommitLineData
d20f480f 1/* objdump.c -- dump information about an object file.
37853673 2 Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
2fa0b342 3
b3a2b497 4This file is part of GNU Binutils.
2fa0b342 5
b3a2b497 6This program is free software; you can redistribute it and/or modify
2fa0b342 7it under the terms of the GNU General Public License as published by
d20f480f 8the Free Software Foundation; either version 2, or (at your option)
2fa0b342
DHW
9any later version.
10
b3a2b497 11This program is distributed in the hope that it will be useful,
2fa0b342
DHW
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
b3a2b497 17along with this program; if not, write to the Free Software
a65619c8 18Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
2fa0b342 19
2fa0b342
DHW
20#include "bfd.h"
21#include "getopt.h"
be1d162b 22#include "progress.h"
e1ec9f07 23#include "bucomm.h"
2fa0b342
DHW
24#include <stdio.h>
25#include <ctype.h>
2e8adbd7 26#include "dis-asm.h"
105da05c 27#include "libiberty.h"
2fa0b342 28
73b8f102
JG
29/* Internal headers for the ELF .stab-dump code - sorry. */
30#define BYTES_IN_WORD 32
31#include "aout/aout64.h"
bf661056 32
746cffcf
ILT
33#ifdef NEED_DECLARATION_FPRINTF
34/* This is needed by INIT_DISASSEMBLE_INFO. */
35extern int fprintf ();
80d19ec1 36#endif
2fa0b342
DHW
37
38char *default_target = NULL; /* default at runtime */
39
e1ec9f07 40extern char *program_version;
2fa0b342 41
249c6fc0 42int show_version = 0; /* show the version number */
2fa0b342
DHW
43int dump_section_contents; /* -s */
44int dump_section_headers; /* -h */
45boolean dump_file_header; /* -f */
46int dump_symtab; /* -t */
de3b08ac 47int dump_dynamic_symtab; /* -T */
2fa0b342 48int dump_reloc_info; /* -r */
de3b08ac 49int dump_dynamic_reloc_info; /* -R */
2fa0b342 50int dump_ar_hdrs; /* -a */
a65619c8 51int dump_private_headers; /* -p */
aa0a709a 52int with_line_numbers; /* -l */
be1d162b 53boolean with_source_code; /* -S */
9b018ecd 54int dump_stab_section_info; /* --stabs */
aa0a709a 55boolean disassemble; /* -d */
d5464baa 56boolean disassemble_all; /* -D */
e1ec9f07 57boolean formats_info; /* -i */
195d1adf 58char *only; /* -j secname */
13e4db2e 59int wide_output; /* -w */
aa21a2a9
ILT
60bfd_vma start_address = (bfd_vma) -1; /* --start-address */
61bfd_vma stop_address = (bfd_vma) -1; /* --stop-address */
195d1adf 62
cef35d48 63/* Extra info to pass to the disassembler address printing function. */
195d1adf
KR
64struct objdump_disasm_info {
65 bfd *abfd;
66 asection *sec;
8b129785 67 boolean require_sec;
195d1adf 68};
2fa0b342 69
cef35d48 70/* Architecture to disassemble for, or default if NULL. */
aa0a709a 71char *machine = (char *) NULL;
f7b839f7
DM
72
73/* The symbol table. */
aa0a709a 74asymbol **syms;
2fa0b342 75
f7b839f7 76/* Number of symbols in `syms'. */
ae5d2ff5 77long symcount = 0;
2fa0b342 78
be1d162b
ILT
79/* The sorted symbol table. */
80asymbol **sorted_syms;
81
82/* Number of symbols in `sorted_syms'. */
83long sorted_symcount = 0;
84
de3b08ac
ILT
85/* The dynamic symbol table. */
86asymbol **dynsyms;
87
88/* Number of symbols in `dynsyms'. */
89long dynsymcount = 0;
90
d9971b83
KR
91/* Forward declarations. */
92
93static void
94display_file PARAMS ((char *filename, char *target));
95
96static void
97dump_data PARAMS ((bfd *abfd));
98
99static void
100dump_relocs PARAMS ((bfd *abfd));
101
102static void
de3b08ac
ILT
103dump_dynamic_relocs PARAMS ((bfd * abfd));
104
105static void
106dump_reloc_set PARAMS ((bfd *, arelent **, long));
107
108static void
109dump_symbols PARAMS ((bfd *abfd, boolean dynamic));
02a68547
ILT
110
111static void
112display_bfd PARAMS ((bfd *abfd));
8f197c94
ILT
113
114static void
115objdump_print_address PARAMS ((bfd_vma, struct disassemble_info *));
be1d162b
ILT
116
117static void
118show_line PARAMS ((bfd *, asection *, bfd_vma));
d9971b83 119\f
2fa0b342 120void
b3a2b497
ILT
121usage (stream, status)
122 FILE *stream;
123 int status;
2fa0b342 124{
b3a2b497 125 fprintf (stream, "\
a65619c8 126Usage: %s [-ahifdDprRtTxsSlw] [-b bfdname] [-m machine] [-j section-name]\n\
d5464baa
ILT
127 [--archive-headers] [--target=bfdname] [--disassemble]\n\
128 [--disassemble-all] [--file-headers] [--section-headers] [--headers]\n\
13e4db2e
SC
129 [--info] [--section=section-name] [--line-numbers] [--source]\n",
130 program_name);
131 fprintf (stream, "\
d5464baa
ILT
132 [--architecture=machine] [--reloc] [--full-contents] [--stabs]\n\
133 [--syms] [--all-headers] [--dynamic-syms] [--dynamic-reloc]\n\
aa21a2a9
ILT
134 [--wide] [--version] [--help] [--private-headers]\n\
135 [--start-address=addr] [--stop-address=addr] objfile...\n\
13e4db2e 136at least one option besides -l (--line-numbers) must be given\n");
be1d162b 137 list_supported_targets (program_name, stream);
b3a2b497 138 exit (status);
2fa0b342
DHW
139}
140
aa21a2a9
ILT
141/* 150 isn't special; it's just an arbitrary non-ASCII char value. */
142
143#define OPTION_START_ADDRESS (150)
144#define OPTION_STOP_ADDRESS (OPTION_START_ADDRESS + 1)
145
aa0a709a
SC
146static struct option long_options[]=
147{
02a68547 148 {"all-headers", no_argument, NULL, 'x'},
a65619c8 149 {"private-headers", no_argument, NULL, 'p'},
02a68547
ILT
150 {"architecture", required_argument, NULL, 'm'},
151 {"archive-headers", no_argument, NULL, 'a'},
152 {"disassemble", no_argument, NULL, 'd'},
d5464baa 153 {"disassemble-all", no_argument, NULL, 'D'},
de3b08ac
ILT
154 {"dynamic-reloc", no_argument, NULL, 'R'},
155 {"dynamic-syms", no_argument, NULL, 'T'},
02a68547
ILT
156 {"file-headers", no_argument, NULL, 'f'},
157 {"full-contents", no_argument, NULL, 's'},
158 {"headers", no_argument, NULL, 'h'},
159 {"help", no_argument, NULL, 'H'},
160 {"info", no_argument, NULL, 'i'},
161 {"line-numbers", no_argument, NULL, 'l'},
162 {"reloc", no_argument, NULL, 'r'},
163 {"section", required_argument, NULL, 'j'},
164 {"section-headers", no_argument, NULL, 'h'},
be1d162b 165 {"source", no_argument, NULL, 'S'},
73b8f102 166 {"stabs", no_argument, &dump_stab_section_info, 1},
aa21a2a9
ILT
167 {"start-address", required_argument, NULL, OPTION_START_ADDRESS},
168 {"stop-address", required_argument, NULL, OPTION_STOP_ADDRESS},
02a68547
ILT
169 {"syms", no_argument, NULL, 't'},
170 {"target", required_argument, NULL, 'b'},
aa21a2a9 171 {"version", no_argument, &show_version, 1},
13e4db2e 172 {"wide", no_argument, &wide_output, 'w'},
d2442698
DM
173 {0, no_argument, 0, 0}
174};
f7b839f7 175\f
2fa0b342 176static void
f7b839f7 177dump_section_header (abfd, section, ignored)
aa0a709a 178 bfd *abfd;
f7b839f7
DM
179 asection *section;
180 PTR ignored;
2fa0b342 181{
f7b839f7 182 char *comma = "";
aa0a709a 183
2fa0b342 184#define PF(x,y) \
f7b839f7
DM
185 if (section->flags & x) { printf("%s%s",comma,y); comma = ", "; }
186
187
188 printf ("SECTION %d [%s]\t: size %08x",
189 section->index,
190 section->name,
191 (unsigned) bfd_get_section_size_before_reloc (section));
192 printf (" vma ");
193 printf_vma (section->vma);
13e4db2e
SC
194 printf (" lma ");
195 printf_vma (section->lma);
196 printf (" align 2**%u%s ",
197 section->alignment_power, (wide_output) ? "" : "\n");
f7b839f7
DM
198 PF (SEC_ALLOC, "ALLOC");
199 PF (SEC_CONSTRUCTOR, "CONSTRUCTOR");
200 PF (SEC_CONSTRUCTOR_TEXT, "CONSTRUCTOR TEXT");
201 PF (SEC_CONSTRUCTOR_DATA, "CONSTRUCTOR DATA");
202 PF (SEC_CONSTRUCTOR_BSS, "CONSTRUCTOR BSS");
203 PF (SEC_LOAD, "LOAD");
204 PF (SEC_RELOC, "RELOC");
195d1adf 205#ifdef SEC_BALIGN
f7b839f7 206 PF (SEC_BALIGN, "BALIGN");
195d1adf 207#endif
f7b839f7
DM
208 PF (SEC_READONLY, "READONLY");
209 PF (SEC_CODE, "CODE");
210 PF (SEC_DATA, "DATA");
211 PF (SEC_ROM, "ROM");
212 PF (SEC_DEBUGGING, "DEBUGGING");
28d1b01e 213 PF (SEC_NEVER_LOAD, "NEVER_LOAD");
f7b839f7 214 printf ("\n");
2fa0b342 215#undef PF
2fa0b342
DHW
216}
217
f7b839f7
DM
218static void
219dump_headers (abfd)
220 bfd *abfd;
221{
222 bfd_map_over_sections (abfd, dump_section_header, (PTR) NULL);
223}
224\f
2fa0b342 225static asymbol **
abdcac0f
DM
226slurp_symtab (abfd)
227 bfd *abfd;
2fa0b342 228{
aa0a709a 229 asymbol **sy = (asymbol **) NULL;
ae5d2ff5 230 long storage;
2fa0b342 231
aa0a709a
SC
232 if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
233 {
f7b839f7
DM
234 printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
235 return NULL;
aa0a709a
SC
236 }
237
ae5d2ff5
ILT
238 storage = bfd_get_symtab_upper_bound (abfd);
239 if (storage < 0)
240 bfd_fatal (bfd_get_filename (abfd));
241
aa0a709a
SC
242 if (storage)
243 {
02a68547 244 sy = (asymbol **) xmalloc (storage);
aa0a709a
SC
245 }
246 symcount = bfd_canonicalize_symtab (abfd, sy);
ae5d2ff5
ILT
247 if (symcount < 0)
248 bfd_fatal (bfd_get_filename (abfd));
249 if (symcount == 0)
de3b08ac
ILT
250 fprintf (stderr, "%s: %s: No symbols\n",
251 program_name, bfd_get_filename (abfd));
252 return sy;
253}
254
255/* Read in the dynamic symbols. */
256
257static asymbol **
258slurp_dynamic_symtab (abfd)
259 bfd *abfd;
260{
261 asymbol **sy = (asymbol **) NULL;
262 long storage;
263
de3b08ac
ILT
264 storage = bfd_get_dynamic_symtab_upper_bound (abfd);
265 if (storage < 0)
28d1b01e
ILT
266 {
267 if (!(bfd_get_file_flags (abfd) & DYNAMIC))
268 {
269 fprintf (stderr, "%s: %s: not a dynamic object\n",
270 program_name, bfd_get_filename (abfd));
271 return NULL;
272 }
273
274 bfd_fatal (bfd_get_filename (abfd));
275 }
de3b08ac
ILT
276
277 if (storage)
278 {
279 sy = (asymbol **) xmalloc (storage);
280 }
281 dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, sy);
282 if (dynsymcount < 0)
283 bfd_fatal (bfd_get_filename (abfd));
284 if (dynsymcount == 0)
285 fprintf (stderr, "%s: %s: No dynamic symbols\n",
286 program_name, bfd_get_filename (abfd));
aa0a709a 287 return sy;
2fa0b342 288}
aa0a709a 289
f7b839f7
DM
290/* Filter out (in place) symbols that are useless for disassembly.
291 COUNT is the number of elements in SYMBOLS.
292 Return the number of useful symbols. */
3ae36cb6 293
ae5d2ff5 294long
f7b839f7
DM
295remove_useless_symbols (symbols, count)
296 asymbol **symbols;
ae5d2ff5 297 long count;
3ae36cb6 298{
f7b839f7 299 register asymbol **in_ptr = symbols, **out_ptr = symbols;
3ae36cb6 300
f7b839f7 301 while (--count >= 0)
3ae36cb6
PB
302 {
303 asymbol *sym = *in_ptr++;
304
305 if (sym->name == NULL || sym->name[0] == '\0')
306 continue;
307 if (sym->flags & (BSF_DEBUGGING))
308 continue;
28d1b01e 309 if (bfd_is_und_section (sym->section)
3ae36cb6
PB
310 || bfd_is_com_section (sym->section))
311 continue;
312
313 *out_ptr++ = sym;
314 }
f7b839f7 315 return out_ptr - symbols;
3ae36cb6
PB
316}
317
37853673
SS
318/* Sort symbols into value order. */
319
aa0a709a 320static int
37853673 321compare_symbols (ap, bp)
d5464baa
ILT
322 const PTR ap;
323 const PTR bp;
2fa0b342 324{
d5464baa
ILT
325 const asymbol *a = *(const asymbol **)ap;
326 const asymbol *b = *(const asymbol **)bp;
2fa0b342 327
be1d162b 328 if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
3ae36cb6 329 return 1;
be1d162b 330 else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
3ae36cb6 331 return -1;
2fa0b342 332
3ae36cb6
PB
333 if (a->section > b->section)
334 return 1;
335 else if (a->section < b->section)
336 return -1;
337 return 0;
2fa0b342
DHW
338}
339
d5464baa
ILT
340/* Sort relocs into address order. */
341
342static int
343compare_relocs (ap, bp)
344 const PTR ap;
345 const PTR bp;
346{
347 const arelent *a = *(const arelent **)ap;
348 const arelent *b = *(const arelent **)bp;
349
350 if (a->address > b->address)
351 return 1;
352 else if (a->address < b->address)
353 return -1;
354
a65619c8
SC
355 /* So that associated relocations tied to the same address show up
356 in the correct order, we don't do any further sorting. */
357 if (a > b)
358 return 1;
359 else if (a < b)
360 return -1;
361 else
362 return 0;
d5464baa
ILT
363}
364
f7b839f7
DM
365/* Print VMA symbolically to INFO if possible. */
366
8f197c94 367static void
545a2768 368objdump_print_address (vma, info)
aa0a709a 369 bfd_vma vma;
545a2768 370 struct disassemble_info *info;
2fa0b342 371{
195d1adf
KR
372 /* @@ For relocateable files, should filter out symbols belonging to
373 the wrong section. Unfortunately, not enough information is supplied
374 to this routine to determine the correct section in all cases. */
375 /* @@ Would it speed things up to cache the last two symbols returned,
376 and maybe their address ranges? For many processors, only one memory
377 operand can be present at a time, so the 2-entry cache wouldn't be
378 constantly churned by code doing heavy memory accesses. */
2fa0b342 379
be1d162b 380 /* Indices in `sorted_syms'. */
ae5d2ff5 381 long min = 0;
be1d162b 382 long max = sorted_symcount;
ae5d2ff5 383 long thisplace;
2fa0b342 384
3ae36cb6
PB
385 fprintf_vma (info->stream, vma);
386
be1d162b 387 if (sorted_symcount < 1)
f7b839f7
DM
388 return;
389
8f197c94
ILT
390 /* Perform a binary search looking for the closest symbol to the
391 required value. We are searching the range (min, max]. */
392 while (min + 1 < max)
aa0a709a 393 {
f7b839f7 394 asymbol *sym;
8f197c94 395
f7b839f7 396 thisplace = (max + min) / 2;
be1d162b 397 sym = sorted_syms[thisplace];
8f197c94 398
13e4db2e 399 if (bfd_asymbol_value (sym) > vma)
f7b839f7 400 max = thisplace;
13e4db2e 401 else if (bfd_asymbol_value (sym) < vma)
f7b839f7
DM
402 min = thisplace;
403 else
aa0a709a 404 {
8f197c94
ILT
405 min = thisplace;
406 break;
aa0a709a 407 }
f7b839f7 408 }
fc5d6074 409
8f197c94
ILT
410 /* The symbol we want is now in min, the low end of the range we
411 were searching. */
412 thisplace = min;
413
f7b839f7
DM
414 {
415 /* If this symbol isn't global, search for one with the same value
416 that is. */
be1d162b 417 bfd_vma val = bfd_asymbol_value (sorted_syms[thisplace]);
ae5d2ff5 418 long i;
be1d162b 419 if (sorted_syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING))
f7b839f7 420 for (i = thisplace - 1; i >= 0; i--)
aa0a709a 421 {
be1d162b
ILT
422 if (bfd_asymbol_value (sorted_syms[i]) == val
423 && (!(sorted_syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
424 || ((sorted_syms[thisplace]->flags & BSF_DEBUGGING)
425 && !(sorted_syms[i]->flags & BSF_DEBUGGING))))
aa0a709a 426 {
f7b839f7
DM
427 thisplace = i;
428 break;
aa0a709a
SC
429 }
430 }
be1d162b
ILT
431 if (sorted_syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING))
432 for (i = thisplace + 1; i < sorted_symcount; i++)
f7b839f7 433 {
be1d162b
ILT
434 if (bfd_asymbol_value (sorted_syms[i]) == val
435 && (!(sorted_syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
436 || ((sorted_syms[thisplace]->flags & BSF_DEBUGGING)
437 && !(sorted_syms[i]->flags & BSF_DEBUGGING))))
195d1adf 438 {
f7b839f7
DM
439 thisplace = i;
440 break;
195d1adf 441 }
f7b839f7
DM
442 }
443 }
444 {
445 /* If the file is relocateable, and the symbol could be from this
446 section, prefer a symbol from this section over symbols from
447 others, even if the other symbol's value might be closer.
448
449 Note that this may be wrong for some symbol references if the
450 sections have overlapping memory ranges, but in that case there's
451 no way to tell what's desired without looking at the relocation
452 table. */
453 struct objdump_disasm_info *aux;
ae5d2ff5 454 long i;
f7b839f7
DM
455
456 aux = (struct objdump_disasm_info *) info->application_data;
be1d162b 457 if (sorted_syms[thisplace]->section != aux->sec
2d054641
ILT
458 && (aux->require_sec
459 || ((aux->abfd->flags & HAS_RELOC) != 0
460 && vma >= bfd_get_section_vma (aux->abfd, aux->sec)
461 && vma < (bfd_get_section_vma (aux->abfd, aux->sec)
462 + bfd_get_section_size_before_reloc (aux->sec)))))
f7b839f7 463 {
be1d162b 464 for (i = thisplace + 1; i < sorted_symcount; i++)
8f197c94 465 {
be1d162b
ILT
466 if (bfd_asymbol_value (sorted_syms[i])
467 != bfd_asymbol_value (sorted_syms[thisplace]))
28d1b01e 468 break;
8f197c94 469 }
28d1b01e 470 --i;
8f197c94
ILT
471 for (; i >= 0; i--)
472 {
be1d162b 473 if (sorted_syms[i]->section == aux->sec)
8f197c94
ILT
474 {
475 thisplace = i;
476 break;
477 }
478 }
2d054641 479
be1d162b 480 if (sorted_syms[thisplace]->section != aux->sec)
2d054641
ILT
481 {
482 /* We didn't find a good symbol with a smaller value.
483 Look for one with a larger value. */
be1d162b 484 for (i = thisplace + 1; i < sorted_symcount; i++)
2d054641 485 {
be1d162b 486 if (sorted_syms[i]->section == aux->sec)
2d054641
ILT
487 {
488 thisplace = i;
489 break;
490 }
491 }
492 }
195d1adf 493 }
f7b839f7 494 }
2d054641 495
be1d162b
ILT
496 fprintf (info->stream, " <%s", sorted_syms[thisplace]->name);
497 if (bfd_asymbol_value (sorted_syms[thisplace]) > vma)
f7b839f7
DM
498 {
499 char buf[30], *p = buf;
be1d162b 500 sprintf_vma (buf, bfd_asymbol_value (sorted_syms[thisplace]) - vma);
f7b839f7
DM
501 while (*p == '0')
502 p++;
503 fprintf (info->stream, "-%s", p);
504 }
be1d162b 505 else if (vma > bfd_asymbol_value (sorted_syms[thisplace]))
f7b839f7
DM
506 {
507 char buf[30], *p = buf;
be1d162b 508 sprintf_vma (buf, vma - bfd_asymbol_value (sorted_syms[thisplace]));
f7b839f7
DM
509 while (*p == '0')
510 p++;
511 fprintf (info->stream, "+%s", p);
2fa0b342 512 }
f7b839f7 513 fprintf (info->stream, ">");
2fa0b342
DHW
514}
515
be1d162b
ILT
516/* Hold the last function name and the last line number we displayed
517 in a disassembly. */
518
519static char *prev_functionname;
520static unsigned int prev_line;
521
522/* We keep a list of all files that we have seen when doing a
523 dissassembly with source, so that we know how much of the file to
524 display. This can be important for inlined functions. */
525
526struct print_file_list
527{
528 struct print_file_list *next;
529 char *filename;
530 unsigned int line;
531 FILE *f;
532};
533
534static struct print_file_list *print_files;
535
536/* The number of preceding context lines to show when we start
537 displaying a file for the first time. */
538
539#define SHOW_PRECEDING_CONTEXT_LINES (5)
540
541/* Skip ahead to a given line in a file, optionally printing each
542 line. */
543
544static void
545skip_to_line PARAMS ((struct print_file_list *, unsigned int, boolean));
546
547static void
548skip_to_line (p, line, show)
549 struct print_file_list *p;
550 unsigned int line;
551 boolean show;
552{
553 while (p->line < line)
554 {
555 char buf[100];
556
557 if (fgets (buf, sizeof buf, p->f) == NULL)
558 {
559 fclose (p->f);
560 p->f = NULL;
561 break;
562 }
563
564 if (show)
565 printf ("%s", buf);
566
567 if (strchr (buf, '\n') != NULL)
568 ++p->line;
569 }
570}
571
572/* Show the line number, or the source line, in a dissassembly
573 listing. */
574
575static void
576show_line (abfd, section, off)
aa0a709a 577 bfd *abfd;
be1d162b
ILT
578 asection *section;
579 bfd_vma off;
2fa0b342 580{
be1d162b
ILT
581 CONST char *filename;
582 CONST char *functionname;
583 unsigned int line;
2e8adbd7 584
be1d162b
ILT
585 if (! with_line_numbers && ! with_source_code)
586 return;
d20f480f 587
be1d162b
ILT
588 if (! bfd_find_nearest_line (abfd, section, syms, off, &filename,
589 &functionname, &line))
590 return;
aa0a709a 591
be1d162b
ILT
592 if (filename != NULL && *filename == '\0')
593 filename = NULL;
594 if (functionname != NULL && *functionname == '\0')
595 functionname = NULL;
aa0a709a 596
be1d162b 597 if (with_line_numbers)
d5464baa 598 {
be1d162b
ILT
599 if (functionname != NULL
600 && (prev_functionname == NULL
601 || strcmp (functionname, prev_functionname) != 0))
602 printf ("%s():\n", functionname);
603 if (line > 0 && line != prev_line)
604 printf ("%s:%u\n", filename == NULL ? "???" : filename, line);
605 }
606
607 if (with_source_code
608 && filename != NULL
609 && line > 0)
610 {
611 struct print_file_list **pp, *p;
612
613 for (pp = &print_files; *pp != NULL; pp = &(*pp)->next)
614 if (strcmp ((*pp)->filename, filename) == 0)
615 break;
616 p = *pp;
617
618 if (p != NULL)
d5464baa 619 {
be1d162b
ILT
620 if (p != print_files)
621 {
622 int l;
623
624 /* We have reencountered a file name which we saw
625 earlier. This implies that either we are dumping out
626 code from an included file, or the same file was
627 linked in more than once. There are two common cases
628 of an included file: inline functions in a header
629 file, and a bison or flex skeleton file. In the
630 former case we want to just start printing (but we
631 back up a few lines to give context); in the latter
632 case we want to continue from where we left off. I
633 can't think of a good way to distinguish the cases,
634 so I used a heuristic based on the file name. */
635 if (strcmp (p->filename + strlen (p->filename) - 2, ".h") != 0)
636 l = p->line;
637 else
638 {
639 l = line - SHOW_PRECEDING_CONTEXT_LINES;
640 if (l <= 0)
641 l = 1;
642 }
d5464baa 643
be1d162b
ILT
644 if (p->f == NULL)
645 {
646 p->f = fopen (p->filename, "r");
647 p->line = 0;
648 }
649 if (p->f != NULL)
650 skip_to_line (p, l, false);
d5464baa 651
be1d162b
ILT
652 if (print_files->f != NULL)
653 {
654 fclose (print_files->f);
655 print_files->f = NULL;
656 }
657 }
d5464baa 658
be1d162b
ILT
659 if (p->f != NULL)
660 {
661 skip_to_line (p, line, true);
662 *pp = p->next;
663 p->next = print_files;
664 print_files = p;
665 }
666 }
667 else
668 {
669 FILE *f;
d5464baa 670
be1d162b
ILT
671 f = fopen (filename, "r");
672 if (f != NULL)
d5464baa 673 {
be1d162b 674 int l;
d5464baa 675
be1d162b
ILT
676 p = ((struct print_file_list *)
677 xmalloc (sizeof (struct print_file_list)));
678 p->filename = xmalloc (strlen (filename) + 1);
679 strcpy (p->filename, filename);
680 p->line = 0;
681 p->f = f;
682
683 if (print_files != NULL && print_files->f != NULL)
684 {
685 fclose (print_files->f);
686 print_files->f = NULL;
687 }
688 p->next = print_files;
689 print_files = p;
690
691 l = line - SHOW_PRECEDING_CONTEXT_LINES;
692 if (l <= 0)
693 l = 1;
694 skip_to_line (p, l, false);
695 if (p->f != NULL)
696 skip_to_line (p, line, true);
d5464baa
ILT
697 }
698 }
699 }
700
be1d162b
ILT
701 if (functionname != NULL
702 && (prev_functionname == NULL
703 || strcmp (functionname, prev_functionname) != 0))
aa0a709a 704 {
be1d162b
ILT
705 if (prev_functionname != NULL)
706 free (prev_functionname);
707 prev_functionname = xmalloc (strlen (functionname) + 1);
708 strcpy (prev_functionname, functionname);
aa0a709a 709 }
2fa0b342 710
be1d162b
ILT
711 if (line > 0 && line != prev_line)
712 prev_line = line;
713}
714
715void
716disassemble_data (abfd)
717 bfd *abfd;
718{
719 long i;
720 unsigned int (*print) () = 0; /* Old style */
721 disassembler_ftype disassemble_fn = 0; /* New style */
722 struct disassemble_info disasm_info;
723 struct objdump_disasm_info aux;
724 asection *section;
725 boolean done_dot = false;
726
727 print_files = NULL;
728 prev_functionname = NULL;
729 prev_line = -1;
730
731 /* We make a copy of syms to sort. We don't want to sort syms
732 because that will screw up the relocs. */
733 sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
734 memcpy (sorted_syms, syms, symcount * sizeof (asymbol *));
735
736 sorted_symcount = remove_useless_symbols (sorted_syms, symcount);
2fa0b342
DHW
737
738 /* Sort the symbols into section and symbol order */
be1d162b 739 qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
2fa0b342 740
cef35d48
DM
741 INIT_DISASSEMBLE_INFO(disasm_info, stdout);
742 disasm_info.application_data = (PTR) &aux;
743 aux.abfd = abfd;
744 disasm_info.print_address_func = objdump_print_address;
745
aa0a709a
SC
746 if (machine != (char *) NULL)
747 {
cef35d48
DM
748 bfd_arch_info_type *info = bfd_scan_arch (machine);
749 if (info == NULL)
aa0a709a
SC
750 {
751 fprintf (stderr, "%s: Can't use supplied machine %s\n",
752 program_name,
753 machine);
754 exit (1);
755 }
756 abfd->arch_info = info;
2fa0b342 757 }
e779a58c 758
cef35d48 759 /* See if we can disassemble using bfd. */
e779a58c 760
aa0a709a
SC
761 if (abfd->arch_info->disassemble)
762 {
763 print = abfd->arch_info->disassemble;
e779a58c 764 }
aa0a709a
SC
765 else
766 {
d5464baa
ILT
767 disassemble_fn = disassembler (abfd);
768 if (!disassemble_fn)
aa0a709a 769 {
aa0a709a
SC
770 fprintf (stderr, "%s: Can't disassemble for architecture %s\n",
771 program_name,
105da05c 772 bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
aa0a709a
SC
773 exit (1);
774 }
aa0a709a 775 }
2fa0b342
DHW
776
777 for (section = abfd->sections;
aa0a709a
SC
778 section != (asection *) NULL;
779 section = section->next)
65cceb78 780 {
cef35d48
DM
781 bfd_byte *data = NULL;
782 bfd_size_type datasize = 0;
be1d162b 783 arelent **relbuf = NULL;
d5464baa
ILT
784 arelent **relpp = NULL;
785 arelent **relppend = NULL;
aa21a2a9 786 long stop;
2fa0b342 787
d5464baa
ILT
788 if ((section->flags & SEC_LOAD) == 0
789 || (! disassemble_all
790 && only == NULL
791 && (section->flags & SEC_CODE) == 0))
cef35d48
DM
792 continue;
793 if (only != (char *) NULL && strcmp (only, section->name) != 0)
794 continue;
2fa0b342 795
d5464baa
ILT
796 if (dump_reloc_info
797 && (section->flags & SEC_RELOC) != 0)
798 {
be1d162b
ILT
799 long relsize;
800
801 relsize = bfd_get_reloc_upper_bound (abfd, section);
802 if (relsize < 0)
803 bfd_fatal (bfd_get_filename (abfd));
804
805 if (relsize > 0)
806 {
807 long relcount;
808
809 relbuf = (arelent **) xmalloc (relsize);
810 relcount = bfd_canonicalize_reloc (abfd, section, relbuf, syms);
811 if (relcount < 0)
812 bfd_fatal (bfd_get_filename (abfd));
813
814 /* Sort the relocs by address. */
815 qsort (relbuf, relcount, sizeof (arelent *), compare_relocs);
816
817 relpp = relbuf;
818 relppend = relpp + relcount;
819 }
d5464baa
ILT
820 }
821
cef35d48 822 printf ("Disassembly of section %s:\n", section->name);
2fa0b342 823
cef35d48
DM
824 datasize = bfd_get_section_size_before_reloc (section);
825 if (datasize == 0)
826 continue;
2fa0b342 827
cef35d48 828 data = (bfd_byte *) xmalloc ((size_t) datasize);
2fa0b342 829
cef35d48 830 bfd_get_section_contents (abfd, section, data, 0, datasize);
2fa0b342 831
cef35d48
DM
832 aux.sec = section;
833 disasm_info.buffer = data;
834 disasm_info.buffer_vma = section->vma;
835 disasm_info.buffer_length = datasize;
aa21a2a9
ILT
836 if (start_address == (bfd_vma) -1
837 || start_address < disasm_info.buffer_vma)
838 i = 0;
839 else
840 i = start_address - disasm_info.buffer_vma;
841 if (stop_address == (bfd_vma) -1)
842 stop = datasize;
843 else
844 {
845 if (stop_address < disasm_info.buffer_vma)
846 stop = 0;
847 else
848 stop = stop_address - disasm_info.buffer_vma;
849 if (stop > disasm_info.buffer_length)
850 stop = disasm_info.buffer_length;
851 }
852 while (i < stop)
cef35d48 853 {
d5464baa 854 int bytes;
13e4db2e 855 boolean need_nl = false;
d5464baa 856
cef35d48
DM
857 if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 0 &&
858 data[i + 3] == 0)
aa0a709a 859 {
cef35d48 860 if (done_dot == false)
aa0a709a 861 {
cef35d48
DM
862 printf ("...\n");
863 done_dot = true;
65cceb78 864 }
d5464baa 865 bytes = 4;
cef35d48
DM
866 }
867 else
868 {
869 done_dot = false;
be1d162b
ILT
870 if (with_line_numbers || with_source_code)
871 show_line (abfd, section, i);
8b129785 872 aux.require_sec = true;
cef35d48 873 objdump_print_address (section->vma + i, &disasm_info);
8b129785 874 aux.require_sec = false;
cef35d48 875 putchar (' ');
65cceb78 876
d5464baa 877 if (disassemble_fn)
cef35d48 878 {
d5464baa
ILT
879 /* New style */
880 bytes = (*disassemble_fn) (section->vma + i, &disasm_info);
cef35d48
DM
881 if (bytes < 0)
882 break;
aa0a709a 883 }
d5464baa
ILT
884 else
885 {
886 /* Old style */
887 bytes = print (section->vma + i, data + i, stdout);
888 }
13e4db2e
SC
889 if (!wide_output)
890 putchar ('\n');
891 else
892 need_nl = true;
96d7950b 893 }
d5464baa
ILT
894
895 if (dump_reloc_info
896 && (section->flags & SEC_RELOC) != 0)
897 {
898 while (relpp < relppend
746cffcf
ILT
899 && ((*relpp)->address >= (bfd_vma) i
900 && (*relpp)->address < (bfd_vma) i + bytes))
d5464baa
ILT
901 {
902 arelent *q;
903 const char *sym_name;
904
905 q = *relpp;
906
907 printf ("\t\tRELOC: ");
908
909 printf_vma (section->vma + q->address);
910
911 printf (" %s ", q->howto->name);
912
913 if (q->sym_ptr_ptr != NULL
914 && *q->sym_ptr_ptr != NULL)
915 {
916 sym_name = bfd_asymbol_name (*q->sym_ptr_ptr);
917 if (sym_name == NULL || *sym_name == '\0')
918 {
919 asection *sym_sec;
920
921 sym_sec = bfd_get_section (*q->sym_ptr_ptr);
922 sym_name = bfd_get_section_name (abfd, sym_sec);
923 if (sym_name == NULL || *sym_name == '\0')
924 sym_name = "*unknown*";
925 }
926 }
927
928 printf ("%s", sym_name);
929
930 if (q->addend)
931 {
932 printf ("+0x");
933 printf_vma (q->addend);
934 }
935
936 printf ("\n");
13e4db2e 937 need_nl = false;
d5464baa
ILT
938 ++relpp;
939 }
940 }
941
13e4db2e
SC
942 if (need_nl)
943 printf ("\n");
944
d5464baa 945 i += bytes;
96d7950b 946 }
be1d162b 947
cef35d48 948 free (data);
be1d162b
ILT
949 if (relbuf != NULL)
950 free (relbuf);
2fa0b342 951 }
2fa0b342 952}
73b8f102 953\f
73b8f102
JG
954
955/* Define a table of stab values and print-strings. We wish the initializer
956 could be a direct-mapped table, but instead we build one the first
957 time we need it. */
958
fe2750e1 959char **stab_name;
73b8f102
JG
960
961struct stab_print {
962 int value;
fe2750e1 963 char *string;
73b8f102
JG
964};
965
966struct stab_print stab_print[] = {
967#define __define_stab(NAME, CODE, STRING) {CODE, STRING},
968#include "aout/stab.def"
969#undef __define_stab
02a68547 970 {0, ""}
73b8f102
JG
971};
972
250e36fe
DM
973void dump_section_stabs PARAMS ((bfd *abfd, char *stabsect_name,
974 char *strsect_name));
249c6fc0 975
250e36fe 976/* Dump the stabs sections from an object file that has a section that
73b8f102
JG
977 uses Sun stabs encoding. It has to use some hooks into BFD because
978 string table sections are not normally visible to BFD callers. */
979
980void
9b018ecd 981dump_stabs (abfd)
73b8f102
JG
982 bfd *abfd;
983{
fe2750e1
SS
984 /* Allocate and initialize stab name array if first time. */
985 if (stab_name == NULL)
73b8f102 986 {
250e36fe
DM
987 int i;
988
fe2750e1
SS
989 stab_name = (char **) xmalloc (256 * sizeof(char *));
990 /* Clear the array. */
73b8f102 991 for (i = 0; i < 256; i++)
fe2750e1
SS
992 stab_name[i] = NULL;
993 /* Fill in the defined stabs. */
994 for (i = 0; *stab_print[i].string; i++)
995 stab_name[stab_print[i].value] = stab_print[i].string;
73b8f102
JG
996 }
997
250e36fe
DM
998 dump_section_stabs (abfd, ".stab", ".stabstr");
999 dump_section_stabs (abfd, ".stab.excl", ".stab.exclstr");
1000 dump_section_stabs (abfd, ".stab.index", ".stab.indexstr");
1001 dump_section_stabs (abfd, "$GDB_SYMBOLS$", "$GDB_STRINGS$");
249c6fc0
RS
1002}
1003
250e36fe
DM
1004static struct internal_nlist *stabs;
1005static bfd_size_type stab_size;
1006
1007static char *strtab;
1008static bfd_size_type stabstr_size;
1009
1010/* Read ABFD's stabs section STABSECT_NAME into `stabs'
1011 and string table section STRSECT_NAME into `strtab'.
1012 If the section exists and was read, allocate the space and return true.
1013 Otherwise return false. */
1014
1015boolean
1016read_section_stabs (abfd, stabsect_name, strsect_name)
249c6fc0 1017 bfd *abfd;
250e36fe
DM
1018 char *stabsect_name;
1019 char *strsect_name;
249c6fc0 1020{
9b018ecd 1021 asection *stabsect, *stabstrsect;
9b018ecd 1022
d5671c53
ILT
1023 stabsect = bfd_get_section_by_name (abfd, stabsect_name);
1024 if (0 == stabsect)
73b8f102 1025 {
250e36fe
DM
1026 printf ("No %s section present\n\n", stabsect_name);
1027 return false;
73b8f102
JG
1028 }
1029
d5671c53
ILT
1030 stabstrsect = bfd_get_section_by_name (abfd, strsect_name);
1031 if (0 == stabstrsect)
73b8f102 1032 {
eae82145 1033 fprintf (stderr, "%s: %s has no %s section\n", program_name,
250e36fe
DM
1034 bfd_get_filename (abfd), strsect_name);
1035 return false;
73b8f102 1036 }
9b018ecd 1037
d5671c53
ILT
1038 stab_size = bfd_section_size (abfd, stabsect);
1039 stabstr_size = bfd_section_size (abfd, stabstrsect);
73b8f102 1040
9b018ecd
ILT
1041 stabs = (struct internal_nlist *) xmalloc (stab_size);
1042 strtab = (char *) xmalloc (stabstr_size);
73b8f102 1043
d5671c53 1044 if (! bfd_get_section_contents (abfd, stabsect, (PTR) stabs, 0, stab_size))
9b018ecd 1045 {
d5671c53
ILT
1046 fprintf (stderr, "%s: Reading %s section of %s failed: %s\n",
1047 program_name, stabsect_name, bfd_get_filename (abfd),
1048 bfd_errmsg (bfd_get_error ()));
1049 free (stabs);
1050 free (strtab);
1051 return false;
73b8f102 1052 }
2fa0b342 1053
d5671c53
ILT
1054 if (! bfd_get_section_contents (abfd, stabstrsect, (PTR) strtab, 0,
1055 stabstr_size))
9b018ecd 1056 {
d5671c53
ILT
1057 fprintf (stderr, "%s: Reading %s section of %s failed: %s\n",
1058 program_name, strsect_name, bfd_get_filename (abfd),
1059 bfd_errmsg (bfd_get_error ()));
1060 free (stabs);
1061 free (strtab);
1062 return false;
73b8f102 1063 }
d5671c53 1064
250e36fe
DM
1065 return true;
1066}
73b8f102
JG
1067
1068#define SWAP_SYMBOL(symp, abfd) \
250e36fe 1069{ \
73b8f102 1070 (symp)->n_strx = bfd_h_get_32(abfd, \
250e36fe 1071 (unsigned char *)&(symp)->n_strx); \
73b8f102 1072 (symp)->n_desc = bfd_h_get_16 (abfd, \
250e36fe 1073 (unsigned char *)&(symp)->n_desc); \
73b8f102 1074 (symp)->n_value = bfd_h_get_32 (abfd, \
250e36fe
DM
1075 (unsigned char *)&(symp)->n_value); \
1076}
73b8f102 1077
250e36fe
DM
1078/* Print ABFD's stabs section STABSECT_NAME (in `stabs'),
1079 using string table section STRSECT_NAME (in `strtab'). */
1080
1081void
1082print_section_stabs (abfd, stabsect_name, strsect_name)
1083 bfd *abfd;
1084 char *stabsect_name;
1085 char *strsect_name;
1086{
1087 int i;
1088 unsigned file_string_table_offset = 0, next_file_string_table_offset = 0;
1089 struct internal_nlist *stabp = stabs,
1090 *stabs_end = (struct internal_nlist *) (stab_size + (char *) stabs);
73b8f102 1091
250e36fe
DM
1092 printf ("Contents of %s section:\n\n", stabsect_name);
1093 printf ("Symnum n_type n_othr n_desc n_value n_strx String\n");
249c6fc0
RS
1094
1095 /* Loop through all symbols and print them.
1096
1097 We start the index at -1 because there is a dummy symbol on
250e36fe 1098 the front of stabs-in-{coff,elf} sections that supplies sizes. */
249c6fc0 1099
250e36fe 1100 for (i = -1; stabp < stabs_end; stabp++, i++)
73b8f102 1101 {
250e36fe 1102 SWAP_SYMBOL (stabp, abfd);
fe2750e1 1103 printf ("\n%-6d ", i);
250e36fe 1104 /* Either print the stab name, or, if unnamed, print its number
fe2750e1 1105 again (makes consistent formatting for tools like awk). */
250e36fe
DM
1106 if (stab_name[stabp->n_type])
1107 printf ("%-6s", stab_name[stabp->n_type]);
105da05c
ILT
1108 else if (stabp->n_type == N_UNDF)
1109 printf ("HdrSym");
fe2750e1 1110 else
105da05c 1111 printf ("%-6d", stabp->n_type);
250e36fe
DM
1112 printf (" %-6d %-6d ", stabp->n_other, stabp->n_desc);
1113 printf_vma (stabp->n_value);
1114 printf (" %-6lu", stabp->n_strx);
249c6fc0
RS
1115
1116 /* Symbols with type == 0 (N_UNDF) specify the length of the
1117 string table associated with this file. We use that info
1118 to know how to relocate the *next* file's string table indices. */
1119
250e36fe 1120 if (stabp->n_type == N_UNDF)
249c6fc0
RS
1121 {
1122 file_string_table_offset = next_file_string_table_offset;
250e36fe 1123 next_file_string_table_offset += stabp->n_value;
249c6fc0 1124 }
249c6fc0 1125 else
e1ec9f07 1126 {
250e36fe 1127 /* Using the (possibly updated) string table offset, print the
e1ec9f07
SS
1128 string (if any) associated with this symbol. */
1129
250e36fe
DM
1130 if ((stabp->n_strx + file_string_table_offset) < stabstr_size)
1131 printf (" %s", &strtab[stabp->n_strx + file_string_table_offset]);
e1ec9f07
SS
1132 else
1133 printf (" *");
1134 }
73b8f102
JG
1135 }
1136 printf ("\n\n");
1137}
249c6fc0 1138
250e36fe
DM
1139void
1140dump_section_stabs (abfd, stabsect_name, strsect_name)
1141 bfd *abfd;
1142 char *stabsect_name;
1143 char *strsect_name;
1144{
13e4db2e 1145 asection *s;
13e4db2e 1146
a65619c8
SC
1147 /* Check for section names for which stabsect_name is a prefix, to
1148 handle .stab0, etc. */
13e4db2e 1149 for (s = abfd->sections;
a65619c8 1150 s != NULL;
13e4db2e
SC
1151 s = s->next)
1152 {
a65619c8
SC
1153 if (strncmp (stabsect_name, s->name, strlen (stabsect_name)) == 0
1154 && strncmp (strsect_name, s->name, strlen (strsect_name)) != 0)
13e4db2e 1155 {
a65619c8
SC
1156 if (read_section_stabs (abfd, s->name, strsect_name))
1157 {
1158 print_section_stabs (abfd, s->name, strsect_name);
1159 free (stabs);
1160 free (strtab);
1161 }
13e4db2e
SC
1162 }
1163 }
250e36fe
DM
1164}
1165\f
eae82145 1166static void
f7b839f7
DM
1167dump_bfd_header (abfd)
1168 bfd *abfd;
1169{
1170 char *comma = "";
1171
1172 printf ("architecture: %s, ",
1173 bfd_printable_arch_mach (bfd_get_arch (abfd),
1174 bfd_get_mach (abfd)));
1175 printf ("flags 0x%08x:\n", abfd->flags);
1176
1177#define PF(x, y) if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
1178 PF (HAS_RELOC, "HAS_RELOC");
1179 PF (EXEC_P, "EXEC_P");
1180 PF (HAS_LINENO, "HAS_LINENO");
1181 PF (HAS_DEBUG, "HAS_DEBUG");
1182 PF (HAS_SYMS, "HAS_SYMS");
1183 PF (HAS_LOCALS, "HAS_LOCALS");
1184 PF (DYNAMIC, "DYNAMIC");
1185 PF (WP_TEXT, "WP_TEXT");
1186 PF (D_PAGED, "D_PAGED");
1187 PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
1188 printf ("\nstart address 0x");
1189 printf_vma (abfd->start_address);
1190}
a65619c8
SC
1191\f
1192static void
1193dump_bfd_private_header (abfd)
1194bfd *abfd;
1195{
1196 bfd_print_private_bfd_data (abfd, stdout);
1197}
02a68547 1198static void
2fa0b342
DHW
1199display_bfd (abfd)
1200 bfd *abfd;
1201{
209e5610
DM
1202 char **matching;
1203
1204 if (!bfd_check_format_matches (abfd, bfd_object, &matching))
aa0a709a 1205 {
cef35d48 1206 bfd_nonfatal (bfd_get_filename (abfd));
8f197c94 1207 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
209e5610
DM
1208 {
1209 list_matching_formats (matching);
1210 free (matching);
1211 }
aa0a709a
SC
1212 return;
1213 }
f7b839f7 1214
cef35d48
DM
1215 printf ("\n%s: file format %s\n", bfd_get_filename (abfd),
1216 abfd->xvec->name);
aa0a709a
SC
1217 if (dump_ar_hdrs)
1218 print_arelt_descr (stdout, abfd, true);
aa0a709a 1219 if (dump_file_header)
f7b839f7 1220 dump_bfd_header (abfd);
a65619c8
SC
1221 if (dump_private_headers)
1222 dump_bfd_private_header (abfd);
f7b839f7 1223 putchar ('\n');
2fa0b342 1224 if (dump_section_headers)
aa0a709a
SC
1225 dump_headers (abfd);
1226 if (dump_symtab || dump_reloc_info || disassemble)
1227 {
1228 syms = slurp_symtab (abfd);
1229 }
de3b08ac
ILT
1230 if (dump_dynamic_symtab || dump_dynamic_reloc_info)
1231 {
1232 dynsyms = slurp_dynamic_symtab (abfd);
1233 }
aa0a709a 1234 if (dump_symtab)
de3b08ac
ILT
1235 dump_symbols (abfd, false);
1236 if (dump_dynamic_symtab)
1237 dump_symbols (abfd, true);
73b8f102 1238 if (dump_stab_section_info)
9b018ecd 1239 dump_stabs (abfd);
d5464baa 1240 if (dump_reloc_info && ! disassemble)
aa0a709a 1241 dump_relocs (abfd);
de3b08ac
ILT
1242 if (dump_dynamic_reloc_info)
1243 dump_dynamic_relocs (abfd);
aa0a709a
SC
1244 if (dump_section_contents)
1245 dump_data (abfd);
1246 if (disassemble)
1247 disassemble_data (abfd);
2fa0b342
DHW
1248}
1249
d9971b83 1250static void
2fa0b342
DHW
1251display_file (filename, target)
1252 char *filename;
1253 char *target;
1254{
1255 bfd *file, *arfile = (bfd *) NULL;
1256
1257 file = bfd_openr (filename, target);
aa0a709a
SC
1258 if (file == NULL)
1259 {
cef35d48 1260 bfd_nonfatal (filename);
aa0a709a
SC
1261 return;
1262 }
2fa0b342 1263
aa0a709a
SC
1264 if (bfd_check_format (file, bfd_archive) == true)
1265 {
8f197c94
ILT
1266 bfd *last_arfile = NULL;
1267
aa0a709a
SC
1268 printf ("In archive %s:\n", bfd_get_filename (file));
1269 for (;;)
1270 {
8f197c94 1271 bfd_set_error (bfd_error_no_error);
aa0a709a
SC
1272
1273 arfile = bfd_openr_next_archived_file (file, arfile);
1274 if (arfile == NULL)
1275 {
8f197c94 1276 if (bfd_get_error () != bfd_error_no_more_archived_files)
d2442698 1277 {
cef35d48 1278 bfd_nonfatal (bfd_get_filename (file));
d2442698 1279 }
8f197c94 1280 break;
aa0a709a 1281 }
2fa0b342 1282
aa0a709a 1283 display_bfd (arfile);
8f197c94
ILT
1284
1285 if (last_arfile != NULL)
1286 bfd_close (last_arfile);
1287 last_arfile = arfile;
aa0a709a 1288 }
8f197c94
ILT
1289
1290 if (last_arfile != NULL)
1291 bfd_close (last_arfile);
2fa0b342 1292 }
2fa0b342 1293 else
aa0a709a 1294 display_bfd (file);
2fa0b342 1295
aa0a709a 1296 bfd_close (file);
2fa0b342
DHW
1297}
1298\f
1299/* Actually display the various requested regions */
1300
d9971b83 1301static void
2fa0b342
DHW
1302dump_data (abfd)
1303 bfd *abfd;
1304{
1305 asection *section;
aa0a709a 1306 bfd_byte *data = 0;
fc5d6074
SC
1307 bfd_size_type datasize = 0;
1308 bfd_size_type i;
aa21a2a9 1309 bfd_size_type start, stop;
2fa0b342
DHW
1310
1311 for (section = abfd->sections; section != NULL; section =
aa0a709a
SC
1312 section->next)
1313 {
1314 int onaline = 16;
2fa0b342 1315
aa0a709a
SC
1316 if (only == (char *) NULL ||
1317 strcmp (only, section->name) == 0)
60c80016 1318 {
aa0a709a
SC
1319 if (section->flags & SEC_HAS_CONTENTS)
1320 {
1321 printf ("Contents of section %s:\n", section->name);
1322
9b018ecd 1323 if (bfd_section_size (abfd, section) == 0)
aa0a709a 1324 continue;
02a68547 1325 data = (bfd_byte *) xmalloc ((size_t) bfd_section_size (abfd, section));
9b018ecd 1326 datasize = bfd_section_size (abfd, section);
2fa0b342 1327
2fa0b342 1328
9b018ecd 1329 bfd_get_section_contents (abfd, section, (PTR) data, 0, bfd_section_size (abfd, section));
2fa0b342 1330
aa21a2a9
ILT
1331 if (start_address == (bfd_vma) -1
1332 || start_address < section->vma)
1333 start = 0;
1334 else
1335 start = start_address - section->vma;
1336 if (stop_address == (bfd_vma) -1)
1337 stop = bfd_section_size (abfd, section);
1338 else
1339 {
1340 if (stop_address < section->vma)
1341 stop = 0;
1342 else
1343 stop = stop_address - section->vma;
1344 if (stop > bfd_section_size (abfd, section))
1345 stop = bfd_section_size (abfd, section);
1346 }
1347 for (i = start; i < stop; i += onaline)
aa0a709a
SC
1348 {
1349 bfd_size_type j;
1350
1351 printf (" %04lx ", (unsigned long int) (i + section->vma));
1352 for (j = i; j < i + onaline; j++)
1353 {
aa21a2a9 1354 if (j < stop)
aa0a709a
SC
1355 printf ("%02x", (unsigned) (data[j]));
1356 else
1357 printf (" ");
1358 if ((j & 3) == 3)
1359 printf (" ");
1360 }
2fa0b342 1361
aa0a709a
SC
1362 printf (" ");
1363 for (j = i; j < i + onaline; j++)
1364 {
aa21a2a9 1365 if (j >= stop)
aa0a709a
SC
1366 printf (" ");
1367 else
1368 printf ("%c", isprint (data[j]) ? data[j] : '.');
1369 }
1370 putchar ('\n');
1371 }
d9971b83 1372 free (data);
60c80016 1373 }
2fa0b342 1374 }
2fa0b342 1375 }
2fa0b342
DHW
1376}
1377
2fa0b342 1378/* Should perhaps share code and display with nm? */
d9971b83 1379static void
de3b08ac 1380dump_symbols (abfd, dynamic)
2fa0b342 1381 bfd *abfd;
de3b08ac 1382 boolean dynamic;
2fa0b342 1383{
de3b08ac
ILT
1384 asymbol **current;
1385 long max;
ae5d2ff5 1386 long count;
2fa0b342 1387
de3b08ac 1388 if (dynamic)
aa0a709a 1389 {
de3b08ac
ILT
1390 current = dynsyms;
1391 max = dynsymcount;
1392 if (max == 0)
1393 return;
1394 printf ("DYNAMIC SYMBOL TABLE:\n");
1395 }
1396 else
1397 {
1398 current = syms;
1399 max = symcount;
1400 if (max == 0)
1401 return;
1402 printf ("SYMBOL TABLE:\n");
1403 }
2fa0b342 1404
de3b08ac
ILT
1405 for (count = 0; count < max; count++)
1406 {
d9971b83 1407 if (*current)
aa0a709a 1408 {
d9971b83
KR
1409 bfd *cur_bfd = bfd_asymbol_bfd(*current);
1410 if (cur_bfd)
1411 {
1412 bfd_print_symbol (cur_bfd,
1413 stdout,
1414 *current, bfd_print_symbol_all);
1415 printf ("\n");
1416 }
aa0a709a
SC
1417 }
1418 current++;
2fa0b342 1419 }
aa0a709a
SC
1420 printf ("\n");
1421 printf ("\n");
2fa0b342
DHW
1422}
1423
d9971b83 1424static void
aa0a709a
SC
1425dump_relocs (abfd)
1426 bfd *abfd;
2fa0b342
DHW
1427{
1428 arelent **relpp;
ae5d2ff5 1429 long relcount;
2fa0b342 1430 asection *a;
aa0a709a
SC
1431
1432 for (a = abfd->sections; a != (asection *) NULL; a = a->next)
1433 {
ae5d2ff5
ILT
1434 long relsize;
1435
28d1b01e 1436 if (bfd_is_abs_section (a))
aa0a709a 1437 continue;
28d1b01e 1438 if (bfd_is_und_section (a))
aa0a709a 1439 continue;
d9971b83 1440 if (bfd_is_com_section (a))
aa0a709a
SC
1441 continue;
1442
195d1adf
KR
1443 if (only)
1444 {
1445 if (strcmp (only, a->name))
1446 continue;
1447 }
1448 else if ((a->flags & SEC_RELOC) == 0)
1449 continue;
1450
aa0a709a
SC
1451 printf ("RELOCATION RECORDS FOR [%s]:", a->name);
1452
ae5d2ff5
ILT
1453 relsize = bfd_get_reloc_upper_bound (abfd, a);
1454 if (relsize < 0)
1455 bfd_fatal (bfd_get_filename (abfd));
1456
1457 if (relsize == 0)
aa0a709a
SC
1458 {
1459 printf (" (none)\n\n");
d20f480f 1460 }
aa0a709a
SC
1461 else
1462 {
ae5d2ff5 1463 relpp = (arelent **) xmalloc (relsize);
aa0a709a 1464 relcount = bfd_canonicalize_reloc (abfd, a, relpp, syms);
ae5d2ff5
ILT
1465 if (relcount < 0)
1466 bfd_fatal (bfd_get_filename (abfd));
1467 else if (relcount == 0)
aa0a709a
SC
1468 {
1469 printf (" (none)\n\n");
d20f480f 1470 }
aa0a709a
SC
1471 else
1472 {
1473 printf ("\n");
de3b08ac 1474 dump_reloc_set (abfd, relpp, relcount);
aa0a709a 1475 printf ("\n\n");
d20f480f 1476 }
de3b08ac 1477 free (relpp);
2fa0b342 1478 }
de3b08ac
ILT
1479 }
1480}
2fa0b342 1481
de3b08ac
ILT
1482static void
1483dump_dynamic_relocs (abfd)
1484 bfd *abfd;
1485{
1486 long relsize;
1487 arelent **relpp;
1488 long relcount;
1489
1490 printf ("DYNAMIC RELOCATION RECORDS");
1491
1492 relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
1493 if (relsize < 0)
1494 bfd_fatal (bfd_get_filename (abfd));
1495
1496 if (relsize == 0)
1497 {
1498 printf (" (none)\n\n");
1499 }
1500 else
1501 {
1502 relpp = (arelent **) xmalloc (relsize);
1503 relcount = bfd_canonicalize_dynamic_reloc (abfd, relpp, dynsyms);
1504 if (relcount < 0)
1505 bfd_fatal (bfd_get_filename (abfd));
1506 else if (relcount == 0)
1507 {
1508 printf (" (none)\n\n");
1509 }
1510 else
1511 {
1512 printf ("\n");
1513 dump_reloc_set (abfd, relpp, relcount);
1514 printf ("\n\n");
1515 }
1516 free (relpp);
1517 }
1518}
1519
1520static void
1521dump_reloc_set (abfd, relpp, relcount)
1522 bfd *abfd;
1523 arelent **relpp;
1524 long relcount;
1525{
1526 arelent **p;
1527
1528 /* Get column headers lined up reasonably. */
1529 {
1530 static int width;
1531 if (width == 0)
1532 {
1533 char buf[30];
1534 sprintf_vma (buf, (bfd_vma) -1);
1535 width = strlen (buf) - 7;
1536 }
1537 printf ("OFFSET %*s TYPE %*s VALUE \n", width, "", 12, "");
1538 }
1539
1540 for (p = relpp; relcount && *p != (arelent *) NULL; p++, relcount--)
1541 {
1542 arelent *q = *p;
1543 CONST char *sym_name;
1544 CONST char *section_name;
1545
aa21a2a9
ILT
1546 if (start_address != (bfd_vma) -1
1547 && q->address < start_address)
1548 continue;
1549 if (stop_address != (bfd_vma) -1
1550 && q->address > stop_address)
1551 continue;
1552
de3b08ac
ILT
1553 if (q->sym_ptr_ptr && *q->sym_ptr_ptr)
1554 {
1555 sym_name = (*(q->sym_ptr_ptr))->name;
1556 section_name = (*(q->sym_ptr_ptr))->section->name;
1557 }
1558 else
1559 {
1560 sym_name = NULL;
1561 section_name = NULL;
1562 }
1563 if (sym_name)
1564 {
1565 printf_vma (q->address);
1566 printf (" %-16s %s",
1567 q->howto->name,
1568 sym_name);
1569 }
1570 else
1571 {
1572 if (section_name == (CONST char *) NULL)
1573 section_name = "*unknown*";
1574 printf_vma (q->address);
1575 printf (" %-16s [%s]",
1576 q->howto->name,
1577 section_name);
1578 }
1579 if (q->addend)
1580 {
1581 printf ("+0x");
1582 printf_vma (q->addend);
1583 }
1584 printf ("\n");
d20f480f 1585 }
2fa0b342 1586}
f7b839f7 1587\f
f7b839f7
DM
1588/* The length of the longest architecture name + 1. */
1589#define LONGEST_ARCH sizeof("rs6000:6000")
1590
be1d162b
ILT
1591#ifndef L_tmpnam
1592#define L_tmpnam 25
1593#endif
1594
f7b839f7
DM
1595/* List the targets that BFD is configured to support, each followed
1596 by its endianness and the architectures it supports. */
1597
1598static void
1599display_target_list ()
1600{
de04bceb 1601 extern char *tmpnam ();
f7b839f7 1602 extern bfd_target *bfd_target_vector[];
be1d162b 1603 char tmparg[L_tmpnam];
de04bceb 1604 char *dummy_name;
f7b839f7
DM
1605 int t;
1606
be1d162b 1607 dummy_name = tmpnam (tmparg);
f7b839f7
DM
1608 for (t = 0; bfd_target_vector[t]; t++)
1609 {
f7b839f7 1610 bfd_target *p = bfd_target_vector[t];
de04bceb 1611 bfd *abfd = bfd_openw (dummy_name, p->name);
105da05c
ILT
1612 int a;
1613
1614 printf ("%s\n (header %s, data %s)\n", p->name,
1615 p->header_byteorder_big_p ? "big endian" : "little endian",
1616 p->byteorder_big_p ? "big endian" : "little endian");
f7b839f7 1617
334d6e76
SS
1618 if (abfd == NULL)
1619 {
de04bceb 1620 bfd_nonfatal (dummy_name);
105da05c 1621 continue;
334d6e76 1622 }
105da05c
ILT
1623
1624 if (! bfd_set_format (abfd, bfd_object))
1625 {
1626 if (bfd_get_error () != bfd_error_invalid_operation)
1627 bfd_nonfatal (p->name);
1628 continue;
1629 }
1630
f7b839f7
DM
1631 for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
1632 if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
1633 printf (" %s\n",
1634 bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
1635 }
de04bceb 1636 unlink (dummy_name);
f7b839f7
DM
1637}
1638
1639/* Print a table showing which architectures are supported for entries
1640 FIRST through LAST-1 of bfd_target_vector (targets across,
1641 architectures down). */
1642
9872a49c 1643static void
abdcac0f
DM
1644display_info_table (first, last)
1645 int first;
1646 int last;
9872a49c 1647{
abdcac0f 1648 extern bfd_target *bfd_target_vector[];
de04bceb 1649 extern char *tmpnam ();
be1d162b 1650 char tmparg[L_tmpnam];
de04bceb
ILT
1651 int t, a;
1652 char *dummy_name;
9872a49c 1653
f7b839f7 1654 /* Print heading of target names. */
ae5d2ff5 1655 printf ("\n%*s", (int) LONGEST_ARCH, " ");
105da05c 1656 for (t = first; t < last && bfd_target_vector[t]; t++)
f7b839f7
DM
1657 printf ("%s ", bfd_target_vector[t]->name);
1658 putchar ('\n');
9872a49c 1659
be1d162b 1660 dummy_name = tmpnam (tmparg);
f7b839f7
DM
1661 for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
1662 if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0)
e779a58c 1663 {
ae5d2ff5
ILT
1664 printf ("%*s ", (int) LONGEST_ARCH - 1,
1665 bfd_printable_arch_mach (a, 0));
105da05c 1666 for (t = first; t < last && bfd_target_vector[t]; t++)
aa0a709a 1667 {
f7b839f7 1668 bfd_target *p = bfd_target_vector[t];
105da05c 1669 boolean ok = true;
de04bceb 1670 bfd *abfd = bfd_openw (dummy_name, p->name);
aa0a709a 1671
334d6e76
SS
1672 if (abfd == NULL)
1673 {
105da05c
ILT
1674 bfd_nonfatal (p->name);
1675 ok = false;
1676 }
1677
1678 if (ok)
1679 {
1680 if (! bfd_set_format (abfd, bfd_object))
1681 {
1682 if (bfd_get_error () != bfd_error_invalid_operation)
1683 bfd_nonfatal (p->name);
1684 ok = false;
1685 }
334d6e76 1686 }
105da05c
ILT
1687
1688 if (ok)
1689 {
1690 if (! bfd_set_arch_mach (abfd, a, 0))
1691 ok = false;
1692 }
1693
1694 if (ok)
aa0a709a
SC
1695 printf ("%s ", p->name);
1696 else
e779a58c 1697 {
f7b839f7 1698 int l = strlen (p->name);
aa0a709a 1699 while (l--)
f7b839f7
DM
1700 putchar ('-');
1701 putchar (' ');
e779a58c 1702 }
e779a58c 1703 }
f7b839f7 1704 putchar ('\n');
e779a58c 1705 }
de04bceb 1706 unlink (dummy_name);
9872a49c 1707}
aa0a709a 1708
f7b839f7
DM
1709/* Print tables of all the target-architecture combinations that
1710 BFD has been configured to support. */
1711
aa0a709a 1712static void
f7b839f7 1713display_target_tables ()
aa0a709a 1714{
f7b839f7 1715 int t, columns;
abdcac0f 1716 extern bfd_target *bfd_target_vector[];
f7b839f7 1717 char *colum;
aa0a709a
SC
1718 extern char *getenv ();
1719
aa0a709a 1720 columns = 0;
f7b839f7
DM
1721 colum = getenv ("COLUMNS");
1722 if (colum != NULL)
aa0a709a 1723 columns = atoi (colum);
f7b839f7 1724 if (columns == 0)
aa0a709a 1725 columns = 80;
f7b839f7 1726
105da05c
ILT
1727 t = 0;
1728 while (bfd_target_vector[t] != NULL)
aa0a709a 1729 {
f7b839f7
DM
1730 int oldt = t, wid;
1731
105da05c
ILT
1732 wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
1733 ++t;
1734 while (wid < columns && bfd_target_vector[t] != NULL)
1735 {
1736 int newwid;
1737
1738 newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
1739 if (newwid >= columns)
1740 break;
1741 wid = newwid;
1742 ++t;
1743 }
f7b839f7 1744 display_info_table (oldt, t);
aa0a709a
SC
1745 }
1746}
1747
f7b839f7
DM
1748static void
1749display_info ()
1750{
1751 printf ("BFD header file version %s\n", BFD_VERSION);
1752 display_target_list ();
1753 display_target_tables ();
1754}
1755
2fa0b342
DHW
1756int
1757main (argc, argv)
1758 int argc;
1759 char **argv;
1760{
1761 int c;
2fa0b342
DHW
1762 char *target = default_target;
1763 boolean seenflag = false;
2fa0b342
DHW
1764
1765 program_name = *argv;
8f197c94
ILT
1766 xmalloc_set_program_name (program_name);
1767
be1d162b
ILT
1768 START_PROGRESS (program_name, 0);
1769
8f197c94 1770 bfd_init ();
2fa0b342 1771
a65619c8 1772 while ((c = getopt_long (argc, argv, "pib:m:VdDlfahrRtTxsSj:w", long_options,
d2442698 1773 (int *) 0))
aa0a709a
SC
1774 != EOF)
1775 {
aa21a2a9
ILT
1776 if (c != 'l' && c != OPTION_START_ADDRESS && c != OPTION_STOP_ADDRESS)
1777 seenflag = true;
aa0a709a
SC
1778 switch (c)
1779 {
b3a2b497
ILT
1780 case 0:
1781 break; /* we've been given a long option */
aa0a709a
SC
1782 case 'm':
1783 machine = optarg;
1784 break;
1785 case 'j':
1786 only = optarg;
1787 break;
1788 case 'l':
1789 with_line_numbers = 1;
1790 break;
1791 case 'b':
1792 target = optarg;
1793 break;
1794 case 'f':
1795 dump_file_header = true;
1796 break;
1797 case 'i':
e1ec9f07 1798 formats_info = true;
aa0a709a 1799 break;
a65619c8
SC
1800 case 'p':
1801 dump_private_headers = 1;
1802 break;
aa0a709a 1803 case 'x':
a65619c8 1804 dump_private_headers = 1;
aa0a709a
SC
1805 dump_symtab = 1;
1806 dump_reloc_info = 1;
1807 dump_file_header = true;
1808 dump_ar_hdrs = 1;
1809 dump_section_headers = 1;
1810 break;
aa0a709a
SC
1811 case 't':
1812 dump_symtab = 1;
1813 break;
de3b08ac
ILT
1814 case 'T':
1815 dump_dynamic_symtab = 1;
1816 break;
aa0a709a
SC
1817 case 'd':
1818 disassemble = true;
1819 break;
d5464baa
ILT
1820 case 'D':
1821 disassemble = disassemble_all = true;
1822 break;
be1d162b
ILT
1823 case 'S':
1824 disassemble = true;
1825 with_source_code = true;
1826 break;
aa0a709a
SC
1827 case 's':
1828 dump_section_contents = 1;
1829 break;
1830 case 'r':
1831 dump_reloc_info = 1;
1832 break;
de3b08ac
ILT
1833 case 'R':
1834 dump_dynamic_reloc_info = 1;
1835 break;
aa0a709a
SC
1836 case 'a':
1837 dump_ar_hdrs = 1;
1838 break;
1839 case 'h':
1840 dump_section_headers = 1;
1841 break;
b3a2b497
ILT
1842 case 'H':
1843 usage (stdout, 0);
249c6fc0
RS
1844 case 'V':
1845 show_version = 1;
1846 break;
13e4db2e
SC
1847 case 'w':
1848 wide_output = 1;
1849 break;
aa21a2a9
ILT
1850 case OPTION_START_ADDRESS:
1851 start_address = parse_vma (optarg, "--start-address");
1852 break;
1853 case OPTION_STOP_ADDRESS:
1854 stop_address = parse_vma (optarg, "--stop-address");
1855 break;
aa0a709a 1856 default:
b3a2b497 1857 usage (stderr, 1);
aa0a709a 1858 }
2fa0b342 1859 }
2fa0b342 1860
249c6fc0 1861 if (show_version)
b3a2b497
ILT
1862 {
1863 printf ("GNU %s version %s\n", program_name, program_version);
1864 exit (0);
1865 }
249c6fc0 1866
2fa0b342 1867 if (seenflag == false)
b3a2b497 1868 usage (stderr, 1);
2fa0b342 1869
e1ec9f07 1870 if (formats_info)
aa0a709a
SC
1871 {
1872 display_info ();
1873 }
1874 else
1875 {
1876 if (optind == argc)
1877 display_file ("a.out", target);
1878 else
1879 for (; optind < argc;)
1880 display_file (argv[optind++], target);
1881 }
be1d162b
ILT
1882
1883 END_PROGRESS (program_name);
1884
2fa0b342
DHW
1885 return 0;
1886}