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