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