* bucomm.c (list_supported_targets): New function.
[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, 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 }