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