Merge Apollo patches from Troy Rollo (troy@cbme.unsw.edu.au):
[deliverable/binutils-gdb.git] / binutils / objdump.c
CommitLineData
d20f480f 1/* objdump.c -- dump information about an object file.
b3a2b497 2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
2fa0b342 3
b3a2b497 4This file is part of GNU Binutils.
2fa0b342 5
b3a2b497 6This program is free software; you can redistribute it and/or modify
2fa0b342 7it under the terms of the GNU General Public License as published by
d20f480f 8the Free Software Foundation; either version 2, or (at your option)
2fa0b342
DHW
9any later version.
10
b3a2b497 11This program is distributed in the hope that it will be useful,
2fa0b342
DHW
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
b3a2b497
ILT
17along with this program; if not, write to the Free Software
18Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
2fa0b342 19
2fa0b342 20#include "bfd.h"
d20f480f 21#include "sysdep.h"
2fa0b342
DHW
22#include "getopt.h"
23#include <stdio.h>
24#include <ctype.h>
2e8adbd7 25#include "dis-asm.h"
2fa0b342 26
73b8f102
JG
27/* Internal headers for the ELF .stab-dump code - sorry. */
28#define BYTES_IN_WORD 32
29#include "aout/aout64.h"
30#include "elf/internal.h"
d086adf8 31extern Elf_Internal_Shdr *bfd_elf_find_section();
bf661056 32
2e8adbd7 33extern char *xmalloc ();
6f575704 34extern int fprintf PARAMS ((FILE *, CONST char *, ...));
2fa0b342
DHW
35
36char *default_target = NULL; /* default at runtime */
37
249c6fc0 38extern *program_version;
2fa0b342
DHW
39char *program_name = NULL;
40
249c6fc0 41int show_version = 0; /* show the version number */
2fa0b342
DHW
42int dump_section_contents; /* -s */
43int dump_section_headers; /* -h */
44boolean dump_file_header; /* -f */
45int dump_symtab; /* -t */
46int dump_reloc_info; /* -r */
47int dump_ar_hdrs; /* -a */
aa0a709a 48int with_line_numbers; /* -l */
9b018ecd 49int dump_stab_section_info; /* --stabs */
aa0a709a
SC
50boolean disassemble; /* -d */
51boolean info; /* -i */
195d1adf
KR
52char *only; /* -j secname */
53
54struct objdump_disasm_info {
55 bfd *abfd;
56 asection *sec;
57};
2fa0b342 58
aa0a709a
SC
59char *machine = (char *) NULL;
60asymbol **syms;
2fa0b342 61
2fa0b342
DHW
62unsigned int storage;
63
64unsigned int symcount = 0;
65
d9971b83
KR
66/* Forward declarations. */
67
68static void
69display_file PARAMS ((char *filename, char *target));
70
71static void
72dump_data PARAMS ((bfd *abfd));
73
74static void
75dump_relocs PARAMS ((bfd *abfd));
76
77static void
78dump_symbols PARAMS ((bfd *abfd));
79\f
2fa0b342 80void
b3a2b497
ILT
81usage (stream, status)
82 FILE *stream;
83 int status;
2fa0b342 84{
b3a2b497 85 fprintf (stream, "\
d2442698 86Usage: %s [-ahifdrtxsl] [-m machine] [-j section_name] [-b bfdname]\n\
9b018ecd 87 [--syms] [--reloc] [--header] [--stabs] [--version] [--help] objfile...\n\
195d1adf 88 at least one option besides -l must be given\n",
b3a2b497
ILT
89 program_name);
90 exit (status);
2fa0b342
DHW
91}
92
aa0a709a
SC
93static struct option long_options[]=
94{
95 {"syms", no_argument, &dump_symtab, 1},
96 {"reloc", no_argument, &dump_reloc_info, 1},
97 {"header", no_argument, &dump_section_headers, 1},
249c6fc0 98 {"version", no_argument, &show_version, 1},
b3a2b497 99 {"help", no_argument, 0, 'H'},
73b8f102 100 {"stabs", no_argument, &dump_stab_section_info, 1},
d2442698
DM
101 {0, no_argument, 0, 0}
102};
2fa0b342
DHW
103
104
2fa0b342 105static void
aa0a709a
SC
106dump_headers (abfd)
107 bfd *abfd;
2fa0b342
DHW
108{
109 asection *section;
aa0a709a 110
2fa0b342
DHW
111 for (section = abfd->sections;
112 section != (asection *) NULL;
aa0a709a
SC
113 section = section->next)
114 {
115 char *comma = "";
116
2fa0b342 117#define PF(x,y) \
e779a58c
JG
118 if (section->flags & x) { printf("%s%s",comma,y); comma = ", "; }
119
120
aa0a709a
SC
121 printf ("SECTION %d [%s]\t: size %08x",
122 section->index,
123 section->name,
124 (unsigned) bfd_get_section_size_before_reloc (section));
125 printf (" vma ");
126 printf_vma (section->vma);
127 printf (" align 2**%u\n ",
128 section->alignment_power);
129 PF (SEC_ALLOC, "ALLOC");
130 PF (SEC_CONSTRUCTOR, "CONSTRUCTOR");
131 PF (SEC_CONSTRUCTOR_TEXT, "CONSTRUCTOR TEXT");
132 PF (SEC_CONSTRUCTOR_DATA, "CONSTRUCTOR DATA");
133 PF (SEC_CONSTRUCTOR_BSS, "CONSTRUCTOR BSS");
134 PF (SEC_LOAD, "LOAD");
135 PF (SEC_RELOC, "RELOC");
195d1adf 136#ifdef SEC_BALIGN
aa0a709a 137 PF (SEC_BALIGN, "BALIGN");
195d1adf 138#endif
aa0a709a
SC
139 PF (SEC_READONLY, "READONLY");
140 PF (SEC_CODE, "CODE");
141 PF (SEC_DATA, "DATA");
142 PF (SEC_ROM, "ROM");
143 printf ("\n");
2fa0b342 144#undef PF
aa0a709a 145 }
2fa0b342
DHW
146}
147
148static asymbol **
aa0a709a
SC
149DEFUN (slurp_symtab, (abfd),
150 bfd * abfd)
2fa0b342 151{
aa0a709a 152 asymbol **sy = (asymbol **) NULL;
2fa0b342 153
aa0a709a
SC
154 if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
155 {
156 (void) printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
157 return (NULL);
158 }
159
160 storage = get_symtab_upper_bound (abfd);
161 if (storage)
162 {
163 sy = (asymbol **) malloc (storage);
164 if (sy == NULL)
165 {
166 fprintf (stderr, "%s: out of memory.\n", program_name);
167 exit (1);
d20f480f 168 }
aa0a709a
SC
169 }
170 symcount = bfd_canonicalize_symtab (abfd, sy);
f50af42b
KR
171 if (symcount <= 0)
172 {
173 fprintf (stderr, "%s: Bad symbol table in \"%s\".\n",
174 program_name, bfd_get_filename (abfd));
175 exit (1);
176 }
aa0a709a 177 return sy;
2fa0b342 178}
aa0a709a 179
3ae36cb6
PB
180/* Filter out (in place) symbols that are useless for dis-assemble.
181 Return count of useful symbols. */
182
183int remove_useless_symbols (syms, count)
184 asymbol **syms;
185 int count;
186{
187 register asymbol **in_ptr = syms;
188 register asymbol **out_ptr = syms;
189
190 while ( --count >= 0 )
191 {
192 asymbol *sym = *in_ptr++;
193
194 if (sym->name == NULL || sym->name[0] == '\0')
195 continue;
196 if (sym->flags & (BSF_DEBUGGING))
197 continue;
198 if (sym->section == &bfd_und_section
199 || bfd_is_com_section (sym->section))
200 continue;
201
202 *out_ptr++ = sym;
203 }
204 return out_ptr - syms;
205}
206
207
2fa0b342 208/* Sort symbols into value order */
aa0a709a
SC
209static int
210comp (ap, bp)
770cde30
JG
211 PTR ap;
212 PTR bp;
2fa0b342 213{
770cde30
JG
214 asymbol *a = *(asymbol **)ap;
215 asymbol *b = *(asymbol **)bp;
2fa0b342 216
3ae36cb6
PB
217 if (a->value > b->value)
218 return 1;
219 else if (a->value < b->value)
220 return -1;
2fa0b342 221
3ae36cb6
PB
222 if (a->section > b->section)
223 return 1;
224 else if (a->section < b->section)
225 return -1;
226 return 0;
2fa0b342
DHW
227}
228
229/* Print the supplied address symbolically if possible */
230void
545a2768 231objdump_print_address (vma, info)
aa0a709a 232 bfd_vma vma;
545a2768 233 struct disassemble_info *info;
2fa0b342
DHW
234{
235 /* Perform a binary search looking for the closest symbol to
195d1adf
KR
236 the required value. */
237 /* @@ For relocateable files, should filter out symbols belonging to
238 the wrong section. Unfortunately, not enough information is supplied
239 to this routine to determine the correct section in all cases. */
240 /* @@ Would it speed things up to cache the last two symbols returned,
241 and maybe their address ranges? For many processors, only one memory
242 operand can be present at a time, so the 2-entry cache wouldn't be
243 constantly churned by code doing heavy memory accesses. */
2fa0b342
DHW
244
245 unsigned int min = 0;
246 unsigned int max = symcount;
247
248 unsigned int thisplace = 1;
aa0a709a 249 unsigned int oldthisplace;
2fa0b342
DHW
250
251 int vardiff;
2fa0b342 252
3ae36cb6
PB
253 fprintf_vma (info->stream, vma);
254
255 if (symcount > 0)
aa0a709a
SC
256 {
257 while (true)
258 {
3ae36cb6 259 asymbol *sym; asection *sym_sec;
aa0a709a
SC
260 oldthisplace = thisplace;
261 thisplace = (max + min) / 2;
262 if (thisplace == oldthisplace)
263 break;
3ae36cb6
PB
264 sym = syms[thisplace];
265 vardiff = sym->value - vma;
266 sym_sec = sym->section;
267
268 if (vardiff > 0)
269 max = thisplace;
270 else if (vardiff < 0)
271 min = thisplace;
aa0a709a 272 else
3ae36cb6 273 goto found;
aa0a709a
SC
274 }
275 /* We've run out of places to look, print the symbol before this one
276 see if this or the symbol before describes this location the best */
fc5d6074 277
aa0a709a
SC
278 if (thisplace != 0)
279 {
280 if (syms[thisplace - 1]->value - vma >
281 syms[thisplace]->value - vma)
282 {
283 /* Previous symbol is in correct section and is closer */
284 thisplace--;
285 }
286 }
fc5d6074 287
3ae36cb6 288 found:
195d1adf
KR
289 {
290 bfd_vma val = syms[thisplace]->value;
291 int i;
292 if (syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING))
293 for (i = thisplace - 1; i >= 0; i--)
294 {
295 if (syms[i]->value == val
296 && (!(syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
297 || ((syms[thisplace]->flags & BSF_DEBUGGING)
298 && !(syms[i]->flags & BSF_DEBUGGING))))
299 {
300 thisplace = i;
301 break;
302 }
303 }
304 if (syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING))
305 for (i = thisplace + 1; i < symcount; i++)
306 {
307 if (syms[i]->value == val
308 && (!(syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
309 || ((syms[thisplace]->flags & BSF_DEBUGGING)
310 && !(syms[i]->flags & BSF_DEBUGGING))))
311 {
312 thisplace = i;
313 break;
314 }
315 }
316 }
317 {
318 /* If the file is relocateable, and the symbol could be from this
319 section, prefer a symbol from this section over symbols from
320 others, even if the other symbol's value might be closer.
321
322 Note that this may be wrong for some symbol references if the
323 sections have overlapping memory ranges, but in that case there's
324 no way to tell what's desired without looking at the relocation
325 table. */
326 struct objdump_disasm_info *aux;
327 int i;
328
329 aux = (struct objdump_disasm_info *) info->application_data;
330 if (aux->abfd->flags & HAS_RELOC
331 && vma >= bfd_get_section_vma (aux->abfd, aux->sec)
332 && vma < (bfd_get_section_vma (aux->abfd, aux->sec)
333 + bfd_get_section_size_before_reloc (aux->sec))
334 && syms[thisplace]->section != aux->sec)
335 {
336 for (i = thisplace + 1; i < symcount; i++)
337 if (syms[i]->value != syms[thisplace]->value)
338 break;
339 while (--i >= 0)
340 if (syms[i]->section == aux->sec)
341 {
342 thisplace = i;
343 break;
344 }
345 }
346 }
3ae36cb6 347 fprintf (info->stream, " <%s", syms[thisplace]->name);
aa0a709a
SC
348 if (syms[thisplace]->value > vma)
349 {
d086adf8
KR
350 char buf[30], *p = buf;
351 sprintf_vma (buf, syms[thisplace]->value - vma);
352 while (*p == '0')
353 p++;
354 fprintf (info->stream, "-%s", p);
aa0a709a 355 }
3ae36cb6 356 else if (vma > syms[thisplace]->value)
aa0a709a 357 {
d086adf8
KR
358 char buf[30], *p = buf;
359 sprintf_vma (buf, vma - syms[thisplace]->value);
360 while (*p == '0')
361 p++;
362 fprintf (info->stream, "+%s", p);
aa0a709a 363 }
3ae36cb6 364 fprintf (info->stream, ">");
2fa0b342 365 }
2fa0b342
DHW
366}
367
195d1adf
KR
368#ifdef ARCH_all
369#define ARCH_a29k
370#define ARCH_alpha
371#define ARCH_h8300
372#define ARCH_h8500
373#define ARCH_hppa
374#define ARCH_i386
375#define ARCH_i960
376#define ARCH_m68k
377#define ARCH_m88k
378#define ARCH_mips
379#define ARCH_sh
380#define ARCH_sparc
381#define ARCH_z8k
382#endif
383
2fa0b342 384void
aa0a709a
SC
385disassemble_data (abfd)
386 bfd *abfd;
2fa0b342
DHW
387{
388 bfd_byte *data = NULL;
aa0a709a 389 bfd_arch_info_type *info;
fc5d6074
SC
390 bfd_size_type datasize = 0;
391 bfd_size_type i;
2e8adbd7
PB
392 unsigned int (*print) ()= 0; /* Old style */
393 disassembler_ftype disassemble = 0; /* New style */
2fa0b342 394 enum bfd_architecture a;
2e8adbd7 395 struct disassemble_info disasm_info;
195d1adf 396 struct objdump_disasm_info aux;
2e8adbd7
PB
397
398 int prevline;
399 CONST char *prev_function = "";
d20f480f 400
2fa0b342 401 asection *section;
aa0a709a 402
2fa0b342 403 /* Replace symbol section relative values with abs values */
96d7950b 404 boolean done_dot = false;
aa0a709a 405
2e8adbd7 406 INIT_DISASSEMBLE_INFO(disasm_info, stdout);
195d1adf
KR
407 disasm_info.application_data = (PTR) &aux;
408 aux.abfd = abfd;
545a2768 409 disasm_info.print_address_func = objdump_print_address;
2e8adbd7 410
aa0a709a
SC
411 for (i = 0; i < symcount; i++)
412 {
2fa0b342 413 syms[i]->value += syms[i]->section->vma;
aa0a709a 414 }
2fa0b342 415
3ae36cb6 416 symcount = remove_useless_symbols (syms, symcount);
2fa0b342
DHW
417
418 /* Sort the symbols into section and symbol order */
aa0a709a 419 (void) qsort (syms, symcount, sizeof (asymbol *), comp);
2fa0b342 420
aa0a709a
SC
421 if (machine != (char *) NULL)
422 {
423 info = bfd_scan_arch (machine);
424 if (info == 0)
425 {
426 fprintf (stderr, "%s: Can't use supplied machine %s\n",
427 program_name,
428 machine);
429 exit (1);
430 }
431 abfd->arch_info = info;
2fa0b342 432 }
e779a58c
JG
433
434 /* See if we can disassemble using bfd */
435
aa0a709a
SC
436 if (abfd->arch_info->disassemble)
437 {
438 print = abfd->arch_info->disassemble;
e779a58c 439 }
aa0a709a
SC
440 else
441 {
442 a = bfd_get_arch (abfd);
443 switch (a)
444 {
195d1adf
KR
445 /* If you add a case to this table, also add it to the
446 ARCH_all definition right above this function. */
447#ifdef ARCH_a29k
448 case bfd_arch_a29k:
449 /* As far as I know we only handle big-endian 29k objects. */
450 disassemble = print_insn_big_a29k;
aa0a709a 451 break;
195d1adf
KR
452#endif
453#ifdef ARCH_alpha
454 case bfd_arch_alpha:
455 disassemble = print_insn_alpha;
12da1775 456 break;
195d1adf
KR
457#endif
458#ifdef ARCH_h8300
3ae36cb6
PB
459 case bfd_arch_h8300:
460 if (bfd_get_mach(abfd) == bfd_mach_h8300h)
461 disassemble = print_insn_h8300h;
462 else
463 disassemble = print_insn_h8300;
464 break;
195d1adf
KR
465#endif
466#ifdef ARCH_h8500
467 case bfd_arch_h8500:
468 disassemble = print_insn_h8500;
6f575704 469 break;
195d1adf
KR
470#endif
471#ifdef ARCH_hppa
472 case bfd_arch_hppa:
473 disassemble = print_insn_hppa;
aa0a709a 474 break;
195d1adf
KR
475#endif
476#ifdef ARCH_i386
477 case bfd_arch_i386:
478 disassemble = print_insn_i386;
aa0a709a 479 break;
195d1adf
KR
480#endif
481#ifdef ARCH_i960
aa0a709a 482 case bfd_arch_i960:
545a2768 483 disassemble = print_insn_i960;
aa0a709a 484 break;
195d1adf
KR
485#endif
486#ifdef ARCH_m68k
487 case bfd_arch_m68k:
488 disassemble = print_insn_m68k;
489 break;
490#endif
491#ifdef ARCH_m88k
b3a2b497
ILT
492 case bfd_arch_m88k:
493 disassemble = print_insn_m88k;
494 break;
195d1adf
KR
495#endif
496#ifdef ARCH_mips
d9971b83 497 case bfd_arch_mips:
2e8adbd7
PB
498 if (abfd->xvec->byteorder_big_p)
499 disassemble = print_insn_big_mips;
500 else
501 disassemble = print_insn_little_mips;
d9971b83 502 break;
195d1adf
KR
503#endif
504#ifdef ARCH_sh
505 case bfd_arch_sh:
506 disassemble = print_insn_sh;
507 break;
508#endif
509#ifdef ARCH_sparc
510 case bfd_arch_sparc:
511 disassemble = print_insn_sparc;
512 break;
513#endif
514#ifdef ARCH_z8k
515 case bfd_arch_z8k:
516 if (bfd_get_mach(abfd) == bfd_mach_z8001)
517 disassemble = print_insn_z8001;
518 else
519 disassemble = print_insn_z8002;
520 break;
521#endif
aa0a709a
SC
522 default:
523 fprintf (stderr, "%s: Can't disassemble for architecture %s\n",
524 program_name,
525 bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
526 exit (1);
527 }
2fa0b342 528
aa0a709a 529 }
2fa0b342
DHW
530
531 for (section = abfd->sections;
aa0a709a
SC
532 section != (asection *) NULL;
533 section = section->next)
65cceb78 534 {
195d1adf 535 aux.sec = section;
2fa0b342 536
aa0a709a
SC
537 if ((section->flags & SEC_LOAD)
538 && (only == (char *) NULL || strcmp (only, section->name) == 0))
539 {
540 printf ("Disassembly of section %s:\n", section->name);
2fa0b342 541
aa0a709a
SC
542 if (bfd_get_section_size_before_reloc (section) == 0)
543 continue;
2fa0b342 544
195d1adf 545 data = (bfd_byte *) malloc ((size_t) bfd_get_section_size_before_reloc (section));
2fa0b342 546
aa0a709a
SC
547 if (data == (bfd_byte *) NULL)
548 {
549 fprintf (stderr, "%s: memory exhausted.\n", program_name);
550 exit (1);
551 }
552 datasize = bfd_get_section_size_before_reloc (section);
2fa0b342 553
aa0a709a 554 bfd_get_section_contents (abfd, section, data, 0, bfd_get_section_size_before_reloc (section));
2fa0b342 555
5d0734a7
JK
556 disasm_info.buffer = data;
557 disasm_info.buffer_vma = section->vma;
558 disasm_info.buffer_length =
559 bfd_get_section_size_before_reloc (section);
aa0a709a 560 i = 0;
5d0734a7 561 while (i < disasm_info.buffer_length)
aa0a709a
SC
562 {
563 if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 0 &&
564 data[i + 3] == 0)
565 {
566 if (done_dot == false)
567 {
568 printf ("...\n");
569 done_dot = true;
65cceb78 570 }
aa0a709a 571 i += 4;
65cceb78 572 }
aa0a709a
SC
573 else
574 {
575 done_dot = false;
576 if (with_line_numbers)
577 {
aa0a709a
SC
578 CONST char *filename;
579 CONST char *functionname;
580 unsigned int line;
581
d9971b83
KR
582 if (bfd_find_nearest_line (abfd,
583 section,
584 syms,
585 section->vma + i,
586 &filename,
587 &functionname,
2e8adbd7 588 &line))
aa0a709a 589 {
2e8adbd7
PB
590 if (functionname && *functionname
591 && strcmp(functionname, prev_function))
592 {
593 printf ("%s():\n", functionname);
594 prev_function = functionname;
595 }
596 if (!filename)
597 filename = "???";
598 if (line && line != prevline)
599 {
600 printf ("%s:%u\n", filename, line);
601 prevline = line;
602 }
aa0a709a
SC
603 }
604 }
545a2768 605 objdump_print_address (section->vma + i, &disasm_info);
aa0a709a 606 printf (" ");
65cceb78 607
2e8adbd7 608 if (disassemble) /* New style */
5d0734a7
JK
609 {
610 int bytes = (*disassemble)(section->vma + i,
611 &disasm_info);
612 if (bytes < 0)
613 break;
614 i += bytes;
615 }
2e8adbd7 616 else /* Old style */
d9971b83
KR
617 i += print (section->vma + i,
618 data + i,
619 stdout);
aa0a709a
SC
620 putchar ('\n');
621 }
96d7950b 622 }
aa0a709a 623 free (data);
96d7950b 624 }
2fa0b342 625 }
2fa0b342 626}
73b8f102 627\f
73b8f102
JG
628
629/* Define a table of stab values and print-strings. We wish the initializer
630 could be a direct-mapped table, but instead we build one the first
631 time we need it. */
632
633#define STAB_STRING_LENGTH 6
634
635char stab_name[256][STAB_STRING_LENGTH];
636
637struct stab_print {
638 int value;
639 char string[STAB_STRING_LENGTH];
640};
641
642struct stab_print stab_print[] = {
643#define __define_stab(NAME, CODE, STRING) {CODE, STRING},
644#include "aout/stab.def"
645#undef __define_stab
646 {0, 0}
647};
648
9b018ecd 649void dump_stabs_1 ();
249c6fc0 650
9b018ecd 651/* This dumps the stabs section from object files that have a section that
73b8f102
JG
652 uses Sun stabs encoding. It has to use some hooks into BFD because
653 string table sections are not normally visible to BFD callers. */
654
655void
9b018ecd 656dump_stabs (abfd)
73b8f102
JG
657 bfd *abfd;
658{
249c6fc0 659 int i;
73b8f102
JG
660
661 /* Initialize stab name array if first time. */
662 if (stab_name[0][0] == 0)
663 {
664 /* Fill in numeric values for all possible strings. */
665 for (i = 0; i < 256; i++)
666 {
667 sprintf (stab_name[i], "%d", i);
668 }
669 for (i = 0; stab_print[i].string[0]; i++)
670 strcpy (stab_name[stab_print[i].value], stab_print[i].string);
671 }
672
9b018ecd
ILT
673 dump_stabs_1 (abfd, ".stab", ".stabstr");
674 dump_stabs_1 (abfd, ".stab.excl", ".stab.exclstr");
675 dump_stabs_1 (abfd, ".stab.index", ".stab.indexstr");
249c6fc0
RS
676}
677
678void
9b018ecd 679dump_stabs_1 (abfd, name1, name2)
249c6fc0
RS
680 bfd *abfd;
681 char *name1; /* Section name of .stab */
682 char *name2; /* Section name of its string section */
683{
d086adf8 684 Elf_Internal_Shdr *stab_hdr, *stabstr_hdr;
9b018ecd 685 asection *stabsect, *stabstrsect;
249c6fc0
RS
686 char *strtab;
687 struct internal_nlist *stabs, *stabs_end;
688 int i;
9b018ecd 689 int stab_size, stabstr_size;
249c6fc0 690 unsigned file_string_table_offset, next_file_string_table_offset;
9b018ecd
ILT
691 int is_elf = (0 == strncmp ("elf", abfd->xvec->name, 3));
692
693 if (is_elf)
694 {
695 stab_hdr = bfd_elf_find_section (abfd, name1);
696 }
697 else
698 {
699 stabsect = bfd_get_section_by_name (abfd, name1);
700 }
249c6fc0 701
9b018ecd 702 if (is_elf ? (0 == stab_hdr) : (0 == stabsect))
73b8f102 703 {
9b018ecd 704 printf ("No %s section present.\n\n", name1);
73b8f102
JG
705 return;
706 }
707
9b018ecd
ILT
708 if (is_elf)
709 {
710 stabstr_hdr = bfd_elf_find_section (abfd, name2);
711 }
712 else
713 {
714 stabstrsect = bfd_get_section_by_name (abfd, name2);
715 }
716
717 if (is_elf ? (0 == stabstr_hdr) : (0 == stabstrsect))
73b8f102 718 {
249c6fc0
RS
719 fprintf (stderr, "%s: %s has no %s section.\n", program_name,
720 abfd->filename, name2);
73b8f102
JG
721 return;
722 }
9b018ecd
ILT
723
724 stab_size = (is_elf ? stab_hdr ->sh_size : bfd_section_size (abfd, stabsect));
725 stabstr_size = (is_elf ? stabstr_hdr->sh_size : bfd_section_size (abfd, stabstrsect));
73b8f102 726
9b018ecd
ILT
727 stabs = (struct internal_nlist *) xmalloc (stab_size);
728 strtab = (char *) xmalloc (stabstr_size);
729 stabs_end = (struct internal_nlist *) (stab_size + (char *) stabs);
73b8f102 730
9b018ecd 731 if (is_elf)
73b8f102 732 {
9b018ecd
ILT
733 if (bfd_seek (abfd, stab_hdr->sh_offset, SEEK_SET) < 0 ||
734 stab_size != bfd_read ((PTR) stabs, stab_size, 1, abfd))
735 {
736 fprintf (stderr, "%s: reading %s section of %s failed.\n",
737 program_name, name1,
738 abfd->filename);
739 return;
740 }
741 }
742 else
743 {
744 bfd_get_section_contents (abfd, stabsect, (PTR) stabs, 0, stab_size);
73b8f102 745 }
2fa0b342 746
9b018ecd 747 if (is_elf)
73b8f102 748 {
9b018ecd
ILT
749 if (bfd_seek (abfd, stabstr_hdr->sh_offset, SEEK_SET) < 0 ||
750 stabstr_size != bfd_read ((PTR) strtab, stabstr_size, 1, abfd))
751 {
752 fprintf (stderr, "%s: reading %s section of %s failed.\n",
753 program_name, name2,
754 abfd->filename);
755 return;
756 }
757 }
758 else
759 {
760 bfd_get_section_contents (abfd, stabstrsect, (PTR) strtab, 0, stabstr_size);
73b8f102
JG
761 }
762
763#define SWAP_SYMBOL(symp, abfd) \
764 { \
765 (symp)->n_strx = bfd_h_get_32(abfd, \
766 (unsigned char *)&(symp)->n_strx); \
767 (symp)->n_desc = bfd_h_get_16 (abfd, \
768 (unsigned char *)&(symp)->n_desc); \
769 (symp)->n_value = bfd_h_get_32 (abfd, \
770 (unsigned char *)&(symp)->n_value); \
771 }
772
249c6fc0 773 printf ("Contents of %s section:\n\n", name1);
73b8f102
JG
774 printf ("Symnum n_type n_othr n_desc n_value n_strx String\n");
775
249c6fc0
RS
776 file_string_table_offset = 0;
777 next_file_string_table_offset = 0;
778
779 /* Loop through all symbols and print them.
780
781 We start the index at -1 because there is a dummy symbol on
73b8f102 782 the front of Sun's stabs-in-elf sections. */
249c6fc0 783
73b8f102
JG
784 for (i = -1; stabs < stabs_end; stabs++, i++)
785 {
786 SWAP_SYMBOL (stabs, abfd);
787 printf ("\n%-6d %-6s %-6d %-6d %08x %-6d", i,
788 stab_name [stabs->n_type],
789 stabs->n_other, stabs->n_desc, stabs->n_value,
790 stabs->n_strx);
249c6fc0
RS
791
792 /* Symbols with type == 0 (N_UNDF) specify the length of the
793 string table associated with this file. We use that info
794 to know how to relocate the *next* file's string table indices. */
795
796 if (stabs->n_type == N_UNDF)
797 {
798 file_string_table_offset = next_file_string_table_offset;
799 next_file_string_table_offset += stabs->n_value;
800 }
801
802 /* Now, using the possibly updated string table offset, print the
803 string (if any) associated with this symbol. */
804
9b018ecd 805 if ((stabs->n_strx + file_string_table_offset) < stabstr_size)
249c6fc0
RS
806 printf (" %s", &strtab[stabs->n_strx + file_string_table_offset]);
807 else
808 printf (" *");
73b8f102
JG
809 }
810 printf ("\n\n");
811}
249c6fc0 812
2fa0b342
DHW
813display_bfd (abfd)
814 bfd *abfd;
815{
816
aa0a709a
SC
817 if (!bfd_check_format (abfd, bfd_object))
818 {
b3a2b497
ILT
819 fprintf (stderr, "%s:%s: %s\n", program_name, abfd->filename,
820 bfd_errmsg (bfd_error));
aa0a709a
SC
821 return;
822 }
2fa0b342 823 printf ("\n%s: file format %s\n", abfd->filename, abfd->xvec->name);
aa0a709a
SC
824 if (dump_ar_hdrs)
825 print_arelt_descr (stdout, abfd, true);
2fa0b342 826
aa0a709a
SC
827 if (dump_file_header)
828 {
829 char *comma = "";
830
831 printf ("architecture: %s, ",
832 bfd_printable_arch_mach (bfd_get_arch (abfd),
833 bfd_get_mach (abfd)));
834 printf ("flags 0x%08x:\n", abfd->flags);
2fa0b342 835
2fa0b342 836#define PF(x, y) if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
aa0a709a
SC
837 PF (HAS_RELOC, "HAS_RELOC");
838 PF (EXEC_P, "EXEC_P");
839 PF (HAS_LINENO, "HAS_LINENO");
840 PF (HAS_DEBUG, "HAS_DEBUG");
841 PF (HAS_SYMS, "HAS_SYMS");
842 PF (HAS_LOCALS, "HAS_LOCALS");
843 PF (DYNAMIC, "DYNAMIC");
844 PF (WP_TEXT, "WP_TEXT");
845 PF (D_PAGED, "D_PAGED");
249c6fc0 846 PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
aa0a709a
SC
847 printf ("\nstart address 0x");
848 printf_vma (abfd->start_address);
849 }
850 printf ("\n");
2fa0b342
DHW
851
852 if (dump_section_headers)
aa0a709a
SC
853 dump_headers (abfd);
854 if (dump_symtab || dump_reloc_info || disassemble)
855 {
856 syms = slurp_symtab (abfd);
857 }
858 if (dump_symtab)
859 dump_symbols (abfd);
73b8f102 860 if (dump_stab_section_info)
9b018ecd 861 dump_stabs (abfd);
aa0a709a
SC
862 if (dump_reloc_info)
863 dump_relocs (abfd);
864 if (dump_section_contents)
865 dump_data (abfd);
3ae36cb6
PB
866 /* Note that disassemble_data re-orders the syms table, but that is
867 safe - as long as it is done last! */
aa0a709a
SC
868 if (disassemble)
869 disassemble_data (abfd);
2fa0b342
DHW
870}
871
d9971b83 872static void
2fa0b342
DHW
873display_file (filename, target)
874 char *filename;
875 char *target;
876{
877 bfd *file, *arfile = (bfd *) NULL;
878
879 file = bfd_openr (filename, target);
aa0a709a
SC
880 if (file == NULL)
881 {
d2442698 882 fprintf (stderr, "%s: ", program_name);
aa0a709a
SC
883 bfd_perror (filename);
884 return;
885 }
2fa0b342 886
aa0a709a
SC
887 if (bfd_check_format (file, bfd_archive) == true)
888 {
889 printf ("In archive %s:\n", bfd_get_filename (file));
890 for (;;)
891 {
892 bfd_error = no_error;
893
894 arfile = bfd_openr_next_archived_file (file, arfile);
895 if (arfile == NULL)
896 {
897 if (bfd_error != no_more_archived_files)
d2442698
DM
898 {
899 fprintf (stderr, "%s: ", program_name);
900 bfd_perror (bfd_get_filename (file));
901 }
aa0a709a
SC
902 return;
903 }
2fa0b342 904
aa0a709a
SC
905 display_bfd (arfile);
906 /* Don't close the archive elements; we need them for next_archive */
907 }
2fa0b342 908 }
2fa0b342 909 else
aa0a709a 910 display_bfd (file);
2fa0b342 911
aa0a709a 912 bfd_close (file);
2fa0b342
DHW
913}
914\f
915/* Actually display the various requested regions */
916
d9971b83 917static void
2fa0b342
DHW
918dump_data (abfd)
919 bfd *abfd;
920{
921 asection *section;
aa0a709a 922 bfd_byte *data = 0;
fc5d6074
SC
923 bfd_size_type datasize = 0;
924 bfd_size_type i;
2fa0b342
DHW
925
926 for (section = abfd->sections; section != NULL; section =
aa0a709a
SC
927 section->next)
928 {
929 int onaline = 16;
2fa0b342 930
aa0a709a
SC
931 if (only == (char *) NULL ||
932 strcmp (only, section->name) == 0)
60c80016 933 {
aa0a709a
SC
934 if (section->flags & SEC_HAS_CONTENTS)
935 {
936 printf ("Contents of section %s:\n", section->name);
937
9b018ecd 938 if (bfd_section_size (abfd, section) == 0)
aa0a709a 939 continue;
9b018ecd 940 data = (bfd_byte *) malloc ((size_t) bfd_section_size (abfd, section));
aa0a709a
SC
941 if (data == (bfd_byte *) NULL)
942 {
943 fprintf (stderr, "%s: memory exhausted.\n", program_name);
944 exit (1);
945 }
9b018ecd 946 datasize = bfd_section_size (abfd, section);
2fa0b342 947
2fa0b342 948
9b018ecd 949 bfd_get_section_contents (abfd, section, (PTR) data, 0, bfd_section_size (abfd, section));
2fa0b342 950
9b018ecd 951 for (i = 0; i < bfd_section_size (abfd, section); i += onaline)
aa0a709a
SC
952 {
953 bfd_size_type j;
954
955 printf (" %04lx ", (unsigned long int) (i + section->vma));
956 for (j = i; j < i + onaline; j++)
957 {
9b018ecd 958 if (j < bfd_section_size (abfd, section))
aa0a709a
SC
959 printf ("%02x", (unsigned) (data[j]));
960 else
961 printf (" ");
962 if ((j & 3) == 3)
963 printf (" ");
964 }
2fa0b342 965
aa0a709a
SC
966 printf (" ");
967 for (j = i; j < i + onaline; j++)
968 {
9b018ecd 969 if (j >= bfd_section_size (abfd, section))
aa0a709a
SC
970 printf (" ");
971 else
972 printf ("%c", isprint (data[j]) ? data[j] : '.');
973 }
974 putchar ('\n');
975 }
d9971b83 976 free (data);
60c80016 977 }
2fa0b342 978 }
2fa0b342 979 }
2fa0b342
DHW
980}
981
2fa0b342 982/* Should perhaps share code and display with nm? */
d9971b83 983static void
2fa0b342
DHW
984dump_symbols (abfd)
985 bfd *abfd;
986{
987
988 unsigned int count;
989 asymbol **current = syms;
2fa0b342 990
aa0a709a 991 printf ("SYMBOL TABLE:\n");
e779a58c 992
aa0a709a
SC
993 for (count = 0; count < symcount; count++)
994 {
2fa0b342 995
d9971b83 996 if (*current)
aa0a709a 997 {
d9971b83
KR
998 bfd *cur_bfd = bfd_asymbol_bfd(*current);
999 if (cur_bfd)
1000 {
1001 bfd_print_symbol (cur_bfd,
1002 stdout,
1003 *current, bfd_print_symbol_all);
1004 printf ("\n");
1005 }
aa0a709a
SC
1006
1007 }
1008 current++;
2fa0b342 1009 }
aa0a709a
SC
1010 printf ("\n");
1011 printf ("\n");
2fa0b342
DHW
1012}
1013
d9971b83 1014static void
aa0a709a
SC
1015dump_relocs (abfd)
1016 bfd *abfd;
2fa0b342
DHW
1017{
1018 arelent **relpp;
1019 unsigned int relcount;
1020 asection *a;
aa0a709a
SC
1021
1022 for (a = abfd->sections; a != (asection *) NULL; a = a->next)
1023 {
1024 if (a == &bfd_abs_section)
1025 continue;
1026 if (a == &bfd_und_section)
1027 continue;
d9971b83 1028 if (bfd_is_com_section (a))
aa0a709a
SC
1029 continue;
1030
195d1adf
KR
1031 if (only)
1032 {
1033 if (strcmp (only, a->name))
1034 continue;
1035 }
1036 else if ((a->flags & SEC_RELOC) == 0)
1037 continue;
1038
aa0a709a
SC
1039 printf ("RELOCATION RECORDS FOR [%s]:", a->name);
1040
1041 if (bfd_get_reloc_upper_bound (abfd, a) == 0)
1042 {
1043 printf (" (none)\n\n");
d20f480f 1044 }
aa0a709a
SC
1045 else
1046 {
d20f480f
SC
1047 arelent **p;
1048
aa0a709a 1049 relpp = (arelent **) xmalloc (bfd_get_reloc_upper_bound (abfd, a));
3ae36cb6 1050 /* Note that this must be done *before* we sort the syms table. */
aa0a709a
SC
1051 relcount = bfd_canonicalize_reloc (abfd, a, relpp, syms);
1052 if (relcount == 0)
1053 {
1054 printf (" (none)\n\n");
d20f480f 1055 }
aa0a709a
SC
1056 else
1057 {
1058 printf ("\n");
195d1adf
KR
1059 /* Get column headers lined up reasonably. */
1060 {
1061 static int width;
1062 if (width == 0)
1063 {
1064 char buf[30];
1065 sprintf_vma (buf, (bfd_vma) -1);
1066 width = strlen (buf) - 7;
1067 }
1068 printf ("OFFSET %*s TYPE %*s VALUE \n", width, "", 12, "");
1069 }
d20f480f 1070
aa0a709a
SC
1071 for (p = relpp; relcount && *p != (arelent *) NULL; p++,
1072 relcount--)
1073 {
d20f480f
SC
1074 arelent *q = *p;
1075 CONST char *sym_name;
aa0a709a
SC
1076 CONST char *section_name = (*(q->sym_ptr_ptr))->section->name;
1077
1078 if (q->sym_ptr_ptr && *q->sym_ptr_ptr)
1079 {
1080 sym_name = (*(q->sym_ptr_ptr))->name;
d20f480f 1081 }
aa0a709a
SC
1082 else
1083 {
d20f480f
SC
1084 sym_name = 0;
1085 }
aa0a709a
SC
1086 if (sym_name)
1087 {
1088 printf_vma (q->address);
195d1adf 1089 printf (" %-16s %s",
aa0a709a
SC
1090 q->howto->name,
1091 sym_name);
d20f480f 1092 }
aa0a709a
SC
1093 else
1094 {
1095 printf_vma (q->address);
195d1adf 1096 printf (" %-16s [%s]",
aa0a709a
SC
1097 q->howto->name,
1098 section_name);
d20f480f 1099 }
aa0a709a
SC
1100 if (q->addend)
1101 {
1102 printf ("+0x");
1103 printf_vma (q->addend);
d20f480f 1104 }
aa0a709a 1105 printf ("\n");
d20f480f 1106 }
aa0a709a
SC
1107 printf ("\n\n");
1108 free (relpp);
d20f480f 1109 }
2fa0b342 1110 }
2fa0b342 1111
d20f480f 1112 }
2fa0b342
DHW
1113}
1114
aa0a709a
SC
1115#ifdef unix
1116#define _DUMMY_NAME_ "/dev/null"
1117#else
1118#define _DUMMY_NAME_ "##dummy"
1119#endif
9872a49c 1120static void
aa0a709a
SC
1121DEFUN (display_info_table, (first, last),
1122 int first AND int last)
9872a49c 1123{
3fdbfe8d 1124 unsigned int i, j;
9872a49c
SC
1125 extern bfd_target *target_vector[];
1126
aa0a709a
SC
1127 printf ("\n%12s", " ");
1128 for (i = first; i++ < last && target_vector[i];)
1129 printf ("%s ", target_vector[i]->name);
1130 printf ("\n");
9872a49c 1131
aa0a709a
SC
1132 for (j = (int) bfd_arch_obscure + 1; (int) j < (int) bfd_arch_last; j++)
1133 if (strcmp (bfd_printable_arch_mach (j, 0), "UNKNOWN!") != 0)
e779a58c 1134 {
aa0a709a
SC
1135 printf ("%11s ", bfd_printable_arch_mach (j, 0));
1136 for (i = first; i++ < last && target_vector[i];)
1137 {
1138 bfd_target *p = target_vector[i];
1139 bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
1140 int l = strlen (p->name);
249c6fc0
RS
1141 int ok;
1142 bfd_set_format (abfd, bfd_object);
1143 ok = bfd_set_arch_mach (abfd, j, 0);
aa0a709a
SC
1144
1145 if (ok)
1146 printf ("%s ", p->name);
1147 else
e779a58c 1148 {
aa0a709a
SC
1149 while (l--)
1150 printf ("%c", ok ? '*' : '-');
1151 printf (" ");
e779a58c 1152 }
e779a58c 1153 }
aa0a709a 1154 printf ("\n");
e779a58c 1155 }
9872a49c 1156}
aa0a709a
SC
1157
1158static void
1159DEFUN_VOID (display_info)
1160{
1161 char *colum;
1162 unsigned int i, j, columns;
1163 extern bfd_target *target_vector[];
1164 extern char *getenv ();
1165
1166 printf ("BFD header file version %s\n", BFD_VERSION);
1167 for (i = 0; target_vector[i]; i++)
1168 {
1169 bfd_target *p = target_vector[i];
1170 bfd *abfd = bfd_openw (_DUMMY_NAME_, p->name);
249c6fc0 1171 bfd_set_format (abfd, bfd_object);
aa0a709a
SC
1172 printf ("%s\n (header %s, data %s)\n", p->name,
1173 p->header_byteorder_big_p ? "big endian" : "little endian",
1174 p->byteorder_big_p ? "big endian" : "little endian");
1175 for (j = (int) bfd_arch_obscure + 1; j < (int) bfd_arch_last; j++)
1176 if (bfd_set_arch_mach (abfd, (enum bfd_architecture) j, 0))
1177 printf (" %s\n",
1178 bfd_printable_arch_mach ((enum bfd_architecture) j, 0));
1179 }
1180 columns = 0;
1181 if (colum = getenv ("COLUMNS"))
1182 columns = atoi (colum);
1183 if (!columns)
1184 columns = 80;
1185 for (i = 0; target_vector[i];)
1186 {
1187 int old;
1188 old = i;
1189 for (j = 12; target_vector[i] && j < columns; i++)
1190 j += strlen (target_vector[i]->name) + 1;
1191 i--;
1192 if (old == i)
1193 break;
1194 display_info_table (old, i);
1195 }
1196}
1197
2fa0b342
DHW
1198/** main and like trivia */
1199int
1200main (argc, argv)
1201 int argc;
1202 char **argv;
1203{
1204 int c;
1205 extern int optind;
1206 extern char *optarg;
1207 char *target = default_target;
1208 boolean seenflag = false;
2fa0b342 1209
aa0a709a 1210 bfd_init ();
2fa0b342
DHW
1211 program_name = *argv;
1212
d2442698
DM
1213 while ((c = getopt_long (argc, argv, "ib:m:Vdlfahrtxsj:", long_options,
1214 (int *) 0))
aa0a709a
SC
1215 != EOF)
1216 {
1217 seenflag = true;
1218 switch (c)
1219 {
b3a2b497
ILT
1220 case 0:
1221 break; /* we've been given a long option */
aa0a709a
SC
1222 case 'm':
1223 machine = optarg;
1224 break;
1225 case 'j':
1226 only = optarg;
1227 break;
1228 case 'l':
1229 with_line_numbers = 1;
1230 break;
1231 case 'b':
1232 target = optarg;
1233 break;
1234 case 'f':
1235 dump_file_header = true;
1236 break;
1237 case 'i':
1238 info = true;
1239 break;
1240 case 'x':
1241 dump_symtab = 1;
1242 dump_reloc_info = 1;
1243 dump_file_header = true;
1244 dump_ar_hdrs = 1;
1245 dump_section_headers = 1;
1246 break;
aa0a709a
SC
1247 case 't':
1248 dump_symtab = 1;
1249 break;
1250 case 'd':
1251 disassemble = true;
1252 break;
1253 case 's':
1254 dump_section_contents = 1;
1255 break;
1256 case 'r':
1257 dump_reloc_info = 1;
1258 break;
1259 case 'a':
1260 dump_ar_hdrs = 1;
1261 break;
1262 case 'h':
1263 dump_section_headers = 1;
1264 break;
b3a2b497
ILT
1265 case 'H':
1266 usage (stdout, 0);
249c6fc0
RS
1267 case 'V':
1268 show_version = 1;
1269 break;
aa0a709a 1270 default:
b3a2b497 1271 usage (stderr, 1);
aa0a709a 1272 }
2fa0b342 1273 }
2fa0b342 1274
249c6fc0 1275 if (show_version)
b3a2b497
ILT
1276 {
1277 printf ("GNU %s version %s\n", program_name, program_version);
1278 exit (0);
1279 }
249c6fc0 1280
2fa0b342 1281 if (seenflag == false)
b3a2b497 1282 usage (stderr, 1);
2fa0b342 1283
aa0a709a
SC
1284 if (info)
1285 {
1286 display_info ();
1287 }
1288 else
1289 {
1290 if (optind == argc)
1291 display_file ("a.out", target);
1292 else
1293 for (; optind < argc;)
1294 display_file (argv[optind++], target);
1295 }
2fa0b342
DHW
1296 return 0;
1297}
This page took 0.14192 seconds and 4 git commands to generate.