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