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