Makefile.in (DISTSTUFF): Don't build binutils.mm.
[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] [-b bfdname]\n\
93 [--syms] [--reloc] [--header] [--version] objfile...\n", program_name);
94 exit (1);
95 }
96
97 static struct option long_options[]=
98 {
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},
105 #endif
106 {0, no_argument, 0, 0}
107 };
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 if (symcount <= 0)
175 {
176 fprintf (stderr, "%s: Bad symbol table in \"%s\".\n",
177 program_name, bfd_get_filename (abfd));
178 exit (1);
179 }
180 return sy;
181 }
182
183 /* Sort symbols into value order */
184 static int
185 comp (ap, bp)
186 PTR ap;
187 PTR bp;
188 {
189 asymbol *a = *(asymbol **)ap;
190 asymbol *b = *(asymbol **)bp;
191 int diff;
192 bfd *a_bfd, *b_bfd;
193
194 if (a->name == (char *) NULL || (a->flags & (BSF_DEBUGGING)))
195 a_bfd = 0;
196 else
197 a_bfd = bfd_asymbol_bfd(a);
198 if (b->name == (char *) NULL || (b->flags & (BSF_DEBUGGING)))
199 b_bfd = 0;
200 else
201 b_bfd = bfd_asymbol_bfd(b);
202
203 diff = a_bfd - b_bfd;
204 if (diff)
205 {
206 return -diff;
207 }
208 diff = a->value - b->value;
209 if (diff)
210 {
211 return diff;
212 }
213 return a->section - b->section;
214 }
215
216 /* Print the supplied address symbolically if possible */
217 void
218 objdump_print_address (vma, info)
219 bfd_vma vma;
220 struct disassemble_info *info;
221 {
222 /* Perform a binary search looking for the closest symbol to
223 the required value */
224
225 unsigned int min = 0;
226 unsigned int max = symcount;
227
228 unsigned int thisplace = 1;
229 unsigned int oldthisplace;
230
231 int vardiff;
232
233 if (symcount == 0)
234 {
235 fprintf_vma (info->stream, vma);
236 }
237 else
238 {
239 while (true)
240 {
241 oldthisplace = thisplace;
242 thisplace = (max + min) / 2;
243 if (thisplace == oldthisplace)
244 break;
245 vardiff = syms[thisplace]->value - vma;
246
247 if (vardiff
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)))
252 {
253 if (vardiff > 0)
254 {
255 max = thisplace;
256 }
257 else
258 {
259 min = thisplace;
260 }
261 }
262 else
263 {
264 /* Totally awesome! the exact right symbol */
265 CONST char *match_name = syms[thisplace]->name;
266 int sym_len = strlen (match_name);
267
268 /* Avoid "filename.o" as a match */
269 if (sym_len > 2
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);
278 return;
279 }
280 }
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 */
283
284 if (thisplace != 0)
285 {
286 if (syms[thisplace - 1]->value - vma >
287 syms[thisplace]->value - vma)
288 {
289 /* Previous symbol is in correct section and is closer */
290 thisplace--;
291 }
292 }
293
294 fprintf_vma (info->stream, vma);
295 if (syms[thisplace]->value > vma)
296 {
297 fprintf (info->stream, " (%s-)", syms[thisplace]->name);
298 fprintf (info->stream, "%04x", syms[thisplace]->value - vma);
299 }
300 else
301 {
302 fprintf (info->stream, " (%s+)", syms[thisplace]->name);
303 fprintf (info->stream, "%04x", vma - syms[thisplace]->value);
304 }
305 }
306 }
307
308 void
309 disassemble_data (abfd)
310 bfd *abfd;
311 {
312 bfd_byte *data = NULL;
313 bfd_arch_info_type *info;
314 bfd_size_type datasize = 0;
315 bfd_size_type i;
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;
321
322 int prevline;
323 CONST char *prev_function = "";
324
325 asection *section;
326
327 /* Replace symbol section relative values with abs values */
328 boolean done_dot = false;
329
330 INIT_DISASSEMBLE_INFO(disasm_info, stdout);
331 disasm_info.print_address_func = objdump_print_address;
332
333 for (i = 0; i < symcount; i++)
334 {
335 syms[i]->value += syms[i]->section->vma;
336 }
337
338 /* We keep a copy of the symbols in the original order */
339 syms2 = slurp_symtab (abfd);
340
341 /* Sort the symbols into section and symbol order */
342 (void) qsort (syms, symcount, sizeof (asymbol *), comp);
343
344 /* Find the first useless symbol */
345 {
346 unsigned int i;
347
348 for (i = 0; i < symcount; i++)
349 {
350 if (syms[i]->name == (char *) NULL
351 || (syms[i]->flags & BSF_DEBUGGING) != 0)
352 {
353 symcount = i;
354 break;
355 }
356 }
357 }
358
359
360 if (machine != (char *) NULL)
361 {
362 info = bfd_scan_arch (machine);
363 if (info == 0)
364 {
365 fprintf (stderr, "%s: Can't use supplied machine %s\n",
366 program_name,
367 machine);
368 exit (1);
369 }
370 abfd->arch_info = info;
371 }
372
373 /* See if we can disassemble using bfd */
374
375 if (abfd->arch_info->disassemble)
376 {
377 print = abfd->arch_info->disassemble;
378 }
379 else
380 {
381 a = bfd_get_arch (abfd);
382 switch (a)
383 {
384 case bfd_arch_sparc:
385 disassemble = print_insn_sparc;
386 break;
387 case bfd_arch_z8k:
388 if (bfd_get_mach(abfd) == bfd_mach_z8001)
389 disassemble = print_insn_z8001;
390 else
391 disassemble = print_insn_z8002;
392 break;
393 case bfd_arch_i386:
394 disassemble = print_insn_i386;
395 break;
396 case bfd_arch_h8500:
397 disassemble = print_insn_h8500;
398 break;
399 case bfd_arch_sh:
400 disassemble = print_insn_sh;
401 break;
402 case bfd_arch_alpha:
403 disassemble = print_insn_alpha;
404 break;
405 case bfd_arch_m68k:
406 disassemble = print_insn_m68k;
407 break;
408 case bfd_arch_a29k:
409 /* As far as I know we only handle big-endian 29k objects. */
410 disassemble = print_insn_big_a29k;
411 break;
412 case bfd_arch_i960:
413 disassemble = print_insn_i960;
414 break;
415 case bfd_arch_mips:
416 if (abfd->xvec->byteorder_big_p)
417 disassemble = print_insn_big_mips;
418 else
419 disassemble = print_insn_little_mips;
420 break;
421 default:
422 fprintf (stderr, "%s: Can't disassemble for architecture %s\n",
423 program_name,
424 bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
425 exit (1);
426 }
427
428 }
429
430 for (section = abfd->sections;
431 section != (asection *) NULL;
432 section = section->next)
433 {
434
435 if ((section->flags & SEC_LOAD)
436 && (only == (char *) NULL || strcmp (only, section->name) == 0))
437 {
438 printf ("Disassembly of section %s:\n", section->name);
439
440 if (bfd_get_section_size_before_reloc (section) == 0)
441 continue;
442
443 data = (bfd_byte *) malloc (bfd_get_section_size_before_reloc (section));
444
445 if (data == (bfd_byte *) NULL)
446 {
447 fprintf (stderr, "%s: memory exhausted.\n", program_name);
448 exit (1);
449 }
450 datasize = bfd_get_section_size_before_reloc (section);
451
452 bfd_get_section_contents (abfd, section, data, 0, bfd_get_section_size_before_reloc (section));
453
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);
458 i = 0;
459 while (i < disasm_info.buffer_length)
460 {
461 if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 0 &&
462 data[i + 3] == 0)
463 {
464 if (done_dot == false)
465 {
466 printf ("...\n");
467 done_dot = true;
468 }
469 i += 4;
470 }
471 else
472 {
473 done_dot = false;
474 if (with_line_numbers)
475 {
476 CONST char *filename;
477 CONST char *functionname;
478 unsigned int line;
479
480 if (bfd_find_nearest_line (abfd,
481 section,
482 syms,
483 section->vma + i,
484 &filename,
485 &functionname,
486 &line))
487 {
488 if (functionname && *functionname
489 && strcmp(functionname, prev_function))
490 {
491 printf ("%s():\n", functionname);
492 prev_function = functionname;
493 }
494 if (!filename)
495 filename = "???";
496 if (line && line != prevline)
497 {
498 printf ("%s:%u\n", filename, line);
499 prevline = line;
500 }
501 }
502 }
503 objdump_print_address (section->vma + i, &disasm_info);
504 printf (" ");
505
506 if (disassemble) /* New style */
507 {
508 int bytes = (*disassemble)(section->vma + i,
509 &disasm_info);
510 if (bytes < 0)
511 break;
512 i += bytes;
513 }
514 else /* Old style */
515 i += print (section->vma + i,
516 data + i,
517 stdout);
518 putchar ('\n');
519 }
520 }
521 free (data);
522 }
523 }
524 }
525 \f
526 #ifdef ELF_STAB_DISPLAY
527
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
530 time we need it. */
531
532 #define STAB_STRING_LENGTH 6
533
534 char stab_name[256][STAB_STRING_LENGTH];
535
536 struct stab_print {
537 int value;
538 char string[STAB_STRING_LENGTH];
539 };
540
541 struct stab_print stab_print[] = {
542 #define __define_stab(NAME, CODE, STRING) {CODE, STRING},
543 #include "aout/stab.def"
544 #undef __define_stab
545 {0, 0}
546 };
547
548 void dump_elf_stabs_1 ();
549
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. */
553
554 void
555 dump_elf_stabs (abfd)
556 bfd *abfd;
557 {
558 int i;
559
560 /* Initialize stab name array if first time. */
561 if (stab_name[0][0] == 0)
562 {
563 /* Fill in numeric values for all possible strings. */
564 for (i = 0; i < 256; i++)
565 {
566 sprintf (stab_name[i], "%d", i);
567 }
568 for (i = 0; stab_print[i].string[0]; i++)
569 strcpy (stab_name[stab_print[i].value], stab_print[i].string);
570 }
571
572 if (0 != strncmp ("elf", abfd->xvec->name, 3))
573 {
574 fprintf (stderr, "%s: %s is not in ELF format.\n", program_name,
575 abfd->filename);
576 return;
577 }
578
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");
582 }
583
584 void
585 dump_elf_stabs_1 (abfd, name1, name2)
586 bfd *abfd;
587 char *name1; /* Section name of .stab */
588 char *name2; /* Section name of its string section */
589 {
590 Elf_Internal_Shdr *stab_hdr, *stabstr_hdr;
591 char *strtab;
592 struct internal_nlist *stabs, *stabs_end;
593 int i;
594 unsigned file_string_table_offset, next_file_string_table_offset;
595
596 stab_hdr = bfd_elf_find_section (abfd, name1);
597 if (0 == stab_hdr)
598 {
599 printf ("Contents of %s section: none.\n\n", name1);
600 return;
601 }
602
603 stabstr_hdr = bfd_elf_find_section (abfd, name2);
604 if (0 == stabstr_hdr)
605 {
606 fprintf (stderr, "%s: %s has no %s section.\n", program_name,
607 abfd->filename, name2);
608 return;
609 }
610
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);
614
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))
617 {
618 fprintf (stderr, "%s: reading %s section of %s failed.\n",
619 program_name, name1,
620 abfd->filename);
621 return;
622 }
623
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,
626 1, abfd))
627 {
628 fprintf (stderr, "%s: reading %s section of %s failed.\n",
629 program_name, name2,
630 abfd->filename);
631 return;
632 }
633
634 #define SWAP_SYMBOL(symp, abfd) \
635 { \
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); \
642 }
643
644 printf ("Contents of %s section:\n\n", name1);
645 printf ("Symnum n_type n_othr n_desc n_value n_strx String\n");
646
647 file_string_table_offset = 0;
648 next_file_string_table_offset = 0;
649
650 /* Loop through all symbols and print them.
651
652 We start the index at -1 because there is a dummy symbol on
653 the front of Sun's stabs-in-elf sections. */
654
655 for (i = -1; stabs < stabs_end; stabs++, i++)
656 {
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,
661 stabs->n_strx);
662
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. */
666
667 if (stabs->n_type == N_UNDF)
668 {
669 file_string_table_offset = next_file_string_table_offset;
670 next_file_string_table_offset += stabs->n_value;
671 }
672
673 /* Now, using the possibly updated string table offset, print the
674 string (if any) associated with this symbol. */
675
676 if ((stabs->n_strx + file_string_table_offset) < stabstr_hdr->sh_size)
677 printf (" %s", &strtab[stabs->n_strx + file_string_table_offset]);
678 else
679 printf (" *");
680 }
681 printf ("\n\n");
682 }
683 #endif /* ELF_STAB_DISPLAY */
684
685 display_bfd (abfd)
686 bfd *abfd;
687 {
688
689 if (!bfd_check_format (abfd, bfd_object))
690 {
691 fprintf (stderr, "%s: %s not an object file\n", program_name,
692 abfd->filename);
693 return;
694 }
695 printf ("\n%s: file format %s\n", abfd->filename, abfd->xvec->name);
696 if (dump_ar_hdrs)
697 print_arelt_descr (stdout, abfd, true);
698
699 if (dump_file_header)
700 {
701 char *comma = "";
702
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);
707
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);
721 }
722 printf ("\n");
723
724 if (dump_section_headers)
725 dump_headers (abfd);
726 if (dump_symtab || dump_reloc_info || disassemble)
727 {
728 syms = slurp_symtab (abfd);
729 }
730 if (dump_symtab)
731 dump_symbols (abfd);
732 #ifdef ELF_STAB_DISPLAY
733 if (dump_stab_section_info)
734 dump_elf_stabs (abfd);
735 #endif
736 if (dump_reloc_info)
737 dump_relocs (abfd);
738 if (dump_section_contents)
739 dump_data (abfd);
740 if (disassemble)
741 disassemble_data (abfd);
742 }
743
744 static void
745 display_file (filename, target)
746 char *filename;
747 char *target;
748 {
749 bfd *file, *arfile = (bfd *) NULL;
750
751 file = bfd_openr (filename, target);
752 if (file == NULL)
753 {
754 fprintf (stderr, "%s: ", program_name);
755 bfd_perror (filename);
756 return;
757 }
758
759 if (bfd_check_format (file, bfd_archive) == true)
760 {
761 printf ("In archive %s:\n", bfd_get_filename (file));
762 for (;;)
763 {
764 bfd_error = no_error;
765
766 arfile = bfd_openr_next_archived_file (file, arfile);
767 if (arfile == NULL)
768 {
769 if (bfd_error != no_more_archived_files)
770 {
771 fprintf (stderr, "%s: ", program_name);
772 bfd_perror (bfd_get_filename (file));
773 }
774 return;
775 }
776
777 display_bfd (arfile);
778 /* Don't close the archive elements; we need them for next_archive */
779 }
780 }
781 else
782 display_bfd (file);
783
784 bfd_close (file);
785 }
786 \f
787 /* Actually display the various requested regions */
788
789 static void
790 dump_data (abfd)
791 bfd *abfd;
792 {
793 asection *section;
794 bfd_byte *data = 0;
795 bfd_size_type datasize = 0;
796 bfd_size_type i;
797
798 for (section = abfd->sections; section != NULL; section =
799 section->next)
800 {
801 int onaline = 16;
802
803 if (only == (char *) NULL ||
804 strcmp (only, section->name) == 0)
805 {
806 if (section->flags & SEC_HAS_CONTENTS)
807 {
808 printf ("Contents of section %s:\n", section->name);
809
810 if (bfd_get_section_size_before_reloc (section) == 0)
811 continue;
812 data = (bfd_byte *) malloc (bfd_get_section_size_before_reloc (section));
813 if (data == (bfd_byte *) NULL)
814 {
815 fprintf (stderr, "%s: memory exhausted.\n", program_name);
816 exit (1);
817 }
818 datasize = bfd_get_section_size_before_reloc (section);
819
820
821 bfd_get_section_contents (abfd, section, (PTR) data, 0, bfd_get_section_size_before_reloc (section));
822
823 for (i = 0; i < bfd_get_section_size_before_reloc (section); i += onaline)
824 {
825 bfd_size_type j;
826
827 printf (" %04lx ", (unsigned long int) (i + section->vma));
828 for (j = i; j < i + onaline; j++)
829 {
830 if (j < bfd_get_section_size_before_reloc (section))
831 printf ("%02x", (unsigned) (data[j]));
832 else
833 printf (" ");
834 if ((j & 3) == 3)
835 printf (" ");
836 }
837
838 printf (" ");
839 for (j = i; j < i + onaline; j++)
840 {
841 if (j >= bfd_get_section_size_before_reloc (section))
842 printf (" ");
843 else
844 printf ("%c", isprint (data[j]) ? data[j] : '.');
845 }
846 putchar ('\n');
847 }
848 free (data);
849 }
850 }
851 }
852 }
853
854 /* Should perhaps share code and display with nm? */
855 static void
856 dump_symbols (abfd)
857 bfd *abfd;
858 {
859
860 unsigned int count;
861 asymbol **current = syms;
862
863 printf ("SYMBOL TABLE:\n");
864
865 for (count = 0; count < symcount; count++)
866 {
867
868 if (*current)
869 {
870 bfd *cur_bfd = bfd_asymbol_bfd(*current);
871 if (cur_bfd)
872 {
873 bfd_print_symbol (cur_bfd,
874 stdout,
875 *current, bfd_print_symbol_all);
876 printf ("\n");
877 }
878
879 }
880 current++;
881 }
882 printf ("\n");
883 printf ("\n");
884 }
885
886 static void
887 dump_relocs (abfd)
888 bfd *abfd;
889 {
890 arelent **relpp;
891 unsigned int relcount;
892 asection *a;
893
894 for (a = abfd->sections; a != (asection *) NULL; a = a->next)
895 {
896 if (a == &bfd_abs_section)
897 continue;
898 if (a == &bfd_und_section)
899 continue;
900 if (bfd_is_com_section (a))
901 continue;
902
903 printf ("RELOCATION RECORDS FOR [%s]:", a->name);
904
905 if (bfd_get_reloc_upper_bound (abfd, a) == 0)
906 {
907 printf (" (none)\n\n");
908 }
909 else
910 {
911 arelent **p;
912
913 relpp = (arelent **) xmalloc (bfd_get_reloc_upper_bound (abfd, a));
914 relcount = bfd_canonicalize_reloc (abfd, a, relpp, syms);
915 if (relcount == 0)
916 {
917 printf (" (none)\n\n");
918 }
919 else
920 {
921 printf ("\n");
922 printf ("OFFSET TYPE VALUE \n");
923
924 for (p = relpp; relcount && *p != (arelent *) NULL; p++,
925 relcount--)
926 {
927 arelent *q = *p;
928 CONST char *sym_name;
929
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;
933
934 if (q->sym_ptr_ptr && *q->sym_ptr_ptr)
935 {
936 sym_name = (*(q->sym_ptr_ptr))->name;
937 }
938 else
939 {
940 sym_name = 0;
941 }
942 if (sym_name)
943 {
944 printf_vma (q->address);
945 printf (" %-8s %s",
946 q->howto->name,
947 sym_name);
948 }
949 else
950 {
951 printf_vma (q->address);
952 printf (" %-8s [%s]",
953 q->howto->name,
954 section_name);
955 }
956 if (q->addend)
957 {
958 printf ("+0x");
959 printf_vma (q->addend);
960 }
961 printf ("\n");
962 }
963 printf ("\n\n");
964 free (relpp);
965 }
966 }
967
968 }
969 }
970
971 #ifdef unix
972 #define _DUMMY_NAME_ "/dev/null"
973 #else
974 #define _DUMMY_NAME_ "##dummy"
975 #endif
976 static void
977 DEFUN (display_info_table, (first, last),
978 int first AND int last)
979 {
980 unsigned int i, j;
981 extern bfd_target *target_vector[];
982
983 printf ("\n%12s", " ");
984 for (i = first; i++ < last && target_vector[i];)
985 printf ("%s ", target_vector[i]->name);
986 printf ("\n");
987
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)
990 {
991 printf ("%11s ", bfd_printable_arch_mach (j, 0));
992 for (i = first; i++ < last && target_vector[i];)
993 {
994 bfd_target *p = target_vector[i];
995 bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
996 int l = strlen (p->name);
997 int ok;
998 bfd_set_format (abfd, bfd_object);
999 ok = bfd_set_arch_mach (abfd, j, 0);
1000
1001 if (ok)
1002 printf ("%s ", p->name);
1003 else
1004 {
1005 while (l--)
1006 printf ("%c", ok ? '*' : '-');
1007 printf (" ");
1008 }
1009 }
1010 printf ("\n");
1011 }
1012 }
1013
1014 static void
1015 DEFUN_VOID (display_info)
1016 {
1017 char *colum;
1018 unsigned int i, j, columns;
1019 extern bfd_target *target_vector[];
1020 extern char *getenv ();
1021
1022 printf ("BFD header file version %s\n", BFD_VERSION);
1023 for (i = 0; target_vector[i]; i++)
1024 {
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))
1033 printf (" %s\n",
1034 bfd_printable_arch_mach ((enum bfd_architecture) j, 0));
1035 }
1036 columns = 0;
1037 if (colum = getenv ("COLUMNS"))
1038 columns = atoi (colum);
1039 if (!columns)
1040 columns = 80;
1041 for (i = 0; target_vector[i];)
1042 {
1043 int old;
1044 old = i;
1045 for (j = 12; target_vector[i] && j < columns; i++)
1046 j += strlen (target_vector[i]->name) + 1;
1047 i--;
1048 if (old == i)
1049 break;
1050 display_info_table (old, i);
1051 }
1052 }
1053
1054 /** main and like trivia */
1055 int
1056 main (argc, argv)
1057 int argc;
1058 char **argv;
1059 {
1060 int c;
1061 extern int optind;
1062 extern char *optarg;
1063 char *target = default_target;
1064 boolean seenflag = false;
1065
1066 bfd_init ();
1067 program_name = *argv;
1068
1069 while ((c = getopt_long (argc, argv, "ib:m:Vdlfahrtxsj:", long_options,
1070 (int *) 0))
1071 != EOF)
1072 {
1073 seenflag = true;
1074 switch (c)
1075 {
1076 case 'm':
1077 machine = optarg;
1078 break;
1079 case 'j':
1080 only = optarg;
1081 break;
1082 case 'l':
1083 with_line_numbers = 1;
1084 break;
1085 case 'b':
1086 target = optarg;
1087 break;
1088 case 'f':
1089 dump_file_header = true;
1090 break;
1091 case 'i':
1092 info = true;
1093 break;
1094 case 'x':
1095 dump_symtab = 1;
1096 dump_reloc_info = 1;
1097 dump_file_header = true;
1098 dump_ar_hdrs = 1;
1099 dump_section_headers = 1;
1100 break;
1101 case 0:
1102 break; /* we've been given a long option */
1103 case 't':
1104 dump_symtab = 1;
1105 break;
1106 case 'd':
1107 disassemble = true;
1108 break;
1109 case 's':
1110 dump_section_contents = 1;
1111 break;
1112 case 'r':
1113 dump_reloc_info = 1;
1114 break;
1115 case 'a':
1116 dump_ar_hdrs = 1;
1117 break;
1118 case 'h':
1119 dump_section_headers = 1;
1120 break;
1121 case 'V':
1122 show_version = 1;
1123 break;
1124 default:
1125 usage ();
1126 }
1127 }
1128
1129 if (show_version)
1130 printf ("%s version %s\n", program_name, program_version);
1131
1132 if (seenflag == false)
1133 usage ();
1134
1135 if (info)
1136 {
1137 display_info ();
1138 }
1139 else
1140 {
1141 if (optind == argc)
1142 display_file ("a.out", target);
1143 else
1144 for (; optind < argc;)
1145 display_file (argv[optind++], target);
1146 }
1147 return 0;
1148 }