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