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