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