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