* Makefile.in (LIB_INSTALL_DIR): New macro.
[deliverable/binutils-gdb.git] / binutils / objdump.c
CommitLineData
d20f480f 1/* objdump.c -- dump information about an object file.
980ef031 2 Copyright 1990, 91, 92, 93, 94, 95, 1996 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 17along with this program; if not, write to the Free Software
a65619c8 18Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
2fa0b342 19
2fa0b342
DHW
20#include "bfd.h"
21#include "getopt.h"
be1d162b 22#include "progress.h"
e1ec9f07 23#include "bucomm.h"
2fa0b342 24#include <ctype.h>
2e8adbd7 25#include "dis-asm.h"
105da05c 26#include "libiberty.h"
e1c14599
ILT
27#include "debug.h"
28#include "budbg.h"
2fa0b342 29
7fc01fc9
ILT
30#ifdef ANSI_PROTOTYPES
31#include <stdarg.h>
32#else
33#include <varargs.h>
34#endif
35
73b8f102
JG
36/* Internal headers for the ELF .stab-dump code - sorry. */
37#define BYTES_IN_WORD 32
38#include "aout/aout64.h"
bf661056 39
746cffcf
ILT
40#ifdef NEED_DECLARATION_FPRINTF
41/* This is needed by INIT_DISASSEMBLE_INFO. */
7fc01fc9 42extern int fprintf PARAMS ((FILE *, const char *, ...));
80d19ec1 43#endif
2fa0b342 44
18f39dfa 45static char *default_target = NULL; /* default at runtime */
2fa0b342 46
e1ec9f07 47extern char *program_version;
2fa0b342 48
18f39dfa
SG
49static int show_version = 0; /* show the version number */
50static int dump_section_contents; /* -s */
51static int dump_section_headers; /* -h */
52static boolean dump_file_header; /* -f */
53static int dump_symtab; /* -t */
54static int dump_dynamic_symtab; /* -T */
55static int dump_reloc_info; /* -r */
56static int dump_dynamic_reloc_info; /* -R */
57static int dump_ar_hdrs; /* -a */
58static int dump_private_headers; /* -p */
59static int with_line_numbers; /* -l */
60static boolean with_source_code; /* -S */
61static int show_raw_insn; /* --show-raw-insn */
62static int dump_stab_section_info; /* --stabs */
63static boolean disassemble; /* -d */
64static boolean disassemble_all; /* -D */
65static boolean formats_info; /* -i */
66static char *only; /* -j secname */
67static int wide_output; /* -w */
68static bfd_vma start_address = (bfd_vma) -1; /* --start-address */
69static bfd_vma stop_address = (bfd_vma) -1; /* --stop-address */
70static int dump_debugging; /* --debugging */
195d1adf 71
cef35d48 72/* Extra info to pass to the disassembler address printing function. */
195d1adf
KR
73struct objdump_disasm_info {
74 bfd *abfd;
75 asection *sec;
8b129785 76 boolean require_sec;
195d1adf 77};
2fa0b342 78
cef35d48 79/* Architecture to disassemble for, or default if NULL. */
18f39dfa
SG
80static char *machine = (char *) NULL;
81
82/* Endianness to disassemble for, or default if BFD_ENDIAN_UNKNOWN. */
83static enum bfd_endian endian = BFD_ENDIAN_UNKNOWN;
f7b839f7
DM
84
85/* The symbol table. */
18f39dfa 86static asymbol **syms;
2fa0b342 87
f7b839f7 88/* Number of symbols in `syms'. */
18f39dfa 89static long symcount = 0;
2fa0b342 90
be1d162b 91/* The sorted symbol table. */
18f39dfa 92static asymbol **sorted_syms;
be1d162b
ILT
93
94/* Number of symbols in `sorted_syms'. */
18f39dfa 95static long sorted_symcount = 0;
be1d162b 96
de3b08ac 97/* The dynamic symbol table. */
18f39dfa 98static asymbol **dynsyms;
de3b08ac
ILT
99
100/* Number of symbols in `dynsyms'. */
18f39dfa 101static long dynsymcount = 0;
de3b08ac 102
d9971b83
KR
103/* Forward declarations. */
104
105static void
106display_file PARAMS ((char *filename, char *target));
107
108static void
109dump_data PARAMS ((bfd *abfd));
110
111static void
112dump_relocs PARAMS ((bfd *abfd));
113
114static void
de3b08ac
ILT
115dump_dynamic_relocs PARAMS ((bfd * abfd));
116
117static void
18f39dfa 118dump_reloc_set PARAMS ((bfd *, asection *, arelent **, long));
de3b08ac
ILT
119
120static void
121dump_symbols PARAMS ((bfd *abfd, boolean dynamic));
02a68547
ILT
122
123static void
124display_bfd PARAMS ((bfd *abfd));
8f197c94 125
c5ba2759 126static void
7fc01fc9 127objdump_print_value PARAMS ((bfd_vma, struct disassemble_info *));
c5ba2759 128
8f197c94
ILT
129static void
130objdump_print_address PARAMS ((bfd_vma, struct disassemble_info *));
be1d162b
ILT
131
132static void
133show_line PARAMS ((bfd *, asection *, bfd_vma));
e1c14599
ILT
134
135static const char *
136endian_string PARAMS ((enum bfd_endian));
d9971b83 137\f
18f39dfa 138static void
b3a2b497
ILT
139usage (stream, status)
140 FILE *stream;
141 int status;
2fa0b342 142{
b3a2b497 143 fprintf (stream, "\
a65619c8 144Usage: %s [-ahifdDprRtTxsSlw] [-b bfdname] [-m machine] [-j section-name]\n\
e1c14599 145 [--archive-headers] [--target=bfdname] [--debugging] [--disassemble]\n\
d5464baa 146 [--disassemble-all] [--file-headers] [--section-headers] [--headers]\n\
13e4db2e
SC
147 [--info] [--section=section-name] [--line-numbers] [--source]\n",
148 program_name);
149 fprintf (stream, "\
d5464baa
ILT
150 [--architecture=machine] [--reloc] [--full-contents] [--stabs]\n\
151 [--syms] [--all-headers] [--dynamic-syms] [--dynamic-reloc]\n\
aa21a2a9 152 [--wide] [--version] [--help] [--private-headers]\n\
458bbd1f 153 [--start-address=addr] [--stop-address=addr]\n\
18f39dfa 154 [--show-raw-insn] [-EB|-EL] [--endian={big|little}] objfile...\n\
13e4db2e 155at least one option besides -l (--line-numbers) must be given\n");
be1d162b 156 list_supported_targets (program_name, stream);
b3a2b497 157 exit (status);
2fa0b342
DHW
158}
159
aa21a2a9
ILT
160/* 150 isn't special; it's just an arbitrary non-ASCII char value. */
161
18f39dfa
SG
162#define OPTION_ENDIAN (150)
163#define OPTION_START_ADDRESS (OPTION_ENDIAN + 1)
aa21a2a9
ILT
164#define OPTION_STOP_ADDRESS (OPTION_START_ADDRESS + 1)
165
aa0a709a
SC
166static struct option long_options[]=
167{
02a68547 168 {"all-headers", no_argument, NULL, 'x'},
a65619c8 169 {"private-headers", no_argument, NULL, 'p'},
02a68547
ILT
170 {"architecture", required_argument, NULL, 'm'},
171 {"archive-headers", no_argument, NULL, 'a'},
e1c14599 172 {"debugging", no_argument, &dump_debugging, 1},
02a68547 173 {"disassemble", no_argument, NULL, 'd'},
d5464baa 174 {"disassemble-all", no_argument, NULL, 'D'},
de3b08ac
ILT
175 {"dynamic-reloc", no_argument, NULL, 'R'},
176 {"dynamic-syms", no_argument, NULL, 'T'},
18f39dfa 177 {"endian", required_argument, NULL, OPTION_ENDIAN},
02a68547
ILT
178 {"file-headers", no_argument, NULL, 'f'},
179 {"full-contents", no_argument, NULL, 's'},
180 {"headers", no_argument, NULL, 'h'},
181 {"help", no_argument, NULL, 'H'},
182 {"info", no_argument, NULL, 'i'},
183 {"line-numbers", no_argument, NULL, 'l'},
184 {"reloc", no_argument, NULL, 'r'},
185 {"section", required_argument, NULL, 'j'},
186 {"section-headers", no_argument, NULL, 'h'},
458bbd1f 187 {"show-raw-insn", no_argument, &show_raw_insn, 1},
be1d162b 188 {"source", no_argument, NULL, 'S'},
73b8f102 189 {"stabs", no_argument, &dump_stab_section_info, 1},
aa21a2a9
ILT
190 {"start-address", required_argument, NULL, OPTION_START_ADDRESS},
191 {"stop-address", required_argument, NULL, OPTION_STOP_ADDRESS},
02a68547
ILT
192 {"syms", no_argument, NULL, 't'},
193 {"target", required_argument, NULL, 'b'},
aa21a2a9 194 {"version", no_argument, &show_version, 1},
13e4db2e 195 {"wide", no_argument, &wide_output, 'w'},
d2442698
DM
196 {0, no_argument, 0, 0}
197};
f7b839f7 198\f
2fa0b342 199static void
f7b839f7 200dump_section_header (abfd, section, ignored)
aa0a709a 201 bfd *abfd;
f7b839f7
DM
202 asection *section;
203 PTR ignored;
2fa0b342 204{
f7b839f7 205 char *comma = "";
aa0a709a 206
38d7c012 207 printf ("%3d %-13s %08lx ", section->index,
1efb2ef0
ILT
208 bfd_get_section_name (abfd, section),
209 (unsigned long) bfd_section_size (abfd, section));
210 printf_vma (bfd_get_section_vma (abfd, section));
211 printf (" ");
212 printf_vma (section->lma);
213 printf (" %08lx 2**%u", section->filepos,
214 bfd_get_section_alignment (abfd, section));
215 if (! wide_output)
216 printf ("\n ");
217 printf (" ");
f7b839f7 218
1efb2ef0
ILT
219#define PF(x, y) \
220 if (section->flags & x) { printf ("%s%s", comma, y); comma = ", "; }
f7b839f7 221
1efb2ef0 222 PF (SEC_HAS_CONTENTS, "CONTENTS");
f7b839f7
DM
223 PF (SEC_ALLOC, "ALLOC");
224 PF (SEC_CONSTRUCTOR, "CONSTRUCTOR");
225 PF (SEC_CONSTRUCTOR_TEXT, "CONSTRUCTOR TEXT");
226 PF (SEC_CONSTRUCTOR_DATA, "CONSTRUCTOR DATA");
227 PF (SEC_CONSTRUCTOR_BSS, "CONSTRUCTOR BSS");
228 PF (SEC_LOAD, "LOAD");
229 PF (SEC_RELOC, "RELOC");
195d1adf 230#ifdef SEC_BALIGN
f7b839f7 231 PF (SEC_BALIGN, "BALIGN");
195d1adf 232#endif
f7b839f7
DM
233 PF (SEC_READONLY, "READONLY");
234 PF (SEC_CODE, "CODE");
235 PF (SEC_DATA, "DATA");
236 PF (SEC_ROM, "ROM");
237 PF (SEC_DEBUGGING, "DEBUGGING");
28d1b01e 238 PF (SEC_NEVER_LOAD, "NEVER_LOAD");
83f4323e 239 PF (SEC_EXCLUDE, "EXCLUDE");
38d7c012
ILT
240 PF (SEC_SORT_ENTRIES, "SORT_ENTRIES");
241
242 if ((section->flags & SEC_LINK_ONCE) != 0)
243 {
244 const char *ls;
245
246 switch (section->flags & SEC_LINK_DUPLICATES)
247 {
248 default:
249 abort ();
250 case SEC_LINK_DUPLICATES_DISCARD:
251 ls = "LINK_ONCE_DISCARD";
252 break;
253 case SEC_LINK_DUPLICATES_ONE_ONLY:
254 ls = "LINK_ONCE_ONE_ONLY";
255 break;
256 case SEC_LINK_DUPLICATES_SAME_SIZE:
257 ls = "LINK_ONCE_SAME_SIZE";
258 break;
259 case SEC_LINK_DUPLICATES_SAME_CONTENTS:
260 ls = "LINK_ONCE_SAME_CONTENTS";
261 break;
262 }
263 printf ("%s%s", comma, ls);
264 comma = ", ";
265 }
266
f7b839f7 267 printf ("\n");
2fa0b342 268#undef PF
2fa0b342
DHW
269}
270
f7b839f7
DM
271static void
272dump_headers (abfd)
273 bfd *abfd;
274{
1efb2ef0
ILT
275 printf ("Sections:\n");
276#ifndef BFD64
277 printf ("Idx Name Size VMA LMA File off Algn\n");
278#else
279 printf ("Idx Name Size VMA LMA File off Algn\n");
280#endif
f7b839f7
DM
281 bfd_map_over_sections (abfd, dump_section_header, (PTR) NULL);
282}
283\f
2fa0b342 284static asymbol **
abdcac0f
DM
285slurp_symtab (abfd)
286 bfd *abfd;
2fa0b342 287{
aa0a709a 288 asymbol **sy = (asymbol **) NULL;
ae5d2ff5 289 long storage;
2fa0b342 290
aa0a709a
SC
291 if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
292 {
f7b839f7 293 printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
c5ba2759 294 symcount = 0;
f7b839f7 295 return NULL;
aa0a709a
SC
296 }
297
ae5d2ff5
ILT
298 storage = bfd_get_symtab_upper_bound (abfd);
299 if (storage < 0)
300 bfd_fatal (bfd_get_filename (abfd));
301
aa0a709a
SC
302 if (storage)
303 {
02a68547 304 sy = (asymbol **) xmalloc (storage);
aa0a709a
SC
305 }
306 symcount = bfd_canonicalize_symtab (abfd, sy);
ae5d2ff5
ILT
307 if (symcount < 0)
308 bfd_fatal (bfd_get_filename (abfd));
309 if (symcount == 0)
de3b08ac
ILT
310 fprintf (stderr, "%s: %s: No symbols\n",
311 program_name, bfd_get_filename (abfd));
312 return sy;
313}
314
315/* Read in the dynamic symbols. */
316
317static asymbol **
318slurp_dynamic_symtab (abfd)
319 bfd *abfd;
320{
321 asymbol **sy = (asymbol **) NULL;
322 long storage;
323
de3b08ac
ILT
324 storage = bfd_get_dynamic_symtab_upper_bound (abfd);
325 if (storage < 0)
28d1b01e
ILT
326 {
327 if (!(bfd_get_file_flags (abfd) & DYNAMIC))
328 {
329 fprintf (stderr, "%s: %s: not a dynamic object\n",
330 program_name, bfd_get_filename (abfd));
c5ba2759 331 dynsymcount = 0;
28d1b01e
ILT
332 return NULL;
333 }
334
335 bfd_fatal (bfd_get_filename (abfd));
336 }
de3b08ac
ILT
337
338 if (storage)
339 {
340 sy = (asymbol **) xmalloc (storage);
341 }
342 dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, sy);
343 if (dynsymcount < 0)
344 bfd_fatal (bfd_get_filename (abfd));
345 if (dynsymcount == 0)
346 fprintf (stderr, "%s: %s: No dynamic symbols\n",
347 program_name, bfd_get_filename (abfd));
aa0a709a 348 return sy;
2fa0b342 349}
aa0a709a 350
f7b839f7
DM
351/* Filter out (in place) symbols that are useless for disassembly.
352 COUNT is the number of elements in SYMBOLS.
353 Return the number of useful symbols. */
3ae36cb6 354
18f39dfa 355static long
f7b839f7
DM
356remove_useless_symbols (symbols, count)
357 asymbol **symbols;
ae5d2ff5 358 long count;
3ae36cb6 359{
f7b839f7 360 register asymbol **in_ptr = symbols, **out_ptr = symbols;
3ae36cb6 361
f7b839f7 362 while (--count >= 0)
3ae36cb6
PB
363 {
364 asymbol *sym = *in_ptr++;
365
366 if (sym->name == NULL || sym->name[0] == '\0')
367 continue;
368 if (sym->flags & (BSF_DEBUGGING))
369 continue;
28d1b01e 370 if (bfd_is_und_section (sym->section)
3ae36cb6
PB
371 || bfd_is_com_section (sym->section))
372 continue;
373
374 *out_ptr++ = sym;
375 }
f7b839f7 376 return out_ptr - symbols;
3ae36cb6
PB
377}
378
e1c14599 379/* Sort symbols into value order. */
37853673 380
aa0a709a 381static int
37853673 382compare_symbols (ap, bp)
d5464baa
ILT
383 const PTR ap;
384 const PTR bp;
2fa0b342 385{
d5464baa
ILT
386 const asymbol *a = *(const asymbol **)ap;
387 const asymbol *b = *(const asymbol **)bp;
db552bda
ILT
388 const char *an, *bn;
389 size_t anl, bnl;
390 boolean af, bf;
e1c14599 391 flagword aflags, bflags;
2fa0b342 392
be1d162b 393 if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
3ae36cb6 394 return 1;
be1d162b 395 else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
3ae36cb6 396 return -1;
2fa0b342 397
3ae36cb6
PB
398 if (a->section > b->section)
399 return 1;
400 else if (a->section < b->section)
401 return -1;
db552bda
ILT
402
403 an = bfd_asymbol_name (a);
404 bn = bfd_asymbol_name (b);
405 anl = strlen (an);
406 bnl = strlen (bn);
407
408 /* The symbols gnu_compiled and gcc2_compiled convey no real
409 information, so put them after other symbols with the same value. */
410
411 af = (strstr (an, "gnu_compiled") != NULL
412 || strstr (an, "gcc2_compiled") != NULL);
413 bf = (strstr (bn, "gnu_compiled") != NULL
414 || strstr (bn, "gcc2_compiled") != NULL);
415
416 if (af && ! bf)
417 return 1;
418 if (! af && bf)
419 return -1;
420
421 /* We use a heuristic for the file name, to try to sort it after
422 more useful symbols. It may not work on non Unix systems, but it
423 doesn't really matter; the only difference is precisely which
424 symbol names get printed. */
425
426#define file_symbol(s, sn, snl) \
427 (((s)->flags & BSF_FILE) != 0 \
428 || ((sn)[(snl) - 2] == '.' \
429 && ((sn)[(snl) - 1] == 'o' \
430 || (sn)[(snl) - 1] == 'a')))
431
432 af = file_symbol (a, an, anl);
433 bf = file_symbol (b, bn, bnl);
434
435 if (af && ! bf)
436 return 1;
437 if (! af && bf)
438 return -1;
439
17aa8284
ILT
440 /* Try to sort global symbols before local symbols before debugging
441 symbols. */
e1c14599
ILT
442
443 aflags = a->flags;
444 bflags = b->flags;
445
446 if ((aflags & BSF_DEBUGGING) != (bflags & BSF_DEBUGGING))
447 {
448 if ((aflags & BSF_DEBUGGING) != 0)
449 return 1;
450 else
451 return -1;
452 }
453 if ((aflags & BSF_LOCAL) != (bflags & BSF_LOCAL))
454 {
455 if ((aflags & BSF_LOCAL) != 0)
456 return 1;
457 else
458 return -1;
459 }
17aa8284
ILT
460 if ((aflags & BSF_GLOBAL) != (bflags & BSF_GLOBAL))
461 {
462 if ((aflags & BSF_GLOBAL) != 0)
463 return -1;
464 else
465 return 1;
466 }
467
468 /* Symbols that start with '.' might be section names, so sort them
469 after symbols that don't start with '.'. */
470 if (an[0] == '.' && bn[0] != '.')
471 return 1;
472 if (an[0] != '.' && bn[0] == '.')
473 return -1;
e1c14599 474
17aa8284
ILT
475 /* Finally, if we can't distinguish them in any other way, try to
476 get consistent results by sorting the symbols by name. */
477 return strcmp (an, bn);
2fa0b342
DHW
478}
479
d5464baa
ILT
480/* Sort relocs into address order. */
481
482static int
483compare_relocs (ap, bp)
484 const PTR ap;
485 const PTR bp;
486{
487 const arelent *a = *(const arelent **)ap;
488 const arelent *b = *(const arelent **)bp;
489
490 if (a->address > b->address)
491 return 1;
492 else if (a->address < b->address)
493 return -1;
494
a65619c8
SC
495 /* So that associated relocations tied to the same address show up
496 in the correct order, we don't do any further sorting. */
497 if (a > b)
498 return 1;
499 else if (a < b)
500 return -1;
501 else
502 return 0;
d5464baa
ILT
503}
504
c5ba2759
ILT
505/* Print VMA to STREAM with no leading zeroes. */
506
507static void
7fc01fc9 508objdump_print_value (vma, info)
c5ba2759 509 bfd_vma vma;
7fc01fc9 510 struct disassemble_info *info;
c5ba2759
ILT
511{
512 char buf[30];
513 char *p;
514
515 sprintf_vma (buf, vma);
516 for (p = buf; *p == '0'; ++p)
517 ;
7fc01fc9 518 (*info->fprintf_func) (info->stream, "%s", p);
c5ba2759
ILT
519}
520
f7b839f7
DM
521/* Print VMA symbolically to INFO if possible. */
522
8f197c94 523static void
545a2768 524objdump_print_address (vma, info)
aa0a709a 525 bfd_vma vma;
545a2768 526 struct disassemble_info *info;
2fa0b342 527{
7fc01fc9
ILT
528 char buf[30];
529
195d1adf
KR
530 /* @@ Would it speed things up to cache the last two symbols returned,
531 and maybe their address ranges? For many processors, only one memory
532 operand can be present at a time, so the 2-entry cache wouldn't be
533 constantly churned by code doing heavy memory accesses. */
2fa0b342 534
be1d162b 535 /* Indices in `sorted_syms'. */
ae5d2ff5 536 long min = 0;
be1d162b 537 long max = sorted_symcount;
ae5d2ff5 538 long thisplace;
2fa0b342 539
7fc01fc9
ILT
540 sprintf_vma (buf, vma);
541 (*info->fprintf_func) (info->stream, "%s", buf);
3ae36cb6 542
be1d162b 543 if (sorted_symcount < 1)
f7b839f7
DM
544 return;
545
8f197c94
ILT
546 /* Perform a binary search looking for the closest symbol to the
547 required value. We are searching the range (min, max]. */
548 while (min + 1 < max)
aa0a709a 549 {
f7b839f7 550 asymbol *sym;
8f197c94 551
f7b839f7 552 thisplace = (max + min) / 2;
be1d162b 553 sym = sorted_syms[thisplace];
8f197c94 554
13e4db2e 555 if (bfd_asymbol_value (sym) > vma)
f7b839f7 556 max = thisplace;
13e4db2e 557 else if (bfd_asymbol_value (sym) < vma)
f7b839f7
DM
558 min = thisplace;
559 else
aa0a709a 560 {
8f197c94
ILT
561 min = thisplace;
562 break;
aa0a709a 563 }
f7b839f7 564 }
fc5d6074 565
8f197c94 566 /* The symbol we want is now in min, the low end of the range we
e1c14599
ILT
567 were searching. If there are several symbols with the same
568 value, we want the first one. */
8f197c94 569 thisplace = min;
db552bda
ILT
570 while (thisplace > 0
571 && (bfd_asymbol_value (sorted_syms[thisplace])
572 == bfd_asymbol_value (sorted_syms[thisplace - 1])))
573 --thisplace;
8f197c94 574
f7b839f7
DM
575 {
576 /* If the file is relocateable, and the symbol could be from this
577 section, prefer a symbol from this section over symbols from
578 others, even if the other symbol's value might be closer.
579
580 Note that this may be wrong for some symbol references if the
581 sections have overlapping memory ranges, but in that case there's
582 no way to tell what's desired without looking at the relocation
583 table. */
584 struct objdump_disasm_info *aux;
ae5d2ff5 585 long i;
f7b839f7
DM
586
587 aux = (struct objdump_disasm_info *) info->application_data;
be1d162b 588 if (sorted_syms[thisplace]->section != aux->sec
2d054641
ILT
589 && (aux->require_sec
590 || ((aux->abfd->flags & HAS_RELOC) != 0
591 && vma >= bfd_get_section_vma (aux->abfd, aux->sec)
592 && vma < (bfd_get_section_vma (aux->abfd, aux->sec)
c5ba2759 593 + bfd_section_size (aux->abfd, aux->sec)))))
f7b839f7 594 {
be1d162b 595 for (i = thisplace + 1; i < sorted_symcount; i++)
8f197c94 596 {
be1d162b
ILT
597 if (bfd_asymbol_value (sorted_syms[i])
598 != bfd_asymbol_value (sorted_syms[thisplace]))
28d1b01e 599 break;
8f197c94 600 }
28d1b01e 601 --i;
8f197c94
ILT
602 for (; i >= 0; i--)
603 {
db552bda
ILT
604 if (sorted_syms[i]->section == aux->sec
605 && (i == 0
606 || sorted_syms[i - 1]->section != aux->sec
607 || (bfd_asymbol_value (sorted_syms[i])
608 != bfd_asymbol_value (sorted_syms[i - 1]))))
8f197c94
ILT
609 {
610 thisplace = i;
611 break;
612 }
613 }
2d054641 614
be1d162b 615 if (sorted_syms[thisplace]->section != aux->sec)
2d054641
ILT
616 {
617 /* We didn't find a good symbol with a smaller value.
618 Look for one with a larger value. */
be1d162b 619 for (i = thisplace + 1; i < sorted_symcount; i++)
2d054641 620 {
be1d162b 621 if (sorted_syms[i]->section == aux->sec)
2d054641
ILT
622 {
623 thisplace = i;
624 break;
625 }
626 }
627 }
c5ba2759
ILT
628
629 if (sorted_syms[thisplace]->section != aux->sec
630 && (aux->require_sec
631 || ((aux->abfd->flags & HAS_RELOC) != 0
632 && vma >= bfd_get_section_vma (aux->abfd, aux->sec)
633 && vma < (bfd_get_section_vma (aux->abfd, aux->sec)
634 + bfd_section_size (aux->abfd, aux->sec)))))
635 {
636 bfd_vma secaddr;
637
7fc01fc9
ILT
638 (*info->fprintf_func) (info->stream, " <%s",
639 bfd_get_section_name (aux->abfd, aux->sec));
c5ba2759
ILT
640 secaddr = bfd_get_section_vma (aux->abfd, aux->sec);
641 if (vma < secaddr)
642 {
7fc01fc9
ILT
643 (*info->fprintf_func) (info->stream, "-");
644 objdump_print_value (secaddr - vma, info);
c5ba2759
ILT
645 }
646 else if (vma > secaddr)
647 {
7fc01fc9
ILT
648 (*info->fprintf_func) (info->stream, "+");
649 objdump_print_value (vma - secaddr, info);
c5ba2759 650 }
7fc01fc9 651 (*info->fprintf_func) (info->stream, ">");
c5ba2759
ILT
652 return;
653 }
195d1adf 654 }
f7b839f7 655 }
2d054641 656
7fc01fc9 657 (*info->fprintf_func) (info->stream, " <%s", sorted_syms[thisplace]->name);
be1d162b 658 if (bfd_asymbol_value (sorted_syms[thisplace]) > vma)
f7b839f7 659 {
7fc01fc9 660 (*info->fprintf_func) (info->stream, "-");
c5ba2759 661 objdump_print_value (bfd_asymbol_value (sorted_syms[thisplace]) - vma,
7fc01fc9 662 info);
f7b839f7 663 }
be1d162b 664 else if (vma > bfd_asymbol_value (sorted_syms[thisplace]))
f7b839f7 665 {
7fc01fc9 666 (*info->fprintf_func) (info->stream, "+");
c5ba2759 667 objdump_print_value (vma - bfd_asymbol_value (sorted_syms[thisplace]),
7fc01fc9 668 info);
2fa0b342 669 }
7fc01fc9 670 (*info->fprintf_func) (info->stream, ">");
2fa0b342
DHW
671}
672
be1d162b
ILT
673/* Hold the last function name and the last line number we displayed
674 in a disassembly. */
675
676static char *prev_functionname;
677static unsigned int prev_line;
678
679/* We keep a list of all files that we have seen when doing a
680 dissassembly with source, so that we know how much of the file to
681 display. This can be important for inlined functions. */
682
683struct print_file_list
684{
685 struct print_file_list *next;
686 char *filename;
687 unsigned int line;
688 FILE *f;
689};
690
691static struct print_file_list *print_files;
692
693/* The number of preceding context lines to show when we start
694 displaying a file for the first time. */
695
696#define SHOW_PRECEDING_CONTEXT_LINES (5)
697
698/* Skip ahead to a given line in a file, optionally printing each
699 line. */
700
701static void
702skip_to_line PARAMS ((struct print_file_list *, unsigned int, boolean));
703
704static void
705skip_to_line (p, line, show)
706 struct print_file_list *p;
707 unsigned int line;
708 boolean show;
709{
710 while (p->line < line)
711 {
712 char buf[100];
713
714 if (fgets (buf, sizeof buf, p->f) == NULL)
715 {
716 fclose (p->f);
717 p->f = NULL;
718 break;
719 }
720
721 if (show)
722 printf ("%s", buf);
723
724 if (strchr (buf, '\n') != NULL)
725 ++p->line;
726 }
727}
728
729/* Show the line number, or the source line, in a dissassembly
730 listing. */
731
732static void
733show_line (abfd, section, off)
aa0a709a 734 bfd *abfd;
be1d162b
ILT
735 asection *section;
736 bfd_vma off;
2fa0b342 737{
be1d162b
ILT
738 CONST char *filename;
739 CONST char *functionname;
740 unsigned int line;
2e8adbd7 741
be1d162b
ILT
742 if (! with_line_numbers && ! with_source_code)
743 return;
d20f480f 744
be1d162b
ILT
745 if (! bfd_find_nearest_line (abfd, section, syms, off, &filename,
746 &functionname, &line))
747 return;
aa0a709a 748
be1d162b
ILT
749 if (filename != NULL && *filename == '\0')
750 filename = NULL;
751 if (functionname != NULL && *functionname == '\0')
752 functionname = NULL;
aa0a709a 753
be1d162b 754 if (with_line_numbers)
d5464baa 755 {
be1d162b
ILT
756 if (functionname != NULL
757 && (prev_functionname == NULL
758 || strcmp (functionname, prev_functionname) != 0))
759 printf ("%s():\n", functionname);
760 if (line > 0 && line != prev_line)
761 printf ("%s:%u\n", filename == NULL ? "???" : filename, line);
762 }
763
764 if (with_source_code
765 && filename != NULL
766 && line > 0)
767 {
768 struct print_file_list **pp, *p;
769
770 for (pp = &print_files; *pp != NULL; pp = &(*pp)->next)
771 if (strcmp ((*pp)->filename, filename) == 0)
772 break;
773 p = *pp;
774
775 if (p != NULL)
d5464baa 776 {
be1d162b
ILT
777 if (p != print_files)
778 {
779 int l;
780
781 /* We have reencountered a file name which we saw
782 earlier. This implies that either we are dumping out
783 code from an included file, or the same file was
784 linked in more than once. There are two common cases
785 of an included file: inline functions in a header
786 file, and a bison or flex skeleton file. In the
787 former case we want to just start printing (but we
788 back up a few lines to give context); in the latter
789 case we want to continue from where we left off. I
790 can't think of a good way to distinguish the cases,
791 so I used a heuristic based on the file name. */
792 if (strcmp (p->filename + strlen (p->filename) - 2, ".h") != 0)
793 l = p->line;
794 else
795 {
796 l = line - SHOW_PRECEDING_CONTEXT_LINES;
797 if (l <= 0)
798 l = 1;
799 }
d5464baa 800
be1d162b
ILT
801 if (p->f == NULL)
802 {
803 p->f = fopen (p->filename, "r");
804 p->line = 0;
805 }
806 if (p->f != NULL)
807 skip_to_line (p, l, false);
d5464baa 808
be1d162b
ILT
809 if (print_files->f != NULL)
810 {
811 fclose (print_files->f);
812 print_files->f = NULL;
813 }
814 }
d5464baa 815
be1d162b
ILT
816 if (p->f != NULL)
817 {
818 skip_to_line (p, line, true);
819 *pp = p->next;
820 p->next = print_files;
821 print_files = p;
822 }
823 }
824 else
825 {
826 FILE *f;
d5464baa 827
be1d162b
ILT
828 f = fopen (filename, "r");
829 if (f != NULL)
d5464baa 830 {
be1d162b 831 int l;
d5464baa 832
be1d162b
ILT
833 p = ((struct print_file_list *)
834 xmalloc (sizeof (struct print_file_list)));
835 p->filename = xmalloc (strlen (filename) + 1);
836 strcpy (p->filename, filename);
837 p->line = 0;
838 p->f = f;
839
840 if (print_files != NULL && print_files->f != NULL)
841 {
842 fclose (print_files->f);
843 print_files->f = NULL;
844 }
845 p->next = print_files;
846 print_files = p;
847
848 l = line - SHOW_PRECEDING_CONTEXT_LINES;
849 if (l <= 0)
850 l = 1;
851 skip_to_line (p, l, false);
852 if (p->f != NULL)
853 skip_to_line (p, line, true);
d5464baa
ILT
854 }
855 }
856 }
857
be1d162b
ILT
858 if (functionname != NULL
859 && (prev_functionname == NULL
860 || strcmp (functionname, prev_functionname) != 0))
aa0a709a 861 {
be1d162b
ILT
862 if (prev_functionname != NULL)
863 free (prev_functionname);
864 prev_functionname = xmalloc (strlen (functionname) + 1);
865 strcpy (prev_functionname, functionname);
aa0a709a 866 }
2fa0b342 867
be1d162b
ILT
868 if (line > 0 && line != prev_line)
869 prev_line = line;
870}
871
7fc01fc9
ILT
872/* Pseudo FILE object for strings. */
873typedef struct {
874 char *buffer;
875 char *current;
876} SFILE;
877
878/* sprintf to a "stream" */
879
880#ifdef ANSI_PROTOTYPES
881static int
882objdump_sprintf (SFILE *f, const char *format, ...)
883{
884 int n;
885 va_list args;
886
887 va_start (args, format);
888 vsprintf (f->current, format, args);
889 f->current += n = strlen (f->current);
890 va_end (args);
891 return n;
892}
893#else
894static int
895objdump_sprintf (va_alist)
896 va_dcl
897{
898 int n;
899 SFILE *f;
900 const char *format;
901 va_list args;
902
903 va_start (args);
904 f = va_arg (args, SFILE *);
905 format = va_arg (args, const char *);
906 vsprintf (f->current, format, args);
907 f->current += n = strlen (f->current);
908 va_end (args);
909 return n;
910}
911#endif
912
18f39dfa 913static void
be1d162b
ILT
914disassemble_data (abfd)
915 bfd *abfd;
916{
917 long i;
be1d162b
ILT
918 disassembler_ftype disassemble_fn = 0; /* New style */
919 struct disassemble_info disasm_info;
920 struct objdump_disasm_info aux;
921 asection *section;
922 boolean done_dot = false;
7fc01fc9
ILT
923 char buf[200];
924 SFILE sfile;
be1d162b
ILT
925
926 print_files = NULL;
927 prev_functionname = NULL;
928 prev_line = -1;
929
930 /* We make a copy of syms to sort. We don't want to sort syms
931 because that will screw up the relocs. */
932 sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
933 memcpy (sorted_syms, syms, symcount * sizeof (asymbol *));
934
935 sorted_symcount = remove_useless_symbols (sorted_syms, symcount);
2fa0b342
DHW
936
937 /* Sort the symbols into section and symbol order */
be1d162b 938 qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
2fa0b342 939
4e050e3b 940 INIT_DISASSEMBLE_INFO(disasm_info, stdout, fprintf);
cef35d48
DM
941 disasm_info.application_data = (PTR) &aux;
942 aux.abfd = abfd;
943 disasm_info.print_address_func = objdump_print_address;
944
aa0a709a
SC
945 if (machine != (char *) NULL)
946 {
db552bda 947 const bfd_arch_info_type *info = bfd_scan_arch (machine);
cef35d48 948 if (info == NULL)
aa0a709a
SC
949 {
950 fprintf (stderr, "%s: Can't use supplied machine %s\n",
951 program_name,
952 machine);
953 exit (1);
954 }
955 abfd->arch_info = info;
2fa0b342 956 }
e779a58c 957
18f39dfa
SG
958 if (endian != BFD_ENDIAN_UNKNOWN)
959 {
960 struct bfd_target *xvec;
961
962 xvec = (struct bfd_target *) xmalloc (sizeof (struct bfd_target));
963 memcpy (xvec, abfd->xvec, sizeof (struct bfd_target));
964 xvec->byteorder = endian;
965 abfd->xvec = xvec;
966 }
967
db552bda
ILT
968 disassemble_fn = disassembler (abfd);
969 if (!disassemble_fn)
aa0a709a 970 {
db552bda
ILT
971 fprintf (stderr, "%s: Can't disassemble for architecture %s\n",
972 program_name,
973 bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
974 exit (1);
aa0a709a 975 }
2fa0b342 976
458bbd1f
DE
977 disasm_info.arch = bfd_get_arch (abfd);
978 disasm_info.mach = bfd_get_mach (abfd);
979 if (bfd_big_endian (abfd))
980 disasm_info.endian = BFD_ENDIAN_BIG;
38aa863c 981 else if (bfd_little_endian (abfd))
458bbd1f 982 disasm_info.endian = BFD_ENDIAN_LITTLE;
38aa863c
DE
983 else
984 /* ??? Aborting here seems too drastic. We could default to big or little
985 instead. */
986 disasm_info.endian = BFD_ENDIAN_UNKNOWN;
458bbd1f 987
2fa0b342 988 for (section = abfd->sections;
aa0a709a
SC
989 section != (asection *) NULL;
990 section = section->next)
65cceb78 991 {
cef35d48
DM
992 bfd_byte *data = NULL;
993 bfd_size_type datasize = 0;
be1d162b 994 arelent **relbuf = NULL;
d5464baa
ILT
995 arelent **relpp = NULL;
996 arelent **relppend = NULL;
aa21a2a9 997 long stop;
2fa0b342 998
d5464baa
ILT
999 if ((section->flags & SEC_LOAD) == 0
1000 || (! disassemble_all
1001 && only == NULL
1002 && (section->flags & SEC_CODE) == 0))
cef35d48
DM
1003 continue;
1004 if (only != (char *) NULL && strcmp (only, section->name) != 0)
1005 continue;
2fa0b342 1006
d5464baa
ILT
1007 if (dump_reloc_info
1008 && (section->flags & SEC_RELOC) != 0)
1009 {
be1d162b
ILT
1010 long relsize;
1011
1012 relsize = bfd_get_reloc_upper_bound (abfd, section);
1013 if (relsize < 0)
1014 bfd_fatal (bfd_get_filename (abfd));
1015
1016 if (relsize > 0)
1017 {
1018 long relcount;
1019
1020 relbuf = (arelent **) xmalloc (relsize);
1021 relcount = bfd_canonicalize_reloc (abfd, section, relbuf, syms);
1022 if (relcount < 0)
1023 bfd_fatal (bfd_get_filename (abfd));
1024
1025 /* Sort the relocs by address. */
1026 qsort (relbuf, relcount, sizeof (arelent *), compare_relocs);
1027
1028 relpp = relbuf;
1029 relppend = relpp + relcount;
1030 }
d5464baa
ILT
1031 }
1032
cef35d48 1033 printf ("Disassembly of section %s:\n", section->name);
2fa0b342 1034
cef35d48
DM
1035 datasize = bfd_get_section_size_before_reloc (section);
1036 if (datasize == 0)
1037 continue;
2fa0b342 1038
cef35d48 1039 data = (bfd_byte *) xmalloc ((size_t) datasize);
2fa0b342 1040
cef35d48 1041 bfd_get_section_contents (abfd, section, data, 0, datasize);
2fa0b342 1042
cef35d48
DM
1043 aux.sec = section;
1044 disasm_info.buffer = data;
1045 disasm_info.buffer_vma = section->vma;
1046 disasm_info.buffer_length = datasize;
aa21a2a9
ILT
1047 if (start_address == (bfd_vma) -1
1048 || start_address < disasm_info.buffer_vma)
1049 i = 0;
1050 else
1051 i = start_address - disasm_info.buffer_vma;
1052 if (stop_address == (bfd_vma) -1)
1053 stop = datasize;
1054 else
1055 {
1056 if (stop_address < disasm_info.buffer_vma)
1057 stop = 0;
1058 else
1059 stop = stop_address - disasm_info.buffer_vma;
1060 if (stop > disasm_info.buffer_length)
1061 stop = disasm_info.buffer_length;
1062 }
1063 while (i < stop)
cef35d48 1064 {
d5464baa 1065 int bytes;
13e4db2e 1066 boolean need_nl = false;
d5464baa 1067
18f39dfa
SG
1068 if (data[i] == 0
1069 && (i + 1 >= stop
1070 || (data[i + 1] == 0
1071 && (i + 2 >= stop
1072 || (data[i + 2] == 0
1073 && (i + 3 >= stop
1074 || data[i + 3] == 0))))))
aa0a709a 1075 {
cef35d48 1076 if (done_dot == false)
aa0a709a 1077 {
cef35d48
DM
1078 printf ("...\n");
1079 done_dot = true;
65cceb78 1080 }
d5464baa 1081 bytes = 4;
cef35d48
DM
1082 }
1083 else
1084 {
1085 done_dot = false;
be1d162b
ILT
1086 if (with_line_numbers || with_source_code)
1087 show_line (abfd, section, i);
8b129785 1088 aux.require_sec = true;
cef35d48 1089 objdump_print_address (section->vma + i, &disasm_info);
8b129785 1090 aux.require_sec = false;
cef35d48 1091 putchar (' ');
65cceb78 1092
7fc01fc9
ILT
1093 sfile.buffer = sfile.current = buf;
1094 disasm_info.fprintf_func = (fprintf_ftype) objdump_sprintf;
1095 disasm_info.stream = (FILE *) &sfile;
db552bda 1096 bytes = (*disassemble_fn) (section->vma + i, &disasm_info);
7fc01fc9
ILT
1097 disasm_info.fprintf_func = (fprintf_ftype) fprintf;
1098 disasm_info.stream = stdout;
db552bda
ILT
1099 if (bytes < 0)
1100 break;
1101
7fc01fc9
ILT
1102 if (show_raw_insn)
1103 {
1104 long j;
1105 for (j = i; j < i + bytes; ++j)
1106 {
1107 printf ("%02x", (unsigned) data[j]);
1108 putchar (' ');
1109 }
1110 /* Separate raw data from instruction by extra space. */
1111 putchar (' ');
1112 }
1113
1114 printf ("%s", sfile.buffer);
1115
13e4db2e
SC
1116 if (!wide_output)
1117 putchar ('\n');
1118 else
1119 need_nl = true;
96d7950b 1120 }
d5464baa
ILT
1121
1122 if (dump_reloc_info
1123 && (section->flags & SEC_RELOC) != 0)
1124 {
1125 while (relpp < relppend
746cffcf
ILT
1126 && ((*relpp)->address >= (bfd_vma) i
1127 && (*relpp)->address < (bfd_vma) i + bytes))
d5464baa
ILT
1128 {
1129 arelent *q;
1130 const char *sym_name;
1131
1132 q = *relpp;
1133
1134 printf ("\t\tRELOC: ");
1135
1136 printf_vma (section->vma + q->address);
1137
1138 printf (" %s ", q->howto->name);
1139
1140 if (q->sym_ptr_ptr != NULL
1141 && *q->sym_ptr_ptr != NULL)
1142 {
1143 sym_name = bfd_asymbol_name (*q->sym_ptr_ptr);
1144 if (sym_name == NULL || *sym_name == '\0')
1145 {
1146 asection *sym_sec;
1147
1148 sym_sec = bfd_get_section (*q->sym_ptr_ptr);
1149 sym_name = bfd_get_section_name (abfd, sym_sec);
1150 if (sym_name == NULL || *sym_name == '\0')
1151 sym_name = "*unknown*";
1152 }
1153 }
38d7c012
ILT
1154 else
1155 sym_name = "*unknown*";
d5464baa
ILT
1156
1157 printf ("%s", sym_name);
1158
1159 if (q->addend)
1160 {
1161 printf ("+0x");
1162 printf_vma (q->addend);
1163 }
1164
1165 printf ("\n");
13e4db2e 1166 need_nl = false;
d5464baa
ILT
1167 ++relpp;
1168 }
1169 }
1170
13e4db2e
SC
1171 if (need_nl)
1172 printf ("\n");
1173
d5464baa 1174 i += bytes;
96d7950b 1175 }
be1d162b 1176
cef35d48 1177 free (data);
be1d162b
ILT
1178 if (relbuf != NULL)
1179 free (relbuf);
2fa0b342 1180 }
c5ba2759 1181 free (sorted_syms);
2fa0b342 1182}
73b8f102 1183\f
73b8f102
JG
1184
1185/* Define a table of stab values and print-strings. We wish the initializer
1186 could be a direct-mapped table, but instead we build one the first
1187 time we need it. */
1188
18f39dfa
SG
1189static void dump_section_stabs PARAMS ((bfd *abfd, char *stabsect_name,
1190 char *strsect_name));
249c6fc0 1191
250e36fe 1192/* Dump the stabs sections from an object file that has a section that
18f39dfa 1193 uses Sun stabs encoding. */
73b8f102 1194
18f39dfa 1195static void
9b018ecd 1196dump_stabs (abfd)
73b8f102
JG
1197 bfd *abfd;
1198{
250e36fe
DM
1199 dump_section_stabs (abfd, ".stab", ".stabstr");
1200 dump_section_stabs (abfd, ".stab.excl", ".stab.exclstr");
1201 dump_section_stabs (abfd, ".stab.index", ".stab.indexstr");
1202 dump_section_stabs (abfd, "$GDB_SYMBOLS$", "$GDB_STRINGS$");
249c6fc0
RS
1203}
1204
18f39dfa 1205static bfd_byte *stabs;
250e36fe
DM
1206static bfd_size_type stab_size;
1207
1208static char *strtab;
1209static bfd_size_type stabstr_size;
1210
1211/* Read ABFD's stabs section STABSECT_NAME into `stabs'
1212 and string table section STRSECT_NAME into `strtab'.
1213 If the section exists and was read, allocate the space and return true.
1214 Otherwise return false. */
1215
18f39dfa 1216static boolean
250e36fe 1217read_section_stabs (abfd, stabsect_name, strsect_name)
249c6fc0 1218 bfd *abfd;
250e36fe
DM
1219 char *stabsect_name;
1220 char *strsect_name;
249c6fc0 1221{
9b018ecd 1222 asection *stabsect, *stabstrsect;
9b018ecd 1223
d5671c53
ILT
1224 stabsect = bfd_get_section_by_name (abfd, stabsect_name);
1225 if (0 == stabsect)
73b8f102 1226 {
250e36fe
DM
1227 printf ("No %s section present\n\n", stabsect_name);
1228 return false;
73b8f102
JG
1229 }
1230
d5671c53
ILT
1231 stabstrsect = bfd_get_section_by_name (abfd, strsect_name);
1232 if (0 == stabstrsect)
73b8f102 1233 {
eae82145 1234 fprintf (stderr, "%s: %s has no %s section\n", program_name,
250e36fe
DM
1235 bfd_get_filename (abfd), strsect_name);
1236 return false;
73b8f102 1237 }
9b018ecd 1238
d5671c53
ILT
1239 stab_size = bfd_section_size (abfd, stabsect);
1240 stabstr_size = bfd_section_size (abfd, stabstrsect);
73b8f102 1241
18f39dfa 1242 stabs = (bfd_byte *) xmalloc (stab_size);
9b018ecd 1243 strtab = (char *) xmalloc (stabstr_size);
73b8f102 1244
d5671c53 1245 if (! bfd_get_section_contents (abfd, stabsect, (PTR) stabs, 0, stab_size))
9b018ecd 1246 {
d5671c53
ILT
1247 fprintf (stderr, "%s: Reading %s section of %s failed: %s\n",
1248 program_name, stabsect_name, bfd_get_filename (abfd),
1249 bfd_errmsg (bfd_get_error ()));
1250 free (stabs);
1251 free (strtab);
1252 return false;
73b8f102 1253 }
2fa0b342 1254
d5671c53
ILT
1255 if (! bfd_get_section_contents (abfd, stabstrsect, (PTR) strtab, 0,
1256 stabstr_size))
9b018ecd 1257 {
d5671c53
ILT
1258 fprintf (stderr, "%s: Reading %s section of %s failed: %s\n",
1259 program_name, strsect_name, bfd_get_filename (abfd),
1260 bfd_errmsg (bfd_get_error ()));
1261 free (stabs);
1262 free (strtab);
1263 return false;
73b8f102 1264 }
d5671c53 1265
250e36fe
DM
1266 return true;
1267}
73b8f102 1268
18f39dfa
SG
1269/* Stabs entries use a 12 byte format:
1270 4 byte string table index
1271 1 byte stab type
1272 1 byte stab other field
1273 2 byte stab desc field
1274 4 byte stab value
1275 FIXME: This will have to change for a 64 bit object format. */
1276
1277#define STRDXOFF (0)
1278#define TYPEOFF (4)
1279#define OTHEROFF (5)
1280#define DESCOFF (6)
1281#define VALOFF (8)
1282#define STABSIZE (12)
73b8f102 1283
250e36fe
DM
1284/* Print ABFD's stabs section STABSECT_NAME (in `stabs'),
1285 using string table section STRSECT_NAME (in `strtab'). */
1286
18f39dfa 1287static void
250e36fe
DM
1288print_section_stabs (abfd, stabsect_name, strsect_name)
1289 bfd *abfd;
1290 char *stabsect_name;
1291 char *strsect_name;
1292{
1293 int i;
1294 unsigned file_string_table_offset = 0, next_file_string_table_offset = 0;
18f39dfa
SG
1295 bfd_byte *stabp, *stabs_end;
1296
1297 stabp = stabs;
1298 stabs_end = stabp + stab_size;
73b8f102 1299
250e36fe
DM
1300 printf ("Contents of %s section:\n\n", stabsect_name);
1301 printf ("Symnum n_type n_othr n_desc n_value n_strx String\n");
249c6fc0
RS
1302
1303 /* Loop through all symbols and print them.
1304
1305 We start the index at -1 because there is a dummy symbol on
250e36fe 1306 the front of stabs-in-{coff,elf} sections that supplies sizes. */
249c6fc0 1307
18f39dfa 1308 for (i = -1; stabp < stabs_end; stabp += STABSIZE, i++)
73b8f102 1309 {
7fc01fc9 1310 const char *name;
18f39dfa
SG
1311 unsigned long strx;
1312 unsigned char type, other;
1313 unsigned short desc;
1314 bfd_vma value;
1315
1316 strx = bfd_h_get_32 (abfd, stabp + STRDXOFF);
1317 type = bfd_h_get_8 (abfd, stabp + TYPEOFF);
1318 other = bfd_h_get_8 (abfd, stabp + OTHEROFF);
1319 desc = bfd_h_get_16 (abfd, stabp + DESCOFF);
1320 value = bfd_h_get_32 (abfd, stabp + VALOFF);
7fc01fc9 1321
fe2750e1 1322 printf ("\n%-6d ", i);
250e36fe 1323 /* Either print the stab name, or, if unnamed, print its number
fe2750e1 1324 again (makes consistent formatting for tools like awk). */
18f39dfa 1325 name = bfd_get_stab_name (type);
7fc01fc9
ILT
1326 if (name != NULL)
1327 printf ("%-6s", name);
18f39dfa 1328 else if (type == N_UNDF)
105da05c 1329 printf ("HdrSym");
fe2750e1 1330 else
18f39dfa
SG
1331 printf ("%-6d", type);
1332 printf (" %-6d %-6d ", other, desc);
1333 printf_vma (value);
1334 printf (" %-6lu", strx);
249c6fc0
RS
1335
1336 /* Symbols with type == 0 (N_UNDF) specify the length of the
1337 string table associated with this file. We use that info
1338 to know how to relocate the *next* file's string table indices. */
1339
18f39dfa 1340 if (type == N_UNDF)
249c6fc0
RS
1341 {
1342 file_string_table_offset = next_file_string_table_offset;
18f39dfa 1343 next_file_string_table_offset += value;
249c6fc0 1344 }
249c6fc0 1345 else
e1ec9f07 1346 {
250e36fe 1347 /* Using the (possibly updated) string table offset, print the
e1ec9f07
SS
1348 string (if any) associated with this symbol. */
1349
18f39dfa
SG
1350 if ((strx + file_string_table_offset) < stabstr_size)
1351 printf (" %s", &strtab[strx + file_string_table_offset]);
e1ec9f07
SS
1352 else
1353 printf (" *");
1354 }
73b8f102
JG
1355 }
1356 printf ("\n\n");
1357}
249c6fc0 1358
18f39dfa 1359static void
250e36fe
DM
1360dump_section_stabs (abfd, stabsect_name, strsect_name)
1361 bfd *abfd;
1362 char *stabsect_name;
1363 char *strsect_name;
1364{
13e4db2e 1365 asection *s;
13e4db2e 1366
a65619c8
SC
1367 /* Check for section names for which stabsect_name is a prefix, to
1368 handle .stab0, etc. */
13e4db2e 1369 for (s = abfd->sections;
a65619c8 1370 s != NULL;
13e4db2e
SC
1371 s = s->next)
1372 {
18f39dfa
SG
1373 int len;
1374
1375 len = strlen (stabsect_name);
1376
1377/* If the prefix matches, and the files section name ends with a nul or a digit,
1378 then we match. Ie: we want either an exact match or a a section followed by
1379 a number. */
1380 if (strncmp (stabsect_name, s->name, len) == 0
1381 && (s->name[len] == '\000' || isdigit (s->name[len])))
13e4db2e 1382 {
a65619c8
SC
1383 if (read_section_stabs (abfd, s->name, strsect_name))
1384 {
1385 print_section_stabs (abfd, s->name, strsect_name);
1386 free (stabs);
1387 free (strtab);
1388 }
13e4db2e
SC
1389 }
1390 }
250e36fe
DM
1391}
1392\f
eae82145 1393static void
f7b839f7
DM
1394dump_bfd_header (abfd)
1395 bfd *abfd;
1396{
1397 char *comma = "";
1398
1399 printf ("architecture: %s, ",
1400 bfd_printable_arch_mach (bfd_get_arch (abfd),
1401 bfd_get_mach (abfd)));
1402 printf ("flags 0x%08x:\n", abfd->flags);
1403
1404#define PF(x, y) if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
1405 PF (HAS_RELOC, "HAS_RELOC");
1406 PF (EXEC_P, "EXEC_P");
1407 PF (HAS_LINENO, "HAS_LINENO");
1408 PF (HAS_DEBUG, "HAS_DEBUG");
1409 PF (HAS_SYMS, "HAS_SYMS");
1410 PF (HAS_LOCALS, "HAS_LOCALS");
1411 PF (DYNAMIC, "DYNAMIC");
1412 PF (WP_TEXT, "WP_TEXT");
1413 PF (D_PAGED, "D_PAGED");
1414 PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
1415 printf ("\nstart address 0x");
1416 printf_vma (abfd->start_address);
38d7c012 1417 printf ("\n");
f7b839f7 1418}
a65619c8
SC
1419\f
1420static void
1421dump_bfd_private_header (abfd)
1422bfd *abfd;
1423{
1424 bfd_print_private_bfd_data (abfd, stdout);
1425}
18f39dfa 1426
02a68547 1427static void
2fa0b342
DHW
1428display_bfd (abfd)
1429 bfd *abfd;
1430{
209e5610
DM
1431 char **matching;
1432
1433 if (!bfd_check_format_matches (abfd, bfd_object, &matching))
aa0a709a 1434 {
cef35d48 1435 bfd_nonfatal (bfd_get_filename (abfd));
8f197c94 1436 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
209e5610
DM
1437 {
1438 list_matching_formats (matching);
1439 free (matching);
1440 }
aa0a709a
SC
1441 return;
1442 }
f7b839f7 1443
cef35d48
DM
1444 printf ("\n%s: file format %s\n", bfd_get_filename (abfd),
1445 abfd->xvec->name);
aa0a709a
SC
1446 if (dump_ar_hdrs)
1447 print_arelt_descr (stdout, abfd, true);
aa0a709a 1448 if (dump_file_header)
f7b839f7 1449 dump_bfd_header (abfd);
a65619c8
SC
1450 if (dump_private_headers)
1451 dump_bfd_private_header (abfd);
f7b839f7 1452 putchar ('\n');
2fa0b342 1453 if (dump_section_headers)
aa0a709a 1454 dump_headers (abfd);
83f4323e 1455 if (dump_symtab || dump_reloc_info || disassemble || dump_debugging)
aa0a709a
SC
1456 {
1457 syms = slurp_symtab (abfd);
1458 }
de3b08ac
ILT
1459 if (dump_dynamic_symtab || dump_dynamic_reloc_info)
1460 {
1461 dynsyms = slurp_dynamic_symtab (abfd);
1462 }
aa0a709a 1463 if (dump_symtab)
de3b08ac
ILT
1464 dump_symbols (abfd, false);
1465 if (dump_dynamic_symtab)
1466 dump_symbols (abfd, true);
73b8f102 1467 if (dump_stab_section_info)
9b018ecd 1468 dump_stabs (abfd);
d5464baa 1469 if (dump_reloc_info && ! disassemble)
aa0a709a 1470 dump_relocs (abfd);
de3b08ac
ILT
1471 if (dump_dynamic_reloc_info)
1472 dump_dynamic_relocs (abfd);
aa0a709a
SC
1473 if (dump_section_contents)
1474 dump_data (abfd);
1475 if (disassemble)
1476 disassemble_data (abfd);
e1c14599
ILT
1477 if (dump_debugging)
1478 {
1479 PTR dhandle;
1480
83f4323e 1481 dhandle = read_debugging_info (abfd, syms, symcount);
e1c14599
ILT
1482 if (dhandle != NULL)
1483 {
1484 if (! print_debugging_info (stdout, dhandle))
1485 fprintf (stderr, "%s: printing debugging information failed\n",
1486 bfd_get_filename (abfd));
1487 }
1488 }
c5ba2759
ILT
1489 if (syms)
1490 {
1491 free (syms);
1492 syms = NULL;
1493 }
1494 if (dynsyms)
1495 {
1496 free (dynsyms);
1497 dynsyms = NULL;
1498 }
2fa0b342
DHW
1499}
1500
d9971b83 1501static void
2fa0b342
DHW
1502display_file (filename, target)
1503 char *filename;
1504 char *target;
1505{
1506 bfd *file, *arfile = (bfd *) NULL;
1507
1508 file = bfd_openr (filename, target);
aa0a709a
SC
1509 if (file == NULL)
1510 {
cef35d48 1511 bfd_nonfatal (filename);
aa0a709a
SC
1512 return;
1513 }
2fa0b342 1514
aa0a709a
SC
1515 if (bfd_check_format (file, bfd_archive) == true)
1516 {
8f197c94
ILT
1517 bfd *last_arfile = NULL;
1518
aa0a709a
SC
1519 printf ("In archive %s:\n", bfd_get_filename (file));
1520 for (;;)
1521 {
8f197c94 1522 bfd_set_error (bfd_error_no_error);
aa0a709a
SC
1523
1524 arfile = bfd_openr_next_archived_file (file, arfile);
1525 if (arfile == NULL)
1526 {
8f197c94 1527 if (bfd_get_error () != bfd_error_no_more_archived_files)
d2442698 1528 {
cef35d48 1529 bfd_nonfatal (bfd_get_filename (file));
d2442698 1530 }
8f197c94 1531 break;
aa0a709a 1532 }
2fa0b342 1533
aa0a709a 1534 display_bfd (arfile);
8f197c94
ILT
1535
1536 if (last_arfile != NULL)
1537 bfd_close (last_arfile);
1538 last_arfile = arfile;
aa0a709a 1539 }
8f197c94
ILT
1540
1541 if (last_arfile != NULL)
1542 bfd_close (last_arfile);
2fa0b342 1543 }
2fa0b342 1544 else
aa0a709a 1545 display_bfd (file);
2fa0b342 1546
aa0a709a 1547 bfd_close (file);
2fa0b342
DHW
1548}
1549\f
1550/* Actually display the various requested regions */
1551
d9971b83 1552static void
2fa0b342
DHW
1553dump_data (abfd)
1554 bfd *abfd;
1555{
1556 asection *section;
aa0a709a 1557 bfd_byte *data = 0;
fc5d6074
SC
1558 bfd_size_type datasize = 0;
1559 bfd_size_type i;
aa21a2a9 1560 bfd_size_type start, stop;
2fa0b342
DHW
1561
1562 for (section = abfd->sections; section != NULL; section =
aa0a709a
SC
1563 section->next)
1564 {
1565 int onaline = 16;
2fa0b342 1566
aa0a709a
SC
1567 if (only == (char *) NULL ||
1568 strcmp (only, section->name) == 0)
60c80016 1569 {
aa0a709a
SC
1570 if (section->flags & SEC_HAS_CONTENTS)
1571 {
1572 printf ("Contents of section %s:\n", section->name);
1573
9b018ecd 1574 if (bfd_section_size (abfd, section) == 0)
aa0a709a 1575 continue;
02a68547 1576 data = (bfd_byte *) xmalloc ((size_t) bfd_section_size (abfd, section));
9b018ecd 1577 datasize = bfd_section_size (abfd, section);
2fa0b342 1578
2fa0b342 1579
9b018ecd 1580 bfd_get_section_contents (abfd, section, (PTR) data, 0, bfd_section_size (abfd, section));
2fa0b342 1581
aa21a2a9
ILT
1582 if (start_address == (bfd_vma) -1
1583 || start_address < section->vma)
1584 start = 0;
1585 else
1586 start = start_address - section->vma;
1587 if (stop_address == (bfd_vma) -1)
1588 stop = bfd_section_size (abfd, section);
1589 else
1590 {
1591 if (stop_address < section->vma)
1592 stop = 0;
1593 else
1594 stop = stop_address - section->vma;
1595 if (stop > bfd_section_size (abfd, section))
1596 stop = bfd_section_size (abfd, section);
1597 }
1598 for (i = start; i < stop; i += onaline)
aa0a709a
SC
1599 {
1600 bfd_size_type j;
1601
1602 printf (" %04lx ", (unsigned long int) (i + section->vma));
1603 for (j = i; j < i + onaline; j++)
1604 {
aa21a2a9 1605 if (j < stop)
aa0a709a
SC
1606 printf ("%02x", (unsigned) (data[j]));
1607 else
1608 printf (" ");
1609 if ((j & 3) == 3)
1610 printf (" ");
1611 }
2fa0b342 1612
aa0a709a
SC
1613 printf (" ");
1614 for (j = i; j < i + onaline; j++)
1615 {
aa21a2a9 1616 if (j >= stop)
aa0a709a
SC
1617 printf (" ");
1618 else
1619 printf ("%c", isprint (data[j]) ? data[j] : '.');
1620 }
1621 putchar ('\n');
1622 }
d9971b83 1623 free (data);
60c80016 1624 }
2fa0b342 1625 }
2fa0b342 1626 }
2fa0b342
DHW
1627}
1628
2fa0b342 1629/* Should perhaps share code and display with nm? */
d9971b83 1630static void
de3b08ac 1631dump_symbols (abfd, dynamic)
2fa0b342 1632 bfd *abfd;
de3b08ac 1633 boolean dynamic;
2fa0b342 1634{
de3b08ac
ILT
1635 asymbol **current;
1636 long max;
ae5d2ff5 1637 long count;
2fa0b342 1638
de3b08ac 1639 if (dynamic)
aa0a709a 1640 {
de3b08ac
ILT
1641 current = dynsyms;
1642 max = dynsymcount;
1643 if (max == 0)
1644 return;
1645 printf ("DYNAMIC SYMBOL TABLE:\n");
1646 }
1647 else
1648 {
1649 current = syms;
1650 max = symcount;
1651 if (max == 0)
1652 return;
1653 printf ("SYMBOL TABLE:\n");
1654 }
2fa0b342 1655
de3b08ac
ILT
1656 for (count = 0; count < max; count++)
1657 {
d9971b83 1658 if (*current)
aa0a709a 1659 {
d9971b83
KR
1660 bfd *cur_bfd = bfd_asymbol_bfd(*current);
1661 if (cur_bfd)
1662 {
1663 bfd_print_symbol (cur_bfd,
1664 stdout,
1665 *current, bfd_print_symbol_all);
1666 printf ("\n");
1667 }
aa0a709a
SC
1668 }
1669 current++;
2fa0b342 1670 }
aa0a709a
SC
1671 printf ("\n");
1672 printf ("\n");
2fa0b342
DHW
1673}
1674
d9971b83 1675static void
aa0a709a
SC
1676dump_relocs (abfd)
1677 bfd *abfd;
2fa0b342
DHW
1678{
1679 arelent **relpp;
ae5d2ff5 1680 long relcount;
2fa0b342 1681 asection *a;
aa0a709a
SC
1682
1683 for (a = abfd->sections; a != (asection *) NULL; a = a->next)
1684 {
ae5d2ff5
ILT
1685 long relsize;
1686
28d1b01e 1687 if (bfd_is_abs_section (a))
aa0a709a 1688 continue;
28d1b01e 1689 if (bfd_is_und_section (a))
aa0a709a 1690 continue;
d9971b83 1691 if (bfd_is_com_section (a))
aa0a709a
SC
1692 continue;
1693
195d1adf
KR
1694 if (only)
1695 {
1696 if (strcmp (only, a->name))
1697 continue;
1698 }
1699 else if ((a->flags & SEC_RELOC) == 0)
1700 continue;
1701
ae5d2ff5
ILT
1702 relsize = bfd_get_reloc_upper_bound (abfd, a);
1703 if (relsize < 0)
1704 bfd_fatal (bfd_get_filename (abfd));
1705
c5ba2759
ILT
1706 printf ("RELOCATION RECORDS FOR [%s]:", a->name);
1707
ae5d2ff5 1708 if (relsize == 0)
aa0a709a
SC
1709 {
1710 printf (" (none)\n\n");
d20f480f 1711 }
aa0a709a
SC
1712 else
1713 {
ae5d2ff5 1714 relpp = (arelent **) xmalloc (relsize);
aa0a709a 1715 relcount = bfd_canonicalize_reloc (abfd, a, relpp, syms);
ae5d2ff5
ILT
1716 if (relcount < 0)
1717 bfd_fatal (bfd_get_filename (abfd));
1718 else if (relcount == 0)
aa0a709a
SC
1719 {
1720 printf (" (none)\n\n");
d20f480f 1721 }
aa0a709a
SC
1722 else
1723 {
1724 printf ("\n");
18f39dfa 1725 dump_reloc_set (abfd, a, relpp, relcount);
aa0a709a 1726 printf ("\n\n");
d20f480f 1727 }
de3b08ac 1728 free (relpp);
2fa0b342 1729 }
de3b08ac
ILT
1730 }
1731}
2fa0b342 1732
de3b08ac
ILT
1733static void
1734dump_dynamic_relocs (abfd)
1735 bfd *abfd;
1736{
1737 long relsize;
1738 arelent **relpp;
1739 long relcount;
1740
de3b08ac
ILT
1741 relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
1742 if (relsize < 0)
1743 bfd_fatal (bfd_get_filename (abfd));
1744
c5ba2759
ILT
1745 printf ("DYNAMIC RELOCATION RECORDS");
1746
de3b08ac
ILT
1747 if (relsize == 0)
1748 {
1749 printf (" (none)\n\n");
1750 }
1751 else
1752 {
1753 relpp = (arelent **) xmalloc (relsize);
1754 relcount = bfd_canonicalize_dynamic_reloc (abfd, relpp, dynsyms);
1755 if (relcount < 0)
1756 bfd_fatal (bfd_get_filename (abfd));
1757 else if (relcount == 0)
1758 {
1759 printf (" (none)\n\n");
1760 }
1761 else
1762 {
1763 printf ("\n");
18f39dfa 1764 dump_reloc_set (abfd, (asection *) NULL, relpp, relcount);
de3b08ac
ILT
1765 printf ("\n\n");
1766 }
1767 free (relpp);
1768 }
1769}
1770
1771static void
18f39dfa 1772dump_reloc_set (abfd, sec, relpp, relcount)
de3b08ac 1773 bfd *abfd;
18f39dfa 1774 asection *sec;
de3b08ac
ILT
1775 arelent **relpp;
1776 long relcount;
1777{
1778 arelent **p;
18f39dfa
SG
1779 char *last_filename, *last_functionname;
1780 unsigned int last_line;
de3b08ac
ILT
1781
1782 /* Get column headers lined up reasonably. */
1783 {
1784 static int width;
1785 if (width == 0)
1786 {
1787 char buf[30];
1788 sprintf_vma (buf, (bfd_vma) -1);
1789 width = strlen (buf) - 7;
1790 }
1791 printf ("OFFSET %*s TYPE %*s VALUE \n", width, "", 12, "");
1792 }
1793
18f39dfa
SG
1794 last_filename = NULL;
1795 last_functionname = NULL;
1796 last_line = 0;
1797
de3b08ac
ILT
1798 for (p = relpp; relcount && *p != (arelent *) NULL; p++, relcount--)
1799 {
1800 arelent *q = *p;
18f39dfa
SG
1801 const char *filename, *functionname;
1802 unsigned int line;
1803 const char *sym_name;
1804 const char *section_name;
de3b08ac 1805
aa21a2a9
ILT
1806 if (start_address != (bfd_vma) -1
1807 && q->address < start_address)
1808 continue;
1809 if (stop_address != (bfd_vma) -1
1810 && q->address > stop_address)
1811 continue;
1812
18f39dfa
SG
1813 if (with_line_numbers
1814 && sec != NULL
1815 && bfd_find_nearest_line (abfd, sec, syms, q->address,
1816 &filename, &functionname, &line))
1817 {
1818 if (functionname != NULL
1819 && (last_functionname == NULL
1820 || strcmp (functionname, last_functionname) != 0))
1821 {
1822 printf ("%s():\n", functionname);
1823 if (last_functionname != NULL)
1824 free (last_functionname);
1825 last_functionname = xstrdup (functionname);
1826 }
1827 if (line > 0
1828 && (line != last_line
1829 || (filename != NULL
1830 && last_filename != NULL
1831 && strcmp (filename, last_filename) != 0)))
1832 {
1833 printf ("%s:%u\n", filename == NULL ? "???" : filename, line);
1834 last_line = line;
1835 if (last_filename != NULL)
1836 free (last_filename);
1837 if (filename == NULL)
1838 last_filename = NULL;
1839 else
1840 last_filename = xstrdup (filename);
1841 }
1842 }
1843
de3b08ac
ILT
1844 if (q->sym_ptr_ptr && *q->sym_ptr_ptr)
1845 {
1846 sym_name = (*(q->sym_ptr_ptr))->name;
1847 section_name = (*(q->sym_ptr_ptr))->section->name;
1848 }
1849 else
1850 {
1851 sym_name = NULL;
1852 section_name = NULL;
1853 }
1854 if (sym_name)
1855 {
1856 printf_vma (q->address);
1857 printf (" %-16s %s",
1858 q->howto->name,
1859 sym_name);
1860 }
1861 else
1862 {
1863 if (section_name == (CONST char *) NULL)
1864 section_name = "*unknown*";
1865 printf_vma (q->address);
1866 printf (" %-16s [%s]",
1867 q->howto->name,
1868 section_name);
1869 }
1870 if (q->addend)
1871 {
1872 printf ("+0x");
1873 printf_vma (q->addend);
1874 }
1875 printf ("\n");
d20f480f 1876 }
2fa0b342 1877}
f7b839f7 1878\f
f7b839f7
DM
1879/* The length of the longest architecture name + 1. */
1880#define LONGEST_ARCH sizeof("rs6000:6000")
1881
be1d162b
ILT
1882#ifndef L_tmpnam
1883#define L_tmpnam 25
1884#endif
1885
e1c14599
ILT
1886static const char *
1887endian_string (endian)
1888 enum bfd_endian endian;
1889{
1890 if (endian == BFD_ENDIAN_BIG)
1891 return "big endian";
1892 else if (endian == BFD_ENDIAN_LITTLE)
1893 return "little endian";
1894 else
1895 return "endianness unknown";
1896}
1897
f7b839f7
DM
1898/* List the targets that BFD is configured to support, each followed
1899 by its endianness and the architectures it supports. */
1900
1901static void
1902display_target_list ()
1903{
de04bceb 1904 extern char *tmpnam ();
f7b839f7 1905 extern bfd_target *bfd_target_vector[];
be1d162b 1906 char tmparg[L_tmpnam];
de04bceb 1907 char *dummy_name;
f7b839f7
DM
1908 int t;
1909
be1d162b 1910 dummy_name = tmpnam (tmparg);
f7b839f7
DM
1911 for (t = 0; bfd_target_vector[t]; t++)
1912 {
f7b839f7 1913 bfd_target *p = bfd_target_vector[t];
de04bceb 1914 bfd *abfd = bfd_openw (dummy_name, p->name);
105da05c
ILT
1915 int a;
1916
1917 printf ("%s\n (header %s, data %s)\n", p->name,
e1c14599
ILT
1918 endian_string (p->header_byteorder),
1919 endian_string (p->byteorder));
f7b839f7 1920
334d6e76
SS
1921 if (abfd == NULL)
1922 {
de04bceb 1923 bfd_nonfatal (dummy_name);
105da05c 1924 continue;
334d6e76 1925 }
105da05c
ILT
1926
1927 if (! bfd_set_format (abfd, bfd_object))
1928 {
1929 if (bfd_get_error () != bfd_error_invalid_operation)
1930 bfd_nonfatal (p->name);
1931 continue;
1932 }
1933
f7b839f7
DM
1934 for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
1935 if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
1936 printf (" %s\n",
1937 bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
1938 }
de04bceb 1939 unlink (dummy_name);
f7b839f7
DM
1940}
1941
1942/* Print a table showing which architectures are supported for entries
1943 FIRST through LAST-1 of bfd_target_vector (targets across,
1944 architectures down). */
1945
9872a49c 1946static void
abdcac0f
DM
1947display_info_table (first, last)
1948 int first;
1949 int last;
9872a49c 1950{
abdcac0f 1951 extern bfd_target *bfd_target_vector[];
de04bceb 1952 extern char *tmpnam ();
be1d162b 1953 char tmparg[L_tmpnam];
de04bceb
ILT
1954 int t, a;
1955 char *dummy_name;
9872a49c 1956
f7b839f7 1957 /* Print heading of target names. */
ae5d2ff5 1958 printf ("\n%*s", (int) LONGEST_ARCH, " ");
105da05c 1959 for (t = first; t < last && bfd_target_vector[t]; t++)
f7b839f7
DM
1960 printf ("%s ", bfd_target_vector[t]->name);
1961 putchar ('\n');
9872a49c 1962
be1d162b 1963 dummy_name = tmpnam (tmparg);
f7b839f7
DM
1964 for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
1965 if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0)
e779a58c 1966 {
ae5d2ff5
ILT
1967 printf ("%*s ", (int) LONGEST_ARCH - 1,
1968 bfd_printable_arch_mach (a, 0));
105da05c 1969 for (t = first; t < last && bfd_target_vector[t]; t++)
aa0a709a 1970 {
f7b839f7 1971 bfd_target *p = bfd_target_vector[t];
105da05c 1972 boolean ok = true;
de04bceb 1973 bfd *abfd = bfd_openw (dummy_name, p->name);
aa0a709a 1974
334d6e76
SS
1975 if (abfd == NULL)
1976 {
105da05c
ILT
1977 bfd_nonfatal (p->name);
1978 ok = false;
1979 }
1980
1981 if (ok)
1982 {
1983 if (! bfd_set_format (abfd, bfd_object))
1984 {
1985 if (bfd_get_error () != bfd_error_invalid_operation)
1986 bfd_nonfatal (p->name);
1987 ok = false;
1988 }
334d6e76 1989 }
105da05c
ILT
1990
1991 if (ok)
1992 {
1993 if (! bfd_set_arch_mach (abfd, a, 0))
1994 ok = false;
1995 }
1996
1997 if (ok)
aa0a709a
SC
1998 printf ("%s ", p->name);
1999 else
e779a58c 2000 {
f7b839f7 2001 int l = strlen (p->name);
aa0a709a 2002 while (l--)
f7b839f7
DM
2003 putchar ('-');
2004 putchar (' ');
e779a58c 2005 }
e779a58c 2006 }
f7b839f7 2007 putchar ('\n');
e779a58c 2008 }
de04bceb 2009 unlink (dummy_name);
9872a49c 2010}
aa0a709a 2011
f7b839f7
DM
2012/* Print tables of all the target-architecture combinations that
2013 BFD has been configured to support. */
2014
aa0a709a 2015static void
f7b839f7 2016display_target_tables ()
aa0a709a 2017{
f7b839f7 2018 int t, columns;
abdcac0f 2019 extern bfd_target *bfd_target_vector[];
f7b839f7 2020 char *colum;
aa0a709a
SC
2021 extern char *getenv ();
2022
aa0a709a 2023 columns = 0;
f7b839f7
DM
2024 colum = getenv ("COLUMNS");
2025 if (colum != NULL)
aa0a709a 2026 columns = atoi (colum);
f7b839f7 2027 if (columns == 0)
aa0a709a 2028 columns = 80;
f7b839f7 2029
105da05c
ILT
2030 t = 0;
2031 while (bfd_target_vector[t] != NULL)
aa0a709a 2032 {
f7b839f7
DM
2033 int oldt = t, wid;
2034
105da05c
ILT
2035 wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
2036 ++t;
2037 while (wid < columns && bfd_target_vector[t] != NULL)
2038 {
2039 int newwid;
2040
2041 newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
2042 if (newwid >= columns)
2043 break;
2044 wid = newwid;
2045 ++t;
2046 }
f7b839f7 2047 display_info_table (oldt, t);
aa0a709a
SC
2048 }
2049}
2050
f7b839f7
DM
2051static void
2052display_info ()
2053{
2054 printf ("BFD header file version %s\n", BFD_VERSION);
2055 display_target_list ();
2056 display_target_tables ();
2057}
2058
2fa0b342
DHW
2059int
2060main (argc, argv)
2061 int argc;
2062 char **argv;
2063{
2064 int c;
2fa0b342
DHW
2065 char *target = default_target;
2066 boolean seenflag = false;
2fa0b342
DHW
2067
2068 program_name = *argv;
8f197c94
ILT
2069 xmalloc_set_program_name (program_name);
2070
be1d162b
ILT
2071 START_PROGRESS (program_name, 0);
2072
8f197c94 2073 bfd_init ();
2fa0b342 2074
18f39dfa
SG
2075 while ((c = getopt_long (argc, argv, "pib:m:VdDlfahrRtTxsSj:wE:",
2076 long_options, (int *) 0))
aa0a709a
SC
2077 != EOF)
2078 {
aa21a2a9
ILT
2079 if (c != 'l' && c != OPTION_START_ADDRESS && c != OPTION_STOP_ADDRESS)
2080 seenflag = true;
aa0a709a
SC
2081 switch (c)
2082 {
b3a2b497
ILT
2083 case 0:
2084 break; /* we've been given a long option */
aa0a709a
SC
2085 case 'm':
2086 machine = optarg;
2087 break;
2088 case 'j':
2089 only = optarg;
2090 break;
2091 case 'l':
2092 with_line_numbers = 1;
2093 break;
2094 case 'b':
2095 target = optarg;
2096 break;
2097 case 'f':
2098 dump_file_header = true;
2099 break;
2100 case 'i':
e1ec9f07 2101 formats_info = true;
aa0a709a 2102 break;
a65619c8
SC
2103 case 'p':
2104 dump_private_headers = 1;
2105 break;
aa0a709a 2106 case 'x':
a65619c8 2107 dump_private_headers = 1;
aa0a709a
SC
2108 dump_symtab = 1;
2109 dump_reloc_info = 1;
2110 dump_file_header = true;
2111 dump_ar_hdrs = 1;
2112 dump_section_headers = 1;
2113 break;
aa0a709a
SC
2114 case 't':
2115 dump_symtab = 1;
2116 break;
de3b08ac
ILT
2117 case 'T':
2118 dump_dynamic_symtab = 1;
2119 break;
aa0a709a
SC
2120 case 'd':
2121 disassemble = true;
2122 break;
d5464baa
ILT
2123 case 'D':
2124 disassemble = disassemble_all = true;
2125 break;
be1d162b
ILT
2126 case 'S':
2127 disassemble = true;
2128 with_source_code = true;
2129 break;
aa0a709a
SC
2130 case 's':
2131 dump_section_contents = 1;
2132 break;
2133 case 'r':
2134 dump_reloc_info = 1;
2135 break;
de3b08ac
ILT
2136 case 'R':
2137 dump_dynamic_reloc_info = 1;
2138 break;
aa0a709a
SC
2139 case 'a':
2140 dump_ar_hdrs = 1;
2141 break;
2142 case 'h':
2143 dump_section_headers = 1;
2144 break;
b3a2b497
ILT
2145 case 'H':
2146 usage (stdout, 0);
249c6fc0
RS
2147 case 'V':
2148 show_version = 1;
2149 break;
13e4db2e
SC
2150 case 'w':
2151 wide_output = 1;
2152 break;
aa21a2a9
ILT
2153 case OPTION_START_ADDRESS:
2154 start_address = parse_vma (optarg, "--start-address");
2155 break;
2156 case OPTION_STOP_ADDRESS:
2157 stop_address = parse_vma (optarg, "--stop-address");
2158 break;
18f39dfa
SG
2159 case 'E':
2160 if (strcmp (optarg, "B") == 0)
2161 endian = BFD_ENDIAN_BIG;
2162 else if (strcmp (optarg, "L") == 0)
2163 endian = BFD_ENDIAN_LITTLE;
2164 else
2165 {
2166 fprintf (stderr, "%s: unrecognized -E option\n", program_name);
2167 usage (stderr, 1);
2168 }
2169 break;
2170 case OPTION_ENDIAN:
2171 if (strncmp (optarg, "big", strlen (optarg)) == 0)
2172 endian = BFD_ENDIAN_BIG;
2173 else if (strncmp (optarg, "little", strlen (optarg)) == 0)
2174 endian = BFD_ENDIAN_LITTLE;
2175 else
2176 {
2177 fprintf (stderr, "%s: unrecognized --endian type `%s'\n",
2178 program_name, optarg);
2179 usage (stderr, 1);
2180 }
2181 break;
aa0a709a 2182 default:
b3a2b497 2183 usage (stderr, 1);
aa0a709a 2184 }
2fa0b342 2185 }
2fa0b342 2186
249c6fc0 2187 if (show_version)
b3a2b497
ILT
2188 {
2189 printf ("GNU %s version %s\n", program_name, program_version);
2190 exit (0);
2191 }
249c6fc0 2192
2fa0b342 2193 if (seenflag == false)
b3a2b497 2194 usage (stderr, 1);
2fa0b342 2195
e1ec9f07 2196 if (formats_info)
aa0a709a
SC
2197 {
2198 display_info ();
2199 }
2200 else
2201 {
2202 if (optind == argc)
2203 display_file ("a.out", target);
2204 else
2205 for (; optind < argc;)
2206 display_file (argv[optind++], target);
2207 }
be1d162b
ILT
2208
2209 END_PROGRESS (program_name);
2210
2fa0b342
DHW
2211 return 0;
2212}
This page took 0.280383 seconds and 4 git commands to generate.