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