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