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