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