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