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