242d6007038433cdb15b48dcde05291a45674d16
[external/binutils.git] / binutils / objdump.c
1 /* objdump.c -- dump information about an object file.
2    Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Diddler.
5
6 BFD 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 BFD 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 BFD; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 /*
21  * Until there is other documentation, refer to the manual page dump(1) in
22  * the system 5 program's reference manual
23  */
24
25 #include "bfd.h"
26 #include "sysdep.h"
27 #include "getopt.h"
28 #include <stdio.h>
29 #include <ctype.h>
30 #include "dis-asm.h"
31
32 #define ELF_STAB_DISPLAY        /* This code works, but uses internal
33                                    bfd and elf stuff.  Flip this define
34                                    off if you need to just use generic
35                                    BFD interfaces.  */
36
37 #ifdef  ELF_STAB_DISPLAY
38 /* Internal headers for the ELF .stab-dump code - sorry.  */
39 #define BYTES_IN_WORD   32
40 #include "aout/aout64.h"
41 #include "elf/internal.h"
42 extern Elf_Internal_Shdr *bfd_elf_find_section();
43 #endif  /* ELF_STAB_DISPLAY */
44
45 extern char *xmalloc ();
46
47 char *default_target = NULL;    /* default at runtime */
48
49 extern *program_version;
50 char *program_name = NULL;
51
52 int show_version = 0;           /* show the version number */
53 int dump_section_contents;      /* -s */
54 int dump_section_headers;       /* -h */
55 boolean dump_file_header;       /* -f */
56 int dump_symtab;                /* -t */
57 int dump_reloc_info;            /* -r */
58 int dump_ar_hdrs;               /* -a */
59 int with_line_numbers;          /* -l */
60 int dump_stab_section_info;     /* -stabs */
61 boolean disassemble;            /* -d */
62 boolean info;                   /* -i */
63 char *only;
64
65 char *machine = (char *) NULL;
66 asymbol **syms;
67 asymbol **syms2;
68
69 unsigned int storage;
70
71 unsigned int symcount = 0;
72
73 /* Forward declarations.  */
74
75 static void
76 display_file PARAMS ((char *filename, char *target));
77
78 static void
79 dump_data PARAMS ((bfd *abfd));
80
81 static void
82 dump_relocs PARAMS ((bfd *abfd));
83
84 static void
85 dump_symbols PARAMS ((bfd *abfd));
86 \f
87 void
88 usage ()
89 {
90   fprintf (stderr, "\
91 usage: %s [-ahifdrtxsl] [-m machine] [-j section_name]\n\
92          [--syms] [--reloc] [--header] [--version] obj ...\n",
93            program_name);
94   exit (1);
95 }
96
97 static struct option long_options[]=
98 {
99   {"syms", no_argument, &dump_symtab, 1},
100   {"reloc", no_argument, &dump_reloc_info, 1},
101   {"header", no_argument, &dump_section_headers, 1},
102   {"version", no_argument, &show_version,    1},
103 #ifdef  ELF_STAB_DISPLAY
104   {"stabs", no_argument, &dump_stab_section_info, 1},
105 #endif
106   {0, no_argument, 0, 0}};
107
108
109 static void
110 dump_headers (abfd)
111      bfd *abfd;
112 {
113   asection *section;
114
115   for (section = abfd->sections;
116        section != (asection *) NULL;
117        section = section->next)
118     {
119       char *comma = "";
120
121 #define PF(x,y) \
122         if (section->flags & x) {  printf("%s%s",comma,y); comma = ", "; }
123
124
125       printf ("SECTION %d [%s]\t: size %08x",
126               section->index,
127               section->name,
128               (unsigned) bfd_get_section_size_before_reloc (section));
129       printf (" vma ");
130       printf_vma (section->vma);
131       printf (" align 2**%u\n ",
132               section->alignment_power);
133       PF (SEC_ALLOC, "ALLOC");
134       PF (SEC_CONSTRUCTOR, "CONSTRUCTOR");
135       PF (SEC_CONSTRUCTOR_TEXT, "CONSTRUCTOR TEXT");
136       PF (SEC_CONSTRUCTOR_DATA, "CONSTRUCTOR DATA");
137       PF (SEC_CONSTRUCTOR_BSS, "CONSTRUCTOR BSS");
138       PF (SEC_LOAD, "LOAD");
139       PF (SEC_RELOC, "RELOC");
140       PF (SEC_BALIGN, "BALIGN");
141       PF (SEC_READONLY, "READONLY");
142       PF (SEC_CODE, "CODE");
143       PF (SEC_DATA, "DATA");
144       PF (SEC_ROM, "ROM");
145       printf ("\n");
146 #undef PF
147     }
148 }
149
150 static asymbol **
151 DEFUN (slurp_symtab, (abfd),
152        bfd * abfd)
153 {
154   asymbol **sy = (asymbol **) NULL;
155
156   if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
157     {
158       (void) printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
159       return (NULL);
160     }
161
162   storage = get_symtab_upper_bound (abfd);
163   if (storage)
164     {
165       sy = (asymbol **) malloc (storage);
166       if (sy == NULL)
167         {
168           fprintf (stderr, "%s: out of memory.\n", program_name);
169           exit (1);
170         }
171     }
172   symcount = bfd_canonicalize_symtab (abfd, sy);
173   return sy;
174 }
175
176 /* Sort symbols into value order */
177 static int 
178 comp (ap, bp)
179      PTR ap;
180      PTR bp;
181 {
182   asymbol *a = *(asymbol **)ap;
183   asymbol *b = *(asymbol **)bp;
184   int diff;
185   bfd *a_bfd, *b_bfd;
186
187   if (a->name == (char *) NULL || (a->flags & (BSF_DEBUGGING)))
188     a_bfd = 0;
189   else
190     a_bfd = bfd_asymbol_bfd(a);
191   if (b->name == (char *) NULL || (b->flags & (BSF_DEBUGGING)))
192     b_bfd = 0;
193   else
194     b_bfd = bfd_asymbol_bfd(b);
195
196   diff = a_bfd - b_bfd;
197   if (diff)
198     {
199       return -diff;
200     }
201   diff = a->value - b->value;
202   if (diff)
203     {
204       return diff;
205     }
206   return a->section - b->section;
207 }
208
209 /* Print the supplied address symbolically if possible */
210 void
211 objdump_print_address (vma, info)
212      bfd_vma vma;
213      struct disassemble_info *info;
214 {
215   /* Perform a binary search looking for the closest symbol to
216      the required value */
217
218   unsigned int min = 0;
219   unsigned int max = symcount;
220
221   unsigned int thisplace = 1;
222   unsigned int oldthisplace;
223
224   int vardiff;
225
226   if (symcount == 0)
227     {
228       fprintf_vma (info->stream, vma);
229     }
230   else
231     {
232       while (true)
233         {
234           oldthisplace = thisplace;
235           thisplace = (max + min) / 2;
236           if (thisplace == oldthisplace)
237             break;
238           vardiff = syms[thisplace]->value - vma;
239
240           if (vardiff
241               /* Check that the value isn't merely a coincidence.
242                  (if not checked, we might print some undefined symbol
243                  for the address 0 rather than "main", for example.  */
244               || !(syms[thisplace]->flags & (BSF_GLOBAL|BSF_LOCAL)))
245             {
246               if (vardiff > 0)
247                 {
248                   max = thisplace;
249                 }
250               else
251                 {
252                   min = thisplace;
253                 }
254             }
255           else
256             {
257               /* Totally awesome! the exact right symbol */
258               CONST char *match_name = syms[thisplace]->name;
259               int sym_len = strlen (match_name);
260
261               /* Avoid "filename.o" as a match */
262               if (sym_len > 2
263                   && match_name[sym_len - 2] == '.'
264                   && match_name[sym_len - 1] == 'o'
265                   && thisplace + 1 < symcount
266                   && syms[thisplace + 1]->value == vma)
267                 match_name = syms[thisplace + 1]->name;
268               /* Totally awesome! the exact right symbol */
269               fprintf_vma (info->stream, vma);
270               fprintf (info->stream, " (%s+)0000", syms[thisplace]->name);
271               return;
272             }
273         }
274       /* We've run out of places to look, print the symbol before this one
275          see if this or the symbol before describes this location the best */
276
277       if (thisplace != 0)
278         {
279           if (syms[thisplace - 1]->value - vma >
280               syms[thisplace]->value - vma)
281             {
282               /* Previous symbol is in correct section and is closer */
283               thisplace--;
284             }
285         }
286
287       fprintf_vma (info->stream, vma);
288       if (syms[thisplace]->value > vma)
289         {
290           fprintf (info->stream, " (%s-)", syms[thisplace]->name);
291           fprintf (info->stream, "%04x", syms[thisplace]->value - vma);
292         }
293       else
294         {
295           fprintf (info->stream, " (%s+)", syms[thisplace]->name);
296           fprintf (info->stream, "%04x", vma - syms[thisplace]->value);
297         }
298     }
299 }
300
301 void
302 disassemble_data (abfd)
303      bfd *abfd;
304 {
305   bfd_byte *data = NULL;
306   bfd_arch_info_type *info;
307   bfd_size_type datasize = 0;
308   bfd_size_type i;
309   unsigned int (*print) ()= 0; /* Old style */
310   disassembler_ftype disassemble = 0; /* New style */
311   unsigned int print_insn_h8300 ();
312   enum bfd_architecture a;
313   struct disassemble_info disasm_info;
314
315   int prevline;
316   CONST char *prev_function = "";
317
318   asection *section;
319
320   /* Replace symbol section relative values with abs values */
321   boolean done_dot = false;
322
323   INIT_DISASSEMBLE_INFO(disasm_info, stdout);
324   disasm_info.print_address_func = objdump_print_address;
325
326   for (i = 0; i < symcount; i++)
327     {
328       syms[i]->value += syms[i]->section->vma;
329     }
330
331   /* We keep a copy of the symbols in the original order */
332   syms2 = slurp_symtab (abfd);
333
334   /* Sort the symbols into section and symbol order */
335   (void) qsort (syms, symcount, sizeof (asymbol *), comp);
336
337   /* Find the first useless symbol */
338   {
339     unsigned int i;
340
341     for (i = 0; i < symcount; i++)
342       {
343         if (syms[i]->name == (char *) NULL
344             || (syms[i]->flags & BSF_DEBUGGING) != 0)
345           {
346             symcount = i;
347             break;
348           }
349       }
350   }
351
352
353   if (machine != (char *) NULL)
354     {
355       info = bfd_scan_arch (machine);
356       if (info == 0)
357         {
358           fprintf (stderr, "%s: Can't use supplied machine %s\n",
359                    program_name,
360                    machine);
361           exit (1);
362         }
363       abfd->arch_info = info;
364     }
365
366   /* See if we can disassemble using bfd */
367
368   if (abfd->arch_info->disassemble)
369     {
370       print = abfd->arch_info->disassemble;
371     }
372   else
373     {
374       a = bfd_get_arch (abfd);
375       switch (a)
376         {
377         case bfd_arch_sparc:
378           disassemble = print_insn_sparc;
379           break;
380         case bfd_arch_z8k:
381           if (bfd_get_mach(abfd) == bfd_mach_z8001)
382            disassemble = print_insn_z8001;
383           else 
384            disassemble = print_insn_z8002;
385           break;
386         case bfd_arch_i386:
387           disassemble = print_insn_i386;
388           break;
389         case bfd_arch_h8500:
390           disassemble = print_insn_h8500;
391           break;
392         case bfd_arch_m68k:
393           disassemble = print_insn_m68k;
394           break;
395         case bfd_arch_a29k:
396           /* As far as I know we only handle big-endian 29k objects.  */
397           disassemble = print_insn_big_a29k;
398           break;
399         case bfd_arch_i960:
400           disassemble = print_insn_i960;
401           break;
402         case bfd_arch_mips:
403           if (abfd->xvec->byteorder_big_p)
404             disassemble = print_insn_big_mips;
405           else
406             disassemble = print_insn_little_mips;
407           break;
408         default:
409           fprintf (stderr, "%s: Can't disassemble for architecture %s\n",
410                    program_name,
411                    bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
412           exit (1);
413         }
414
415     }
416
417   for (section = abfd->sections;
418        section != (asection *) NULL;
419        section = section->next)
420     {
421
422       if ((section->flags & SEC_LOAD)
423           && (only == (char *) NULL || strcmp (only, section->name) == 0))
424         {
425           printf ("Disassembly of section %s:\n", section->name);
426
427           if (bfd_get_section_size_before_reloc (section) == 0)
428             continue;
429
430           data = (bfd_byte *) malloc (bfd_get_section_size_before_reloc (section));
431
432           if (data == (bfd_byte *) NULL)
433             {
434               fprintf (stderr, "%s: memory exhausted.\n", program_name);
435               exit (1);
436             }
437           datasize = bfd_get_section_size_before_reloc (section);
438
439           bfd_get_section_contents (abfd, section, data, 0, bfd_get_section_size_before_reloc (section));
440
441           disasm_info.buffer = data;
442           disasm_info.buffer_vma = section->vma;
443           disasm_info.buffer_length =
444             bfd_get_section_size_before_reloc (section);
445           i = 0;
446           while (i < disasm_info.buffer_length)
447             {
448               if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 0 &&
449                   data[i + 3] == 0)
450                 {
451                   if (done_dot == false)
452                     {
453                       printf ("...\n");
454                       done_dot = true;
455                     }
456                   i += 4;
457                 }
458               else
459                 {
460                   done_dot = false;
461                   if (with_line_numbers)
462                     {
463                       CONST char *filename;
464                       CONST char *functionname;
465                       unsigned int line;
466
467                       if (bfd_find_nearest_line (abfd,
468                                                  section,
469                                                  syms,
470                                                  section->vma + i,
471                                                  &filename,
472                                                  &functionname,
473                                                  &line))
474                         {
475                           if (functionname && *functionname
476                               && strcmp(functionname, prev_function))
477                             {
478                               printf ("%s():\n", functionname);
479                               prev_function = functionname;
480                             }
481                           if (!filename)
482                             filename = "???";
483                           if (line && line != prevline)
484                             {
485                               printf ("%s:%u\n", filename, line);
486                               prevline = line;
487                             }
488                         }
489                     }
490                   objdump_print_address (section->vma + i, &disasm_info);
491                   printf (" ");
492
493                   if (disassemble) /* New style */
494                     {
495                       int bytes = (*disassemble)(section->vma + i,
496                                                  &disasm_info);
497                       if (bytes < 0)
498                         break;
499                       i += bytes;
500                     }
501                   else /* Old style */
502                     i += print (section->vma + i,
503                                 data + i,
504                                 stdout);
505                   putchar ('\n');
506                 }
507             }
508           free (data);
509         }
510     }
511 }
512 \f
513 #ifdef  ELF_STAB_DISPLAY
514
515 /* Define a table of stab values and print-strings.  We wish the initializer
516    could be a direct-mapped table, but instead we build one the first
517    time we need it.  */
518
519 #define STAB_STRING_LENGTH      6
520
521 char stab_name[256][STAB_STRING_LENGTH];
522
523 struct stab_print {
524   int value;
525   char string[STAB_STRING_LENGTH];
526 };
527
528 struct stab_print stab_print[] = {
529 #define __define_stab(NAME, CODE, STRING) {CODE, STRING},
530 #include "aout/stab.def"
531 #undef __define_stab
532   {0, 0}
533 };
534
535 void dump_elf_stabs_1 ();
536
537 /* This is a kludge for dumping the stabs section from an ELF file that
538    uses Sun stabs encoding.  It has to use some hooks into BFD because
539    string table sections are not normally visible to BFD callers.  */
540
541 void
542 dump_elf_stabs (abfd)
543      bfd *abfd;
544 {
545   int i;
546
547   /* Initialize stab name array if first time.  */
548   if (stab_name[0][0] == 0) 
549     {
550       /* Fill in numeric values for all possible strings.  */
551       for (i = 0; i < 256; i++)
552         {
553           sprintf (stab_name[i], "%d", i);
554         }
555       for (i = 0; stab_print[i].string[0]; i++)
556         strcpy (stab_name[stab_print[i].value], stab_print[i].string);
557     }
558
559   if (0 != strncmp ("elf", abfd->xvec->name, 3))
560     {
561       fprintf (stderr, "%s: %s is not in ELF format.\n", program_name,
562                abfd->filename);
563       return;
564     }
565
566   dump_elf_stabs_1 (abfd, ".stab", ".stabstr");
567   dump_elf_stabs_1 (abfd, ".stab.excl", ".stab.exclstr");
568   dump_elf_stabs_1 (abfd, ".stab.index", ".stab.indexstr");
569 }
570
571 void
572 dump_elf_stabs_1 (abfd, name1, name2)
573      bfd *abfd;
574      char *name1;               /* Section name of .stab */
575      char *name2;               /* Section name of its string section */
576 {
577   Elf_Internal_Shdr *stab_hdr, *stabstr_hdr;
578   char *strtab;
579   struct internal_nlist *stabs, *stabs_end;
580   int i;
581   unsigned file_string_table_offset, next_file_string_table_offset;
582
583   stab_hdr = bfd_elf_find_section (abfd, name1);
584   if (0 == stab_hdr)
585     {
586       printf ("Contents of %s section:  none.\n\n", name1);
587       return;
588     }
589
590   stabstr_hdr = bfd_elf_find_section (abfd, name2);
591   if (0 == stabstr_hdr)
592     {
593       fprintf (stderr, "%s: %s has no %s section.\n", program_name,
594                abfd->filename, name2);
595       return;
596     }
597
598   stabs  = (struct internal_nlist *) xmalloc (stab_hdr   ->sh_size);
599   strtab = (char *)                  xmalloc (stabstr_hdr->sh_size);
600   stabs_end = (struct internal_nlist *) (stab_hdr->sh_size + (char *)stabs);
601   
602   if (bfd_seek (abfd, stab_hdr->sh_offset, SEEK_SET) < 0 ||
603       stab_hdr->sh_size != bfd_read ((PTR)stabs, stab_hdr->sh_size, 1, abfd))
604     {
605       fprintf (stderr, "%s: reading %s section of %s failed.\n",
606                program_name, name1, 
607                abfd->filename);
608       return;
609     }
610
611   if (bfd_seek (abfd, stabstr_hdr->sh_offset, SEEK_SET) < 0 ||
612       stabstr_hdr->sh_size != bfd_read ((PTR)strtab, stabstr_hdr->sh_size,
613                                         1, abfd))
614     {
615       fprintf (stderr, "%s: reading %s section of %s failed.\n",
616                program_name, name2,
617                abfd->filename);
618       return;
619     }
620
621 #define SWAP_SYMBOL(symp, abfd) \
622   { \
623     (symp)->n_strx = bfd_h_get_32(abfd,                 \
624                                 (unsigned char *)&(symp)->n_strx);      \
625     (symp)->n_desc = bfd_h_get_16 (abfd,                        \
626                                 (unsigned char *)&(symp)->n_desc);      \
627     (symp)->n_value = bfd_h_get_32 (abfd,                       \
628                                 (unsigned char *)&(symp)->n_value);     \
629   }
630
631   printf ("Contents of %s section:\n\n", name1);
632   printf ("Symnum n_type n_othr n_desc n_value  n_strx String\n");
633
634   file_string_table_offset = 0;
635   next_file_string_table_offset = 0;
636
637   /* Loop through all symbols and print them.
638
639      We start the index at -1 because there is a dummy symbol on
640      the front of Sun's stabs-in-elf sections.  */
641
642   for (i = -1; stabs < stabs_end; stabs++, i++)
643     {
644       SWAP_SYMBOL (stabs, abfd);
645       printf ("\n%-6d %-6s %-6d %-6d %08x %-6d", i,
646               stab_name [stabs->n_type],
647               stabs->n_other, stabs->n_desc, stabs->n_value,
648               stabs->n_strx);
649
650       /* Symbols with type == 0 (N_UNDF) specify the length of the
651          string table associated with this file.  We use that info
652          to know how to relocate the *next* file's string table indices.  */
653
654       if (stabs->n_type == N_UNDF)
655         {
656           file_string_table_offset = next_file_string_table_offset;
657           next_file_string_table_offset += stabs->n_value;
658         }
659
660       /* Now, using the possibly updated string table offset, print the
661          string (if any) associated with this symbol.  */
662
663       if ((stabs->n_strx + file_string_table_offset) < stabstr_hdr->sh_size)
664         printf (" %s", &strtab[stabs->n_strx + file_string_table_offset]);
665       else
666         printf (" *");
667     }
668   printf ("\n\n");
669 }
670 #endif  /* ELF_STAB_DISPLAY */
671
672 display_bfd (abfd)
673      bfd *abfd;
674 {
675
676   if (!bfd_check_format (abfd, bfd_object))
677     {
678       fprintf (stderr, "%s: %s not an object file\n", program_name,
679                abfd->filename);
680       return;
681     }
682   printf ("\n%s:     file format %s\n", abfd->filename, abfd->xvec->name);
683   if (dump_ar_hdrs)
684     print_arelt_descr (stdout, abfd, true);
685
686   if (dump_file_header)
687     {
688       char *comma = "";
689
690       printf ("architecture: %s, ",
691               bfd_printable_arch_mach (bfd_get_arch (abfd),
692                                        bfd_get_mach (abfd)));
693       printf ("flags 0x%08x:\n", abfd->flags);
694
695 #define PF(x, y)    if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
696       PF (HAS_RELOC, "HAS_RELOC");
697       PF (EXEC_P, "EXEC_P");
698       PF (HAS_LINENO, "HAS_LINENO");
699       PF (HAS_DEBUG, "HAS_DEBUG");
700       PF (HAS_SYMS, "HAS_SYMS");
701       PF (HAS_LOCALS, "HAS_LOCALS");
702       PF (DYNAMIC, "DYNAMIC");
703       PF (WP_TEXT, "WP_TEXT");
704       PF (D_PAGED, "D_PAGED");
705       PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
706       printf ("\nstart address 0x");
707       printf_vma (abfd->start_address);
708     }
709   printf ("\n");
710
711   if (dump_section_headers)
712     dump_headers (abfd);
713   if (dump_symtab || dump_reloc_info || disassemble)
714     {
715       syms = slurp_symtab (abfd);
716     }
717   if (dump_symtab)
718     dump_symbols (abfd);
719 #ifdef  ELF_STAB_DISPLAY
720   if (dump_stab_section_info)
721     dump_elf_stabs (abfd);
722 #endif
723   if (dump_reloc_info)
724     dump_relocs (abfd);
725   if (dump_section_contents)
726     dump_data (abfd);
727   if (disassemble)
728     disassemble_data (abfd);
729 }
730
731 static void
732 display_file (filename, target)
733      char *filename;
734      char *target;
735 {
736   bfd *file, *arfile = (bfd *) NULL;
737
738   file = bfd_openr (filename, target);
739   if (file == NULL)
740     {
741       bfd_perror (filename);
742       return;
743     }
744
745   if (bfd_check_format (file, bfd_archive) == true)
746     {
747       printf ("In archive %s:\n", bfd_get_filename (file));
748       for (;;)
749         {
750           bfd_error = no_error;
751
752           arfile = bfd_openr_next_archived_file (file, arfile);
753           if (arfile == NULL)
754             {
755               if (bfd_error != no_more_archived_files)
756                 bfd_perror (bfd_get_filename (file));
757               return;
758             }
759
760           display_bfd (arfile);
761           /* Don't close the archive elements; we need them for next_archive */
762         }
763     }
764   else
765     display_bfd (file);
766
767   bfd_close (file);
768 }
769 \f
770 /* Actually display the various requested regions */
771
772 static void
773 dump_data (abfd)
774      bfd *abfd;
775 {
776   asection *section;
777   bfd_byte *data = 0;
778   bfd_size_type datasize = 0;
779   bfd_size_type i;
780
781   for (section = abfd->sections; section != NULL; section =
782        section->next)
783     {
784       int onaline = 16;
785
786       if (only == (char *) NULL ||
787           strcmp (only, section->name) == 0)
788         {
789           if (section->flags & SEC_HAS_CONTENTS)
790             {
791               printf ("Contents of section %s:\n", section->name);
792
793               if (bfd_get_section_size_before_reloc (section) == 0)
794                 continue;
795               data = (bfd_byte *) malloc (bfd_get_section_size_before_reloc (section));
796               if (data == (bfd_byte *) NULL)
797                 {
798                   fprintf (stderr, "%s: memory exhausted.\n", program_name);
799                   exit (1);
800                 }
801               datasize = bfd_get_section_size_before_reloc (section);
802
803
804               bfd_get_section_contents (abfd, section, (PTR) data, 0, bfd_get_section_size_before_reloc (section));
805
806               for (i = 0; i < bfd_get_section_size_before_reloc (section); i += onaline)
807                 {
808                   bfd_size_type j;
809
810                   printf (" %04lx ", (unsigned long int) (i + section->vma));
811                   for (j = i; j < i + onaline; j++)
812                     {
813                       if (j < bfd_get_section_size_before_reloc (section))
814                         printf ("%02x", (unsigned) (data[j]));
815                       else
816                         printf ("  ");
817                       if ((j & 3) == 3)
818                         printf (" ");
819                     }
820
821                   printf (" ");
822                   for (j = i; j < i + onaline; j++)
823                     {
824                       if (j >= bfd_get_section_size_before_reloc (section))
825                         printf (" ");
826                       else
827                         printf ("%c", isprint (data[j]) ? data[j] : '.');
828                     }
829                   putchar ('\n');
830                 }
831               free (data);
832             }
833         }
834     }
835 }
836
837 /* Should perhaps share code and display with nm? */
838 static void
839 dump_symbols (abfd)
840      bfd *abfd;
841 {
842
843   unsigned int count;
844   asymbol **current = syms;
845
846   printf ("SYMBOL TABLE:\n");
847
848   for (count = 0; count < symcount; count++)
849     {
850
851       if (*current)
852         {
853           bfd *cur_bfd = bfd_asymbol_bfd(*current);
854           if (cur_bfd)
855             {
856               bfd_print_symbol (cur_bfd,
857                                 stdout,
858                                 *current, bfd_print_symbol_all);
859               printf ("\n");
860             }
861
862         }
863       current++;
864     }
865   printf ("\n");
866   printf ("\n");
867 }
868
869 static void
870 dump_relocs (abfd)
871      bfd *abfd;
872 {
873   arelent **relpp;
874   unsigned int relcount;
875   asection *a;
876
877   for (a = abfd->sections; a != (asection *) NULL; a = a->next)
878     {
879       if (a == &bfd_abs_section)
880         continue;
881       if (a == &bfd_und_section)
882         continue;
883       if (bfd_is_com_section (a))
884         continue;
885
886       printf ("RELOCATION RECORDS FOR [%s]:", a->name);
887
888       if (bfd_get_reloc_upper_bound (abfd, a) == 0)
889         {
890           printf (" (none)\n\n");
891         }
892       else
893         {
894           arelent **p;
895
896           relpp = (arelent **) xmalloc (bfd_get_reloc_upper_bound (abfd, a));
897           relcount = bfd_canonicalize_reloc (abfd, a, relpp, syms);
898           if (relcount == 0)
899             {
900               printf (" (none)\n\n");
901             }
902           else
903             {
904               printf ("\n");
905               printf ("OFFSET   TYPE      VALUE \n");
906
907               for (p = relpp; relcount && *p != (arelent *) NULL; p++,
908                    relcount--)
909                 {
910                   arelent *q = *p;
911                   CONST char *sym_name;
912
913                   /*      CONST char *section_name =        q->section == (asection *)NULL ? "*abs" :*/
914                   /*      q->section->name;*/
915                   CONST char *section_name = (*(q->sym_ptr_ptr))->section->name;
916
917                   if (q->sym_ptr_ptr && *q->sym_ptr_ptr)
918                     {
919                       sym_name = (*(q->sym_ptr_ptr))->name;
920                     }
921                   else
922                     {
923                       sym_name = 0;
924                     }
925                   if (sym_name)
926                     {
927                       printf_vma (q->address);
928                       printf (" %-8s  %s",
929                               q->howto->name,
930                               sym_name);
931                     }
932                   else
933                     {
934                       printf_vma (q->address);
935                       printf (" %-8s  [%s]",
936                               q->howto->name,
937                               section_name);
938                     }
939                   if (q->addend)
940                     {
941                       printf ("+0x");
942                       printf_vma (q->addend);
943                     }
944                   printf ("\n");
945                 }
946               printf ("\n\n");
947               free (relpp);
948             }
949         }
950
951     }
952 }
953
954 #ifdef unix
955 #define _DUMMY_NAME_ "/dev/null"
956 #else
957 #define _DUMMY_NAME_ "##dummy"
958 #endif
959 static void
960 DEFUN (display_info_table, (first, last),
961        int first AND int last)
962 {
963   unsigned int i, j;
964   extern bfd_target *target_vector[];
965
966   printf ("\n%12s", " ");
967   for (i = first; i++ < last && target_vector[i];)
968     printf ("%s ", target_vector[i]->name);
969   printf ("\n");
970
971   for (j = (int) bfd_arch_obscure + 1; (int) j < (int) bfd_arch_last; j++)
972     if (strcmp (bfd_printable_arch_mach (j, 0), "UNKNOWN!") != 0)
973       {
974         printf ("%11s ", bfd_printable_arch_mach (j, 0));
975         for (i = first; i++ < last && target_vector[i];)
976           {
977             bfd_target *p = target_vector[i];
978             bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
979             int l = strlen (p->name);
980             int ok;
981             bfd_set_format (abfd, bfd_object);
982             ok = bfd_set_arch_mach (abfd, j, 0);
983
984             if (ok)
985               printf ("%s ", p->name);
986             else
987               {
988                 while (l--)
989                   printf ("%c", ok ? '*' : '-');
990                 printf (" ");
991               }
992           }
993         printf ("\n");
994       }
995 }
996
997 static void
998 DEFUN_VOID (display_info)
999 {
1000   char *colum;
1001   unsigned int i, j, columns;
1002   extern bfd_target *target_vector[];
1003   extern char *getenv ();
1004
1005   printf ("BFD header file version %s\n", BFD_VERSION);
1006   for (i = 0; target_vector[i]; i++)
1007     {
1008       bfd_target *p = target_vector[i];
1009       bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
1010       bfd_set_format (abfd, bfd_object);
1011       printf ("%s\n (header %s, data %s)\n", p->name,
1012               p->header_byteorder_big_p ? "big endian" : "little endian",
1013               p->byteorder_big_p ? "big endian" : "little endian");
1014       for (j = (int) bfd_arch_obscure + 1; j < (int) bfd_arch_last; j++)
1015         if (bfd_set_arch_mach (abfd, (enum bfd_architecture) j, 0))
1016           printf ("  %s\n",
1017                   bfd_printable_arch_mach ((enum bfd_architecture) j, 0));
1018     }
1019   columns = 0;
1020   if (colum = getenv ("COLUMNS"))
1021     columns = atoi (colum);
1022   if (!columns)
1023     columns = 80;
1024   for (i = 0; target_vector[i];)
1025     {
1026       int old;
1027       old = i;
1028       for (j = 12; target_vector[i] && j < columns; i++)
1029         j += strlen (target_vector[i]->name) + 1;
1030       i--;
1031       if (old == i)
1032         break;
1033       display_info_table (old, i);
1034     }
1035 }
1036
1037 /** main and like trivia */
1038 int
1039 main (argc, argv)
1040      int argc;
1041      char **argv;
1042 {
1043   int c;
1044   extern int optind;
1045   extern char *optarg;
1046   char *target = default_target;
1047   boolean seenflag = false;
1048   int ind = 0;
1049
1050   bfd_init ();
1051   program_name = *argv;
1052
1053   while ((c = getopt_long (argc, argv, "ib:m:Vdlfahrtxsj:", long_options, &ind))
1054          != EOF)
1055     {
1056       seenflag = true;
1057       switch (c)
1058         {
1059         case 'm':
1060           machine = optarg;
1061           break;
1062         case 'j':
1063           only = optarg;
1064           break;
1065         case 'l':
1066           with_line_numbers = 1;
1067           break;
1068         case 'b':
1069           target = optarg;
1070           break;
1071         case 'f':
1072           dump_file_header = true;
1073           break;
1074         case 'i':
1075           info = true;
1076           break;
1077         case 'x':
1078           dump_symtab = 1;
1079           dump_reloc_info = 1;
1080           dump_file_header = true;
1081           dump_ar_hdrs = 1;
1082           dump_section_headers = 1;
1083           break;
1084         case 0:
1085           break;                /* we've been given a long option */
1086         case 't':
1087           dump_symtab = 1;
1088           break;
1089         case 'd':
1090           disassemble = true;
1091           break;
1092         case 's':
1093           dump_section_contents = 1;
1094           break;
1095         case 'r':
1096           dump_reloc_info = 1;
1097           break;
1098         case 'a':
1099           dump_ar_hdrs = 1;
1100           break;
1101         case 'h':
1102           dump_section_headers = 1;
1103           break;
1104         case 'V':
1105           show_version = 1;
1106           break;
1107         default:
1108           usage ();
1109         }
1110     }
1111
1112   if (show_version)
1113     printf ("%s version %s\n", program_name, program_version);
1114
1115   if (seenflag == false)
1116     usage ();
1117
1118   if (info)
1119     {
1120       display_info ();
1121     }
1122   else
1123     {
1124       if (optind == argc)
1125         display_file ("a.out", target);
1126       else
1127         for (; optind < argc;)
1128           display_file (argv[optind++], target);
1129     }
1130   return 0;
1131 }