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