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