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