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