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