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