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