1 /* objdump.c -- dump information about an object file.
2 Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Diddler.
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)
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.
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. */
21 * Until there is other documentation, refer to the manual page dump(1) in
22 * the system 5 program's reference manual
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
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 */
45 extern char *xmalloc ();
46 extern int fprintf PARAMS ((FILE *, CONST char *, ...));
48 char *default_target = NULL; /* default at runtime */
50 extern *program_version;
51 char *program_name = NULL;
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 */
66 char *machine = (char *) NULL;
72 unsigned int symcount = 0;
74 /* Forward declarations. */
77 display_file PARAMS ((char *filename, char *target));
80 dump_data PARAMS ((bfd *abfd));
83 dump_relocs PARAMS ((bfd *abfd));
86 dump_symbols PARAMS ((bfd *abfd));
92 Usage: %s [-ahifdrtxsl] [-m machine] [-j section_name] [-b bfdname]\n\
93 [--syms] [--reloc] [--header] [--version] objfile...\n", program_name);
97 static struct option long_options[]=
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},
106 {0, no_argument, 0, 0}
116 for (section = abfd->sections;
117 section != (asection *) NULL;
118 section = section->next)
123 if (section->flags & x) { printf("%s%s",comma,y); comma = ", "; }
126 printf ("SECTION %d [%s]\t: size %08x",
129 (unsigned) bfd_get_section_size_before_reloc (section));
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");
152 DEFUN (slurp_symtab, (abfd),
155 asymbol **sy = (asymbol **) NULL;
157 if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
159 (void) printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
163 storage = get_symtab_upper_bound (abfd);
166 sy = (asymbol **) malloc (storage);
169 fprintf (stderr, "%s: out of memory.\n", program_name);
173 symcount = bfd_canonicalize_symtab (abfd, sy);
176 fprintf (stderr, "%s: Bad symbol table in \"%s\".\n",
177 program_name, bfd_get_filename (abfd));
183 /* Sort symbols into value order */
189 asymbol *a = *(asymbol **)ap;
190 asymbol *b = *(asymbol **)bp;
194 if (a->name == (char *) NULL || (a->flags & (BSF_DEBUGGING)))
197 a_bfd = bfd_asymbol_bfd(a);
198 if (b->name == (char *) NULL || (b->flags & (BSF_DEBUGGING)))
201 b_bfd = bfd_asymbol_bfd(b);
203 diff = a_bfd - b_bfd;
208 diff = a->value - b->value;
213 return a->section - b->section;
216 /* Print the supplied address symbolically if possible */
218 objdump_print_address (vma, info)
220 struct disassemble_info *info;
222 /* Perform a binary search looking for the closest symbol to
223 the required value */
225 unsigned int min = 0;
226 unsigned int max = symcount;
228 unsigned int thisplace = 1;
229 unsigned int oldthisplace;
235 fprintf_vma (info->stream, vma);
241 oldthisplace = thisplace;
242 thisplace = (max + min) / 2;
243 if (thisplace == oldthisplace)
245 vardiff = syms[thisplace]->value - vma;
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)))
264 /* Totally awesome! the exact right symbol */
265 CONST char *match_name = syms[thisplace]->name;
266 int sym_len = strlen (match_name);
268 /* Avoid "filename.o" as a match */
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);
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 */
286 if (syms[thisplace - 1]->value - vma >
287 syms[thisplace]->value - vma)
289 /* Previous symbol is in correct section and is closer */
294 fprintf_vma (info->stream, vma);
295 if (syms[thisplace]->value > vma)
297 fprintf (info->stream, " (%s-)", syms[thisplace]->name);
298 fprintf (info->stream, "%04x", syms[thisplace]->value - vma);
302 fprintf (info->stream, " (%s+)", syms[thisplace]->name);
303 fprintf (info->stream, "%04x", vma - syms[thisplace]->value);
309 disassemble_data (abfd)
312 bfd_byte *data = NULL;
313 bfd_arch_info_type *info;
314 bfd_size_type datasize = 0;
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;
323 CONST char *prev_function = "";
327 /* Replace symbol section relative values with abs values */
328 boolean done_dot = false;
330 INIT_DISASSEMBLE_INFO(disasm_info, stdout);
331 disasm_info.print_address_func = objdump_print_address;
333 for (i = 0; i < symcount; i++)
335 syms[i]->value += syms[i]->section->vma;
338 /* We keep a copy of the symbols in the original order */
339 syms2 = slurp_symtab (abfd);
341 /* Sort the symbols into section and symbol order */
342 (void) qsort (syms, symcount, sizeof (asymbol *), comp);
344 /* Find the first useless symbol */
348 for (i = 0; i < symcount; i++)
350 if (syms[i]->name == (char *) NULL
351 || (syms[i]->flags & BSF_DEBUGGING) != 0)
360 if (machine != (char *) NULL)
362 info = bfd_scan_arch (machine);
365 fprintf (stderr, "%s: Can't use supplied machine %s\n",
370 abfd->arch_info = info;
373 /* See if we can disassemble using bfd */
375 if (abfd->arch_info->disassemble)
377 print = abfd->arch_info->disassemble;
381 a = bfd_get_arch (abfd);
385 disassemble = print_insn_sparc;
388 if (bfd_get_mach(abfd) == bfd_mach_z8001)
389 disassemble = print_insn_z8001;
391 disassemble = print_insn_z8002;
394 disassemble = print_insn_i386;
397 disassemble = print_insn_h8500;
400 disassemble = print_insn_sh;
403 disassemble = print_insn_alpha;
406 disassemble = print_insn_m68k;
409 /* As far as I know we only handle big-endian 29k objects. */
410 disassemble = print_insn_big_a29k;
413 disassemble = print_insn_i960;
416 if (abfd->xvec->byteorder_big_p)
417 disassemble = print_insn_big_mips;
419 disassemble = print_insn_little_mips;
422 fprintf (stderr, "%s: Can't disassemble for architecture %s\n",
424 bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
430 for (section = abfd->sections;
431 section != (asection *) NULL;
432 section = section->next)
435 if ((section->flags & SEC_LOAD)
436 && (only == (char *) NULL || strcmp (only, section->name) == 0))
438 printf ("Disassembly of section %s:\n", section->name);
440 if (bfd_get_section_size_before_reloc (section) == 0)
443 data = (bfd_byte *) malloc (bfd_get_section_size_before_reloc (section));
445 if (data == (bfd_byte *) NULL)
447 fprintf (stderr, "%s: memory exhausted.\n", program_name);
450 datasize = bfd_get_section_size_before_reloc (section);
452 bfd_get_section_contents (abfd, section, data, 0, bfd_get_section_size_before_reloc (section));
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);
459 while (i < disasm_info.buffer_length)
461 if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 0 &&
464 if (done_dot == false)
474 if (with_line_numbers)
476 CONST char *filename;
477 CONST char *functionname;
480 if (bfd_find_nearest_line (abfd,
488 if (functionname && *functionname
489 && strcmp(functionname, prev_function))
491 printf ("%s():\n", functionname);
492 prev_function = functionname;
496 if (line && line != prevline)
498 printf ("%s:%u\n", filename, line);
503 objdump_print_address (section->vma + i, &disasm_info);
506 if (disassemble) /* New style */
508 int bytes = (*disassemble)(section->vma + i,
515 i += print (section->vma + i,
526 #ifdef ELF_STAB_DISPLAY
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
532 #define STAB_STRING_LENGTH 6
534 char stab_name[256][STAB_STRING_LENGTH];
538 char string[STAB_STRING_LENGTH];
541 struct stab_print stab_print[] = {
542 #define __define_stab(NAME, CODE, STRING) {CODE, STRING},
543 #include "aout/stab.def"
548 void dump_elf_stabs_1 ();
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. */
555 dump_elf_stabs (abfd)
560 /* Initialize stab name array if first time. */
561 if (stab_name[0][0] == 0)
563 /* Fill in numeric values for all possible strings. */
564 for (i = 0; i < 256; i++)
566 sprintf (stab_name[i], "%d", i);
568 for (i = 0; stab_print[i].string[0]; i++)
569 strcpy (stab_name[stab_print[i].value], stab_print[i].string);
572 if (0 != strncmp ("elf", abfd->xvec->name, 3))
574 fprintf (stderr, "%s: %s is not in ELF format.\n", program_name,
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");
585 dump_elf_stabs_1 (abfd, name1, name2)
587 char *name1; /* Section name of .stab */
588 char *name2; /* Section name of its string section */
590 Elf32_Internal_Shdr *stab_hdr, *stabstr_hdr;
592 struct internal_nlist *stabs, *stabs_end;
594 unsigned file_string_table_offset, next_file_string_table_offset;
596 stab_hdr = bfd_elf32_find_section (abfd, name1);
599 printf ("Contents of %s section: none.\n\n", name1);
603 stabstr_hdr = bfd_elf32_find_section (abfd, name2);
604 if (0 == stabstr_hdr)
606 fprintf (stderr, "%s: %s has no %s section.\n", program_name,
607 abfd->filename, name2);
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);
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))
618 fprintf (stderr, "%s: reading %s section of %s failed.\n",
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,
628 fprintf (stderr, "%s: reading %s section of %s failed.\n",
634 #define SWAP_SYMBOL(symp, abfd) \
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); \
644 printf ("Contents of %s section:\n\n", name1);
645 printf ("Symnum n_type n_othr n_desc n_value n_strx String\n");
647 file_string_table_offset = 0;
648 next_file_string_table_offset = 0;
650 /* Loop through all symbols and print them.
652 We start the index at -1 because there is a dummy symbol on
653 the front of Sun's stabs-in-elf sections. */
655 for (i = -1; stabs < stabs_end; stabs++, i++)
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,
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. */
667 if (stabs->n_type == N_UNDF)
669 file_string_table_offset = next_file_string_table_offset;
670 next_file_string_table_offset += stabs->n_value;
673 /* Now, using the possibly updated string table offset, print the
674 string (if any) associated with this symbol. */
676 if ((stabs->n_strx + file_string_table_offset) < stabstr_hdr->sh_size)
677 printf (" %s", &strtab[stabs->n_strx + file_string_table_offset]);
683 #endif /* ELF_STAB_DISPLAY */
689 if (!bfd_check_format (abfd, bfd_object))
691 fprintf (stderr, "%s: %s not an object file\n", program_name,
695 printf ("\n%s: file format %s\n", abfd->filename, abfd->xvec->name);
697 print_arelt_descr (stdout, abfd, true);
699 if (dump_file_header)
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);
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);
724 if (dump_section_headers)
726 if (dump_symtab || dump_reloc_info || disassemble)
728 syms = slurp_symtab (abfd);
732 #ifdef ELF_STAB_DISPLAY
733 if (dump_stab_section_info)
734 dump_elf_stabs (abfd);
738 if (dump_section_contents)
741 disassemble_data (abfd);
745 display_file (filename, target)
749 bfd *file, *arfile = (bfd *) NULL;
751 file = bfd_openr (filename, target);
754 fprintf (stderr, "%s: ", program_name);
755 bfd_perror (filename);
759 if (bfd_check_format (file, bfd_archive) == true)
761 printf ("In archive %s:\n", bfd_get_filename (file));
764 bfd_error = no_error;
766 arfile = bfd_openr_next_archived_file (file, arfile);
769 if (bfd_error != no_more_archived_files)
771 fprintf (stderr, "%s: ", program_name);
772 bfd_perror (bfd_get_filename (file));
777 display_bfd (arfile);
778 /* Don't close the archive elements; we need them for next_archive */
787 /* Actually display the various requested regions */
795 bfd_size_type datasize = 0;
798 for (section = abfd->sections; section != NULL; section =
803 if (only == (char *) NULL ||
804 strcmp (only, section->name) == 0)
806 if (section->flags & SEC_HAS_CONTENTS)
808 printf ("Contents of section %s:\n", section->name);
810 if (bfd_get_section_size_before_reloc (section) == 0)
812 data = (bfd_byte *) malloc (bfd_get_section_size_before_reloc (section));
813 if (data == (bfd_byte *) NULL)
815 fprintf (stderr, "%s: memory exhausted.\n", program_name);
818 datasize = bfd_get_section_size_before_reloc (section);
821 bfd_get_section_contents (abfd, section, (PTR) data, 0, bfd_get_section_size_before_reloc (section));
823 for (i = 0; i < bfd_get_section_size_before_reloc (section); i += onaline)
827 printf (" %04lx ", (unsigned long int) (i + section->vma));
828 for (j = i; j < i + onaline; j++)
830 if (j < bfd_get_section_size_before_reloc (section))
831 printf ("%02x", (unsigned) (data[j]));
839 for (j = i; j < i + onaline; j++)
841 if (j >= bfd_get_section_size_before_reloc (section))
844 printf ("%c", isprint (data[j]) ? data[j] : '.');
854 /* Should perhaps share code and display with nm? */
861 asymbol **current = syms;
863 printf ("SYMBOL TABLE:\n");
865 for (count = 0; count < symcount; count++)
870 bfd *cur_bfd = bfd_asymbol_bfd(*current);
873 bfd_print_symbol (cur_bfd,
875 *current, bfd_print_symbol_all);
891 unsigned int relcount;
894 for (a = abfd->sections; a != (asection *) NULL; a = a->next)
896 if (a == &bfd_abs_section)
898 if (a == &bfd_und_section)
900 if (bfd_is_com_section (a))
903 printf ("RELOCATION RECORDS FOR [%s]:", a->name);
905 if (bfd_get_reloc_upper_bound (abfd, a) == 0)
907 printf (" (none)\n\n");
913 relpp = (arelent **) xmalloc (bfd_get_reloc_upper_bound (abfd, a));
914 relcount = bfd_canonicalize_reloc (abfd, a, relpp, syms);
917 printf (" (none)\n\n");
922 printf ("OFFSET TYPE VALUE \n");
924 for (p = relpp; relcount && *p != (arelent *) NULL; p++,
928 CONST char *sym_name;
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;
934 if (q->sym_ptr_ptr && *q->sym_ptr_ptr)
936 sym_name = (*(q->sym_ptr_ptr))->name;
944 printf_vma (q->address);
951 printf_vma (q->address);
952 printf (" %-8s [%s]",
959 printf_vma (q->addend);
972 #define _DUMMY_NAME_ "/dev/null"
974 #define _DUMMY_NAME_ "##dummy"
977 DEFUN (display_info_table, (first, last),
978 int first AND int last)
981 extern bfd_target *target_vector[];
983 printf ("\n%12s", " ");
984 for (i = first; i++ < last && target_vector[i];)
985 printf ("%s ", target_vector[i]->name);
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)
991 printf ("%11s ", bfd_printable_arch_mach (j, 0));
992 for (i = first; i++ < last && target_vector[i];)
994 bfd_target *p = target_vector[i];
995 bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
996 int l = strlen (p->name);
998 bfd_set_format (abfd, bfd_object);
999 ok = bfd_set_arch_mach (abfd, j, 0);
1002 printf ("%s ", p->name);
1006 printf ("%c", ok ? '*' : '-');
1015 DEFUN_VOID (display_info)
1018 unsigned int i, j, columns;
1019 extern bfd_target *target_vector[];
1020 extern char *getenv ();
1022 printf ("BFD header file version %s\n", BFD_VERSION);
1023 for (i = 0; target_vector[i]; i++)
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))
1034 bfd_printable_arch_mach ((enum bfd_architecture) j, 0));
1037 if (colum = getenv ("COLUMNS"))
1038 columns = atoi (colum);
1041 for (i = 0; target_vector[i];)
1045 for (j = 12; target_vector[i] && j < columns; i++)
1046 j += strlen (target_vector[i]->name) + 1;
1050 display_info_table (old, i);
1054 /** main and like trivia */
1062 extern char *optarg;
1063 char *target = default_target;
1064 boolean seenflag = false;
1067 program_name = *argv;
1069 while ((c = getopt_long (argc, argv, "ib:m:Vdlfahrtxsj:", long_options,
1083 with_line_numbers = 1;
1089 dump_file_header = true;
1096 dump_reloc_info = 1;
1097 dump_file_header = true;
1099 dump_section_headers = 1;
1102 break; /* we've been given a long option */
1110 dump_section_contents = 1;
1113 dump_reloc_info = 1;
1119 dump_section_headers = 1;
1130 printf ("%s version %s\n", program_name, program_version);
1132 if (seenflag == false)
1142 display_file ("a.out", target);
1144 for (; optind < argc;)
1145 display_file (argv[optind++], target);