* mn10300-dis.c: Rough cut at printing some operands.
[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
18f39dfa
SG
47static int show_version = 0; /* show the version number */
48static int dump_section_contents; /* -s */
49static int dump_section_headers; /* -h */
50static boolean dump_file_header; /* -f */
51static int dump_symtab; /* -t */
52static int dump_dynamic_symtab; /* -T */
53static int dump_reloc_info; /* -r */
54static int dump_dynamic_reloc_info; /* -R */
55static int dump_ar_hdrs; /* -a */
56static int dump_private_headers; /* -p */
57static int with_line_numbers; /* -l */
58static boolean with_source_code; /* -S */
59static int show_raw_insn; /* --show-raw-insn */
60static int dump_stab_section_info; /* --stabs */
61static boolean disassemble; /* -d */
62static boolean disassemble_all; /* -D */
63static boolean formats_info; /* -i */
64static char *only; /* -j secname */
65static int wide_output; /* -w */
66static bfd_vma start_address = (bfd_vma) -1; /* --start-address */
67static bfd_vma stop_address = (bfd_vma) -1; /* --stop-address */
68static int dump_debugging; /* --debugging */
195d1adf 69
cef35d48 70/* Extra info to pass to the disassembler address printing function. */
195d1adf
KR
71struct objdump_disasm_info {
72 bfd *abfd;
73 asection *sec;
8b129785 74 boolean require_sec;
195d1adf 75};
2fa0b342 76
cef35d48 77/* Architecture to disassemble for, or default if NULL. */
18f39dfa
SG
78static char *machine = (char *) NULL;
79
80/* Endianness to disassemble for, or default if BFD_ENDIAN_UNKNOWN. */
81static enum bfd_endian endian = BFD_ENDIAN_UNKNOWN;
f7b839f7
DM
82
83/* The symbol table. */
18f39dfa 84static asymbol **syms;
2fa0b342 85
f7b839f7 86/* Number of symbols in `syms'. */
18f39dfa 87static long symcount = 0;
2fa0b342 88
be1d162b 89/* The sorted symbol table. */
18f39dfa 90static asymbol **sorted_syms;
be1d162b
ILT
91
92/* Number of symbols in `sorted_syms'. */
18f39dfa 93static long sorted_symcount = 0;
be1d162b 94
de3b08ac 95/* The dynamic symbol table. */
18f39dfa 96static asymbol **dynsyms;
de3b08ac
ILT
97
98/* Number of symbols in `dynsyms'. */
18f39dfa 99static long dynsymcount = 0;
de3b08ac 100
d9971b83
KR
101/* Forward declarations. */
102
103static void
104display_file PARAMS ((char *filename, char *target));
105
106static void
107dump_data PARAMS ((bfd *abfd));
108
109static void
110dump_relocs PARAMS ((bfd *abfd));
111
112static void
de3b08ac
ILT
113dump_dynamic_relocs PARAMS ((bfd * abfd));
114
115static void
18f39dfa 116dump_reloc_set PARAMS ((bfd *, asection *, arelent **, long));
de3b08ac
ILT
117
118static void
119dump_symbols PARAMS ((bfd *abfd, boolean dynamic));
02a68547
ILT
120
121static void
122display_bfd PARAMS ((bfd *abfd));
8f197c94 123
c5ba2759 124static void
7fc01fc9 125objdump_print_value PARAMS ((bfd_vma, struct disassemble_info *));
c5ba2759 126
8f197c94
ILT
127static void
128objdump_print_address PARAMS ((bfd_vma, struct disassemble_info *));
be1d162b
ILT
129
130static void
131show_line PARAMS ((bfd *, asection *, bfd_vma));
e1c14599
ILT
132
133static const char *
134endian_string PARAMS ((enum bfd_endian));
d9971b83 135\f
18f39dfa 136static void
b3a2b497
ILT
137usage (stream, status)
138 FILE *stream;
139 int status;
2fa0b342 140{
b3a2b497 141 fprintf (stream, "\
a65619c8 142Usage: %s [-ahifdDprRtTxsSlw] [-b bfdname] [-m machine] [-j section-name]\n\
e1c14599 143 [--archive-headers] [--target=bfdname] [--debugging] [--disassemble]\n\
d5464baa 144 [--disassemble-all] [--file-headers] [--section-headers] [--headers]\n\
13e4db2e
SC
145 [--info] [--section=section-name] [--line-numbers] [--source]\n",
146 program_name);
147 fprintf (stream, "\
d5464baa
ILT
148 [--architecture=machine] [--reloc] [--full-contents] [--stabs]\n\
149 [--syms] [--all-headers] [--dynamic-syms] [--dynamic-reloc]\n\
aa21a2a9 150 [--wide] [--version] [--help] [--private-headers]\n\
458bbd1f 151 [--start-address=addr] [--stop-address=addr]\n\
18f39dfa 152 [--show-raw-insn] [-EB|-EL] [--endian={big|little}] objfile...\n\
13e4db2e 153at least one option besides -l (--line-numbers) must be given\n");
be1d162b 154 list_supported_targets (program_name, stream);
7f924d55
ILT
155 if (status == 0)
156 fprintf (stream, "Report bugs to bug-gnu-utils@prep.ai.mit.edu\n");
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
7f924d55 977 disasm_info.flavour = bfd_get_flavour (abfd);
458bbd1f
DE
978 disasm_info.arch = bfd_get_arch (abfd);
979 disasm_info.mach = bfd_get_mach (abfd);
980 if (bfd_big_endian (abfd))
981 disasm_info.endian = BFD_ENDIAN_BIG;
38aa863c 982 else if (bfd_little_endian (abfd))
458bbd1f 983 disasm_info.endian = BFD_ENDIAN_LITTLE;
38aa863c
DE
984 else
985 /* ??? Aborting here seems too drastic. We could default to big or little
986 instead. */
987 disasm_info.endian = BFD_ENDIAN_UNKNOWN;
458bbd1f 988
2fa0b342 989 for (section = abfd->sections;
aa0a709a
SC
990 section != (asection *) NULL;
991 section = section->next)
65cceb78 992 {
cef35d48
DM
993 bfd_byte *data = NULL;
994 bfd_size_type datasize = 0;
be1d162b 995 arelent **relbuf = NULL;
d5464baa
ILT
996 arelent **relpp = NULL;
997 arelent **relppend = NULL;
aa21a2a9 998 long stop;
2fa0b342 999
d5464baa
ILT
1000 if ((section->flags & SEC_LOAD) == 0
1001 || (! disassemble_all
1002 && only == NULL
1003 && (section->flags & SEC_CODE) == 0))
cef35d48
DM
1004 continue;
1005 if (only != (char *) NULL && strcmp (only, section->name) != 0)
1006 continue;
2fa0b342 1007
d5464baa
ILT
1008 if (dump_reloc_info
1009 && (section->flags & SEC_RELOC) != 0)
1010 {
be1d162b
ILT
1011 long relsize;
1012
1013 relsize = bfd_get_reloc_upper_bound (abfd, section);
1014 if (relsize < 0)
1015 bfd_fatal (bfd_get_filename (abfd));
1016
1017 if (relsize > 0)
1018 {
1019 long relcount;
1020
1021 relbuf = (arelent **) xmalloc (relsize);
1022 relcount = bfd_canonicalize_reloc (abfd, section, relbuf, syms);
1023 if (relcount < 0)
1024 bfd_fatal (bfd_get_filename (abfd));
1025
1026 /* Sort the relocs by address. */
1027 qsort (relbuf, relcount, sizeof (arelent *), compare_relocs);
1028
1029 relpp = relbuf;
1030 relppend = relpp + relcount;
1031 }
d5464baa
ILT
1032 }
1033
cef35d48 1034 printf ("Disassembly of section %s:\n", section->name);
2fa0b342 1035
cef35d48
DM
1036 datasize = bfd_get_section_size_before_reloc (section);
1037 if (datasize == 0)
1038 continue;
2fa0b342 1039
cef35d48 1040 data = (bfd_byte *) xmalloc ((size_t) datasize);
2fa0b342 1041
cef35d48 1042 bfd_get_section_contents (abfd, section, data, 0, datasize);
2fa0b342 1043
cef35d48
DM
1044 aux.sec = section;
1045 disasm_info.buffer = data;
1046 disasm_info.buffer_vma = section->vma;
1047 disasm_info.buffer_length = datasize;
aa21a2a9
ILT
1048 if (start_address == (bfd_vma) -1
1049 || start_address < disasm_info.buffer_vma)
1050 i = 0;
1051 else
1052 i = start_address - disasm_info.buffer_vma;
1053 if (stop_address == (bfd_vma) -1)
1054 stop = datasize;
1055 else
1056 {
1057 if (stop_address < disasm_info.buffer_vma)
1058 stop = 0;
1059 else
1060 stop = stop_address - disasm_info.buffer_vma;
1061 if (stop > disasm_info.buffer_length)
1062 stop = disasm_info.buffer_length;
1063 }
1064 while (i < stop)
cef35d48 1065 {
d5464baa 1066 int bytes;
13e4db2e 1067 boolean need_nl = false;
d5464baa 1068
18f39dfa
SG
1069 if (data[i] == 0
1070 && (i + 1 >= stop
1071 || (data[i + 1] == 0
1072 && (i + 2 >= stop
1073 || (data[i + 2] == 0
1074 && (i + 3 >= stop
1075 || data[i + 3] == 0))))))
aa0a709a 1076 {
cef35d48 1077 if (done_dot == false)
aa0a709a 1078 {
cef35d48
DM
1079 printf ("...\n");
1080 done_dot = true;
65cceb78 1081 }
d5464baa 1082 bytes = 4;
cef35d48
DM
1083 }
1084 else
1085 {
1086 done_dot = false;
be1d162b
ILT
1087 if (with_line_numbers || with_source_code)
1088 show_line (abfd, section, i);
8b129785 1089 aux.require_sec = true;
cef35d48 1090 objdump_print_address (section->vma + i, &disasm_info);
8b129785 1091 aux.require_sec = false;
cef35d48 1092 putchar (' ');
65cceb78 1093
7fc01fc9
ILT
1094 sfile.buffer = sfile.current = buf;
1095 disasm_info.fprintf_func = (fprintf_ftype) objdump_sprintf;
1096 disasm_info.stream = (FILE *) &sfile;
db552bda 1097 bytes = (*disassemble_fn) (section->vma + i, &disasm_info);
7fc01fc9
ILT
1098 disasm_info.fprintf_func = (fprintf_ftype) fprintf;
1099 disasm_info.stream = stdout;
db552bda
ILT
1100 if (bytes < 0)
1101 break;
1102
7fc01fc9
ILT
1103 if (show_raw_insn)
1104 {
1105 long j;
1106 for (j = i; j < i + bytes; ++j)
1107 {
1108 printf ("%02x", (unsigned) data[j]);
1109 putchar (' ');
1110 }
1111 /* Separate raw data from instruction by extra space. */
1112 putchar (' ');
1113 }
1114
1115 printf ("%s", sfile.buffer);
1116
13e4db2e
SC
1117 if (!wide_output)
1118 putchar ('\n');
1119 else
1120 need_nl = true;
96d7950b 1121 }
d5464baa
ILT
1122
1123 if (dump_reloc_info
1124 && (section->flags & SEC_RELOC) != 0)
1125 {
1126 while (relpp < relppend
746cffcf
ILT
1127 && ((*relpp)->address >= (bfd_vma) i
1128 && (*relpp)->address < (bfd_vma) i + bytes))
d5464baa
ILT
1129 {
1130 arelent *q;
1131 const char *sym_name;
1132
1133 q = *relpp;
1134
1135 printf ("\t\tRELOC: ");
1136
1137 printf_vma (section->vma + q->address);
1138
1139 printf (" %s ", q->howto->name);
1140
1141 if (q->sym_ptr_ptr != NULL
1142 && *q->sym_ptr_ptr != NULL)
1143 {
1144 sym_name = bfd_asymbol_name (*q->sym_ptr_ptr);
1145 if (sym_name == NULL || *sym_name == '\0')
1146 {
1147 asection *sym_sec;
1148
1149 sym_sec = bfd_get_section (*q->sym_ptr_ptr);
1150 sym_name = bfd_get_section_name (abfd, sym_sec);
1151 if (sym_name == NULL || *sym_name == '\0')
1152 sym_name = "*unknown*";
1153 }
1154 }
38d7c012
ILT
1155 else
1156 sym_name = "*unknown*";
d5464baa
ILT
1157
1158 printf ("%s", sym_name);
1159
1160 if (q->addend)
1161 {
1162 printf ("+0x");
1163 printf_vma (q->addend);
1164 }
1165
1166 printf ("\n");
13e4db2e 1167 need_nl = false;
d5464baa
ILT
1168 ++relpp;
1169 }
1170 }
1171
13e4db2e
SC
1172 if (need_nl)
1173 printf ("\n");
1174
d5464baa 1175 i += bytes;
96d7950b 1176 }
be1d162b 1177
cef35d48 1178 free (data);
be1d162b
ILT
1179 if (relbuf != NULL)
1180 free (relbuf);
2fa0b342 1181 }
c5ba2759 1182 free (sorted_syms);
2fa0b342 1183}
73b8f102 1184\f
73b8f102
JG
1185
1186/* Define a table of stab values and print-strings. We wish the initializer
1187 could be a direct-mapped table, but instead we build one the first
1188 time we need it. */
1189
18f39dfa
SG
1190static void dump_section_stabs PARAMS ((bfd *abfd, char *stabsect_name,
1191 char *strsect_name));
249c6fc0 1192
250e36fe 1193/* Dump the stabs sections from an object file that has a section that
18f39dfa 1194 uses Sun stabs encoding. */
73b8f102 1195
18f39dfa 1196static void
9b018ecd 1197dump_stabs (abfd)
73b8f102
JG
1198 bfd *abfd;
1199{
250e36fe
DM
1200 dump_section_stabs (abfd, ".stab", ".stabstr");
1201 dump_section_stabs (abfd, ".stab.excl", ".stab.exclstr");
1202 dump_section_stabs (abfd, ".stab.index", ".stab.indexstr");
1203 dump_section_stabs (abfd, "$GDB_SYMBOLS$", "$GDB_STRINGS$");
249c6fc0
RS
1204}
1205
18f39dfa 1206static bfd_byte *stabs;
250e36fe
DM
1207static bfd_size_type stab_size;
1208
1209static char *strtab;
1210static bfd_size_type stabstr_size;
1211
1212/* Read ABFD's stabs section STABSECT_NAME into `stabs'
1213 and string table section STRSECT_NAME into `strtab'.
1214 If the section exists and was read, allocate the space and return true.
1215 Otherwise return false. */
1216
18f39dfa 1217static boolean
250e36fe 1218read_section_stabs (abfd, stabsect_name, strsect_name)
249c6fc0 1219 bfd *abfd;
250e36fe
DM
1220 char *stabsect_name;
1221 char *strsect_name;
249c6fc0 1222{
9b018ecd 1223 asection *stabsect, *stabstrsect;
9b018ecd 1224
d5671c53
ILT
1225 stabsect = bfd_get_section_by_name (abfd, stabsect_name);
1226 if (0 == stabsect)
73b8f102 1227 {
250e36fe
DM
1228 printf ("No %s section present\n\n", stabsect_name);
1229 return false;
73b8f102
JG
1230 }
1231
d5671c53
ILT
1232 stabstrsect = bfd_get_section_by_name (abfd, strsect_name);
1233 if (0 == stabstrsect)
73b8f102 1234 {
eae82145 1235 fprintf (stderr, "%s: %s has no %s section\n", program_name,
250e36fe
DM
1236 bfd_get_filename (abfd), strsect_name);
1237 return false;
73b8f102 1238 }
9b018ecd 1239
d5671c53
ILT
1240 stab_size = bfd_section_size (abfd, stabsect);
1241 stabstr_size = bfd_section_size (abfd, stabstrsect);
73b8f102 1242
18f39dfa 1243 stabs = (bfd_byte *) xmalloc (stab_size);
9b018ecd 1244 strtab = (char *) xmalloc (stabstr_size);
73b8f102 1245
d5671c53 1246 if (! bfd_get_section_contents (abfd, stabsect, (PTR) stabs, 0, stab_size))
9b018ecd 1247 {
d5671c53
ILT
1248 fprintf (stderr, "%s: Reading %s section of %s failed: %s\n",
1249 program_name, stabsect_name, bfd_get_filename (abfd),
1250 bfd_errmsg (bfd_get_error ()));
1251 free (stabs);
1252 free (strtab);
1253 return false;
73b8f102 1254 }
2fa0b342 1255
d5671c53
ILT
1256 if (! bfd_get_section_contents (abfd, stabstrsect, (PTR) strtab, 0,
1257 stabstr_size))
9b018ecd 1258 {
d5671c53
ILT
1259 fprintf (stderr, "%s: Reading %s section of %s failed: %s\n",
1260 program_name, strsect_name, bfd_get_filename (abfd),
1261 bfd_errmsg (bfd_get_error ()));
1262 free (stabs);
1263 free (strtab);
1264 return false;
73b8f102 1265 }
d5671c53 1266
250e36fe
DM
1267 return true;
1268}
73b8f102 1269
18f39dfa
SG
1270/* Stabs entries use a 12 byte format:
1271 4 byte string table index
1272 1 byte stab type
1273 1 byte stab other field
1274 2 byte stab desc field
1275 4 byte stab value
1276 FIXME: This will have to change for a 64 bit object format. */
1277
1278#define STRDXOFF (0)
1279#define TYPEOFF (4)
1280#define OTHEROFF (5)
1281#define DESCOFF (6)
1282#define VALOFF (8)
1283#define STABSIZE (12)
73b8f102 1284
250e36fe
DM
1285/* Print ABFD's stabs section STABSECT_NAME (in `stabs'),
1286 using string table section STRSECT_NAME (in `strtab'). */
1287
18f39dfa 1288static void
250e36fe
DM
1289print_section_stabs (abfd, stabsect_name, strsect_name)
1290 bfd *abfd;
1291 char *stabsect_name;
1292 char *strsect_name;
1293{
1294 int i;
1295 unsigned file_string_table_offset = 0, next_file_string_table_offset = 0;
18f39dfa
SG
1296 bfd_byte *stabp, *stabs_end;
1297
1298 stabp = stabs;
1299 stabs_end = stabp + stab_size;
73b8f102 1300
250e36fe
DM
1301 printf ("Contents of %s section:\n\n", stabsect_name);
1302 printf ("Symnum n_type n_othr n_desc n_value n_strx String\n");
249c6fc0
RS
1303
1304 /* Loop through all symbols and print them.
1305
1306 We start the index at -1 because there is a dummy symbol on
250e36fe 1307 the front of stabs-in-{coff,elf} sections that supplies sizes. */
249c6fc0 1308
18f39dfa 1309 for (i = -1; stabp < stabs_end; stabp += STABSIZE, i++)
73b8f102 1310 {
7fc01fc9 1311 const char *name;
18f39dfa
SG
1312 unsigned long strx;
1313 unsigned char type, other;
1314 unsigned short desc;
1315 bfd_vma value;
1316
1317 strx = bfd_h_get_32 (abfd, stabp + STRDXOFF);
1318 type = bfd_h_get_8 (abfd, stabp + TYPEOFF);
1319 other = bfd_h_get_8 (abfd, stabp + OTHEROFF);
1320 desc = bfd_h_get_16 (abfd, stabp + DESCOFF);
1321 value = bfd_h_get_32 (abfd, stabp + VALOFF);
7fc01fc9 1322
fe2750e1 1323 printf ("\n%-6d ", i);
250e36fe 1324 /* Either print the stab name, or, if unnamed, print its number
fe2750e1 1325 again (makes consistent formatting for tools like awk). */
18f39dfa 1326 name = bfd_get_stab_name (type);
7fc01fc9
ILT
1327 if (name != NULL)
1328 printf ("%-6s", name);
18f39dfa 1329 else if (type == N_UNDF)
105da05c 1330 printf ("HdrSym");
fe2750e1 1331 else
18f39dfa
SG
1332 printf ("%-6d", type);
1333 printf (" %-6d %-6d ", other, desc);
1334 printf_vma (value);
1335 printf (" %-6lu", strx);
249c6fc0
RS
1336
1337 /* Symbols with type == 0 (N_UNDF) specify the length of the
1338 string table associated with this file. We use that info
1339 to know how to relocate the *next* file's string table indices. */
1340
18f39dfa 1341 if (type == N_UNDF)
249c6fc0
RS
1342 {
1343 file_string_table_offset = next_file_string_table_offset;
18f39dfa 1344 next_file_string_table_offset += value;
249c6fc0 1345 }
249c6fc0 1346 else
e1ec9f07 1347 {
250e36fe 1348 /* Using the (possibly updated) string table offset, print the
e1ec9f07
SS
1349 string (if any) associated with this symbol. */
1350
18f39dfa
SG
1351 if ((strx + file_string_table_offset) < stabstr_size)
1352 printf (" %s", &strtab[strx + file_string_table_offset]);
e1ec9f07
SS
1353 else
1354 printf (" *");
1355 }
73b8f102
JG
1356 }
1357 printf ("\n\n");
1358}
249c6fc0 1359
18f39dfa 1360static void
250e36fe
DM
1361dump_section_stabs (abfd, stabsect_name, strsect_name)
1362 bfd *abfd;
1363 char *stabsect_name;
1364 char *strsect_name;
1365{
13e4db2e 1366 asection *s;
13e4db2e 1367
a65619c8
SC
1368 /* Check for section names for which stabsect_name is a prefix, to
1369 handle .stab0, etc. */
13e4db2e 1370 for (s = abfd->sections;
a65619c8 1371 s != NULL;
13e4db2e
SC
1372 s = s->next)
1373 {
18f39dfa
SG
1374 int len;
1375
1376 len = strlen (stabsect_name);
1377
1378/* If the prefix matches, and the files section name ends with a nul or a digit,
1379 then we match. Ie: we want either an exact match or a a section followed by
1380 a number. */
1381 if (strncmp (stabsect_name, s->name, len) == 0
1382 && (s->name[len] == '\000' || isdigit (s->name[len])))
13e4db2e 1383 {
a65619c8
SC
1384 if (read_section_stabs (abfd, s->name, strsect_name))
1385 {
1386 print_section_stabs (abfd, s->name, strsect_name);
1387 free (stabs);
1388 free (strtab);
1389 }
13e4db2e
SC
1390 }
1391 }
250e36fe
DM
1392}
1393\f
eae82145 1394static void
f7b839f7
DM
1395dump_bfd_header (abfd)
1396 bfd *abfd;
1397{
1398 char *comma = "";
1399
1400 printf ("architecture: %s, ",
1401 bfd_printable_arch_mach (bfd_get_arch (abfd),
1402 bfd_get_mach (abfd)));
1403 printf ("flags 0x%08x:\n", abfd->flags);
1404
1405#define PF(x, y) if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
1406 PF (HAS_RELOC, "HAS_RELOC");
1407 PF (EXEC_P, "EXEC_P");
1408 PF (HAS_LINENO, "HAS_LINENO");
1409 PF (HAS_DEBUG, "HAS_DEBUG");
1410 PF (HAS_SYMS, "HAS_SYMS");
1411 PF (HAS_LOCALS, "HAS_LOCALS");
1412 PF (DYNAMIC, "DYNAMIC");
1413 PF (WP_TEXT, "WP_TEXT");
1414 PF (D_PAGED, "D_PAGED");
1415 PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
1416 printf ("\nstart address 0x");
1417 printf_vma (abfd->start_address);
38d7c012 1418 printf ("\n");
f7b839f7 1419}
a65619c8
SC
1420\f
1421static void
1422dump_bfd_private_header (abfd)
1423bfd *abfd;
1424{
1425 bfd_print_private_bfd_data (abfd, stdout);
1426}
18f39dfa 1427
02a68547 1428static void
2fa0b342
DHW
1429display_bfd (abfd)
1430 bfd *abfd;
1431{
209e5610
DM
1432 char **matching;
1433
1434 if (!bfd_check_format_matches (abfd, bfd_object, &matching))
aa0a709a 1435 {
cef35d48 1436 bfd_nonfatal (bfd_get_filename (abfd));
8f197c94 1437 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
209e5610
DM
1438 {
1439 list_matching_formats (matching);
1440 free (matching);
1441 }
aa0a709a
SC
1442 return;
1443 }
f7b839f7 1444
cef35d48
DM
1445 printf ("\n%s: file format %s\n", bfd_get_filename (abfd),
1446 abfd->xvec->name);
aa0a709a
SC
1447 if (dump_ar_hdrs)
1448 print_arelt_descr (stdout, abfd, true);
aa0a709a 1449 if (dump_file_header)
f7b839f7 1450 dump_bfd_header (abfd);
a65619c8
SC
1451 if (dump_private_headers)
1452 dump_bfd_private_header (abfd);
f7b839f7 1453 putchar ('\n');
2fa0b342 1454 if (dump_section_headers)
aa0a709a 1455 dump_headers (abfd);
83f4323e 1456 if (dump_symtab || dump_reloc_info || disassemble || dump_debugging)
aa0a709a
SC
1457 {
1458 syms = slurp_symtab (abfd);
1459 }
de3b08ac
ILT
1460 if (dump_dynamic_symtab || dump_dynamic_reloc_info)
1461 {
1462 dynsyms = slurp_dynamic_symtab (abfd);
1463 }
aa0a709a 1464 if (dump_symtab)
de3b08ac
ILT
1465 dump_symbols (abfd, false);
1466 if (dump_dynamic_symtab)
1467 dump_symbols (abfd, true);
73b8f102 1468 if (dump_stab_section_info)
9b018ecd 1469 dump_stabs (abfd);
d5464baa 1470 if (dump_reloc_info && ! disassemble)
aa0a709a 1471 dump_relocs (abfd);
de3b08ac
ILT
1472 if (dump_dynamic_reloc_info)
1473 dump_dynamic_relocs (abfd);
aa0a709a
SC
1474 if (dump_section_contents)
1475 dump_data (abfd);
1476 if (disassemble)
1477 disassemble_data (abfd);
e1c14599
ILT
1478 if (dump_debugging)
1479 {
1480 PTR dhandle;
1481
83f4323e 1482 dhandle = read_debugging_info (abfd, syms, symcount);
e1c14599
ILT
1483 if (dhandle != NULL)
1484 {
1485 if (! print_debugging_info (stdout, dhandle))
1486 fprintf (stderr, "%s: printing debugging information failed\n",
1487 bfd_get_filename (abfd));
1488 }
1489 }
c5ba2759
ILT
1490 if (syms)
1491 {
1492 free (syms);
1493 syms = NULL;
1494 }
1495 if (dynsyms)
1496 {
1497 free (dynsyms);
1498 dynsyms = NULL;
1499 }
2fa0b342
DHW
1500}
1501
d9971b83 1502static void
2fa0b342
DHW
1503display_file (filename, target)
1504 char *filename;
1505 char *target;
1506{
1507 bfd *file, *arfile = (bfd *) NULL;
1508
1509 file = bfd_openr (filename, target);
aa0a709a
SC
1510 if (file == NULL)
1511 {
cef35d48 1512 bfd_nonfatal (filename);
aa0a709a
SC
1513 return;
1514 }
2fa0b342 1515
aa0a709a
SC
1516 if (bfd_check_format (file, bfd_archive) == true)
1517 {
8f197c94
ILT
1518 bfd *last_arfile = NULL;
1519
aa0a709a
SC
1520 printf ("In archive %s:\n", bfd_get_filename (file));
1521 for (;;)
1522 {
8f197c94 1523 bfd_set_error (bfd_error_no_error);
aa0a709a
SC
1524
1525 arfile = bfd_openr_next_archived_file (file, arfile);
1526 if (arfile == NULL)
1527 {
8f197c94 1528 if (bfd_get_error () != bfd_error_no_more_archived_files)
d2442698 1529 {
cef35d48 1530 bfd_nonfatal (bfd_get_filename (file));
d2442698 1531 }
8f197c94 1532 break;
aa0a709a 1533 }
2fa0b342 1534
aa0a709a 1535 display_bfd (arfile);
8f197c94
ILT
1536
1537 if (last_arfile != NULL)
1538 bfd_close (last_arfile);
1539 last_arfile = arfile;
aa0a709a 1540 }
8f197c94
ILT
1541
1542 if (last_arfile != NULL)
1543 bfd_close (last_arfile);
2fa0b342 1544 }
2fa0b342 1545 else
aa0a709a 1546 display_bfd (file);
2fa0b342 1547
aa0a709a 1548 bfd_close (file);
2fa0b342
DHW
1549}
1550\f
1551/* Actually display the various requested regions */
1552
d9971b83 1553static void
2fa0b342
DHW
1554dump_data (abfd)
1555 bfd *abfd;
1556{
1557 asection *section;
aa0a709a 1558 bfd_byte *data = 0;
fc5d6074
SC
1559 bfd_size_type datasize = 0;
1560 bfd_size_type i;
aa21a2a9 1561 bfd_size_type start, stop;
2fa0b342
DHW
1562
1563 for (section = abfd->sections; section != NULL; section =
aa0a709a
SC
1564 section->next)
1565 {
1566 int onaline = 16;
2fa0b342 1567
aa0a709a
SC
1568 if (only == (char *) NULL ||
1569 strcmp (only, section->name) == 0)
60c80016 1570 {
aa0a709a
SC
1571 if (section->flags & SEC_HAS_CONTENTS)
1572 {
1573 printf ("Contents of section %s:\n", section->name);
1574
9b018ecd 1575 if (bfd_section_size (abfd, section) == 0)
aa0a709a 1576 continue;
02a68547 1577 data = (bfd_byte *) xmalloc ((size_t) bfd_section_size (abfd, section));
9b018ecd 1578 datasize = bfd_section_size (abfd, section);
2fa0b342 1579
2fa0b342 1580
9b018ecd 1581 bfd_get_section_contents (abfd, section, (PTR) data, 0, bfd_section_size (abfd, section));
2fa0b342 1582
aa21a2a9
ILT
1583 if (start_address == (bfd_vma) -1
1584 || start_address < section->vma)
1585 start = 0;
1586 else
1587 start = start_address - section->vma;
1588 if (stop_address == (bfd_vma) -1)
1589 stop = bfd_section_size (abfd, section);
1590 else
1591 {
1592 if (stop_address < section->vma)
1593 stop = 0;
1594 else
1595 stop = stop_address - section->vma;
1596 if (stop > bfd_section_size (abfd, section))
1597 stop = bfd_section_size (abfd, section);
1598 }
1599 for (i = start; i < stop; i += onaline)
aa0a709a
SC
1600 {
1601 bfd_size_type j;
1602
1603 printf (" %04lx ", (unsigned long int) (i + section->vma));
1604 for (j = i; j < i + onaline; j++)
1605 {
aa21a2a9 1606 if (j < stop)
aa0a709a
SC
1607 printf ("%02x", (unsigned) (data[j]));
1608 else
1609 printf (" ");
1610 if ((j & 3) == 3)
1611 printf (" ");
1612 }
2fa0b342 1613
aa0a709a
SC
1614 printf (" ");
1615 for (j = i; j < i + onaline; j++)
1616 {
aa21a2a9 1617 if (j >= stop)
aa0a709a
SC
1618 printf (" ");
1619 else
1620 printf ("%c", isprint (data[j]) ? data[j] : '.');
1621 }
1622 putchar ('\n');
1623 }
d9971b83 1624 free (data);
60c80016 1625 }
2fa0b342 1626 }
2fa0b342 1627 }
2fa0b342
DHW
1628}
1629
2fa0b342 1630/* Should perhaps share code and display with nm? */
d9971b83 1631static void
de3b08ac 1632dump_symbols (abfd, dynamic)
2fa0b342 1633 bfd *abfd;
de3b08ac 1634 boolean dynamic;
2fa0b342 1635{
de3b08ac
ILT
1636 asymbol **current;
1637 long max;
ae5d2ff5 1638 long count;
2fa0b342 1639
de3b08ac 1640 if (dynamic)
aa0a709a 1641 {
de3b08ac
ILT
1642 current = dynsyms;
1643 max = dynsymcount;
1644 if (max == 0)
1645 return;
1646 printf ("DYNAMIC SYMBOL TABLE:\n");
1647 }
1648 else
1649 {
1650 current = syms;
1651 max = symcount;
1652 if (max == 0)
1653 return;
1654 printf ("SYMBOL TABLE:\n");
1655 }
2fa0b342 1656
de3b08ac
ILT
1657 for (count = 0; count < max; count++)
1658 {
d9971b83 1659 if (*current)
aa0a709a 1660 {
d9971b83
KR
1661 bfd *cur_bfd = bfd_asymbol_bfd(*current);
1662 if (cur_bfd)
1663 {
1664 bfd_print_symbol (cur_bfd,
1665 stdout,
1666 *current, bfd_print_symbol_all);
1667 printf ("\n");
1668 }
aa0a709a
SC
1669 }
1670 current++;
2fa0b342 1671 }
aa0a709a
SC
1672 printf ("\n");
1673 printf ("\n");
2fa0b342
DHW
1674}
1675
d9971b83 1676static void
aa0a709a
SC
1677dump_relocs (abfd)
1678 bfd *abfd;
2fa0b342
DHW
1679{
1680 arelent **relpp;
ae5d2ff5 1681 long relcount;
2fa0b342 1682 asection *a;
aa0a709a
SC
1683
1684 for (a = abfd->sections; a != (asection *) NULL; a = a->next)
1685 {
ae5d2ff5
ILT
1686 long relsize;
1687
28d1b01e 1688 if (bfd_is_abs_section (a))
aa0a709a 1689 continue;
28d1b01e 1690 if (bfd_is_und_section (a))
aa0a709a 1691 continue;
d9971b83 1692 if (bfd_is_com_section (a))
aa0a709a
SC
1693 continue;
1694
195d1adf
KR
1695 if (only)
1696 {
1697 if (strcmp (only, a->name))
1698 continue;
1699 }
1700 else if ((a->flags & SEC_RELOC) == 0)
1701 continue;
1702
ae5d2ff5
ILT
1703 relsize = bfd_get_reloc_upper_bound (abfd, a);
1704 if (relsize < 0)
1705 bfd_fatal (bfd_get_filename (abfd));
1706
c5ba2759
ILT
1707 printf ("RELOCATION RECORDS FOR [%s]:", a->name);
1708
ae5d2ff5 1709 if (relsize == 0)
aa0a709a
SC
1710 {
1711 printf (" (none)\n\n");
d20f480f 1712 }
aa0a709a
SC
1713 else
1714 {
ae5d2ff5 1715 relpp = (arelent **) xmalloc (relsize);
aa0a709a 1716 relcount = bfd_canonicalize_reloc (abfd, a, relpp, syms);
ae5d2ff5
ILT
1717 if (relcount < 0)
1718 bfd_fatal (bfd_get_filename (abfd));
1719 else if (relcount == 0)
aa0a709a
SC
1720 {
1721 printf (" (none)\n\n");
d20f480f 1722 }
aa0a709a
SC
1723 else
1724 {
1725 printf ("\n");
18f39dfa 1726 dump_reloc_set (abfd, a, relpp, relcount);
aa0a709a 1727 printf ("\n\n");
d20f480f 1728 }
de3b08ac 1729 free (relpp);
2fa0b342 1730 }
de3b08ac
ILT
1731 }
1732}
2fa0b342 1733
de3b08ac
ILT
1734static void
1735dump_dynamic_relocs (abfd)
1736 bfd *abfd;
1737{
1738 long relsize;
1739 arelent **relpp;
1740 long relcount;
1741
de3b08ac
ILT
1742 relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
1743 if (relsize < 0)
1744 bfd_fatal (bfd_get_filename (abfd));
1745
c5ba2759
ILT
1746 printf ("DYNAMIC RELOCATION RECORDS");
1747
de3b08ac
ILT
1748 if (relsize == 0)
1749 {
1750 printf (" (none)\n\n");
1751 }
1752 else
1753 {
1754 relpp = (arelent **) xmalloc (relsize);
1755 relcount = bfd_canonicalize_dynamic_reloc (abfd, relpp, dynsyms);
1756 if (relcount < 0)
1757 bfd_fatal (bfd_get_filename (abfd));
1758 else if (relcount == 0)
1759 {
1760 printf (" (none)\n\n");
1761 }
1762 else
1763 {
1764 printf ("\n");
18f39dfa 1765 dump_reloc_set (abfd, (asection *) NULL, relpp, relcount);
de3b08ac
ILT
1766 printf ("\n\n");
1767 }
1768 free (relpp);
1769 }
1770}
1771
1772static void
18f39dfa 1773dump_reloc_set (abfd, sec, relpp, relcount)
de3b08ac 1774 bfd *abfd;
18f39dfa 1775 asection *sec;
de3b08ac
ILT
1776 arelent **relpp;
1777 long relcount;
1778{
1779 arelent **p;
18f39dfa
SG
1780 char *last_filename, *last_functionname;
1781 unsigned int last_line;
de3b08ac
ILT
1782
1783 /* Get column headers lined up reasonably. */
1784 {
1785 static int width;
1786 if (width == 0)
1787 {
1788 char buf[30];
1789 sprintf_vma (buf, (bfd_vma) -1);
1790 width = strlen (buf) - 7;
1791 }
1792 printf ("OFFSET %*s TYPE %*s VALUE \n", width, "", 12, "");
1793 }
1794
18f39dfa
SG
1795 last_filename = NULL;
1796 last_functionname = NULL;
1797 last_line = 0;
1798
de3b08ac
ILT
1799 for (p = relpp; relcount && *p != (arelent *) NULL; p++, relcount--)
1800 {
1801 arelent *q = *p;
18f39dfa
SG
1802 const char *filename, *functionname;
1803 unsigned int line;
1804 const char *sym_name;
1805 const char *section_name;
de3b08ac 1806
aa21a2a9
ILT
1807 if (start_address != (bfd_vma) -1
1808 && q->address < start_address)
1809 continue;
1810 if (stop_address != (bfd_vma) -1
1811 && q->address > stop_address)
1812 continue;
1813
18f39dfa
SG
1814 if (with_line_numbers
1815 && sec != NULL
1816 && bfd_find_nearest_line (abfd, sec, syms, q->address,
1817 &filename, &functionname, &line))
1818 {
1819 if (functionname != NULL
1820 && (last_functionname == NULL
1821 || strcmp (functionname, last_functionname) != 0))
1822 {
1823 printf ("%s():\n", functionname);
1824 if (last_functionname != NULL)
1825 free (last_functionname);
1826 last_functionname = xstrdup (functionname);
1827 }
1828 if (line > 0
1829 && (line != last_line
1830 || (filename != NULL
1831 && last_filename != NULL
1832 && strcmp (filename, last_filename) != 0)))
1833 {
1834 printf ("%s:%u\n", filename == NULL ? "???" : filename, line);
1835 last_line = line;
1836 if (last_filename != NULL)
1837 free (last_filename);
1838 if (filename == NULL)
1839 last_filename = NULL;
1840 else
1841 last_filename = xstrdup (filename);
1842 }
1843 }
1844
de3b08ac
ILT
1845 if (q->sym_ptr_ptr && *q->sym_ptr_ptr)
1846 {
1847 sym_name = (*(q->sym_ptr_ptr))->name;
1848 section_name = (*(q->sym_ptr_ptr))->section->name;
1849 }
1850 else
1851 {
1852 sym_name = NULL;
1853 section_name = NULL;
1854 }
1855 if (sym_name)
1856 {
1857 printf_vma (q->address);
1858 printf (" %-16s %s",
1859 q->howto->name,
1860 sym_name);
1861 }
1862 else
1863 {
1864 if (section_name == (CONST char *) NULL)
1865 section_name = "*unknown*";
1866 printf_vma (q->address);
1867 printf (" %-16s [%s]",
1868 q->howto->name,
1869 section_name);
1870 }
1871 if (q->addend)
1872 {
1873 printf ("+0x");
1874 printf_vma (q->addend);
1875 }
1876 printf ("\n");
d20f480f 1877 }
2fa0b342 1878}
f7b839f7 1879\f
f7b839f7
DM
1880/* The length of the longest architecture name + 1. */
1881#define LONGEST_ARCH sizeof("rs6000:6000")
1882
e1c14599
ILT
1883static const char *
1884endian_string (endian)
1885 enum bfd_endian endian;
1886{
1887 if (endian == BFD_ENDIAN_BIG)
1888 return "big endian";
1889 else if (endian == BFD_ENDIAN_LITTLE)
1890 return "little endian";
1891 else
1892 return "endianness unknown";
1893}
1894
f7b839f7
DM
1895/* List the targets that BFD is configured to support, each followed
1896 by its endianness and the architectures it supports. */
1897
1898static void
1899display_target_list ()
1900{
1901 extern bfd_target *bfd_target_vector[];
de04bceb 1902 char *dummy_name;
f7b839f7
DM
1903 int t;
1904
7f924d55 1905 dummy_name = choose_temp_base ();
f7b839f7
DM
1906 for (t = 0; bfd_target_vector[t]; t++)
1907 {
f7b839f7 1908 bfd_target *p = bfd_target_vector[t];
de04bceb 1909 bfd *abfd = bfd_openw (dummy_name, p->name);
105da05c
ILT
1910 int a;
1911
1912 printf ("%s\n (header %s, data %s)\n", p->name,
e1c14599
ILT
1913 endian_string (p->header_byteorder),
1914 endian_string (p->byteorder));
f7b839f7 1915
334d6e76
SS
1916 if (abfd == NULL)
1917 {
de04bceb 1918 bfd_nonfatal (dummy_name);
105da05c 1919 continue;
334d6e76 1920 }
105da05c
ILT
1921
1922 if (! bfd_set_format (abfd, bfd_object))
1923 {
1924 if (bfd_get_error () != bfd_error_invalid_operation)
1925 bfd_nonfatal (p->name);
1926 continue;
1927 }
1928
f7b839f7
DM
1929 for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
1930 if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
1931 printf (" %s\n",
1932 bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
1933 }
de04bceb 1934 unlink (dummy_name);
7f924d55 1935 free (dummy_name);
f7b839f7
DM
1936}
1937
1938/* Print a table showing which architectures are supported for entries
1939 FIRST through LAST-1 of bfd_target_vector (targets across,
1940 architectures down). */
1941
9872a49c 1942static void
abdcac0f
DM
1943display_info_table (first, last)
1944 int first;
1945 int last;
9872a49c 1946{
abdcac0f 1947 extern bfd_target *bfd_target_vector[];
de04bceb
ILT
1948 int t, a;
1949 char *dummy_name;
9872a49c 1950
f7b839f7 1951 /* Print heading of target names. */
ae5d2ff5 1952 printf ("\n%*s", (int) LONGEST_ARCH, " ");
105da05c 1953 for (t = first; t < last && bfd_target_vector[t]; t++)
f7b839f7
DM
1954 printf ("%s ", bfd_target_vector[t]->name);
1955 putchar ('\n');
9872a49c 1956
7f924d55 1957 dummy_name = choose_temp_base ();
f7b839f7
DM
1958 for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
1959 if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0)
e779a58c 1960 {
ae5d2ff5
ILT
1961 printf ("%*s ", (int) LONGEST_ARCH - 1,
1962 bfd_printable_arch_mach (a, 0));
105da05c 1963 for (t = first; t < last && bfd_target_vector[t]; t++)
aa0a709a 1964 {
f7b839f7 1965 bfd_target *p = bfd_target_vector[t];
105da05c 1966 boolean ok = true;
de04bceb 1967 bfd *abfd = bfd_openw (dummy_name, p->name);
aa0a709a 1968
334d6e76
SS
1969 if (abfd == NULL)
1970 {
105da05c
ILT
1971 bfd_nonfatal (p->name);
1972 ok = false;
1973 }
1974
1975 if (ok)
1976 {
1977 if (! bfd_set_format (abfd, bfd_object))
1978 {
1979 if (bfd_get_error () != bfd_error_invalid_operation)
1980 bfd_nonfatal (p->name);
1981 ok = false;
1982 }
334d6e76 1983 }
105da05c
ILT
1984
1985 if (ok)
1986 {
1987 if (! bfd_set_arch_mach (abfd, a, 0))
1988 ok = false;
1989 }
1990
1991 if (ok)
aa0a709a
SC
1992 printf ("%s ", p->name);
1993 else
e779a58c 1994 {
f7b839f7 1995 int l = strlen (p->name);
aa0a709a 1996 while (l--)
f7b839f7
DM
1997 putchar ('-');
1998 putchar (' ');
e779a58c 1999 }
e779a58c 2000 }
f7b839f7 2001 putchar ('\n');
e779a58c 2002 }
de04bceb 2003 unlink (dummy_name);
7f924d55 2004 free (dummy_name);
9872a49c 2005}
aa0a709a 2006
f7b839f7
DM
2007/* Print tables of all the target-architecture combinations that
2008 BFD has been configured to support. */
2009
aa0a709a 2010static void
f7b839f7 2011display_target_tables ()
aa0a709a 2012{
f7b839f7 2013 int t, columns;
abdcac0f 2014 extern bfd_target *bfd_target_vector[];
f7b839f7 2015 char *colum;
aa0a709a
SC
2016 extern char *getenv ();
2017
aa0a709a 2018 columns = 0;
f7b839f7
DM
2019 colum = getenv ("COLUMNS");
2020 if (colum != NULL)
aa0a709a 2021 columns = atoi (colum);
f7b839f7 2022 if (columns == 0)
aa0a709a 2023 columns = 80;
f7b839f7 2024
105da05c
ILT
2025 t = 0;
2026 while (bfd_target_vector[t] != NULL)
aa0a709a 2027 {
f7b839f7
DM
2028 int oldt = t, wid;
2029
105da05c
ILT
2030 wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
2031 ++t;
2032 while (wid < columns && bfd_target_vector[t] != NULL)
2033 {
2034 int newwid;
2035
2036 newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
2037 if (newwid >= columns)
2038 break;
2039 wid = newwid;
2040 ++t;
2041 }
f7b839f7 2042 display_info_table (oldt, t);
aa0a709a
SC
2043 }
2044}
2045
f7b839f7
DM
2046static void
2047display_info ()
2048{
2049 printf ("BFD header file version %s\n", BFD_VERSION);
2050 display_target_list ();
2051 display_target_tables ();
2052}
2053
2fa0b342
DHW
2054int
2055main (argc, argv)
2056 int argc;
2057 char **argv;
2058{
2059 int c;
2fa0b342
DHW
2060 char *target = default_target;
2061 boolean seenflag = false;
2fa0b342
DHW
2062
2063 program_name = *argv;
8f197c94
ILT
2064 xmalloc_set_program_name (program_name);
2065
be1d162b
ILT
2066 START_PROGRESS (program_name, 0);
2067
8f197c94 2068 bfd_init ();
2fa0b342 2069
18f39dfa
SG
2070 while ((c = getopt_long (argc, argv, "pib:m:VdDlfahrRtTxsSj:wE:",
2071 long_options, (int *) 0))
aa0a709a
SC
2072 != EOF)
2073 {
aa21a2a9
ILT
2074 if (c != 'l' && c != OPTION_START_ADDRESS && c != OPTION_STOP_ADDRESS)
2075 seenflag = true;
aa0a709a
SC
2076 switch (c)
2077 {
b3a2b497
ILT
2078 case 0:
2079 break; /* we've been given a long option */
aa0a709a
SC
2080 case 'm':
2081 machine = optarg;
2082 break;
2083 case 'j':
2084 only = optarg;
2085 break;
2086 case 'l':
2087 with_line_numbers = 1;
2088 break;
2089 case 'b':
2090 target = optarg;
2091 break;
2092 case 'f':
2093 dump_file_header = true;
2094 break;
2095 case 'i':
e1ec9f07 2096 formats_info = true;
aa0a709a 2097 break;
a65619c8
SC
2098 case 'p':
2099 dump_private_headers = 1;
2100 break;
aa0a709a 2101 case 'x':
a65619c8 2102 dump_private_headers = 1;
aa0a709a
SC
2103 dump_symtab = 1;
2104 dump_reloc_info = 1;
2105 dump_file_header = true;
2106 dump_ar_hdrs = 1;
2107 dump_section_headers = 1;
2108 break;
aa0a709a
SC
2109 case 't':
2110 dump_symtab = 1;
2111 break;
de3b08ac
ILT
2112 case 'T':
2113 dump_dynamic_symtab = 1;
2114 break;
aa0a709a
SC
2115 case 'd':
2116 disassemble = true;
2117 break;
d5464baa
ILT
2118 case 'D':
2119 disassemble = disassemble_all = true;
2120 break;
be1d162b
ILT
2121 case 'S':
2122 disassemble = true;
2123 with_source_code = true;
2124 break;
aa0a709a
SC
2125 case 's':
2126 dump_section_contents = 1;
2127 break;
2128 case 'r':
2129 dump_reloc_info = 1;
2130 break;
de3b08ac
ILT
2131 case 'R':
2132 dump_dynamic_reloc_info = 1;
2133 break;
aa0a709a
SC
2134 case 'a':
2135 dump_ar_hdrs = 1;
2136 break;
2137 case 'h':
2138 dump_section_headers = 1;
2139 break;
b3a2b497
ILT
2140 case 'H':
2141 usage (stdout, 0);
249c6fc0
RS
2142 case 'V':
2143 show_version = 1;
2144 break;
13e4db2e
SC
2145 case 'w':
2146 wide_output = 1;
2147 break;
aa21a2a9
ILT
2148 case OPTION_START_ADDRESS:
2149 start_address = parse_vma (optarg, "--start-address");
2150 break;
2151 case OPTION_STOP_ADDRESS:
2152 stop_address = parse_vma (optarg, "--stop-address");
2153 break;
18f39dfa
SG
2154 case 'E':
2155 if (strcmp (optarg, "B") == 0)
2156 endian = BFD_ENDIAN_BIG;
2157 else if (strcmp (optarg, "L") == 0)
2158 endian = BFD_ENDIAN_LITTLE;
2159 else
2160 {
2161 fprintf (stderr, "%s: unrecognized -E option\n", program_name);
2162 usage (stderr, 1);
2163 }
2164 break;
2165 case OPTION_ENDIAN:
2166 if (strncmp (optarg, "big", strlen (optarg)) == 0)
2167 endian = BFD_ENDIAN_BIG;
2168 else if (strncmp (optarg, "little", strlen (optarg)) == 0)
2169 endian = BFD_ENDIAN_LITTLE;
2170 else
2171 {
2172 fprintf (stderr, "%s: unrecognized --endian type `%s'\n",
2173 program_name, optarg);
2174 usage (stderr, 1);
2175 }
2176 break;
aa0a709a 2177 default:
b3a2b497 2178 usage (stderr, 1);
aa0a709a 2179 }
2fa0b342 2180 }
2fa0b342 2181
249c6fc0 2182 if (show_version)
7f924d55 2183 print_version ("objdump");
249c6fc0 2184
2fa0b342 2185 if (seenflag == false)
b3a2b497 2186 usage (stderr, 1);
2fa0b342 2187
e1ec9f07 2188 if (formats_info)
aa0a709a
SC
2189 {
2190 display_info ();
2191 }
2192 else
2193 {
2194 if (optind == argc)
2195 display_file ("a.out", target);
2196 else
2197 for (; optind < argc;)
2198 display_file (argv[optind++], target);
2199 }
be1d162b
ILT
2200
2201 END_PROGRESS (program_name);
2202
2fa0b342
DHW
2203 return 0;
2204}
This page took 0.288546 seconds and 4 git commands to generate.