Wed Jun 10 07:53:24 1992 Steve Chamberlain (sac@thepub.cygnus.com)
[binutils-gdb.git] / binutils / objdump.c
1 /* objdump.c -- dump information about an object file.
2 Copyright (C) 1990, 1991 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
31
32
33 char *xmalloc ();
34
35 char *default_target = NULL; /* default at runtime */
36
37 char *program_name = NULL;
38
39 int dump_section_contents; /* -s */
40 int dump_section_headers; /* -h */
41 boolean dump_file_header; /* -f */
42 int dump_symtab; /* -t */
43 int dump_reloc_info; /* -r */
44 int dump_ar_hdrs; /* -a */
45 int with_line_numbers; /* -l */
46 boolean disassemble; /* -d */
47 boolean info; /* -i */
48 char *only;
49
50 PROTO (void, display_file, (char *filename, char *target));
51 PROTO (void, dump_data, (bfd * abfd));
52 PROTO (void, dump_relocs, (bfd * abfd));
53 PROTO (void, dump_symbols, (bfd * abfd));
54 PROTO (void, print_arelt_descr, (FILE *, bfd * abfd, boolean verbose));
55 \f
56
57
58
59
60
61
62 char *machine = (char *) NULL;
63 asymbol **syms;
64 asymbol **syms2;
65
66
67 unsigned int storage;
68
69 unsigned int symcount = 0;
70
71 void
72 usage ()
73 {
74 fprintf (stderr,
75 "usage: %s [-ahifdrtxsl] [-m machine] [-j section_name] obj ...\n",
76 program_name);
77 exit (1);
78 }
79
80 static struct option long_options[]=
81 {
82 {"syms", no_argument, &dump_symtab, 1},
83 {"reloc", no_argument, &dump_reloc_info, 1},
84 {"header", no_argument, &dump_section_headers, 1},
85 {0, no_argument, 0, 0}};
86
87
88
89 static void
90 dump_headers (abfd)
91 bfd *abfd;
92 {
93 asection *section;
94
95 for (section = abfd->sections;
96 section != (asection *) NULL;
97 section = section->next)
98 {
99 char *comma = "";
100
101 #define PF(x,y) \
102 if (section->flags & x) { printf("%s%s",comma,y); comma = ", "; }
103
104
105 printf ("SECTION %d [%s]\t: size %08x",
106 section->index,
107 section->name,
108 (unsigned) bfd_get_section_size_before_reloc (section));
109 printf (" vma ");
110 printf_vma (section->vma);
111 printf (" align 2**%u\n ",
112 section->alignment_power);
113 PF (SEC_ALLOC, "ALLOC");
114 PF (SEC_CONSTRUCTOR, "CONSTRUCTOR");
115 PF (SEC_CONSTRUCTOR_TEXT, "CONSTRUCTOR TEXT");
116 PF (SEC_CONSTRUCTOR_DATA, "CONSTRUCTOR DATA");
117 PF (SEC_CONSTRUCTOR_BSS, "CONSTRUCTOR BSS");
118 PF (SEC_LOAD, "LOAD");
119 PF (SEC_RELOC, "RELOC");
120 PF (SEC_BALIGN, "BALIGN");
121 PF (SEC_READONLY, "READONLY");
122 PF (SEC_CODE, "CODE");
123 PF (SEC_DATA, "DATA");
124 PF (SEC_ROM, "ROM");
125 printf ("\n");
126 #undef PF
127 }
128 }
129
130 static asymbol **
131 DEFUN (slurp_symtab, (abfd),
132 bfd * abfd)
133 {
134 asymbol **sy = (asymbol **) NULL;
135
136 if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
137 {
138 (void) printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
139 return (NULL);
140 }
141
142 storage = get_symtab_upper_bound (abfd);
143 if (storage)
144 {
145 sy = (asymbol **) malloc (storage);
146 if (sy == NULL)
147 {
148 fprintf (stderr, "%s: out of memory.\n", program_name);
149 exit (1);
150 }
151 }
152 symcount = bfd_canonicalize_symtab (abfd, sy);
153 return sy;
154 }
155
156 /* Sort symbols into value order */
157 static int
158 comp (ap, bp)
159 asymbol **ap;
160 asymbol **bp;
161 {
162 asymbol *a = *ap;
163 asymbol *b = *bp;
164 int diff;
165
166 if (a->name == (char *) NULL || (a->flags & (BSF_DEBUGGING)))
167 a->the_bfd = 0;
168 if (b->name == (char *) NULL || (b->flags & (BSF_DEBUGGING)))
169 b->the_bfd = 0;
170
171 diff = a->the_bfd - b->the_bfd;
172 if (diff)
173 {
174 return -diff;
175 }
176 diff = a->value - b->value;
177 if (diff)
178 {
179 return diff;
180 }
181 return a->section - b->section;
182 }
183
184 /* Print the supplied address symbolically if possible */
185 void
186 print_address (vma, stream)
187 bfd_vma vma;
188 FILE *stream;
189 {
190 /* Perform a binary search looking for the closest symbol to
191 the required value */
192
193 unsigned int min = 0;
194 unsigned int max = symcount;
195
196 unsigned int thisplace = 1;
197 unsigned int oldthisplace;
198
199 int vardiff;
200
201 if (symcount == 0)
202 {
203 fprintf_vma (stream, vma);
204 }
205 else
206 {
207 while (true)
208 {
209 oldthisplace = thisplace;
210 thisplace = (max + min) / 2;
211 if (thisplace == oldthisplace)
212 break;
213 vardiff = syms[thisplace]->value - vma;
214
215 if (vardiff)
216 {
217 if (vardiff > 0)
218 {
219 max = thisplace;
220 }
221 else
222 {
223 min = thisplace;
224 }
225 }
226 else
227 {
228 /* Totally awesome! the exact right symbol */
229 CONST char *match_name = syms[thisplace]->name;
230 int sym_len = strlen (match_name);
231
232 /* Avoid "filename.o" as a match */
233 if (sym_len > 2
234 && match_name[sym_len - 2] == '.'
235 && match_name[sym_len - 1] == 'o'
236 && thisplace + 1 < symcount
237 && syms[thisplace + 1]->value == vma)
238 match_name = syms[thisplace + 1]->name;
239 /* Totally awesome! the exact right symbol */
240 fprintf_vma (stream, vma);
241 fprintf (stream, " (%s+)0000", syms[thisplace]->name);
242 return;
243 }
244 }
245 /* We've run out of places to look, print the symbol before this one
246 see if this or the symbol before describes this location the best */
247
248 if (thisplace != 0)
249 {
250 if (syms[thisplace - 1]->value - vma >
251 syms[thisplace]->value - vma)
252 {
253 /* Previous symbol is in correct section and is closer */
254 thisplace--;
255 }
256 }
257
258 fprintf_vma (stream, vma);
259 if (syms[thisplace]->value > vma)
260 {
261 fprintf (stream, " (%s-)", syms[thisplace]->name);
262 fprintf (stream, "%04x", syms[thisplace]->value - vma);
263 }
264 else
265 {
266 fprintf (stream, " (%s+)", syms[thisplace]->name);
267 fprintf (stream, "%04x", vma - syms[thisplace]->value);
268 }
269 }
270 }
271
272 void
273 disassemble_data (abfd)
274 bfd *abfd;
275 {
276 bfd_byte *data = NULL;
277 bfd_arch_info_type *info;
278 bfd_size_type datasize = 0;
279 bfd_size_type i;
280 unsigned int (*print) ()= 0;
281 unsigned int print_insn_m68k ();
282 unsigned int print_insn_a29k ();
283 unsigned int print_insn_i960 ();
284 unsigned int print_insn_sparc ();
285 unsigned int print_insn_i386 ();
286 unsigned int print_insn_h8300 ();
287 enum bfd_architecture a;
288
289 asection *section;
290
291 /* Replace symbol section relative values with abs values */
292 boolean done_dot = false;
293
294 for (i = 0; i < symcount; i++)
295 {
296 syms[i]->value += syms[i]->section->vma;
297 }
298
299 /* We keep a copy of the symbols in the original order */
300 syms2 = slurp_symtab (abfd);
301
302 /* Sort the symbols into section and symbol order */
303 (void) qsort (syms, symcount, sizeof (asymbol *), comp);
304
305 /* Find the first useless symbol */
306 {
307 unsigned int i;
308
309 for (i = 0; i < symcount; i++)
310 {
311 if (syms[i]->the_bfd == 0)
312 {
313 symcount = i;
314 break;
315 }
316 }
317 }
318
319
320 if (machine != (char *) NULL)
321 {
322 info = bfd_scan_arch (machine);
323 if (info == 0)
324 {
325 fprintf (stderr, "%s: Can't use supplied machine %s\n",
326 program_name,
327 machine);
328 exit (1);
329 }
330 abfd->arch_info = info;
331 }
332
333 /* See if we can disassemble using bfd */
334
335 if (abfd->arch_info->disassemble)
336 {
337 print = abfd->arch_info->disassemble;
338 }
339 else
340 {
341 a = bfd_get_arch (abfd);
342 switch (a)
343 {
344 case bfd_arch_sparc:
345 print = print_insn_sparc;
346 break;
347 case bfd_arch_i386:
348 print = print_insn_i386;
349 break;
350 case bfd_arch_m68k:
351 print = print_insn_m68k;
352 break;
353 case bfd_arch_a29k:
354 print = print_insn_a29k;
355 break;
356 case bfd_arch_i960:
357 print = print_insn_i960;
358 break;
359 default:
360 fprintf (stderr, "%s: Can't disassemble for architecture %s\n",
361 program_name,
362 bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
363 exit (1);
364 }
365
366 }
367
368 for (section = abfd->sections;
369 section != (asection *) NULL;
370 section = section->next)
371 {
372
373 if ((section->flags & SEC_LOAD)
374 && (only == (char *) NULL || strcmp (only, section->name) == 0))
375 {
376 printf ("Disassembly of section %s:\n", section->name);
377
378 if (bfd_get_section_size_before_reloc (section) == 0)
379 continue;
380
381 data = (bfd_byte *) malloc (bfd_get_section_size_before_reloc (section));
382
383 if (data == (bfd_byte *) NULL)
384 {
385 fprintf (stderr, "%s: memory exhausted.\n", program_name);
386 exit (1);
387 }
388 datasize = bfd_get_section_size_before_reloc (section);
389
390 bfd_get_section_contents (abfd, section, data, 0, bfd_get_section_size_before_reloc (section));
391
392 i = 0;
393 while (i < bfd_get_section_size_before_reloc (section))
394 {
395 if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 0 &&
396 data[i + 3] == 0)
397 {
398 if (done_dot == false)
399 {
400 printf ("...\n");
401 done_dot = true;
402 }
403 i += 4;
404 }
405 else
406 {
407 done_dot = false;
408 if (with_line_numbers)
409 {
410 static prevline;
411 CONST char *filename;
412 CONST char *functionname;
413 unsigned int line;
414
415 bfd_find_nearest_line (abfd,
416 section,
417 syms,
418 section->vma + i,
419 &filename,
420 &functionname,
421 &line);
422
423 if (filename && functionname && line && line != prevline)
424 {
425 printf ("%s:%u\n", filename, line);
426 prevline = line;
427 }
428 }
429 print_address (section->vma + i, stdout);
430 printf (" ");
431
432 i += print (section->vma + i,
433 data + i,
434 stdout);
435 putchar ('\n');
436 }
437 }
438 free (data);
439 }
440 }
441 }
442
443 void
444 display_bfd (abfd)
445 bfd *abfd;
446 {
447
448 if (!bfd_check_format (abfd, bfd_object))
449 {
450 fprintf (stderr, "%s: %s not an object file\n", program_name,
451 abfd->filename);
452 return;
453 }
454 printf ("\n%s: file format %s\n", abfd->filename, abfd->xvec->name);
455 if (dump_ar_hdrs)
456 print_arelt_descr (stdout, abfd, true);
457
458 if (dump_file_header)
459 {
460 char *comma = "";
461
462 printf ("architecture: %s, ",
463 bfd_printable_arch_mach (bfd_get_arch (abfd),
464 bfd_get_mach (abfd)));
465 printf ("flags 0x%08x:\n", abfd->flags);
466
467 #define PF(x, y) if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
468 PF (HAS_RELOC, "HAS_RELOC");
469 PF (EXEC_P, "EXEC_P");
470 PF (HAS_LINENO, "HAS_LINENO");
471 PF (HAS_DEBUG, "HAS_DEBUG");
472 PF (HAS_SYMS, "HAS_SYMS");
473 PF (HAS_LOCALS, "HAS_LOCALS");
474 PF (DYNAMIC, "DYNAMIC");
475 PF (WP_TEXT, "WP_TEXT");
476 PF (D_PAGED, "D_PAGED");
477 printf ("\nstart address 0x");
478 printf_vma (abfd->start_address);
479 }
480 printf ("\n");
481
482 if (dump_section_headers)
483 dump_headers (abfd);
484 if (dump_symtab || dump_reloc_info || disassemble)
485 {
486 syms = slurp_symtab (abfd);
487 }
488 if (dump_symtab)
489 dump_symbols (abfd);
490 if (dump_reloc_info)
491 dump_relocs (abfd);
492 if (dump_section_contents)
493 dump_data (abfd);
494 if (disassemble)
495 disassemble_data (abfd);
496 }
497
498 void
499 display_file (filename, target)
500 char *filename;
501 char *target;
502 {
503 bfd *file, *arfile = (bfd *) NULL;
504
505 file = bfd_openr (filename, target);
506 if (file == NULL)
507 {
508 bfd_perror (filename);
509 return;
510 }
511
512 if (bfd_check_format (file, bfd_archive) == true)
513 {
514 printf ("In archive %s:\n", bfd_get_filename (file));
515 for (;;)
516 {
517 bfd_error = no_error;
518
519 arfile = bfd_openr_next_archived_file (file, arfile);
520 if (arfile == NULL)
521 {
522 if (bfd_error != no_more_archived_files)
523 bfd_perror (bfd_get_filename (file));
524 return;
525 }
526
527 display_bfd (arfile);
528 /* Don't close the archive elements; we need them for next_archive */
529 }
530 }
531 else
532 display_bfd (file);
533
534 bfd_close (file);
535 }
536 \f
537 /* Actually display the various requested regions */
538
539 void
540 dump_data (abfd)
541 bfd *abfd;
542 {
543 asection *section;
544 bfd_byte *data = 0;
545 bfd_size_type datasize = 0;
546 bfd_size_type i;
547
548 for (section = abfd->sections; section != NULL; section =
549 section->next)
550 {
551 int onaline = 16;
552
553 if (only == (char *) NULL ||
554 strcmp (only, section->name) == 0)
555 {
556 if (section->flags & SEC_HAS_CONTENTS)
557 {
558 printf ("Contents of section %s:\n", section->name);
559
560 if (bfd_get_section_size_before_reloc (section) == 0)
561 continue;
562 data = (bfd_byte *) malloc (bfd_get_section_size_before_reloc (section));
563 if (data == (bfd_byte *) NULL)
564 {
565 fprintf (stderr, "%s: memory exhausted.\n", program_name);
566 exit (1);
567 }
568 datasize = bfd_get_section_size_before_reloc (section);
569
570
571 bfd_get_section_contents (abfd, section, (PTR) data, 0, bfd_get_section_size_before_reloc (section));
572
573 for (i = 0; i < bfd_get_section_size_before_reloc (section); i += onaline)
574 {
575 bfd_size_type j;
576
577 printf (" %04lx ", (unsigned long int) (i + section->vma));
578 for (j = i; j < i + onaline; j++)
579 {
580 if (j < bfd_get_section_size_before_reloc (section))
581 printf ("%02x", (unsigned) (data[j]));
582 else
583 printf (" ");
584 if ((j & 3) == 3)
585 printf (" ");
586 }
587
588 printf (" ");
589 for (j = i; j < i + onaline; j++)
590 {
591 if (j >= bfd_get_section_size_before_reloc (section))
592 printf (" ");
593 else
594 printf ("%c", isprint (data[j]) ? data[j] : '.');
595 }
596 putchar ('\n');
597 }
598 }
599 }
600 free (data);
601 }
602 }
603
604 /* Should perhaps share code and display with nm? */
605 void
606 dump_symbols (abfd)
607 bfd *abfd;
608 {
609
610 unsigned int count;
611 asymbol **current = syms;
612
613 printf ("SYMBOL TABLE:\n");
614
615 for (count = 0; count < symcount; count++)
616 {
617
618 if (*current && (*current)->the_bfd)
619 {
620 bfd_print_symbol ((*current)->the_bfd,
621 stdout,
622 *current, bfd_print_symbol_all);
623
624 printf ("\n");
625
626 }
627 current++;
628 }
629 printf ("\n");
630 printf ("\n");
631 }
632
633 void
634 dump_relocs (abfd)
635 bfd *abfd;
636 {
637 arelent **relpp;
638 unsigned int relcount;
639 asection *a;
640
641 for (a = abfd->sections; a != (asection *) NULL; a = a->next)
642 {
643 if (a == &bfd_abs_section)
644 continue;
645 if (a == &bfd_und_section)
646 continue;
647 if (a == &bfd_com_section)
648 continue;
649
650 printf ("RELOCATION RECORDS FOR [%s]:", a->name);
651
652 if (bfd_get_reloc_upper_bound (abfd, a) == 0)
653 {
654 printf (" (none)\n\n");
655 }
656 else
657 {
658 arelent **p;
659
660 relpp = (arelent **) xmalloc (bfd_get_reloc_upper_bound (abfd, a));
661 relcount = bfd_canonicalize_reloc (abfd, a, relpp, syms);
662 if (relcount == 0)
663 {
664 printf (" (none)\n\n");
665 }
666 else
667 {
668 printf ("\n");
669 printf ("OFFSET TYPE VALUE \n");
670
671 for (p = relpp; relcount && *p != (arelent *) NULL; p++,
672 relcount--)
673 {
674 arelent *q = *p;
675 CONST char *sym_name;
676
677 /* CONST char *section_name = q->section == (asection *)NULL ? "*abs" :*/
678 /* q->section->name;*/
679 CONST char *section_name = (*(q->sym_ptr_ptr))->section->name;
680
681 if (q->sym_ptr_ptr && *q->sym_ptr_ptr)
682 {
683 sym_name = (*(q->sym_ptr_ptr))->name;
684 }
685 else
686 {
687 sym_name = 0;
688 }
689 if (sym_name)
690 {
691 printf_vma (q->address);
692 printf (" %-8s %s",
693 q->howto->name,
694 sym_name);
695 }
696 else
697 {
698 printf_vma (q->address);
699 printf (" %-8s [%s]",
700 q->howto->name,
701 section_name);
702 }
703 if (q->addend)
704 {
705 printf ("+0x");
706 printf_vma (q->addend);
707 }
708 printf ("\n");
709 }
710 printf ("\n\n");
711 free (relpp);
712 }
713 }
714
715 }
716 }
717
718 #ifdef unix
719 #define _DUMMY_NAME_ "/dev/null"
720 #else
721 #define _DUMMY_NAME_ "##dummy"
722 #endif
723 static void
724 DEFUN (display_info_table, (first, last),
725 int first AND int last)
726 {
727 unsigned int i, j;
728 extern bfd_target *target_vector[];
729
730 printf ("\n%12s", " ");
731 for (i = first; i++ < last && target_vector[i];)
732 printf ("%s ", target_vector[i]->name);
733 printf ("\n");
734
735 for (j = (int) bfd_arch_obscure + 1; (int) j < (int) bfd_arch_last; j++)
736 if (strcmp (bfd_printable_arch_mach (j, 0), "UNKNOWN!") != 0)
737 {
738 printf ("%11s ", bfd_printable_arch_mach (j, 0));
739 for (i = first; i++ < last && target_vector[i];)
740 {
741 bfd_target *p = target_vector[i];
742 bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
743 int l = strlen (p->name);
744 int ok = bfd_set_arch_mach (abfd, j, 0);
745
746 if (ok)
747 printf ("%s ", p->name);
748 else
749 {
750 while (l--)
751 printf ("%c", ok ? '*' : '-');
752 printf (" ");
753 }
754 }
755 printf ("\n");
756 }
757 }
758
759 static void
760 DEFUN_VOID (display_info)
761 {
762 char *colum;
763 unsigned int i, j, columns;
764 extern bfd_target *target_vector[];
765 extern char *getenv ();
766
767 printf ("BFD header file version %s\n", BFD_VERSION);
768 for (i = 0; target_vector[i]; i++)
769 {
770 bfd_target *p = target_vector[i];
771 bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
772
773 printf ("%s\n (header %s, data %s)\n", p->name,
774 p->header_byteorder_big_p ? "big endian" : "little endian",
775 p->byteorder_big_p ? "big endian" : "little endian");
776 for (j = (int) bfd_arch_obscure + 1; j < (int) bfd_arch_last; j++)
777 if (bfd_set_arch_mach (abfd, (enum bfd_architecture) j, 0))
778 printf (" %s\n",
779 bfd_printable_arch_mach ((enum bfd_architecture) j, 0));
780 }
781 columns = 0;
782 if (colum = getenv ("COLUMNS"))
783 columns = atoi (colum);
784 if (!columns)
785 columns = 80;
786 for (i = 0; target_vector[i];)
787 {
788 int old;
789 old = i;
790 for (j = 12; target_vector[i] && j < columns; i++)
791 j += strlen (target_vector[i]->name) + 1;
792 i--;
793 if (old == i)
794 break;
795 display_info_table (old, i);
796 }
797 }
798
799 /** main and like trivia */
800 int
801 main (argc, argv)
802 int argc;
803 char **argv;
804 {
805 int c;
806 extern int optind;
807 extern char *optarg;
808 char *target = default_target;
809 boolean seenflag = false;
810 int ind = 0;
811
812 bfd_init ();
813 program_name = *argv;
814
815 while ((c = getopt_long (argc, argv, "ib:m:dlfahrtxsj:", long_options, &ind))
816 != EOF)
817 {
818 seenflag = true;
819 switch (c)
820 {
821 case 'm':
822 machine = optarg;
823 break;
824 case 'j':
825 only = optarg;
826 break;
827 case 'l':
828 with_line_numbers = 1;
829 break;
830 case 'b':
831 target = optarg;
832 break;
833 case 'f':
834 dump_file_header = true;
835 break;
836 case 'i':
837 info = true;
838 break;
839 case 'x':
840 dump_symtab = 1;
841 dump_reloc_info = 1;
842 dump_file_header = true;
843 dump_ar_hdrs = 1;
844 dump_section_headers = 1;
845 break;
846 case 0:
847 break; /* we've been given a long option */
848 case 't':
849 dump_symtab = 1;
850 break;
851 case 'd':
852 disassemble = true;
853 break;
854 case 's':
855 dump_section_contents = 1;
856 break;
857 case 'r':
858 dump_reloc_info = 1;
859 break;
860 case 'a':
861 dump_ar_hdrs = 1;
862 break;
863 case 'h':
864 dump_section_headers = 1;
865 break;
866 default:
867 usage ();
868 }
869 }
870
871 if (seenflag == false)
872 usage ();
873
874 if (info)
875 {
876 display_info ();
877 }
878 else
879 {
880 if (optind == argc)
881 display_file ("a.out", target);
882 else
883 for (; optind < argc;)
884 display_file (argv[optind++], target);
885 }
886 return 0;
887 }