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