* mpw-config.in (TDEFINES): Define as empty in makefile frag.
[deliverable/binutils-gdb.git] / binutils / objdump.c
CommitLineData
d20f480f 1/* objdump.c -- dump information about an object file.
37853673 2 Copyright 1990, 1991, 1992, 1993, 1994 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 22#include "getopt.h"
be1d162b 23#include "progress.h"
e1ec9f07 24#include "bucomm.h"
2fa0b342
DHW
25#include <stdio.h>
26#include <ctype.h>
2e8adbd7 27#include "dis-asm.h"
105da05c 28#include "libiberty.h"
2fa0b342 29
73b8f102
JG
30/* Internal headers for the ELF .stab-dump code - sorry. */
31#define BYTES_IN_WORD 32
32#include "aout/aout64.h"
bf661056 33
80d19ec1 34#ifndef FPRINTF_ALREADY_DECLARED
6f575704 35extern int fprintf PARAMS ((FILE *, CONST char *, ...));
80d19ec1 36#endif
2fa0b342
DHW
37
38char *default_target = NULL; /* default at runtime */
39
e1ec9f07 40extern char *program_version;
2fa0b342 41
249c6fc0 42int show_version = 0; /* show the version number */
2fa0b342
DHW
43int dump_section_contents; /* -s */
44int dump_section_headers; /* -h */
45boolean dump_file_header; /* -f */
46int dump_symtab; /* -t */
de3b08ac 47int dump_dynamic_symtab; /* -T */
2fa0b342 48int dump_reloc_info; /* -r */
de3b08ac 49int dump_dynamic_reloc_info; /* -R */
2fa0b342 50int dump_ar_hdrs; /* -a */
aa0a709a 51int with_line_numbers; /* -l */
be1d162b 52boolean with_source_code; /* -S */
9b018ecd 53int dump_stab_section_info; /* --stabs */
aa0a709a 54boolean disassemble; /* -d */
d5464baa 55boolean disassemble_all; /* -D */
e1ec9f07 56boolean formats_info; /* -i */
195d1adf
KR
57char *only; /* -j secname */
58
cef35d48 59/* Extra info to pass to the disassembler address printing function. */
195d1adf
KR
60struct objdump_disasm_info {
61 bfd *abfd;
62 asection *sec;
8b129785 63 boolean require_sec;
195d1adf 64};
2fa0b342 65
cef35d48 66/* Architecture to disassemble for, or default if NULL. */
aa0a709a 67char *machine = (char *) NULL;
f7b839f7
DM
68
69/* The symbol table. */
aa0a709a 70asymbol **syms;
2fa0b342 71
f7b839f7 72/* Number of symbols in `syms'. */
ae5d2ff5 73long symcount = 0;
2fa0b342 74
be1d162b
ILT
75/* The sorted symbol table. */
76asymbol **sorted_syms;
77
78/* Number of symbols in `sorted_syms'. */
79long sorted_symcount = 0;
80
de3b08ac
ILT
81/* The dynamic symbol table. */
82asymbol **dynsyms;
83
84/* Number of symbols in `dynsyms'. */
85long dynsymcount = 0;
86
d9971b83
KR
87/* Forward declarations. */
88
89static void
90display_file PARAMS ((char *filename, char *target));
91
92static void
93dump_data PARAMS ((bfd *abfd));
94
95static void
96dump_relocs PARAMS ((bfd *abfd));
97
98static void
de3b08ac
ILT
99dump_dynamic_relocs PARAMS ((bfd * abfd));
100
101static void
102dump_reloc_set PARAMS ((bfd *, arelent **, long));
103
104static void
105dump_symbols PARAMS ((bfd *abfd, boolean dynamic));
02a68547
ILT
106
107static void
108display_bfd PARAMS ((bfd *abfd));
8f197c94
ILT
109
110static void
111objdump_print_address PARAMS ((bfd_vma, struct disassemble_info *));
be1d162b
ILT
112
113static void
114show_line PARAMS ((bfd *, asection *, bfd_vma));
d9971b83 115\f
2fa0b342 116void
b3a2b497
ILT
117usage (stream, status)
118 FILE *stream;
119 int status;
2fa0b342 120{
b3a2b497 121 fprintf (stream, "\
be1d162b 122Usage: %s [-ahifdDrRtTxsSl] [-b bfdname] [-m machine] [-j section-name]\n\
d5464baa
ILT
123 [--archive-headers] [--target=bfdname] [--disassemble]\n\
124 [--disassemble-all] [--file-headers] [--section-headers] [--headers]\n\
be1d162b 125 [--info] [--section=section-name] [--line-numbers] [--source]\n\
d5464baa
ILT
126 [--architecture=machine] [--reloc] [--full-contents] [--stabs]\n\
127 [--syms] [--all-headers] [--dynamic-syms] [--dynamic-reloc]\n\
de3b08ac 128 [--version] [--help] objfile...\n\
02a68547 129at least one option besides -l (--line-numbers) must be given\n",
b3a2b497 130 program_name);
be1d162b 131 list_supported_targets (program_name, stream);
b3a2b497 132 exit (status);
2fa0b342
DHW
133}
134
aa0a709a
SC
135static struct option long_options[]=
136{
02a68547
ILT
137 {"all-headers", no_argument, NULL, 'x'},
138 {"architecture", required_argument, NULL, 'm'},
139 {"archive-headers", no_argument, NULL, 'a'},
140 {"disassemble", no_argument, NULL, 'd'},
d5464baa 141 {"disassemble-all", no_argument, NULL, 'D'},
de3b08ac
ILT
142 {"dynamic-reloc", no_argument, NULL, 'R'},
143 {"dynamic-syms", no_argument, NULL, 'T'},
02a68547
ILT
144 {"file-headers", no_argument, NULL, 'f'},
145 {"full-contents", no_argument, NULL, 's'},
146 {"headers", no_argument, NULL, 'h'},
147 {"help", no_argument, NULL, 'H'},
148 {"info", no_argument, NULL, 'i'},
149 {"line-numbers", no_argument, NULL, 'l'},
150 {"reloc", no_argument, NULL, 'r'},
151 {"section", required_argument, NULL, 'j'},
152 {"section-headers", no_argument, NULL, 'h'},
be1d162b 153 {"source", no_argument, NULL, 'S'},
73b8f102 154 {"stabs", no_argument, &dump_stab_section_info, 1},
02a68547
ILT
155 {"syms", no_argument, NULL, 't'},
156 {"target", required_argument, NULL, 'b'},
157 {"version", no_argument, &show_version, 1},
d2442698
DM
158 {0, no_argument, 0, 0}
159};
f7b839f7 160\f
2fa0b342 161static void
f7b839f7 162dump_section_header (abfd, section, ignored)
aa0a709a 163 bfd *abfd;
f7b839f7
DM
164 asection *section;
165 PTR ignored;
2fa0b342 166{
f7b839f7 167 char *comma = "";
aa0a709a 168
2fa0b342 169#define PF(x,y) \
f7b839f7
DM
170 if (section->flags & x) { printf("%s%s",comma,y); comma = ", "; }
171
172
173 printf ("SECTION %d [%s]\t: size %08x",
174 section->index,
175 section->name,
176 (unsigned) bfd_get_section_size_before_reloc (section));
177 printf (" vma ");
178 printf_vma (section->vma);
179 printf (" align 2**%u\n ",
180 section->alignment_power);
181 PF (SEC_ALLOC, "ALLOC");
182 PF (SEC_CONSTRUCTOR, "CONSTRUCTOR");
183 PF (SEC_CONSTRUCTOR_TEXT, "CONSTRUCTOR TEXT");
184 PF (SEC_CONSTRUCTOR_DATA, "CONSTRUCTOR DATA");
185 PF (SEC_CONSTRUCTOR_BSS, "CONSTRUCTOR BSS");
186 PF (SEC_LOAD, "LOAD");
187 PF (SEC_RELOC, "RELOC");
195d1adf 188#ifdef SEC_BALIGN
f7b839f7 189 PF (SEC_BALIGN, "BALIGN");
195d1adf 190#endif
f7b839f7
DM
191 PF (SEC_READONLY, "READONLY");
192 PF (SEC_CODE, "CODE");
193 PF (SEC_DATA, "DATA");
194 PF (SEC_ROM, "ROM");
195 PF (SEC_DEBUGGING, "DEBUGGING");
28d1b01e 196 PF (SEC_NEVER_LOAD, "NEVER_LOAD");
f7b839f7 197 printf ("\n");
2fa0b342 198#undef PF
2fa0b342
DHW
199}
200
f7b839f7
DM
201static void
202dump_headers (abfd)
203 bfd *abfd;
204{
205 bfd_map_over_sections (abfd, dump_section_header, (PTR) NULL);
206}
207\f
2fa0b342 208static asymbol **
abdcac0f
DM
209slurp_symtab (abfd)
210 bfd *abfd;
2fa0b342 211{
aa0a709a 212 asymbol **sy = (asymbol **) NULL;
ae5d2ff5 213 long storage;
2fa0b342 214
aa0a709a
SC
215 if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
216 {
f7b839f7
DM
217 printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
218 return NULL;
aa0a709a
SC
219 }
220
ae5d2ff5
ILT
221 storage = bfd_get_symtab_upper_bound (abfd);
222 if (storage < 0)
223 bfd_fatal (bfd_get_filename (abfd));
224
aa0a709a
SC
225 if (storage)
226 {
02a68547 227 sy = (asymbol **) xmalloc (storage);
aa0a709a
SC
228 }
229 symcount = bfd_canonicalize_symtab (abfd, sy);
ae5d2ff5
ILT
230 if (symcount < 0)
231 bfd_fatal (bfd_get_filename (abfd));
232 if (symcount == 0)
de3b08ac
ILT
233 fprintf (stderr, "%s: %s: No symbols\n",
234 program_name, bfd_get_filename (abfd));
235 return sy;
236}
237
238/* Read in the dynamic symbols. */
239
240static asymbol **
241slurp_dynamic_symtab (abfd)
242 bfd *abfd;
243{
244 asymbol **sy = (asymbol **) NULL;
245 long storage;
246
de3b08ac
ILT
247 storage = bfd_get_dynamic_symtab_upper_bound (abfd);
248 if (storage < 0)
28d1b01e
ILT
249 {
250 if (!(bfd_get_file_flags (abfd) & DYNAMIC))
251 {
252 fprintf (stderr, "%s: %s: not a dynamic object\n",
253 program_name, bfd_get_filename (abfd));
254 return NULL;
255 }
256
257 bfd_fatal (bfd_get_filename (abfd));
258 }
de3b08ac
ILT
259
260 if (storage)
261 {
262 sy = (asymbol **) xmalloc (storage);
263 }
264 dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, sy);
265 if (dynsymcount < 0)
266 bfd_fatal (bfd_get_filename (abfd));
267 if (dynsymcount == 0)
268 fprintf (stderr, "%s: %s: No dynamic symbols\n",
269 program_name, bfd_get_filename (abfd));
aa0a709a 270 return sy;
2fa0b342 271}
aa0a709a 272
f7b839f7
DM
273/* Filter out (in place) symbols that are useless for disassembly.
274 COUNT is the number of elements in SYMBOLS.
275 Return the number of useful symbols. */
3ae36cb6 276
ae5d2ff5 277long
f7b839f7
DM
278remove_useless_symbols (symbols, count)
279 asymbol **symbols;
ae5d2ff5 280 long count;
3ae36cb6 281{
f7b839f7 282 register asymbol **in_ptr = symbols, **out_ptr = symbols;
3ae36cb6 283
f7b839f7 284 while (--count >= 0)
3ae36cb6
PB
285 {
286 asymbol *sym = *in_ptr++;
287
288 if (sym->name == NULL || sym->name[0] == '\0')
289 continue;
290 if (sym->flags & (BSF_DEBUGGING))
291 continue;
28d1b01e 292 if (bfd_is_und_section (sym->section)
3ae36cb6
PB
293 || bfd_is_com_section (sym->section))
294 continue;
295
296 *out_ptr++ = sym;
297 }
f7b839f7 298 return out_ptr - symbols;
3ae36cb6
PB
299}
300
37853673
SS
301/* Sort symbols into value order. */
302
aa0a709a 303static int
37853673 304compare_symbols (ap, bp)
d5464baa
ILT
305 const PTR ap;
306 const PTR bp;
2fa0b342 307{
d5464baa
ILT
308 const asymbol *a = *(const asymbol **)ap;
309 const asymbol *b = *(const asymbol **)bp;
2fa0b342 310
be1d162b 311 if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
3ae36cb6 312 return 1;
be1d162b 313 else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
3ae36cb6 314 return -1;
2fa0b342 315
3ae36cb6
PB
316 if (a->section > b->section)
317 return 1;
318 else if (a->section < b->section)
319 return -1;
320 return 0;
2fa0b342
DHW
321}
322
d5464baa
ILT
323/* Sort relocs into address order. */
324
325static int
326compare_relocs (ap, bp)
327 const PTR ap;
328 const PTR bp;
329{
330 const arelent *a = *(const arelent **)ap;
331 const arelent *b = *(const arelent **)bp;
332
333 if (a->address > b->address)
334 return 1;
335 else if (a->address < b->address)
336 return -1;
337
338 return compare_symbols ((const PTR) a->sym_ptr_ptr,
339 (const PTR) b->sym_ptr_ptr);
340}
341
f7b839f7
DM
342/* Print VMA symbolically to INFO if possible. */
343
8f197c94 344static void
545a2768 345objdump_print_address (vma, info)
aa0a709a 346 bfd_vma vma;
545a2768 347 struct disassemble_info *info;
2fa0b342 348{
195d1adf
KR
349 /* @@ For relocateable files, should filter out symbols belonging to
350 the wrong section. Unfortunately, not enough information is supplied
351 to this routine to determine the correct section in all cases. */
352 /* @@ Would it speed things up to cache the last two symbols returned,
353 and maybe their address ranges? For many processors, only one memory
354 operand can be present at a time, so the 2-entry cache wouldn't be
355 constantly churned by code doing heavy memory accesses. */
2fa0b342 356
be1d162b 357 /* Indices in `sorted_syms'. */
ae5d2ff5 358 long min = 0;
be1d162b 359 long max = sorted_symcount;
ae5d2ff5 360 long thisplace;
2fa0b342 361
8f197c94 362 bfd_signed_vma vardiff;
2fa0b342 363
3ae36cb6
PB
364 fprintf_vma (info->stream, vma);
365
be1d162b 366 if (sorted_symcount < 1)
f7b839f7
DM
367 return;
368
8f197c94
ILT
369 /* Perform a binary search looking for the closest symbol to the
370 required value. We are searching the range (min, max]. */
371 while (min + 1 < max)
aa0a709a 372 {
f7b839f7 373 asymbol *sym;
8f197c94 374
f7b839f7 375 thisplace = (max + min) / 2;
be1d162b 376 sym = sorted_syms[thisplace];
8f197c94 377
be1d162b 378 vardiff = bfd_asymbol_value (sym) - vma;
f7b839f7
DM
379
380 if (vardiff > 0)
381 max = thisplace;
382 else if (vardiff < 0)
383 min = thisplace;
384 else
aa0a709a 385 {
8f197c94
ILT
386 min = thisplace;
387 break;
aa0a709a 388 }
f7b839f7 389 }
fc5d6074 390
8f197c94
ILT
391 /* The symbol we want is now in min, the low end of the range we
392 were searching. */
393 thisplace = min;
394
f7b839f7
DM
395 {
396 /* If this symbol isn't global, search for one with the same value
397 that is. */
be1d162b 398 bfd_vma val = bfd_asymbol_value (sorted_syms[thisplace]);
ae5d2ff5 399 long i;
be1d162b 400 if (sorted_syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING))
f7b839f7 401 for (i = thisplace - 1; i >= 0; i--)
aa0a709a 402 {
be1d162b
ILT
403 if (bfd_asymbol_value (sorted_syms[i]) == val
404 && (!(sorted_syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
405 || ((sorted_syms[thisplace]->flags & BSF_DEBUGGING)
406 && !(sorted_syms[i]->flags & BSF_DEBUGGING))))
aa0a709a 407 {
f7b839f7
DM
408 thisplace = i;
409 break;
aa0a709a
SC
410 }
411 }
be1d162b
ILT
412 if (sorted_syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING))
413 for (i = thisplace + 1; i < sorted_symcount; i++)
f7b839f7 414 {
be1d162b
ILT
415 if (bfd_asymbol_value (sorted_syms[i]) == val
416 && (!(sorted_syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
417 || ((sorted_syms[thisplace]->flags & BSF_DEBUGGING)
418 && !(sorted_syms[i]->flags & BSF_DEBUGGING))))
195d1adf 419 {
f7b839f7
DM
420 thisplace = i;
421 break;
195d1adf 422 }
f7b839f7
DM
423 }
424 }
425 {
426 /* If the file is relocateable, and the symbol could be from this
427 section, prefer a symbol from this section over symbols from
428 others, even if the other symbol's value might be closer.
429
430 Note that this may be wrong for some symbol references if the
431 sections have overlapping memory ranges, but in that case there's
432 no way to tell what's desired without looking at the relocation
433 table. */
434 struct objdump_disasm_info *aux;
ae5d2ff5 435 long i;
f7b839f7
DM
436
437 aux = (struct objdump_disasm_info *) info->application_data;
be1d162b 438 if (sorted_syms[thisplace]->section != aux->sec
2d054641
ILT
439 && (aux->require_sec
440 || ((aux->abfd->flags & HAS_RELOC) != 0
441 && vma >= bfd_get_section_vma (aux->abfd, aux->sec)
442 && vma < (bfd_get_section_vma (aux->abfd, aux->sec)
443 + bfd_get_section_size_before_reloc (aux->sec)))))
f7b839f7 444 {
be1d162b 445 for (i = thisplace + 1; i < sorted_symcount; i++)
8f197c94 446 {
be1d162b
ILT
447 if (bfd_asymbol_value (sorted_syms[i])
448 != bfd_asymbol_value (sorted_syms[thisplace]))
28d1b01e 449 break;
8f197c94 450 }
28d1b01e 451 --i;
8f197c94
ILT
452 for (; i >= 0; i--)
453 {
be1d162b 454 if (sorted_syms[i]->section == aux->sec)
8f197c94
ILT
455 {
456 thisplace = i;
457 break;
458 }
459 }
2d054641 460
be1d162b 461 if (sorted_syms[thisplace]->section != aux->sec)
2d054641
ILT
462 {
463 /* We didn't find a good symbol with a smaller value.
464 Look for one with a larger value. */
be1d162b 465 for (i = thisplace + 1; i < sorted_symcount; i++)
2d054641 466 {
be1d162b 467 if (sorted_syms[i]->section == aux->sec)
2d054641
ILT
468 {
469 thisplace = i;
470 break;
471 }
472 }
473 }
195d1adf 474 }
f7b839f7 475 }
2d054641 476
be1d162b
ILT
477 fprintf (info->stream, " <%s", sorted_syms[thisplace]->name);
478 if (bfd_asymbol_value (sorted_syms[thisplace]) > vma)
f7b839f7
DM
479 {
480 char buf[30], *p = buf;
be1d162b 481 sprintf_vma (buf, bfd_asymbol_value (sorted_syms[thisplace]) - vma);
f7b839f7
DM
482 while (*p == '0')
483 p++;
484 fprintf (info->stream, "-%s", p);
485 }
be1d162b 486 else if (vma > bfd_asymbol_value (sorted_syms[thisplace]))
f7b839f7
DM
487 {
488 char buf[30], *p = buf;
be1d162b 489 sprintf_vma (buf, vma - bfd_asymbol_value (sorted_syms[thisplace]));
f7b839f7
DM
490 while (*p == '0')
491 p++;
492 fprintf (info->stream, "+%s", p);
2fa0b342 493 }
f7b839f7 494 fprintf (info->stream, ">");
2fa0b342
DHW
495}
496
be1d162b
ILT
497/* Hold the last function name and the last line number we displayed
498 in a disassembly. */
499
500static char *prev_functionname;
501static unsigned int prev_line;
502
503/* We keep a list of all files that we have seen when doing a
504 dissassembly with source, so that we know how much of the file to
505 display. This can be important for inlined functions. */
506
507struct print_file_list
508{
509 struct print_file_list *next;
510 char *filename;
511 unsigned int line;
512 FILE *f;
513};
514
515static struct print_file_list *print_files;
516
517/* The number of preceding context lines to show when we start
518 displaying a file for the first time. */
519
520#define SHOW_PRECEDING_CONTEXT_LINES (5)
521
522/* Skip ahead to a given line in a file, optionally printing each
523 line. */
524
525static void
526skip_to_line PARAMS ((struct print_file_list *, unsigned int, boolean));
527
528static void
529skip_to_line (p, line, show)
530 struct print_file_list *p;
531 unsigned int line;
532 boolean show;
533{
534 while (p->line < line)
535 {
536 char buf[100];
537
538 if (fgets (buf, sizeof buf, p->f) == NULL)
539 {
540 fclose (p->f);
541 p->f = NULL;
542 break;
543 }
544
545 if (show)
546 printf ("%s", buf);
547
548 if (strchr (buf, '\n') != NULL)
549 ++p->line;
550 }
551}
552
553/* Show the line number, or the source line, in a dissassembly
554 listing. */
555
556static void
557show_line (abfd, section, off)
aa0a709a 558 bfd *abfd;
be1d162b
ILT
559 asection *section;
560 bfd_vma off;
2fa0b342 561{
be1d162b
ILT
562 CONST char *filename;
563 CONST char *functionname;
564 unsigned int line;
2e8adbd7 565
be1d162b
ILT
566 if (! with_line_numbers && ! with_source_code)
567 return;
d20f480f 568
be1d162b
ILT
569 if (! bfd_find_nearest_line (abfd, section, syms, off, &filename,
570 &functionname, &line))
571 return;
aa0a709a 572
be1d162b
ILT
573 if (filename != NULL && *filename == '\0')
574 filename = NULL;
575 if (functionname != NULL && *functionname == '\0')
576 functionname = NULL;
aa0a709a 577
be1d162b 578 if (with_line_numbers)
d5464baa 579 {
be1d162b
ILT
580 if (functionname != NULL
581 && (prev_functionname == NULL
582 || strcmp (functionname, prev_functionname) != 0))
583 printf ("%s():\n", functionname);
584 if (line > 0 && line != prev_line)
585 printf ("%s:%u\n", filename == NULL ? "???" : filename, line);
586 }
587
588 if (with_source_code
589 && filename != NULL
590 && line > 0)
591 {
592 struct print_file_list **pp, *p;
593
594 for (pp = &print_files; *pp != NULL; pp = &(*pp)->next)
595 if (strcmp ((*pp)->filename, filename) == 0)
596 break;
597 p = *pp;
598
599 if (p != NULL)
d5464baa 600 {
be1d162b
ILT
601 if (p != print_files)
602 {
603 int l;
604
605 /* We have reencountered a file name which we saw
606 earlier. This implies that either we are dumping out
607 code from an included file, or the same file was
608 linked in more than once. There are two common cases
609 of an included file: inline functions in a header
610 file, and a bison or flex skeleton file. In the
611 former case we want to just start printing (but we
612 back up a few lines to give context); in the latter
613 case we want to continue from where we left off. I
614 can't think of a good way to distinguish the cases,
615 so I used a heuristic based on the file name. */
616 if (strcmp (p->filename + strlen (p->filename) - 2, ".h") != 0)
617 l = p->line;
618 else
619 {
620 l = line - SHOW_PRECEDING_CONTEXT_LINES;
621 if (l <= 0)
622 l = 1;
623 }
d5464baa 624
be1d162b
ILT
625 if (p->f == NULL)
626 {
627 p->f = fopen (p->filename, "r");
628 p->line = 0;
629 }
630 if (p->f != NULL)
631 skip_to_line (p, l, false);
d5464baa 632
be1d162b
ILT
633 if (print_files->f != NULL)
634 {
635 fclose (print_files->f);
636 print_files->f = NULL;
637 }
638 }
d5464baa 639
be1d162b
ILT
640 if (p->f != NULL)
641 {
642 skip_to_line (p, line, true);
643 *pp = p->next;
644 p->next = print_files;
645 print_files = p;
646 }
647 }
648 else
649 {
650 FILE *f;
d5464baa 651
be1d162b
ILT
652 f = fopen (filename, "r");
653 if (f != NULL)
d5464baa 654 {
be1d162b 655 int l;
d5464baa 656
be1d162b
ILT
657 p = ((struct print_file_list *)
658 xmalloc (sizeof (struct print_file_list)));
659 p->filename = xmalloc (strlen (filename) + 1);
660 strcpy (p->filename, filename);
661 p->line = 0;
662 p->f = f;
663
664 if (print_files != NULL && print_files->f != NULL)
665 {
666 fclose (print_files->f);
667 print_files->f = NULL;
668 }
669 p->next = print_files;
670 print_files = p;
671
672 l = line - SHOW_PRECEDING_CONTEXT_LINES;
673 if (l <= 0)
674 l = 1;
675 skip_to_line (p, l, false);
676 if (p->f != NULL)
677 skip_to_line (p, line, true);
d5464baa
ILT
678 }
679 }
680 }
681
be1d162b
ILT
682 if (functionname != NULL
683 && (prev_functionname == NULL
684 || strcmp (functionname, prev_functionname) != 0))
aa0a709a 685 {
be1d162b
ILT
686 if (prev_functionname != NULL)
687 free (prev_functionname);
688 prev_functionname = xmalloc (strlen (functionname) + 1);
689 strcpy (prev_functionname, functionname);
aa0a709a 690 }
2fa0b342 691
be1d162b
ILT
692 if (line > 0 && line != prev_line)
693 prev_line = line;
694}
695
696void
697disassemble_data (abfd)
698 bfd *abfd;
699{
700 long i;
701 unsigned int (*print) () = 0; /* Old style */
702 disassembler_ftype disassemble_fn = 0; /* New style */
703 struct disassemble_info disasm_info;
704 struct objdump_disasm_info aux;
705 asection *section;
706 boolean done_dot = false;
707
708 print_files = NULL;
709 prev_functionname = NULL;
710 prev_line = -1;
711
712 /* We make a copy of syms to sort. We don't want to sort syms
713 because that will screw up the relocs. */
714 sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
715 memcpy (sorted_syms, syms, symcount * sizeof (asymbol *));
716
717 sorted_symcount = remove_useless_symbols (sorted_syms, symcount);
2fa0b342
DHW
718
719 /* Sort the symbols into section and symbol order */
be1d162b 720 qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
2fa0b342 721
cef35d48
DM
722 INIT_DISASSEMBLE_INFO(disasm_info, stdout);
723 disasm_info.application_data = (PTR) &aux;
724 aux.abfd = abfd;
725 disasm_info.print_address_func = objdump_print_address;
726
aa0a709a
SC
727 if (machine != (char *) NULL)
728 {
cef35d48
DM
729 bfd_arch_info_type *info = bfd_scan_arch (machine);
730 if (info == NULL)
aa0a709a
SC
731 {
732 fprintf (stderr, "%s: Can't use supplied machine %s\n",
733 program_name,
734 machine);
735 exit (1);
736 }
737 abfd->arch_info = info;
2fa0b342 738 }
e779a58c 739
cef35d48 740 /* See if we can disassemble using bfd. */
e779a58c 741
aa0a709a
SC
742 if (abfd->arch_info->disassemble)
743 {
744 print = abfd->arch_info->disassemble;
e779a58c 745 }
aa0a709a
SC
746 else
747 {
d5464baa
ILT
748 disassemble_fn = disassembler (abfd);
749 if (!disassemble_fn)
aa0a709a 750 {
aa0a709a
SC
751 fprintf (stderr, "%s: Can't disassemble for architecture %s\n",
752 program_name,
105da05c 753 bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
aa0a709a
SC
754 exit (1);
755 }
aa0a709a 756 }
2fa0b342
DHW
757
758 for (section = abfd->sections;
aa0a709a
SC
759 section != (asection *) NULL;
760 section = section->next)
65cceb78 761 {
cef35d48
DM
762 bfd_byte *data = NULL;
763 bfd_size_type datasize = 0;
be1d162b 764 arelent **relbuf = NULL;
d5464baa
ILT
765 arelent **relpp = NULL;
766 arelent **relppend = NULL;
2fa0b342 767
d5464baa
ILT
768 if ((section->flags & SEC_LOAD) == 0
769 || (! disassemble_all
770 && only == NULL
771 && (section->flags & SEC_CODE) == 0))
cef35d48
DM
772 continue;
773 if (only != (char *) NULL && strcmp (only, section->name) != 0)
774 continue;
2fa0b342 775
d5464baa
ILT
776 if (dump_reloc_info
777 && (section->flags & SEC_RELOC) != 0)
778 {
be1d162b
ILT
779 long relsize;
780
781 relsize = bfd_get_reloc_upper_bound (abfd, section);
782 if (relsize < 0)
783 bfd_fatal (bfd_get_filename (abfd));
784
785 if (relsize > 0)
786 {
787 long relcount;
788
789 relbuf = (arelent **) xmalloc (relsize);
790 relcount = bfd_canonicalize_reloc (abfd, section, relbuf, syms);
791 if (relcount < 0)
792 bfd_fatal (bfd_get_filename (abfd));
793
794 /* Sort the relocs by address. */
795 qsort (relbuf, relcount, sizeof (arelent *), compare_relocs);
796
797 relpp = relbuf;
798 relppend = relpp + relcount;
799 }
d5464baa
ILT
800 }
801
cef35d48 802 printf ("Disassembly of section %s:\n", section->name);
2fa0b342 803
cef35d48
DM
804 datasize = bfd_get_section_size_before_reloc (section);
805 if (datasize == 0)
806 continue;
2fa0b342 807
cef35d48 808 data = (bfd_byte *) xmalloc ((size_t) datasize);
2fa0b342 809
cef35d48 810 bfd_get_section_contents (abfd, section, data, 0, datasize);
2fa0b342 811
cef35d48
DM
812 aux.sec = section;
813 disasm_info.buffer = data;
814 disasm_info.buffer_vma = section->vma;
815 disasm_info.buffer_length = datasize;
816 i = 0;
817 while (i < disasm_info.buffer_length)
818 {
d5464baa
ILT
819 int bytes;
820
cef35d48
DM
821 if (data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 0 &&
822 data[i + 3] == 0)
aa0a709a 823 {
cef35d48 824 if (done_dot == false)
aa0a709a 825 {
cef35d48
DM
826 printf ("...\n");
827 done_dot = true;
65cceb78 828 }
d5464baa 829 bytes = 4;
cef35d48
DM
830 }
831 else
832 {
833 done_dot = false;
be1d162b
ILT
834 if (with_line_numbers || with_source_code)
835 show_line (abfd, section, i);
8b129785 836 aux.require_sec = true;
cef35d48 837 objdump_print_address (section->vma + i, &disasm_info);
8b129785 838 aux.require_sec = false;
cef35d48 839 putchar (' ');
65cceb78 840
d5464baa 841 if (disassemble_fn)
cef35d48 842 {
d5464baa
ILT
843 /* New style */
844 bytes = (*disassemble_fn) (section->vma + i, &disasm_info);
cef35d48
DM
845 if (bytes < 0)
846 break;
aa0a709a 847 }
d5464baa
ILT
848 else
849 {
850 /* Old style */
851 bytes = print (section->vma + i, data + i, stdout);
852 }
cef35d48 853 putchar ('\n');
96d7950b 854 }
d5464baa
ILT
855
856 if (dump_reloc_info
857 && (section->flags & SEC_RELOC) != 0)
858 {
859 while (relpp < relppend
860 && ((*relpp)->address >= i
861 && (*relpp)->address < i + bytes))
862 {
863 arelent *q;
864 const char *sym_name;
865
866 q = *relpp;
867
868 printf ("\t\tRELOC: ");
869
870 printf_vma (section->vma + q->address);
871
872 printf (" %s ", q->howto->name);
873
874 if (q->sym_ptr_ptr != NULL
875 && *q->sym_ptr_ptr != NULL)
876 {
877 sym_name = bfd_asymbol_name (*q->sym_ptr_ptr);
878 if (sym_name == NULL || *sym_name == '\0')
879 {
880 asection *sym_sec;
881
882 sym_sec = bfd_get_section (*q->sym_ptr_ptr);
883 sym_name = bfd_get_section_name (abfd, sym_sec);
884 if (sym_name == NULL || *sym_name == '\0')
885 sym_name = "*unknown*";
886 }
887 }
888
889 printf ("%s", sym_name);
890
891 if (q->addend)
892 {
893 printf ("+0x");
894 printf_vma (q->addend);
895 }
896
897 printf ("\n");
898
899 ++relpp;
900 }
901 }
902
903 i += bytes;
96d7950b 904 }
be1d162b 905
cef35d48 906 free (data);
be1d162b
ILT
907 if (relbuf != NULL)
908 free (relbuf);
2fa0b342 909 }
2fa0b342 910}
73b8f102 911\f
73b8f102
JG
912
913/* Define a table of stab values and print-strings. We wish the initializer
914 could be a direct-mapped table, but instead we build one the first
915 time we need it. */
916
fe2750e1 917char **stab_name;
73b8f102
JG
918
919struct stab_print {
920 int value;
fe2750e1 921 char *string;
73b8f102
JG
922};
923
924struct stab_print stab_print[] = {
925#define __define_stab(NAME, CODE, STRING) {CODE, STRING},
926#include "aout/stab.def"
927#undef __define_stab
02a68547 928 {0, ""}
73b8f102
JG
929};
930
250e36fe
DM
931void dump_section_stabs PARAMS ((bfd *abfd, char *stabsect_name,
932 char *strsect_name));
249c6fc0 933
250e36fe 934/* Dump the stabs sections from an object file that has a section that
73b8f102
JG
935 uses Sun stabs encoding. It has to use some hooks into BFD because
936 string table sections are not normally visible to BFD callers. */
937
938void
9b018ecd 939dump_stabs (abfd)
73b8f102
JG
940 bfd *abfd;
941{
fe2750e1
SS
942 /* Allocate and initialize stab name array if first time. */
943 if (stab_name == NULL)
73b8f102 944 {
250e36fe
DM
945 int i;
946
fe2750e1
SS
947 stab_name = (char **) xmalloc (256 * sizeof(char *));
948 /* Clear the array. */
73b8f102 949 for (i = 0; i < 256; i++)
fe2750e1
SS
950 stab_name[i] = NULL;
951 /* Fill in the defined stabs. */
952 for (i = 0; *stab_print[i].string; i++)
953 stab_name[stab_print[i].value] = stab_print[i].string;
73b8f102
JG
954 }
955
250e36fe
DM
956 dump_section_stabs (abfd, ".stab", ".stabstr");
957 dump_section_stabs (abfd, ".stab.excl", ".stab.exclstr");
958 dump_section_stabs (abfd, ".stab.index", ".stab.indexstr");
959 dump_section_stabs (abfd, "$GDB_SYMBOLS$", "$GDB_STRINGS$");
249c6fc0
RS
960}
961
250e36fe
DM
962static struct internal_nlist *stabs;
963static bfd_size_type stab_size;
964
965static char *strtab;
966static bfd_size_type stabstr_size;
967
968/* Read ABFD's stabs section STABSECT_NAME into `stabs'
969 and string table section STRSECT_NAME into `strtab'.
970 If the section exists and was read, allocate the space and return true.
971 Otherwise return false. */
972
973boolean
974read_section_stabs (abfd, stabsect_name, strsect_name)
249c6fc0 975 bfd *abfd;
250e36fe
DM
976 char *stabsect_name;
977 char *strsect_name;
249c6fc0 978{
9b018ecd 979 asection *stabsect, *stabstrsect;
9b018ecd 980
d5671c53
ILT
981 stabsect = bfd_get_section_by_name (abfd, stabsect_name);
982 if (0 == stabsect)
73b8f102 983 {
250e36fe
DM
984 printf ("No %s section present\n\n", stabsect_name);
985 return false;
73b8f102
JG
986 }
987
d5671c53
ILT
988 stabstrsect = bfd_get_section_by_name (abfd, strsect_name);
989 if (0 == stabstrsect)
73b8f102 990 {
eae82145 991 fprintf (stderr, "%s: %s has no %s section\n", program_name,
250e36fe
DM
992 bfd_get_filename (abfd), strsect_name);
993 return false;
73b8f102 994 }
9b018ecd 995
d5671c53
ILT
996 stab_size = bfd_section_size (abfd, stabsect);
997 stabstr_size = bfd_section_size (abfd, stabstrsect);
73b8f102 998
9b018ecd
ILT
999 stabs = (struct internal_nlist *) xmalloc (stab_size);
1000 strtab = (char *) xmalloc (stabstr_size);
73b8f102 1001
d5671c53 1002 if (! bfd_get_section_contents (abfd, stabsect, (PTR) stabs, 0, stab_size))
9b018ecd 1003 {
d5671c53
ILT
1004 fprintf (stderr, "%s: Reading %s section of %s failed: %s\n",
1005 program_name, stabsect_name, bfd_get_filename (abfd),
1006 bfd_errmsg (bfd_get_error ()));
1007 free (stabs);
1008 free (strtab);
1009 return false;
73b8f102 1010 }
2fa0b342 1011
d5671c53
ILT
1012 if (! bfd_get_section_contents (abfd, stabstrsect, (PTR) strtab, 0,
1013 stabstr_size))
9b018ecd 1014 {
d5671c53
ILT
1015 fprintf (stderr, "%s: Reading %s section of %s failed: %s\n",
1016 program_name, strsect_name, bfd_get_filename (abfd),
1017 bfd_errmsg (bfd_get_error ()));
1018 free (stabs);
1019 free (strtab);
1020 return false;
73b8f102 1021 }
d5671c53 1022
250e36fe
DM
1023 return true;
1024}
73b8f102
JG
1025
1026#define SWAP_SYMBOL(symp, abfd) \
250e36fe 1027{ \
73b8f102 1028 (symp)->n_strx = bfd_h_get_32(abfd, \
250e36fe 1029 (unsigned char *)&(symp)->n_strx); \
73b8f102 1030 (symp)->n_desc = bfd_h_get_16 (abfd, \
250e36fe 1031 (unsigned char *)&(symp)->n_desc); \
73b8f102 1032 (symp)->n_value = bfd_h_get_32 (abfd, \
250e36fe
DM
1033 (unsigned char *)&(symp)->n_value); \
1034}
73b8f102 1035
250e36fe
DM
1036/* Print ABFD's stabs section STABSECT_NAME (in `stabs'),
1037 using string table section STRSECT_NAME (in `strtab'). */
1038
1039void
1040print_section_stabs (abfd, stabsect_name, strsect_name)
1041 bfd *abfd;
1042 char *stabsect_name;
1043 char *strsect_name;
1044{
1045 int i;
1046 unsigned file_string_table_offset = 0, next_file_string_table_offset = 0;
1047 struct internal_nlist *stabp = stabs,
1048 *stabs_end = (struct internal_nlist *) (stab_size + (char *) stabs);
73b8f102 1049
250e36fe
DM
1050 printf ("Contents of %s section:\n\n", stabsect_name);
1051 printf ("Symnum n_type n_othr n_desc n_value n_strx String\n");
249c6fc0
RS
1052
1053 /* Loop through all symbols and print them.
1054
1055 We start the index at -1 because there is a dummy symbol on
250e36fe 1056 the front of stabs-in-{coff,elf} sections that supplies sizes. */
249c6fc0 1057
250e36fe 1058 for (i = -1; stabp < stabs_end; stabp++, i++)
73b8f102 1059 {
250e36fe 1060 SWAP_SYMBOL (stabp, abfd);
fe2750e1 1061 printf ("\n%-6d ", i);
250e36fe 1062 /* Either print the stab name, or, if unnamed, print its number
fe2750e1 1063 again (makes consistent formatting for tools like awk). */
250e36fe
DM
1064 if (stab_name[stabp->n_type])
1065 printf ("%-6s", stab_name[stabp->n_type]);
105da05c
ILT
1066 else if (stabp->n_type == N_UNDF)
1067 printf ("HdrSym");
fe2750e1 1068 else
105da05c 1069 printf ("%-6d", stabp->n_type);
250e36fe
DM
1070 printf (" %-6d %-6d ", stabp->n_other, stabp->n_desc);
1071 printf_vma (stabp->n_value);
1072 printf (" %-6lu", stabp->n_strx);
249c6fc0
RS
1073
1074 /* Symbols with type == 0 (N_UNDF) specify the length of the
1075 string table associated with this file. We use that info
1076 to know how to relocate the *next* file's string table indices. */
1077
250e36fe 1078 if (stabp->n_type == N_UNDF)
249c6fc0
RS
1079 {
1080 file_string_table_offset = next_file_string_table_offset;
250e36fe 1081 next_file_string_table_offset += stabp->n_value;
249c6fc0 1082 }
249c6fc0 1083 else
e1ec9f07 1084 {
250e36fe 1085 /* Using the (possibly updated) string table offset, print the
e1ec9f07
SS
1086 string (if any) associated with this symbol. */
1087
250e36fe
DM
1088 if ((stabp->n_strx + file_string_table_offset) < stabstr_size)
1089 printf (" %s", &strtab[stabp->n_strx + file_string_table_offset]);
e1ec9f07
SS
1090 else
1091 printf (" *");
1092 }
73b8f102
JG
1093 }
1094 printf ("\n\n");
1095}
249c6fc0 1096
250e36fe
DM
1097void
1098dump_section_stabs (abfd, stabsect_name, strsect_name)
1099 bfd *abfd;
1100 char *stabsect_name;
1101 char *strsect_name;
1102{
1103 if (read_section_stabs (abfd, stabsect_name, strsect_name))
1104 {
1105 print_section_stabs (abfd, stabsect_name, strsect_name);
1106 free (stabs);
1107 free (strtab);
1108 }
1109}
1110\f
eae82145 1111static void
f7b839f7
DM
1112dump_bfd_header (abfd)
1113 bfd *abfd;
1114{
1115 char *comma = "";
1116
1117 printf ("architecture: %s, ",
1118 bfd_printable_arch_mach (bfd_get_arch (abfd),
1119 bfd_get_mach (abfd)));
1120 printf ("flags 0x%08x:\n", abfd->flags);
1121
1122#define PF(x, y) if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
1123 PF (HAS_RELOC, "HAS_RELOC");
1124 PF (EXEC_P, "EXEC_P");
1125 PF (HAS_LINENO, "HAS_LINENO");
1126 PF (HAS_DEBUG, "HAS_DEBUG");
1127 PF (HAS_SYMS, "HAS_SYMS");
1128 PF (HAS_LOCALS, "HAS_LOCALS");
1129 PF (DYNAMIC, "DYNAMIC");
1130 PF (WP_TEXT, "WP_TEXT");
1131 PF (D_PAGED, "D_PAGED");
1132 PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
1133 printf ("\nstart address 0x");
1134 printf_vma (abfd->start_address);
1135}
1136
02a68547 1137static void
2fa0b342
DHW
1138display_bfd (abfd)
1139 bfd *abfd;
1140{
209e5610
DM
1141 char **matching;
1142
1143 if (!bfd_check_format_matches (abfd, bfd_object, &matching))
aa0a709a 1144 {
cef35d48 1145 bfd_nonfatal (bfd_get_filename (abfd));
8f197c94 1146 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
209e5610
DM
1147 {
1148 list_matching_formats (matching);
1149 free (matching);
1150 }
aa0a709a
SC
1151 return;
1152 }
f7b839f7 1153
cef35d48
DM
1154 printf ("\n%s: file format %s\n", bfd_get_filename (abfd),
1155 abfd->xvec->name);
aa0a709a
SC
1156 if (dump_ar_hdrs)
1157 print_arelt_descr (stdout, abfd, true);
aa0a709a 1158 if (dump_file_header)
f7b839f7
DM
1159 dump_bfd_header (abfd);
1160 putchar ('\n');
2fa0b342 1161 if (dump_section_headers)
aa0a709a
SC
1162 dump_headers (abfd);
1163 if (dump_symtab || dump_reloc_info || disassemble)
1164 {
1165 syms = slurp_symtab (abfd);
1166 }
de3b08ac
ILT
1167 if (dump_dynamic_symtab || dump_dynamic_reloc_info)
1168 {
1169 dynsyms = slurp_dynamic_symtab (abfd);
1170 }
aa0a709a 1171 if (dump_symtab)
de3b08ac
ILT
1172 dump_symbols (abfd, false);
1173 if (dump_dynamic_symtab)
1174 dump_symbols (abfd, true);
73b8f102 1175 if (dump_stab_section_info)
9b018ecd 1176 dump_stabs (abfd);
d5464baa 1177 if (dump_reloc_info && ! disassemble)
aa0a709a 1178 dump_relocs (abfd);
de3b08ac
ILT
1179 if (dump_dynamic_reloc_info)
1180 dump_dynamic_relocs (abfd);
aa0a709a
SC
1181 if (dump_section_contents)
1182 dump_data (abfd);
1183 if (disassemble)
1184 disassemble_data (abfd);
2fa0b342
DHW
1185}
1186
d9971b83 1187static void
2fa0b342
DHW
1188display_file (filename, target)
1189 char *filename;
1190 char *target;
1191{
1192 bfd *file, *arfile = (bfd *) NULL;
1193
1194 file = bfd_openr (filename, target);
aa0a709a
SC
1195 if (file == NULL)
1196 {
cef35d48 1197 bfd_nonfatal (filename);
aa0a709a
SC
1198 return;
1199 }
2fa0b342 1200
aa0a709a
SC
1201 if (bfd_check_format (file, bfd_archive) == true)
1202 {
8f197c94
ILT
1203 bfd *last_arfile = NULL;
1204
aa0a709a
SC
1205 printf ("In archive %s:\n", bfd_get_filename (file));
1206 for (;;)
1207 {
8f197c94 1208 bfd_set_error (bfd_error_no_error);
aa0a709a
SC
1209
1210 arfile = bfd_openr_next_archived_file (file, arfile);
1211 if (arfile == NULL)
1212 {
8f197c94 1213 if (bfd_get_error () != bfd_error_no_more_archived_files)
d2442698 1214 {
cef35d48 1215 bfd_nonfatal (bfd_get_filename (file));
d2442698 1216 }
8f197c94 1217 break;
aa0a709a 1218 }
2fa0b342 1219
aa0a709a 1220 display_bfd (arfile);
8f197c94
ILT
1221
1222 if (last_arfile != NULL)
1223 bfd_close (last_arfile);
1224 last_arfile = arfile;
aa0a709a 1225 }
8f197c94
ILT
1226
1227 if (last_arfile != NULL)
1228 bfd_close (last_arfile);
2fa0b342 1229 }
2fa0b342 1230 else
aa0a709a 1231 display_bfd (file);
2fa0b342 1232
aa0a709a 1233 bfd_close (file);
2fa0b342
DHW
1234}
1235\f
1236/* Actually display the various requested regions */
1237
d9971b83 1238static void
2fa0b342
DHW
1239dump_data (abfd)
1240 bfd *abfd;
1241{
1242 asection *section;
aa0a709a 1243 bfd_byte *data = 0;
fc5d6074
SC
1244 bfd_size_type datasize = 0;
1245 bfd_size_type i;
2fa0b342
DHW
1246
1247 for (section = abfd->sections; section != NULL; section =
aa0a709a
SC
1248 section->next)
1249 {
1250 int onaline = 16;
2fa0b342 1251
aa0a709a
SC
1252 if (only == (char *) NULL ||
1253 strcmp (only, section->name) == 0)
60c80016 1254 {
aa0a709a
SC
1255 if (section->flags & SEC_HAS_CONTENTS)
1256 {
1257 printf ("Contents of section %s:\n", section->name);
1258
9b018ecd 1259 if (bfd_section_size (abfd, section) == 0)
aa0a709a 1260 continue;
02a68547 1261 data = (bfd_byte *) xmalloc ((size_t) bfd_section_size (abfd, section));
9b018ecd 1262 datasize = bfd_section_size (abfd, section);
2fa0b342 1263
2fa0b342 1264
9b018ecd 1265 bfd_get_section_contents (abfd, section, (PTR) data, 0, bfd_section_size (abfd, section));
2fa0b342 1266
9b018ecd 1267 for (i = 0; i < bfd_section_size (abfd, section); i += onaline)
aa0a709a
SC
1268 {
1269 bfd_size_type j;
1270
1271 printf (" %04lx ", (unsigned long int) (i + section->vma));
1272 for (j = i; j < i + onaline; j++)
1273 {
9b018ecd 1274 if (j < bfd_section_size (abfd, section))
aa0a709a
SC
1275 printf ("%02x", (unsigned) (data[j]));
1276 else
1277 printf (" ");
1278 if ((j & 3) == 3)
1279 printf (" ");
1280 }
2fa0b342 1281
aa0a709a
SC
1282 printf (" ");
1283 for (j = i; j < i + onaline; j++)
1284 {
9b018ecd 1285 if (j >= bfd_section_size (abfd, section))
aa0a709a
SC
1286 printf (" ");
1287 else
1288 printf ("%c", isprint (data[j]) ? data[j] : '.');
1289 }
1290 putchar ('\n');
1291 }
d9971b83 1292 free (data);
60c80016 1293 }
2fa0b342 1294 }
2fa0b342 1295 }
2fa0b342
DHW
1296}
1297
2fa0b342 1298/* Should perhaps share code and display with nm? */
d9971b83 1299static void
de3b08ac 1300dump_symbols (abfd, dynamic)
2fa0b342 1301 bfd *abfd;
de3b08ac 1302 boolean dynamic;
2fa0b342 1303{
de3b08ac
ILT
1304 asymbol **current;
1305 long max;
ae5d2ff5 1306 long count;
2fa0b342 1307
de3b08ac 1308 if (dynamic)
aa0a709a 1309 {
de3b08ac
ILT
1310 current = dynsyms;
1311 max = dynsymcount;
1312 if (max == 0)
1313 return;
1314 printf ("DYNAMIC SYMBOL TABLE:\n");
1315 }
1316 else
1317 {
1318 current = syms;
1319 max = symcount;
1320 if (max == 0)
1321 return;
1322 printf ("SYMBOL TABLE:\n");
1323 }
2fa0b342 1324
de3b08ac
ILT
1325 for (count = 0; count < max; count++)
1326 {
d9971b83 1327 if (*current)
aa0a709a 1328 {
d9971b83
KR
1329 bfd *cur_bfd = bfd_asymbol_bfd(*current);
1330 if (cur_bfd)
1331 {
1332 bfd_print_symbol (cur_bfd,
1333 stdout,
1334 *current, bfd_print_symbol_all);
1335 printf ("\n");
1336 }
aa0a709a
SC
1337 }
1338 current++;
2fa0b342 1339 }
aa0a709a
SC
1340 printf ("\n");
1341 printf ("\n");
2fa0b342
DHW
1342}
1343
d9971b83 1344static void
aa0a709a
SC
1345dump_relocs (abfd)
1346 bfd *abfd;
2fa0b342
DHW
1347{
1348 arelent **relpp;
ae5d2ff5 1349 long relcount;
2fa0b342 1350 asection *a;
aa0a709a
SC
1351
1352 for (a = abfd->sections; a != (asection *) NULL; a = a->next)
1353 {
ae5d2ff5
ILT
1354 long relsize;
1355
28d1b01e 1356 if (bfd_is_abs_section (a))
aa0a709a 1357 continue;
28d1b01e 1358 if (bfd_is_und_section (a))
aa0a709a 1359 continue;
d9971b83 1360 if (bfd_is_com_section (a))
aa0a709a
SC
1361 continue;
1362
195d1adf
KR
1363 if (only)
1364 {
1365 if (strcmp (only, a->name))
1366 continue;
1367 }
1368 else if ((a->flags & SEC_RELOC) == 0)
1369 continue;
1370
aa0a709a
SC
1371 printf ("RELOCATION RECORDS FOR [%s]:", a->name);
1372
ae5d2ff5
ILT
1373 relsize = bfd_get_reloc_upper_bound (abfd, a);
1374 if (relsize < 0)
1375 bfd_fatal (bfd_get_filename (abfd));
1376
1377 if (relsize == 0)
aa0a709a
SC
1378 {
1379 printf (" (none)\n\n");
d20f480f 1380 }
aa0a709a
SC
1381 else
1382 {
ae5d2ff5 1383 relpp = (arelent **) xmalloc (relsize);
aa0a709a 1384 relcount = bfd_canonicalize_reloc (abfd, a, relpp, syms);
ae5d2ff5
ILT
1385 if (relcount < 0)
1386 bfd_fatal (bfd_get_filename (abfd));
1387 else if (relcount == 0)
aa0a709a
SC
1388 {
1389 printf (" (none)\n\n");
d20f480f 1390 }
aa0a709a
SC
1391 else
1392 {
1393 printf ("\n");
de3b08ac 1394 dump_reloc_set (abfd, relpp, relcount);
aa0a709a 1395 printf ("\n\n");
d20f480f 1396 }
de3b08ac 1397 free (relpp);
2fa0b342 1398 }
de3b08ac
ILT
1399 }
1400}
2fa0b342 1401
de3b08ac
ILT
1402static void
1403dump_dynamic_relocs (abfd)
1404 bfd *abfd;
1405{
1406 long relsize;
1407 arelent **relpp;
1408 long relcount;
1409
1410 printf ("DYNAMIC RELOCATION RECORDS");
1411
1412 relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
1413 if (relsize < 0)
1414 bfd_fatal (bfd_get_filename (abfd));
1415
1416 if (relsize == 0)
1417 {
1418 printf (" (none)\n\n");
1419 }
1420 else
1421 {
1422 relpp = (arelent **) xmalloc (relsize);
1423 relcount = bfd_canonicalize_dynamic_reloc (abfd, relpp, dynsyms);
1424 if (relcount < 0)
1425 bfd_fatal (bfd_get_filename (abfd));
1426 else if (relcount == 0)
1427 {
1428 printf (" (none)\n\n");
1429 }
1430 else
1431 {
1432 printf ("\n");
1433 dump_reloc_set (abfd, relpp, relcount);
1434 printf ("\n\n");
1435 }
1436 free (relpp);
1437 }
1438}
1439
1440static void
1441dump_reloc_set (abfd, relpp, relcount)
1442 bfd *abfd;
1443 arelent **relpp;
1444 long relcount;
1445{
1446 arelent **p;
1447
1448 /* Get column headers lined up reasonably. */
1449 {
1450 static int width;
1451 if (width == 0)
1452 {
1453 char buf[30];
1454 sprintf_vma (buf, (bfd_vma) -1);
1455 width = strlen (buf) - 7;
1456 }
1457 printf ("OFFSET %*s TYPE %*s VALUE \n", width, "", 12, "");
1458 }
1459
1460 for (p = relpp; relcount && *p != (arelent *) NULL; p++, relcount--)
1461 {
1462 arelent *q = *p;
1463 CONST char *sym_name;
1464 CONST char *section_name;
1465
1466 if (q->sym_ptr_ptr && *q->sym_ptr_ptr)
1467 {
1468 sym_name = (*(q->sym_ptr_ptr))->name;
1469 section_name = (*(q->sym_ptr_ptr))->section->name;
1470 }
1471 else
1472 {
1473 sym_name = NULL;
1474 section_name = NULL;
1475 }
1476 if (sym_name)
1477 {
1478 printf_vma (q->address);
1479 printf (" %-16s %s",
1480 q->howto->name,
1481 sym_name);
1482 }
1483 else
1484 {
1485 if (section_name == (CONST char *) NULL)
1486 section_name = "*unknown*";
1487 printf_vma (q->address);
1488 printf (" %-16s [%s]",
1489 q->howto->name,
1490 section_name);
1491 }
1492 if (q->addend)
1493 {
1494 printf ("+0x");
1495 printf_vma (q->addend);
1496 }
1497 printf ("\n");
d20f480f 1498 }
2fa0b342 1499}
f7b839f7 1500\f
f7b839f7
DM
1501/* The length of the longest architecture name + 1. */
1502#define LONGEST_ARCH sizeof("rs6000:6000")
1503
be1d162b
ILT
1504#ifndef L_tmpnam
1505#define L_tmpnam 25
1506#endif
1507
f7b839f7
DM
1508/* List the targets that BFD is configured to support, each followed
1509 by its endianness and the architectures it supports. */
1510
1511static void
1512display_target_list ()
1513{
de04bceb 1514 extern char *tmpnam ();
f7b839f7 1515 extern bfd_target *bfd_target_vector[];
be1d162b 1516 char tmparg[L_tmpnam];
de04bceb 1517 char *dummy_name;
f7b839f7
DM
1518 int t;
1519
be1d162b 1520 dummy_name = tmpnam (tmparg);
f7b839f7
DM
1521 for (t = 0; bfd_target_vector[t]; t++)
1522 {
f7b839f7 1523 bfd_target *p = bfd_target_vector[t];
de04bceb 1524 bfd *abfd = bfd_openw (dummy_name, p->name);
105da05c
ILT
1525 int a;
1526
1527 printf ("%s\n (header %s, data %s)\n", p->name,
1528 p->header_byteorder_big_p ? "big endian" : "little endian",
1529 p->byteorder_big_p ? "big endian" : "little endian");
f7b839f7 1530
334d6e76
SS
1531 if (abfd == NULL)
1532 {
de04bceb 1533 bfd_nonfatal (dummy_name);
105da05c 1534 continue;
334d6e76 1535 }
105da05c
ILT
1536
1537 if (! bfd_set_format (abfd, bfd_object))
1538 {
1539 if (bfd_get_error () != bfd_error_invalid_operation)
1540 bfd_nonfatal (p->name);
1541 continue;
1542 }
1543
f7b839f7
DM
1544 for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
1545 if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
1546 printf (" %s\n",
1547 bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
1548 }
de04bceb 1549 unlink (dummy_name);
f7b839f7
DM
1550}
1551
1552/* Print a table showing which architectures are supported for entries
1553 FIRST through LAST-1 of bfd_target_vector (targets across,
1554 architectures down). */
1555
9872a49c 1556static void
abdcac0f
DM
1557display_info_table (first, last)
1558 int first;
1559 int last;
9872a49c 1560{
abdcac0f 1561 extern bfd_target *bfd_target_vector[];
de04bceb 1562 extern char *tmpnam ();
be1d162b 1563 char tmparg[L_tmpnam];
de04bceb
ILT
1564 int t, a;
1565 char *dummy_name;
9872a49c 1566
f7b839f7 1567 /* Print heading of target names. */
ae5d2ff5 1568 printf ("\n%*s", (int) LONGEST_ARCH, " ");
105da05c 1569 for (t = first; t < last && bfd_target_vector[t]; t++)
f7b839f7
DM
1570 printf ("%s ", bfd_target_vector[t]->name);
1571 putchar ('\n');
9872a49c 1572
be1d162b 1573 dummy_name = tmpnam (tmparg);
f7b839f7
DM
1574 for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
1575 if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0)
e779a58c 1576 {
ae5d2ff5
ILT
1577 printf ("%*s ", (int) LONGEST_ARCH - 1,
1578 bfd_printable_arch_mach (a, 0));
105da05c 1579 for (t = first; t < last && bfd_target_vector[t]; t++)
aa0a709a 1580 {
f7b839f7 1581 bfd_target *p = bfd_target_vector[t];
105da05c 1582 boolean ok = true;
de04bceb 1583 bfd *abfd = bfd_openw (dummy_name, p->name);
aa0a709a 1584
334d6e76
SS
1585 if (abfd == NULL)
1586 {
105da05c
ILT
1587 bfd_nonfatal (p->name);
1588 ok = false;
1589 }
1590
1591 if (ok)
1592 {
1593 if (! bfd_set_format (abfd, bfd_object))
1594 {
1595 if (bfd_get_error () != bfd_error_invalid_operation)
1596 bfd_nonfatal (p->name);
1597 ok = false;
1598 }
334d6e76 1599 }
105da05c
ILT
1600
1601 if (ok)
1602 {
1603 if (! bfd_set_arch_mach (abfd, a, 0))
1604 ok = false;
1605 }
1606
1607 if (ok)
aa0a709a
SC
1608 printf ("%s ", p->name);
1609 else
e779a58c 1610 {
f7b839f7 1611 int l = strlen (p->name);
aa0a709a 1612 while (l--)
f7b839f7
DM
1613 putchar ('-');
1614 putchar (' ');
e779a58c 1615 }
e779a58c 1616 }
f7b839f7 1617 putchar ('\n');
e779a58c 1618 }
de04bceb 1619 unlink (dummy_name);
9872a49c 1620}
aa0a709a 1621
f7b839f7
DM
1622/* Print tables of all the target-architecture combinations that
1623 BFD has been configured to support. */
1624
aa0a709a 1625static void
f7b839f7 1626display_target_tables ()
aa0a709a 1627{
f7b839f7 1628 int t, columns;
abdcac0f 1629 extern bfd_target *bfd_target_vector[];
f7b839f7 1630 char *colum;
aa0a709a
SC
1631 extern char *getenv ();
1632
aa0a709a 1633 columns = 0;
f7b839f7
DM
1634 colum = getenv ("COLUMNS");
1635 if (colum != NULL)
aa0a709a 1636 columns = atoi (colum);
f7b839f7 1637 if (columns == 0)
aa0a709a 1638 columns = 80;
f7b839f7 1639
105da05c
ILT
1640 t = 0;
1641 while (bfd_target_vector[t] != NULL)
aa0a709a 1642 {
f7b839f7
DM
1643 int oldt = t, wid;
1644
105da05c
ILT
1645 wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
1646 ++t;
1647 while (wid < columns && bfd_target_vector[t] != NULL)
1648 {
1649 int newwid;
1650
1651 newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
1652 if (newwid >= columns)
1653 break;
1654 wid = newwid;
1655 ++t;
1656 }
f7b839f7 1657 display_info_table (oldt, t);
aa0a709a
SC
1658 }
1659}
1660
f7b839f7
DM
1661static void
1662display_info ()
1663{
1664 printf ("BFD header file version %s\n", BFD_VERSION);
1665 display_target_list ();
1666 display_target_tables ();
1667}
1668
2fa0b342
DHW
1669int
1670main (argc, argv)
1671 int argc;
1672 char **argv;
1673{
1674 int c;
2fa0b342
DHW
1675 char *target = default_target;
1676 boolean seenflag = false;
2fa0b342
DHW
1677
1678 program_name = *argv;
8f197c94
ILT
1679 xmalloc_set_program_name (program_name);
1680
be1d162b
ILT
1681 START_PROGRESS (program_name, 0);
1682
8f197c94 1683 bfd_init ();
2fa0b342 1684
be1d162b 1685 while ((c = getopt_long (argc, argv, "ib:m:VdDlfahrRtTxsSj:", long_options,
d2442698 1686 (int *) 0))
aa0a709a
SC
1687 != EOF)
1688 {
1689 seenflag = true;
1690 switch (c)
1691 {
b3a2b497
ILT
1692 case 0:
1693 break; /* we've been given a long option */
aa0a709a
SC
1694 case 'm':
1695 machine = optarg;
1696 break;
1697 case 'j':
1698 only = optarg;
1699 break;
1700 case 'l':
1701 with_line_numbers = 1;
1702 break;
1703 case 'b':
1704 target = optarg;
1705 break;
1706 case 'f':
1707 dump_file_header = true;
1708 break;
1709 case 'i':
e1ec9f07 1710 formats_info = true;
aa0a709a
SC
1711 break;
1712 case 'x':
1713 dump_symtab = 1;
1714 dump_reloc_info = 1;
1715 dump_file_header = true;
1716 dump_ar_hdrs = 1;
1717 dump_section_headers = 1;
1718 break;
aa0a709a
SC
1719 case 't':
1720 dump_symtab = 1;
1721 break;
de3b08ac
ILT
1722 case 'T':
1723 dump_dynamic_symtab = 1;
1724 break;
aa0a709a
SC
1725 case 'd':
1726 disassemble = true;
1727 break;
d5464baa
ILT
1728 case 'D':
1729 disassemble = disassemble_all = true;
1730 break;
be1d162b
ILT
1731 case 'S':
1732 disassemble = true;
1733 with_source_code = true;
1734 break;
aa0a709a
SC
1735 case 's':
1736 dump_section_contents = 1;
1737 break;
1738 case 'r':
1739 dump_reloc_info = 1;
1740 break;
de3b08ac
ILT
1741 case 'R':
1742 dump_dynamic_reloc_info = 1;
1743 break;
aa0a709a
SC
1744 case 'a':
1745 dump_ar_hdrs = 1;
1746 break;
1747 case 'h':
1748 dump_section_headers = 1;
1749 break;
b3a2b497
ILT
1750 case 'H':
1751 usage (stdout, 0);
249c6fc0
RS
1752 case 'V':
1753 show_version = 1;
1754 break;
aa0a709a 1755 default:
b3a2b497 1756 usage (stderr, 1);
aa0a709a 1757 }
2fa0b342 1758 }
2fa0b342 1759
249c6fc0 1760 if (show_version)
b3a2b497
ILT
1761 {
1762 printf ("GNU %s version %s\n", program_name, program_version);
1763 exit (0);
1764 }
249c6fc0 1765
2fa0b342 1766 if (seenflag == false)
b3a2b497 1767 usage (stderr, 1);
2fa0b342 1768
e1ec9f07 1769 if (formats_info)
aa0a709a
SC
1770 {
1771 display_info ();
1772 }
1773 else
1774 {
1775 if (optind == argc)
1776 display_file ("a.out", target);
1777 else
1778 for (; optind < argc;)
1779 display_file (argv[optind++], target);
1780 }
be1d162b
ILT
1781
1782 END_PROGRESS (program_name);
1783
2fa0b342
DHW
1784 return 0;
1785}
This page took 0.221241 seconds and 4 git commands to generate.