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