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