fix doc bug
[deliverable/binutils-gdb.git] / binutils / objdump.c
CommitLineData
d20f480f 1/* objdump.c -- dump information about an object file.
b3a2b497 2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
2fa0b342 3
b3a2b497 4This file is part of GNU Binutils.
2fa0b342 5
b3a2b497 6This program is free software; you can redistribute it and/or modify
2fa0b342 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
b3a2b497 11This program is distributed in the hope that it will be useful,
2fa0b342
DHW
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
b3a2b497
ILT
17along with this program; if not, write to the Free Software
18Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
2fa0b342 19
2fa0b342 20#include "bfd.h"
d20f480f 21#include "sysdep.h"
2fa0b342
DHW
22#include "getopt.h"
23#include <stdio.h>
24#include <ctype.h>
2e8adbd7 25#include "dis-asm.h"
2fa0b342 26
73b8f102
JG
27#define ELF_STAB_DISPLAY /* This code works, but uses internal
28 bfd and elf stuff. Flip this define
29 off if you need to just use generic
30 BFD interfaces. */
31
32#ifdef ELF_STAB_DISPLAY
33/* Internal headers for the ELF .stab-dump code - sorry. */
34#define BYTES_IN_WORD 32
35#include "aout/aout64.h"
36#include "elf/internal.h"
d086adf8 37extern Elf_Internal_Shdr *bfd_elf_find_section();
73b8f102 38#endif /* ELF_STAB_DISPLAY */
bf661056 39
2e8adbd7 40extern char *xmalloc ();
6f575704 41extern int fprintf PARAMS ((FILE *, CONST char *, ...));
2fa0b342
DHW
42
43char *default_target = NULL; /* default at runtime */
44
249c6fc0 45extern *program_version;
2fa0b342
DHW
46char *program_name = NULL;
47
249c6fc0 48int show_version = 0; /* show the version number */
2fa0b342
DHW
49int dump_section_contents; /* -s */
50int dump_section_headers; /* -h */
51boolean dump_file_header; /* -f */
52int dump_symtab; /* -t */
53int dump_reloc_info; /* -r */
54int dump_ar_hdrs; /* -a */
aa0a709a 55int with_line_numbers; /* -l */
73b8f102 56int dump_stab_section_info; /* -stabs */
aa0a709a
SC
57boolean disassemble; /* -d */
58boolean info; /* -i */
2fa0b342
DHW
59char *only;
60
aa0a709a
SC
61char *machine = (char *) NULL;
62asymbol **syms;
2fa0b342 63
2fa0b342
DHW
64unsigned int storage;
65
66unsigned int symcount = 0;
67
d9971b83
KR
68/* Forward declarations. */
69
70static void
71display_file PARAMS ((char *filename, char *target));
72
73static void
74dump_data PARAMS ((bfd *abfd));
75
76static void
77dump_relocs PARAMS ((bfd *abfd));
78
79static void
80dump_symbols PARAMS ((bfd *abfd));
81\f
2fa0b342 82void
b3a2b497
ILT
83usage (stream, status)
84 FILE *stream;
85 int status;
2fa0b342 86{
b3a2b497 87 fprintf (stream, "\
d2442698 88Usage: %s [-ahifdrtxsl] [-m machine] [-j section_name] [-b bfdname]\n\
b3a2b497
ILT
89 [--syms] [--reloc] [--header] [--version] [--help] objfile...\n",
90 program_name);
91 exit (status);
2fa0b342
DHW
92}
93
aa0a709a
SC
94static struct option long_options[]=
95{
96 {"syms", no_argument, &dump_symtab, 1},
97 {"reloc", no_argument, &dump_reloc_info, 1},
98 {"header", no_argument, &dump_section_headers, 1},
249c6fc0 99 {"version", no_argument, &show_version, 1},
b3a2b497 100 {"help", no_argument, 0, 'H'},
73b8f102
JG
101#ifdef ELF_STAB_DISPLAY
102 {"stabs", no_argument, &dump_stab_section_info, 1},
103#endif
d2442698
DM
104 {0, no_argument, 0, 0}
105};
2fa0b342
DHW
106
107
2fa0b342 108static void
aa0a709a
SC
109dump_headers (abfd)
110 bfd *abfd;
2fa0b342
DHW
111{
112 asection *section;
aa0a709a 113
2fa0b342
DHW
114 for (section = abfd->sections;
115 section != (asection *) NULL;
aa0a709a
SC
116 section = section->next)
117 {
118 char *comma = "";
119
2fa0b342 120#define PF(x,y) \
e779a58c
JG
121 if (section->flags & x) { printf("%s%s",comma,y); comma = ", "; }
122
123
aa0a709a
SC
124 printf ("SECTION %d [%s]\t: size %08x",
125 section->index,
126 section->name,
127 (unsigned) bfd_get_section_size_before_reloc (section));
128 printf (" vma ");
129 printf_vma (section->vma);
130 printf (" align 2**%u\n ",
131 section->alignment_power);
132 PF (SEC_ALLOC, "ALLOC");
133 PF (SEC_CONSTRUCTOR, "CONSTRUCTOR");
134 PF (SEC_CONSTRUCTOR_TEXT, "CONSTRUCTOR TEXT");
135 PF (SEC_CONSTRUCTOR_DATA, "CONSTRUCTOR DATA");
136 PF (SEC_CONSTRUCTOR_BSS, "CONSTRUCTOR BSS");
137 PF (SEC_LOAD, "LOAD");
138 PF (SEC_RELOC, "RELOC");
139 PF (SEC_BALIGN, "BALIGN");
140 PF (SEC_READONLY, "READONLY");
141 PF (SEC_CODE, "CODE");
142 PF (SEC_DATA, "DATA");
143 PF (SEC_ROM, "ROM");
144 printf ("\n");
2fa0b342 145#undef PF
aa0a709a 146 }
2fa0b342
DHW
147}
148
149static asymbol **
aa0a709a
SC
150DEFUN (slurp_symtab, (abfd),
151 bfd * abfd)
2fa0b342 152{
aa0a709a 153 asymbol **sy = (asymbol **) NULL;
2fa0b342 154
aa0a709a
SC
155 if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
156 {
157 (void) printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
158 return (NULL);
159 }
160
161 storage = get_symtab_upper_bound (abfd);
162 if (storage)
163 {
164 sy = (asymbol **) malloc (storage);
165 if (sy == NULL)
166 {
167 fprintf (stderr, "%s: out of memory.\n", program_name);
168 exit (1);
d20f480f 169 }
aa0a709a
SC
170 }
171 symcount = bfd_canonicalize_symtab (abfd, sy);
f50af42b
KR
172 if (symcount <= 0)
173 {
174 fprintf (stderr, "%s: Bad symbol table in \"%s\".\n",
175 program_name, bfd_get_filename (abfd));
176 exit (1);
177 }
aa0a709a 178 return sy;
2fa0b342 179}
aa0a709a 180
3ae36cb6
PB
181/* Filter out (in place) symbols that are useless for dis-assemble.
182 Return count of useful symbols. */
183
184int remove_useless_symbols (syms, count)
185 asymbol **syms;
186 int count;
187{
188 register asymbol **in_ptr = syms;
189 register asymbol **out_ptr = syms;
190
191 while ( --count >= 0 )
192 {
193 asymbol *sym = *in_ptr++;
194
195 if (sym->name == NULL || sym->name[0] == '\0')
196 continue;
197 if (sym->flags & (BSF_DEBUGGING))
198 continue;
199 if (sym->section == &bfd_und_section
200 || bfd_is_com_section (sym->section))
201 continue;
202
203 *out_ptr++ = sym;
204 }
205 return out_ptr - syms;
206}
207
208
2fa0b342 209/* Sort symbols into value order */
aa0a709a
SC
210static int
211comp (ap, bp)
770cde30
JG
212 PTR ap;
213 PTR bp;
2fa0b342 214{
770cde30
JG
215 asymbol *a = *(asymbol **)ap;
216 asymbol *b = *(asymbol **)bp;
2fa0b342 217
3ae36cb6
PB
218 if (a->value > b->value)
219 return 1;
220 else if (a->value < b->value)
221 return -1;
2fa0b342 222
3ae36cb6
PB
223 if (a->section > b->section)
224 return 1;
225 else if (a->section < b->section)
226 return -1;
227 return 0;
2fa0b342
DHW
228}
229
230/* Print the supplied address symbolically if possible */
231void
545a2768 232objdump_print_address (vma, info)
aa0a709a 233 bfd_vma vma;
545a2768 234 struct disassemble_info *info;
2fa0b342
DHW
235{
236 /* Perform a binary search looking for the closest symbol to
237 the required value */
238
239 unsigned int min = 0;
240 unsigned int max = symcount;
241
242 unsigned int thisplace = 1;
aa0a709a 243 unsigned int oldthisplace;
2fa0b342
DHW
244
245 int vardiff;
2fa0b342 246
3ae36cb6
PB
247 fprintf_vma (info->stream, vma);
248
249 if (symcount > 0)
aa0a709a
SC
250 {
251 while (true)
252 {
3ae36cb6 253 asymbol *sym; asection *sym_sec;
aa0a709a
SC
254 oldthisplace = thisplace;
255 thisplace = (max + min) / 2;
256 if (thisplace == oldthisplace)
257 break;
3ae36cb6
PB
258 sym = syms[thisplace];
259 vardiff = sym->value - vma;
260 sym_sec = sym->section;
261
262 if (vardiff > 0)
263 max = thisplace;
264 else if (vardiff < 0)
265 min = thisplace;
aa0a709a 266 else
3ae36cb6 267 goto found;
aa0a709a
SC
268 }
269 /* We've run out of places to look, print the symbol before this one
270 see if this or the symbol before describes this location the best */
fc5d6074 271
aa0a709a
SC
272 if (thisplace != 0)
273 {
274 if (syms[thisplace - 1]->value - vma >
275 syms[thisplace]->value - vma)
276 {
277 /* Previous symbol is in correct section and is closer */
278 thisplace--;
279 }
280 }
fc5d6074 281
3ae36cb6
PB
282 found:
283 fprintf (info->stream, " <%s", syms[thisplace]->name);
aa0a709a
SC
284 if (syms[thisplace]->value > vma)
285 {
d086adf8
KR
286 char buf[30], *p = buf;
287 sprintf_vma (buf, syms[thisplace]->value - vma);
288 while (*p == '0')
289 p++;
290 fprintf (info->stream, "-%s", p);
aa0a709a 291 }
3ae36cb6 292 else if (vma > syms[thisplace]->value)
aa0a709a 293 {
d086adf8
KR
294 char buf[30], *p = buf;
295 sprintf_vma (buf, vma - syms[thisplace]->value);
296 while (*p == '0')
297 p++;
298 fprintf (info->stream, "+%s", p);
aa0a709a 299 }
3ae36cb6 300 fprintf (info->stream, ">");
2fa0b342 301 }
2fa0b342
DHW
302}
303
304void
aa0a709a
SC
305disassemble_data (abfd)
306 bfd *abfd;
2fa0b342
DHW
307{
308 bfd_byte *data = NULL;
aa0a709a 309 bfd_arch_info_type *info;
fc5d6074
SC
310 bfd_size_type datasize = 0;
311 bfd_size_type i;
2e8adbd7
PB
312 unsigned int (*print) ()= 0; /* Old style */
313 disassembler_ftype disassemble = 0; /* New style */
2fa0b342 314 enum bfd_architecture a;
2e8adbd7
PB
315 struct disassemble_info disasm_info;
316
317 int prevline;
318 CONST char *prev_function = "";
d20f480f 319
2fa0b342 320 asection *section;
aa0a709a 321
2fa0b342 322 /* Replace symbol section relative values with abs values */
96d7950b 323 boolean done_dot = false;
aa0a709a 324
2e8adbd7 325 INIT_DISASSEMBLE_INFO(disasm_info, stdout);
545a2768 326 disasm_info.print_address_func = objdump_print_address;
2e8adbd7 327
aa0a709a
SC
328 for (i = 0; i < symcount; i++)
329 {
2fa0b342 330 syms[i]->value += syms[i]->section->vma;
aa0a709a 331 }
2fa0b342 332
3ae36cb6 333 symcount = remove_useless_symbols (syms, symcount);
2fa0b342
DHW
334
335 /* Sort the symbols into section and symbol order */
aa0a709a 336 (void) qsort (syms, symcount, sizeof (asymbol *), comp);
2fa0b342 337
aa0a709a
SC
338 if (machine != (char *) NULL)
339 {
340 info = bfd_scan_arch (machine);
341 if (info == 0)
342 {
343 fprintf (stderr, "%s: Can't use supplied machine %s\n",
344 program_name,
345 machine);
346 exit (1);
347 }
348 abfd->arch_info = info;
2fa0b342 349 }
e779a58c
JG
350
351 /* See if we can disassemble using bfd */
352
aa0a709a
SC
353 if (abfd->arch_info->disassemble)
354 {
355 print = abfd->arch_info->disassemble;
e779a58c 356 }
aa0a709a
SC
357 else
358 {
359 a = bfd_get_arch (abfd);
360 switch (a)
361 {
362 case bfd_arch_sparc:
f7ed13c7 363 disassemble = print_insn_sparc;
aa0a709a 364 break;
d9971b83
KR
365 case bfd_arch_z8k:
366 if (bfd_get_mach(abfd) == bfd_mach_z8001)
2e8adbd7 367 disassemble = print_insn_z8001;
d9971b83 368 else
2e8adbd7 369 disassemble = print_insn_z8002;
d9971b83 370 break;
aa0a709a 371 case bfd_arch_i386:
2e8adbd7 372 disassemble = print_insn_i386;
aa0a709a 373 break;
12da1775
KR
374 case bfd_arch_h8500:
375 disassemble = print_insn_h8500;
376 break;
3ae36cb6
PB
377 case bfd_arch_h8300:
378 if (bfd_get_mach(abfd) == bfd_mach_h8300h)
379 disassemble = print_insn_h8300h;
380 else
381 disassemble = print_insn_h8300;
382 break;
6f575704
SC
383 case bfd_arch_sh:
384 disassemble = print_insn_sh;
385 break;
386 case bfd_arch_alpha:
387 disassemble = print_insn_alpha;
388 break;
aa0a709a 389 case bfd_arch_m68k:
2e8adbd7 390 disassemble = print_insn_m68k;
aa0a709a
SC
391 break;
392 case bfd_arch_a29k:
545a2768
ILT
393 /* As far as I know we only handle big-endian 29k objects. */
394 disassemble = print_insn_big_a29k;
aa0a709a
SC
395 break;
396 case bfd_arch_i960:
545a2768 397 disassemble = print_insn_i960;
aa0a709a 398 break;
b3a2b497
ILT
399 case bfd_arch_m88k:
400 disassemble = print_insn_m88k;
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{
d086adf8 577 Elf_Internal_Shdr *stab_hdr, *stabstr_hdr;
249c6fc0
RS
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
d086adf8 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
d086adf8 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 {
b3a2b497
ILT
678 fprintf (stderr, "%s:%s: %s\n", program_name, abfd->filename,
679 bfd_errmsg (bfd_error));
aa0a709a
SC
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);
3ae36cb6
PB
727 /* Note that disassemble_data re-orders the syms table, but that is
728 safe - as long as it is done last! */
aa0a709a
SC
729 if (disassemble)
730 disassemble_data (abfd);
2fa0b342
DHW
731}
732
d9971b83 733static void
2fa0b342
DHW
734display_file (filename, target)
735 char *filename;
736 char *target;
737{
738 bfd *file, *arfile = (bfd *) NULL;
739
740 file = bfd_openr (filename, target);
aa0a709a
SC
741 if (file == NULL)
742 {
d2442698 743 fprintf (stderr, "%s: ", program_name);
aa0a709a
SC
744 bfd_perror (filename);
745 return;
746 }
2fa0b342 747
aa0a709a
SC
748 if (bfd_check_format (file, bfd_archive) == true)
749 {
750 printf ("In archive %s:\n", bfd_get_filename (file));
751 for (;;)
752 {
753 bfd_error = no_error;
754
755 arfile = bfd_openr_next_archived_file (file, arfile);
756 if (arfile == NULL)
757 {
758 if (bfd_error != no_more_archived_files)
d2442698
DM
759 {
760 fprintf (stderr, "%s: ", program_name);
761 bfd_perror (bfd_get_filename (file));
762 }
aa0a709a
SC
763 return;
764 }
2fa0b342 765
aa0a709a
SC
766 display_bfd (arfile);
767 /* Don't close the archive elements; we need them for next_archive */
768 }
2fa0b342 769 }
2fa0b342 770 else
aa0a709a 771 display_bfd (file);
2fa0b342 772
aa0a709a 773 bfd_close (file);
2fa0b342
DHW
774}
775\f
776/* Actually display the various requested regions */
777
d9971b83 778static void
2fa0b342
DHW
779dump_data (abfd)
780 bfd *abfd;
781{
782 asection *section;
aa0a709a 783 bfd_byte *data = 0;
fc5d6074
SC
784 bfd_size_type datasize = 0;
785 bfd_size_type i;
2fa0b342
DHW
786
787 for (section = abfd->sections; section != NULL; section =
aa0a709a
SC
788 section->next)
789 {
790 int onaline = 16;
2fa0b342 791
aa0a709a
SC
792 if (only == (char *) NULL ||
793 strcmp (only, section->name) == 0)
60c80016 794 {
aa0a709a
SC
795 if (section->flags & SEC_HAS_CONTENTS)
796 {
797 printf ("Contents of section %s:\n", section->name);
798
799 if (bfd_get_section_size_before_reloc (section) == 0)
800 continue;
801 data = (bfd_byte *) malloc (bfd_get_section_size_before_reloc (section));
802 if (data == (bfd_byte *) NULL)
803 {
804 fprintf (stderr, "%s: memory exhausted.\n", program_name);
805 exit (1);
806 }
807 datasize = bfd_get_section_size_before_reloc (section);
2fa0b342 808
2fa0b342 809
aa0a709a 810 bfd_get_section_contents (abfd, section, (PTR) data, 0, bfd_get_section_size_before_reloc (section));
2fa0b342 811
aa0a709a
SC
812 for (i = 0; i < bfd_get_section_size_before_reloc (section); i += onaline)
813 {
814 bfd_size_type j;
815
816 printf (" %04lx ", (unsigned long int) (i + section->vma));
817 for (j = i; j < i + onaline; j++)
818 {
819 if (j < bfd_get_section_size_before_reloc (section))
820 printf ("%02x", (unsigned) (data[j]));
821 else
822 printf (" ");
823 if ((j & 3) == 3)
824 printf (" ");
825 }
2fa0b342 826
aa0a709a
SC
827 printf (" ");
828 for (j = i; j < i + onaline; j++)
829 {
830 if (j >= bfd_get_section_size_before_reloc (section))
831 printf (" ");
832 else
833 printf ("%c", isprint (data[j]) ? data[j] : '.');
834 }
835 putchar ('\n');
836 }
d9971b83 837 free (data);
60c80016 838 }
2fa0b342 839 }
2fa0b342 840 }
2fa0b342
DHW
841}
842
2fa0b342 843/* Should perhaps share code and display with nm? */
d9971b83 844static void
2fa0b342
DHW
845dump_symbols (abfd)
846 bfd *abfd;
847{
848
849 unsigned int count;
850 asymbol **current = syms;
2fa0b342 851
aa0a709a 852 printf ("SYMBOL TABLE:\n");
e779a58c 853
aa0a709a
SC
854 for (count = 0; count < symcount; count++)
855 {
2fa0b342 856
d9971b83 857 if (*current)
aa0a709a 858 {
d9971b83
KR
859 bfd *cur_bfd = bfd_asymbol_bfd(*current);
860 if (cur_bfd)
861 {
862 bfd_print_symbol (cur_bfd,
863 stdout,
864 *current, bfd_print_symbol_all);
865 printf ("\n");
866 }
aa0a709a
SC
867
868 }
869 current++;
2fa0b342 870 }
aa0a709a
SC
871 printf ("\n");
872 printf ("\n");
2fa0b342
DHW
873}
874
d9971b83 875static void
aa0a709a
SC
876dump_relocs (abfd)
877 bfd *abfd;
2fa0b342
DHW
878{
879 arelent **relpp;
880 unsigned int relcount;
881 asection *a;
aa0a709a
SC
882
883 for (a = abfd->sections; a != (asection *) NULL; a = a->next)
884 {
885 if (a == &bfd_abs_section)
886 continue;
887 if (a == &bfd_und_section)
888 continue;
d9971b83 889 if (bfd_is_com_section (a))
aa0a709a
SC
890 continue;
891
892 printf ("RELOCATION RECORDS FOR [%s]:", a->name);
893
894 if (bfd_get_reloc_upper_bound (abfd, a) == 0)
895 {
896 printf (" (none)\n\n");
d20f480f 897 }
aa0a709a
SC
898 else
899 {
d20f480f
SC
900 arelent **p;
901
aa0a709a 902 relpp = (arelent **) xmalloc (bfd_get_reloc_upper_bound (abfd, a));
3ae36cb6 903 /* Note that this must be done *before* we sort the syms table. */
aa0a709a
SC
904 relcount = bfd_canonicalize_reloc (abfd, a, relpp, syms);
905 if (relcount == 0)
906 {
907 printf (" (none)\n\n");
d20f480f 908 }
aa0a709a
SC
909 else
910 {
911 printf ("\n");
912 printf ("OFFSET TYPE VALUE \n");
d20f480f 913
aa0a709a
SC
914 for (p = relpp; relcount && *p != (arelent *) NULL; p++,
915 relcount--)
916 {
d20f480f
SC
917 arelent *q = *p;
918 CONST char *sym_name;
aa0a709a 919
d20f480f
SC
920 /* CONST char *section_name = q->section == (asection *)NULL ? "*abs" :*/
921 /* q->section->name;*/
aa0a709a
SC
922 CONST char *section_name = (*(q->sym_ptr_ptr))->section->name;
923
924 if (q->sym_ptr_ptr && *q->sym_ptr_ptr)
925 {
926 sym_name = (*(q->sym_ptr_ptr))->name;
d20f480f 927 }
aa0a709a
SC
928 else
929 {
d20f480f
SC
930 sym_name = 0;
931 }
aa0a709a
SC
932 if (sym_name)
933 {
934 printf_vma (q->address);
935 printf (" %-8s %s",
936 q->howto->name,
937 sym_name);
d20f480f 938 }
aa0a709a
SC
939 else
940 {
941 printf_vma (q->address);
942 printf (" %-8s [%s]",
943 q->howto->name,
944 section_name);
d20f480f 945 }
aa0a709a
SC
946 if (q->addend)
947 {
948 printf ("+0x");
949 printf_vma (q->addend);
d20f480f 950 }
aa0a709a 951 printf ("\n");
d20f480f 952 }
aa0a709a
SC
953 printf ("\n\n");
954 free (relpp);
d20f480f 955 }
2fa0b342 956 }
2fa0b342 957
d20f480f 958 }
2fa0b342
DHW
959}
960
aa0a709a
SC
961#ifdef unix
962#define _DUMMY_NAME_ "/dev/null"
963#else
964#define _DUMMY_NAME_ "##dummy"
965#endif
9872a49c 966static void
aa0a709a
SC
967DEFUN (display_info_table, (first, last),
968 int first AND int last)
9872a49c 969{
3fdbfe8d 970 unsigned int i, j;
9872a49c
SC
971 extern bfd_target *target_vector[];
972
aa0a709a
SC
973 printf ("\n%12s", " ");
974 for (i = first; i++ < last && target_vector[i];)
975 printf ("%s ", target_vector[i]->name);
976 printf ("\n");
9872a49c 977
aa0a709a
SC
978 for (j = (int) bfd_arch_obscure + 1; (int) j < (int) bfd_arch_last; j++)
979 if (strcmp (bfd_printable_arch_mach (j, 0), "UNKNOWN!") != 0)
e779a58c 980 {
aa0a709a
SC
981 printf ("%11s ", bfd_printable_arch_mach (j, 0));
982 for (i = first; i++ < last && target_vector[i];)
983 {
984 bfd_target *p = target_vector[i];
985 bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
986 int l = strlen (p->name);
249c6fc0
RS
987 int ok;
988 bfd_set_format (abfd, bfd_object);
989 ok = bfd_set_arch_mach (abfd, j, 0);
aa0a709a
SC
990
991 if (ok)
992 printf ("%s ", p->name);
993 else
e779a58c 994 {
aa0a709a
SC
995 while (l--)
996 printf ("%c", ok ? '*' : '-');
997 printf (" ");
e779a58c 998 }
e779a58c 999 }
aa0a709a 1000 printf ("\n");
e779a58c 1001 }
9872a49c 1002}
aa0a709a
SC
1003
1004static void
1005DEFUN_VOID (display_info)
1006{
1007 char *colum;
1008 unsigned int i, j, columns;
1009 extern bfd_target *target_vector[];
1010 extern char *getenv ();
1011
1012 printf ("BFD header file version %s\n", BFD_VERSION);
1013 for (i = 0; target_vector[i]; i++)
1014 {
1015 bfd_target *p = target_vector[i];
1016 bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
249c6fc0 1017 bfd_set_format (abfd, bfd_object);
aa0a709a
SC
1018 printf ("%s\n (header %s, data %s)\n", p->name,
1019 p->header_byteorder_big_p ? "big endian" : "little endian",
1020 p->byteorder_big_p ? "big endian" : "little endian");
1021 for (j = (int) bfd_arch_obscure + 1; j < (int) bfd_arch_last; j++)
1022 if (bfd_set_arch_mach (abfd, (enum bfd_architecture) j, 0))
1023 printf (" %s\n",
1024 bfd_printable_arch_mach ((enum bfd_architecture) j, 0));
1025 }
1026 columns = 0;
1027 if (colum = getenv ("COLUMNS"))
1028 columns = atoi (colum);
1029 if (!columns)
1030 columns = 80;
1031 for (i = 0; target_vector[i];)
1032 {
1033 int old;
1034 old = i;
1035 for (j = 12; target_vector[i] && j < columns; i++)
1036 j += strlen (target_vector[i]->name) + 1;
1037 i--;
1038 if (old == i)
1039 break;
1040 display_info_table (old, i);
1041 }
1042}
1043
2fa0b342
DHW
1044/** main and like trivia */
1045int
1046main (argc, argv)
1047 int argc;
1048 char **argv;
1049{
1050 int c;
1051 extern int optind;
1052 extern char *optarg;
1053 char *target = default_target;
1054 boolean seenflag = false;
2fa0b342 1055
aa0a709a 1056 bfd_init ();
2fa0b342
DHW
1057 program_name = *argv;
1058
d2442698
DM
1059 while ((c = getopt_long (argc, argv, "ib:m:Vdlfahrtxsj:", long_options,
1060 (int *) 0))
aa0a709a
SC
1061 != EOF)
1062 {
1063 seenflag = true;
1064 switch (c)
1065 {
b3a2b497
ILT
1066 case 0:
1067 break; /* we've been given a long option */
aa0a709a
SC
1068 case 'm':
1069 machine = optarg;
1070 break;
1071 case 'j':
1072 only = optarg;
1073 break;
1074 case 'l':
1075 with_line_numbers = 1;
1076 break;
1077 case 'b':
1078 target = optarg;
1079 break;
1080 case 'f':
1081 dump_file_header = true;
1082 break;
1083 case 'i':
1084 info = true;
1085 break;
1086 case 'x':
1087 dump_symtab = 1;
1088 dump_reloc_info = 1;
1089 dump_file_header = true;
1090 dump_ar_hdrs = 1;
1091 dump_section_headers = 1;
1092 break;
aa0a709a
SC
1093 case 't':
1094 dump_symtab = 1;
1095 break;
1096 case 'd':
1097 disassemble = true;
1098 break;
1099 case 's':
1100 dump_section_contents = 1;
1101 break;
1102 case 'r':
1103 dump_reloc_info = 1;
1104 break;
1105 case 'a':
1106 dump_ar_hdrs = 1;
1107 break;
1108 case 'h':
1109 dump_section_headers = 1;
1110 break;
b3a2b497
ILT
1111 case 'H':
1112 usage (stdout, 0);
249c6fc0
RS
1113 case 'V':
1114 show_version = 1;
1115 break;
aa0a709a 1116 default:
b3a2b497 1117 usage (stderr, 1);
aa0a709a 1118 }
2fa0b342 1119 }
2fa0b342 1120
249c6fc0 1121 if (show_version)
b3a2b497
ILT
1122 {
1123 printf ("GNU %s version %s\n", program_name, program_version);
1124 exit (0);
1125 }
249c6fc0 1126
2fa0b342 1127 if (seenflag == false)
b3a2b497 1128 usage (stderr, 1);
2fa0b342 1129
aa0a709a
SC
1130 if (info)
1131 {
1132 display_info ();
1133 }
1134 else
1135 {
1136 if (optind == argc)
1137 display_file ("a.out", target);
1138 else
1139 for (; optind < argc;)
1140 display_file (argv[optind++], target);
1141 }
2fa0b342
DHW
1142 return 0;
1143}
This page took 0.138044 seconds and 4 git commands to generate.