/* objdump.c -- dump information about an object file.
- Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001
+ Free Software Foundation, Inc.
This file is part of GNU Binutils.
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
-#include "getopt.h"
#include "progress.h"
#include "bucomm.h"
-#include <ctype.h>
+#include "getopt.h"
+#include "safe-ctype.h"
#include "dis-asm.h"
#include "libiberty.h"
+#include "demangle.h"
#include "debug.h"
#include "budbg.h"
-#ifdef ANSI_PROTOTYPES
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
/* Internal headers for the ELF .stab-dump code - sorry. */
#define BYTES_IN_WORD 32
#include "aout/aout64.h"
extern int fprintf PARAMS ((FILE *, const char *, ...));
#endif
+/* Exit status. */
+static int exit_status = 0;
+
static char *default_target = NULL; /* default at runtime */
static int show_version = 0; /* show the version number */
static boolean with_source_code; /* -S */
static int show_raw_insn; /* --show-raw-insn */
static int dump_stab_section_info; /* --stabs */
+static int do_demangle; /* -C, --demangle */
static boolean disassemble; /* -d */
static boolean disassemble_all; /* -D */
static int disassemble_zeroes; /* --disassemble-zeroes */
static bfd_vma start_address = (bfd_vma) -1; /* --start-address */
static bfd_vma stop_address = (bfd_vma) -1; /* --stop-address */
static int dump_debugging; /* --debugging */
+static bfd_vma adjust_section_vma = 0; /* --adjust-vma */
+static int file_start_context = 0; /* --file-start-context */
/* Extra info to pass to the disassembler address printing function. */
struct objdump_disasm_info {
/* Architecture to disassemble for, or default if NULL. */
static char *machine = (char *) NULL;
+/* Target specific options to the disassembler. */
+static char *disassembler_options = (char *) NULL;
+
/* Endianness to disassemble for, or default if BFD_ENDIAN_UNKNOWN. */
static enum bfd_endian endian = BFD_ENDIAN_UNKNOWN;
/* Number of symbols in `dynsyms'. */
static long dynsymcount = 0;
-/* Forward declarations. */
-
-static void
-display_file PARAMS ((char *filename, char *target));
-
-static void
-dump_data PARAMS ((bfd *abfd));
-
-static void
-dump_relocs PARAMS ((bfd *abfd));
-
-static void
-dump_dynamic_relocs PARAMS ((bfd * abfd));
-
-static void
-dump_reloc_set PARAMS ((bfd *, asection *, arelent **, long));
-
-static void
-dump_symbols PARAMS ((bfd *abfd, boolean dynamic));
-
-static void
-display_bfd PARAMS ((bfd *abfd));
-
-static void
-objdump_print_value PARAMS ((bfd_vma, struct disassemble_info *, boolean));
-
-static asymbol *
-find_symbol_for_address PARAMS ((bfd *, asection *, bfd_vma, boolean, long *));
-
-static void
-objdump_print_addr_with_sym PARAMS ((bfd *, asection *, asymbol *, bfd_vma,
- struct disassemble_info *, boolean));
-
-static void
-objdump_print_addr PARAMS ((bfd_vma, struct disassemble_info *, boolean));
-
-static void
-objdump_print_address PARAMS ((bfd_vma, struct disassemble_info *));
-
-static void
-show_line PARAMS ((bfd *, asection *, bfd_vma));
-
-static void
-disassemble_bytes PARAMS ((struct disassemble_info *, disassembler_ftype,
- boolean, bfd_byte *, long, long, arelent ***,
- arelent **));
-
-static void
-disassemble_data PARAMS ((bfd *));
-
-static const char *
-endian_string PARAMS ((enum bfd_endian));
+/* Static declarations. */
+
+static void usage PARAMS ((FILE *, int));
+static void nonfatal PARAMS ((const char *));
+static void display_file PARAMS ((char *filename, char *target));
+static void dump_section_header PARAMS ((bfd *, asection *, PTR));
+static void dump_headers PARAMS ((bfd *));
+static void dump_data PARAMS ((bfd *abfd));
+static void dump_relocs PARAMS ((bfd *abfd));
+static void dump_dynamic_relocs PARAMS ((bfd * abfd));
+static void dump_reloc_set PARAMS ((bfd *, asection *, arelent **, long));
+static void dump_symbols PARAMS ((bfd *abfd, boolean dynamic));
+static void dump_bfd_header PARAMS ((bfd *));
+static void dump_bfd_private_header PARAMS ((bfd *));
+static void dump_bfd PARAMS ((bfd *));
+static void display_bfd PARAMS ((bfd *abfd));
+static void display_target_list PARAMS ((void));
+static void display_info_table PARAMS ((int, int));
+static void display_target_tables PARAMS ((void));
+static void display_info PARAMS ((void));
+static void objdump_print_value
+ PARAMS ((bfd_vma, struct disassemble_info *, boolean));
+static void objdump_print_symname
+ PARAMS ((bfd *, struct disassemble_info *, asymbol *));
+static asymbol *find_symbol_for_address
+ PARAMS ((bfd *, asection *, bfd_vma, boolean, long *));
+static void objdump_print_addr_with_sym
+ PARAMS ((bfd *, asection *, asymbol *, bfd_vma,
+ struct disassemble_info *, boolean));
+static void objdump_print_addr
+ PARAMS ((bfd_vma, struct disassemble_info *, boolean));
+static void objdump_print_address
+ PARAMS ((bfd_vma, struct disassemble_info *));
+static int objdump_symbol_at_address
+ PARAMS ((bfd_vma, struct disassemble_info *));
+static void show_line PARAMS ((bfd *, asection *, bfd_vma));
+static void disassemble_bytes
+ PARAMS ((struct disassemble_info *, disassembler_ftype, boolean,
+ bfd_byte *, bfd_vma, bfd_vma, arelent ***, arelent **));
+static void disassemble_data PARAMS ((bfd *));
+static const char *endian_string PARAMS ((enum bfd_endian));
+static asymbol ** slurp_symtab PARAMS ((bfd *));
+static asymbol ** slurp_dynamic_symtab PARAMS ((bfd *));
+static long remove_useless_symbols PARAMS ((asymbol **, long));
+static int compare_symbols PARAMS ((const PTR, const PTR));
+static int compare_relocs PARAMS ((const PTR, const PTR));
+static void dump_stabs PARAMS ((bfd *));
+static boolean read_section_stabs PARAMS ((bfd *, const char *, const char *));
+static void print_section_stabs PARAMS ((bfd *, const char *, const char *));
\f
static void
usage (stream, status)
FILE *stream;
int status;
{
- fprintf (stream, "\
-Usage: %s [-ahifdDprRtTxsSlw] [-b bfdname] [-m machine] [-j section-name]\n\
- [--archive-headers] [--target=bfdname] [--debugging] [--disassemble]\n\
- [--disassemble-all] [--disassemble-zeroes] [--file-headers]\n\
- [--section-headers] [--headers]\n\
- [--info] [--section=section-name] [--line-numbers] [--source]\n",
- program_name);
- fprintf (stream, "\
- [--architecture=machine] [--reloc] [--full-contents] [--stabs]\n\
- [--syms] [--all-headers] [--dynamic-syms] [--dynamic-reloc]\n\
- [--wide] [--version] [--help] [--private-headers]\n\
- [--start-address=addr] [--stop-address=addr]\n\
- [--prefix-addresses] [--show-raw-insn]\n\
- [-EB|-EL] [--endian={big|little}] objfile...\n\
-at least one option besides -l (--line-numbers) must be given\n");
- list_supported_targets (program_name, stream);
+ fprintf (stream, _("Usage: %s <option(s)> <file(s)>\n"), program_name);
+ fprintf (stream, _(" Display information from object <file(s)>.\n"));
+ fprintf (stream, _(" At least one of the following switches must be given:\n"));
+ fprintf (stream, _("\
+ -a, --archive-headers Display archive header information\n\
+ -f, --file-headers Display the contents of the overall file header\n\
+ -p, --private-headers Display object format specific file header contents\n\
+ -h, --[section-]headers Display the contents of the section headers\n\
+ -x, --all-headers Display the contents of all headers\n\
+ -d, --disassemble Display assembler contents of executable sections\n\
+ -D, --disassemble-all Display assembler contents of all sections\n\
+ -S, --source Intermix source code with disassembly\n\
+ -s, --full-contents Display the full contents of all sections requested\n\
+ -g, --debugging Display debug information in object file\n\
+ -G, --stabs Display (in raw form) any STABS info in the file\n\
+ -t, --syms Display the contents of the symbol table(s)\n\
+ -T, --dynamic-syms Display the contents of the dynamic symbol table\n\
+ -r, --reloc Display the relocation entries in the file\n\
+ -R, --dynamic-reloc Display the dynamic relocation entries in the file\n\
+ -v, --version Display this program's version number\n\
+ -i, --info List object formats and architectures supported\n\
+ -H, --help Display this information\n\
+"));
+ if (status != 2)
+ {
+ fprintf (stream, _("\n The following switches are optional:\n"));
+ fprintf (stream, _("\
+ -b, --target=BFDNAME Specify the target object format as BFDNAME\n\
+ -m, --architecture=MACHINE Specify the target architecture as MACHINE\n\
+ -j, --section=NAME Only display information for section NAME\n\
+ -M, --disassembler-options=OPT Pass text OPT on to the disassembler\n\
+ -EB --endian=big Assume big endian format when disassembling\n\
+ -EL --endian=little Assume little endian format when disassembling\n\
+ --file-start-context Include context from start of file (with -S)\n\
+ -l, --line-numbers Include line numbers and filenames in output\n\
+ -C, --demangle[=STYLE] Decode mangled/processed symbol names\n\
+ The STYLE, if specified, can be `auto', 'gnu',\n\
+ 'lucid', 'arm', 'hp', 'edg', or 'gnu-new-abi'\n\
+ -w, --wide Format output for more than 80 columns\n\
+ -z, --disassemble-zeroes Do not skip blocks of zeroes when disassembling\n\
+ --start-address=ADDR Only process data whoes address is >= ADDR\n\
+ --stop-address=ADDR Only process data whoes address is <= ADDR\n\
+ --prefix-addresses Print complete address alongside disassembly\n\
+ --[no-]show-raw-insn Display hex alongside symbolic disassembly\n\
+ --adjust-vma=OFFSET Add OFFSET to all displayed section addresses\n\
+\n"));
+ list_supported_targets (program_name, stream);
+ list_supported_architectures (program_name, stream);
+
+ disassembler_usage (stream);
+ }
if (status == 0)
- fprintf (stream, "Report bugs to bug-gnu-utils@prep.ai.mit.edu\n");
+ fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO);
exit (status);
}
#define OPTION_ENDIAN (150)
#define OPTION_START_ADDRESS (OPTION_ENDIAN + 1)
#define OPTION_STOP_ADDRESS (OPTION_START_ADDRESS + 1)
+#define OPTION_ADJUST_VMA (OPTION_STOP_ADDRESS + 1)
static struct option long_options[]=
{
+ {"adjust-vma", required_argument, NULL, OPTION_ADJUST_VMA},
{"all-headers", no_argument, NULL, 'x'},
{"private-headers", no_argument, NULL, 'p'},
{"architecture", required_argument, NULL, 'm'},
{"archive-headers", no_argument, NULL, 'a'},
- {"debugging", no_argument, &dump_debugging, 1},
+ {"debugging", no_argument, NULL, 'g'},
+ {"demangle", optional_argument, NULL, 'C'},
{"disassemble", no_argument, NULL, 'd'},
{"disassemble-all", no_argument, NULL, 'D'},
- {"disassemble-zeroes", no_argument, &disassemble_zeroes, 1},
+ {"disassembler-options", required_argument, NULL, 'M'},
+ {"disassemble-zeroes", no_argument, NULL, 'z'},
{"dynamic-reloc", no_argument, NULL, 'R'},
{"dynamic-syms", no_argument, NULL, 'T'},
{"endian", required_argument, NULL, OPTION_ENDIAN},
{"file-headers", no_argument, NULL, 'f'},
+ {"file-start-context", no_argument, &file_start_context, 1},
{"full-contents", no_argument, NULL, 's'},
{"headers", no_argument, NULL, 'h'},
{"help", no_argument, NULL, 'H'},
{"info", no_argument, NULL, 'i'},
{"line-numbers", no_argument, NULL, 'l'},
+ {"no-show-raw-insn", no_argument, &show_raw_insn, -1},
{"prefix-addresses", no_argument, &prefix_addresses, 1},
{"reloc", no_argument, NULL, 'r'},
{"section", required_argument, NULL, 'j'},
{"section-headers", no_argument, NULL, 'h'},
{"show-raw-insn", no_argument, &show_raw_insn, 1},
{"source", no_argument, NULL, 'S'},
- {"stabs", no_argument, &dump_stab_section_info, 1},
+ {"stabs", no_argument, NULL, 'G'},
{"start-address", required_argument, NULL, OPTION_START_ADDRESS},
{"stop-address", required_argument, NULL, OPTION_STOP_ADDRESS},
{"syms", no_argument, NULL, 't'},
{"target", required_argument, NULL, 'b'},
- {"version", no_argument, &show_version, 1},
- {"wide", no_argument, &wide_output, 'w'},
+ {"version", no_argument, NULL, 'V'},
+ {"wide", no_argument, NULL, 'w'},
{0, no_argument, 0, 0}
};
\f
static void
+nonfatal (msg)
+ const char *msg;
+{
+ bfd_nonfatal (msg);
+ exit_status = 1;
+}
+\f
+static void
dump_section_header (abfd, section, ignored)
- bfd *abfd;
+ bfd *abfd ATTRIBUTE_UNUSED;
asection *section;
- PTR ignored;
+ PTR ignored ATTRIBUTE_UNUSED;
{
char *comma = "";
+ unsigned int opb = bfd_octets_per_byte (abfd);
printf ("%3d %-13s %08lx ", section->index,
bfd_get_section_name (abfd, section),
- (unsigned long) bfd_section_size (abfd, section));
- printf_vma (bfd_get_section_vma (abfd, section));
+ (unsigned long) bfd_section_size (abfd, section) / opb);
+ bfd_printf_vma (abfd, bfd_get_section_vma (abfd, section));
printf (" ");
- printf_vma (section->lma);
- printf (" %08lx 2**%u", section->filepos,
+ bfd_printf_vma (abfd, section->lma);
+ printf (" %08lx 2**%u", (unsigned long) section->filepos,
bfd_get_section_alignment (abfd, section));
if (! wide_output)
printf ("\n ");
PF (SEC_HAS_CONTENTS, "CONTENTS");
PF (SEC_ALLOC, "ALLOC");
PF (SEC_CONSTRUCTOR, "CONSTRUCTOR");
- PF (SEC_CONSTRUCTOR_TEXT, "CONSTRUCTOR TEXT");
- PF (SEC_CONSTRUCTOR_DATA, "CONSTRUCTOR DATA");
- PF (SEC_CONSTRUCTOR_BSS, "CONSTRUCTOR BSS");
PF (SEC_LOAD, "LOAD");
PF (SEC_RELOC, "RELOC");
-#ifdef SEC_BALIGN
- PF (SEC_BALIGN, "BALIGN");
-#endif
PF (SEC_READONLY, "READONLY");
PF (SEC_CODE, "CODE");
PF (SEC_DATA, "DATA");
PF (SEC_NEVER_LOAD, "NEVER_LOAD");
PF (SEC_EXCLUDE, "EXCLUDE");
PF (SEC_SORT_ENTRIES, "SORT_ENTRIES");
+ PF (SEC_BLOCK, "BLOCK");
+ PF (SEC_CLINK, "CLINK");
+ PF (SEC_SMALL_DATA, "SMALL_DATA");
+ PF (SEC_SHARED, "SHARED");
+ PF (SEC_ARCH_BIT_0, "ARCH_BIT_0");
+ PF (SEC_THREAD_LOCAL, "THREAD_LOCAL");
if ((section->flags & SEC_LINK_ONCE) != 0)
{
break;
}
printf ("%s%s", comma, ls);
+
+ if (section->comdat != NULL)
+ printf (" (COMDAT %s %ld)", section->comdat->name,
+ section->comdat->symbol);
+
comma = ", ";
}
dump_headers (abfd)
bfd *abfd;
{
- printf ("Sections:\n");
+ printf (_("Sections:\n"));
+
#ifndef BFD64
- printf ("Idx Name Size VMA LMA File off Algn\n");
+ printf (_("Idx Name Size VMA LMA File off Algn"));
#else
- printf ("Idx Name Size VMA LMA File off Algn\n");
+ /* With BFD64, non-ELF returns -1 and wants always 64 bit addresses. */
+ if (bfd_get_arch_size (abfd) == 32)
+ printf (_("Idx Name Size VMA LMA File off Algn"));
+ else
+ printf (_("Idx Name Size VMA LMA File off Algn"));
#endif
+
+ if (wide_output)
+ printf (_(" Flags"));
+ printf ("\n");
+
bfd_map_over_sections (abfd, dump_section_header, (PTR) NULL);
}
\f
if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
{
- printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
+ non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
symcount = 0;
return NULL;
}
if (symcount < 0)
bfd_fatal (bfd_get_filename (abfd));
if (symcount == 0)
- fprintf (stderr, "%s: %s: No symbols\n",
- program_name, bfd_get_filename (abfd));
+ non_fatal (_("%s: no symbols"), bfd_get_filename (abfd));
return sy;
}
{
if (!(bfd_get_file_flags (abfd) & DYNAMIC))
{
- fprintf (stderr, "%s: %s: not a dynamic object\n",
- program_name, bfd_get_filename (abfd));
+ non_fatal (_("%s: not a dynamic object"), bfd_get_filename (abfd));
dynsymcount = 0;
return NULL;
}
if (dynsymcount < 0)
bfd_fatal (bfd_get_filename (abfd));
if (dynsymcount == 0)
- fprintf (stderr, "%s: %s: No dynamic symbols\n",
- program_name, bfd_get_filename (abfd));
+ non_fatal (_("%s: No dynamic symbols"), bfd_get_filename (abfd));
return sy;
}
/* Filter out (in place) symbols that are useless for disassembly.
COUNT is the number of elements in SYMBOLS.
- Return the number of useful symbols. */
+ Return the number of useful symbols. */
static long
remove_useless_symbols (symbols, count)
/* Sort symbols into value order. */
-static int
+static int
compare_symbols (ap, bp)
const PTR ap;
const PTR bp;
{
char buf[30];
char *p;
+ struct objdump_disasm_info *aux
+ = (struct objdump_disasm_info *) info->application_data;
- sprintf_vma (buf, vma);
+ bfd_sprintf_vma (aux->abfd, buf, vma);
if (! skip_zeroes)
p = buf;
else
(*info->fprintf_func) (info->stream, "%s", p);
}
+/* Print the name of a symbol. */
+
+static void
+objdump_print_symname (abfd, info, sym)
+ bfd *abfd;
+ struct disassemble_info *info;
+ asymbol *sym;
+{
+ char *alloc;
+ const char *name;
+ const char *print;
+
+ alloc = NULL;
+ name = bfd_asymbol_name (sym);
+ if (! do_demangle || name[0] == '\0')
+ print = name;
+ else
+ {
+ /* Demangle the name. */
+ if (bfd_get_symbol_leading_char (abfd) == name[0])
+ ++name;
+
+ alloc = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
+ if (alloc == NULL)
+ print = name;
+ else
+ print = alloc;
+ }
+
+ if (info != NULL)
+ (*info->fprintf_func) (info->stream, "%s", print);
+ else
+ printf ("%s", print);
+
+ if (alloc != NULL)
+ free (alloc);
+}
+
/* Locate a symbol given a bfd, a section, and a VMA. If REQUIRE_SEC
is true, then always require the symbol to be in the section. This
returns NULL if there is no suitable symbol. If PLACE is not NULL,
long min = 0;
long max = sorted_symcount;
long thisplace;
+ unsigned int opb = bfd_octets_per_byte (abfd);
if (sorted_symcount < 1)
return NULL;
/* If the file is relocateable, and the symbol could be from this
section, prefer a symbol from this section over symbols from
others, even if the other symbol's value might be closer.
-
+
Note that this may be wrong for some symbol references if the
sections have overlapping memory ranges, but in that case there's
no way to tell what's desired without looking at the relocation
|| ((abfd->flags & HAS_RELOC) != 0
&& vma >= bfd_get_section_vma (abfd, sec)
&& vma < (bfd_get_section_vma (abfd, sec)
- + bfd_section_size (abfd, sec)))))
+ + bfd_section_size (abfd, sec) / opb))))
{
long i;
secaddr = bfd_get_section_vma (abfd, sec);
if (vma < secaddr)
{
- (*info->fprintf_func) (info->stream, "-");
+ (*info->fprintf_func) (info->stream, "-0x");
objdump_print_value (secaddr - vma, info, true);
}
else if (vma > secaddr)
{
- (*info->fprintf_func) (info->stream, "+");
+ (*info->fprintf_func) (info->stream, "+0x");
objdump_print_value (vma - secaddr, info, true);
}
(*info->fprintf_func) (info->stream, ">");
}
else
{
- (*info->fprintf_func) (info->stream, " <%s", sym->name);
+ (*info->fprintf_func) (info->stream, " <");
+ objdump_print_symname (abfd, info, sym);
if (bfd_asymbol_value (sym) > vma)
{
- (*info->fprintf_func) (info->stream, "-");
+ (*info->fprintf_func) (info->stream, "-0x");
objdump_print_value (bfd_asymbol_value (sym) - vma, info, true);
}
else if (vma > bfd_asymbol_value (sym))
{
- (*info->fprintf_func) (info->stream, "+");
+ (*info->fprintf_func) (info->stream, "+0x");
objdump_print_value (vma - bfd_asymbol_value (sym), info, true);
}
(*info->fprintf_func) (info->stream, ">");
if (sorted_symcount < 1)
{
+ (*info->fprintf_func) (info->stream, "0x");
objdump_print_value (vma, info, skip_zeroes);
return;
}
objdump_print_addr (vma, info, ! prefix_addresses);
}
+/* Determine of the given address has a symbol associated with it. */
+
+static int
+objdump_symbol_at_address (vma, info)
+ bfd_vma vma;
+ struct disassemble_info * info;
+{
+ struct objdump_disasm_info * aux;
+ asymbol * sym;
+
+ /* No symbols - do not bother checking. */
+ if (sorted_symcount < 1)
+ return 0;
+
+ aux = (struct objdump_disasm_info *) info->application_data;
+ sym = find_symbol_for_address (aux->abfd, aux->sec, vma, aux->require_sec,
+ (long *) NULL);
+
+ return (sym != NULL && (bfd_asymbol_value (sym) == vma));
+}
+
/* Hold the last function name and the last line number we displayed
in a disassembly. */
if (strchr (buf, '\n') != NULL)
++p->line;
}
-}
+}
/* Show the line number, or the source line, in a dissassembly
listing. */
static void
-show_line (abfd, section, off)
+show_line (abfd, section, addr_offset)
bfd *abfd;
asection *section;
- bfd_vma off;
+ bfd_vma addr_offset;
{
CONST char *filename;
CONST char *functionname;
if (! with_line_numbers && ! with_source_code)
return;
- if (! bfd_find_nearest_line (abfd, section, syms, off, &filename,
+ if (! bfd_find_nearest_line (abfd, section, syms, addr_offset, &filename,
&functionname, &line))
return;
else
{
l = line - SHOW_PRECEDING_CONTEXT_LINES;
- if (l <= 0)
- l = 1;
+ if (l < 0)
+ l = 0;
}
if (p->f == NULL)
p->next = print_files;
print_files = p;
- l = line - SHOW_PRECEDING_CONTEXT_LINES;
- if (l <= 0)
- l = 1;
+ if (file_start_context)
+ l = 0;
+ else
+ l = line - SHOW_PRECEDING_CONTEXT_LINES;
+ if (l < 0)
+ l = 0;
skip_to_line (p, l, false);
if (p->f != NULL)
skip_to_line (p, line, true);
}
/* Pseudo FILE object for strings. */
-typedef struct {
+typedef struct
+{
char *buffer;
+ size_t size;
char *current;
} SFILE;
/* sprintf to a "stream" */
-#ifdef ANSI_PROTOTYPES
static int
-objdump_sprintf (SFILE *f, const char *format, ...)
+objdump_sprintf VPARAMS ((SFILE *f, const char *format, ...))
{
- int n;
- va_list args;
+ char *buf;
+ size_t n;
- va_start (args, format);
- vsprintf (f->current, format, args);
- f->current += n = strlen (f->current);
- va_end (args);
- return n;
-}
-#else
-static int
-objdump_sprintf (va_alist)
- va_dcl
-{
- int n;
- SFILE *f;
- const char *format;
- va_list args;
-
- va_start (args);
- f = va_arg (args, SFILE *);
- format = va_arg (args, const char *);
- vsprintf (f->current, format, args);
- f->current += n = strlen (f->current);
- va_end (args);
+ VA_OPEN (args, format);
+ VA_FIXEDARG (args, SFILE *, f);
+ VA_FIXEDARG (args, const char *, format);
+
+ vasprintf (&buf, format, args);
+
+ if (buf == NULL)
+ {
+ va_end (args);
+ fatal (_("Out of virtual memory"));
+ }
+
+ n = strlen (buf);
+
+ while ((size_t) ((f->buffer + f->size) - f->current) < n + 1)
+ {
+ size_t curroff;
+
+ curroff = f->current - f->buffer;
+ f->size *= 2;
+ f->buffer = xrealloc (f->buffer, f->size);
+ f->current = f->buffer + curroff;
+ }
+
+ memcpy (f->current, buf, n);
+ f->current += n;
+ f->current[0] = '\0';
+
+ free (buf);
+
+ VA_CLOSE (args);
return n;
}
-#endif
/* The number of zeroes we want to see before we start skipping them.
The number is arbitrarily chosen. */
+#ifndef SKIP_ZEROES
#define SKIP_ZEROES (8)
+#endif
/* The number of zeroes to skip at the end of a section. If the
number of zeroes at the end is between SKIP_ZEROES_AT_END and
attempt to avoid disassembling zeroes inserted by section
alignment. */
+#ifndef SKIP_ZEROES_AT_END
#define SKIP_ZEROES_AT_END (3)
+#endif
/* Disassemble some data in memory between given values. */
static void
-disassemble_bytes (info, disassemble_fn, insns, data, start, stop, relppp,
+disassemble_bytes (info, disassemble_fn, insns, data,
+ start_offset, stop_offset, relppp,
relppend)
struct disassemble_info *info;
disassembler_ftype disassemble_fn;
boolean insns;
bfd_byte *data;
- long start;
- long stop;
+ bfd_vma start_offset;
+ bfd_vma stop_offset;
arelent ***relppp;
arelent **relppend;
{
struct objdump_disasm_info *aux;
asection *section;
- int bytes_per_line;
+ int octets_per_line;
boolean done_dot;
int skip_addr_chars;
- long i;
+ bfd_vma addr_offset;
+ int opb = info->octets_per_byte;
aux = (struct objdump_disasm_info *) info->application_data;
section = aux->sec;
if (insns)
- bytes_per_line = 4;
+ octets_per_line = 4;
else
- bytes_per_line = 16;
+ octets_per_line = 16;
/* Figure out how many characters to skip at the start of an
address, to make the disassembly look nicer. We discard leading
char buf[30];
char *s;
- sprintf_vma (buf,
- section->vma + bfd_section_size (section->owner, section));
+ bfd_sprintf_vma
+ (aux->abfd, buf,
+ (section->vma
+ + bfd_section_size (section->owner, section) / opb));
s = buf;
while (s[0] == '0' && s[1] == '0' && s[2] == '0' && s[3] == '0'
&& s[4] == '0')
info->insn_info_valid = 0;
done_dot = false;
- i = start;
- while (i < stop)
+ addr_offset = start_offset;
+ while (addr_offset < stop_offset)
{
- long z;
- int bytes;
+ bfd_vma z;
+ int octets = 0;
boolean need_nl = false;
- /* If we see more than SKIP_ZEROES bytes of zeroes, we just
+ /* If we see more than SKIP_ZEROES octets of zeroes, we just
print `...'. */
- for (z = i; z < stop; z++)
+ for (z = addr_offset * opb; z < stop_offset * opb; z++)
if (data[z] != 0)
break;
if (! disassemble_zeroes
&& (info->insn_info_valid == 0
|| info->branch_delay_insns == 0)
- && (z - i >= SKIP_ZEROES
- || (z == stop && z - i < SKIP_ZEROES_AT_END)))
+ && (z - addr_offset * opb >= SKIP_ZEROES
+ || (z == stop_offset * opb &&
+ z - addr_offset * opb < SKIP_ZEROES_AT_END)))
{
printf ("\t...\n");
- /* If there are more nonzero bytes to follow, we only skip
+ /* If there are more nonzero octets to follow, we only skip
zeroes in multiples of 4, to try to avoid running over
the start of an instruction which happens to start with
zero. */
- if (z != stop)
- z = i + ((z - i) &~ 3);
+ if (z != stop_offset * opb)
+ z = addr_offset * opb + ((z - addr_offset * opb) &~ 3);
- bytes = z - i;
+ octets = z - addr_offset * opb;
}
else
{
- char buf[1000];
+ char buf[50];
SFILE sfile;
+ int bpc = 0;
int pb = 0;
done_dot = false;
if (with_line_numbers || with_source_code)
- show_line (aux->abfd, section, i);
+ /* The line number tables will refer to unadjusted
+ section VMAs, so we must undo any VMA modifications
+ when calling show_line. */
+ show_line (aux->abfd, section, addr_offset - adjust_section_vma);
if (! prefix_addresses)
{
char *s;
- sprintf_vma (buf, section->vma + i);
+ bfd_sprintf_vma (aux->abfd, buf, section->vma + addr_offset);
for (s = buf + skip_addr_chars; *s == '0'; s++)
*s = ' ';
if (*s == '\0')
else
{
aux->require_sec = true;
- objdump_print_address (section->vma + i, info);
+ objdump_print_address (section->vma + addr_offset, info);
aux->require_sec = false;
putchar (' ');
}
if (insns)
{
- sfile.buffer = sfile.current = buf;
+ sfile.size = 120;
+ sfile.buffer = xmalloc (sfile.size);
+ sfile.current = sfile.buffer;
info->fprintf_func = (fprintf_ftype) objdump_sprintf;
info->stream = (FILE *) &sfile;
info->bytes_per_line = 0;
- bytes = (*disassemble_fn) (section->vma + i, info);
+ info->bytes_per_chunk = 0;
+
+#ifdef DISASSEMBLER_NEEDS_RELOCS
+ /* FIXME: This is wrong. It tests the number of octets
+ in the last instruction, not the current one. */
+ if (*relppp < relppend
+ && (**relppp)->address >= addr_offset
+ && (**relppp)->address <= addr_offset + octets / opb)
+ info->flags = INSN_HAS_RELOC;
+ else
+#endif
+ info->flags = 0;
+
+ octets = (*disassemble_fn) (section->vma + addr_offset, info);
info->fprintf_func = (fprintf_ftype) fprintf;
info->stream = stdout;
if (info->bytes_per_line != 0)
- bytes_per_line = info->bytes_per_line;
- if (bytes < 0)
- break;
+ octets_per_line = info->bytes_per_line;
+ if (octets < 0)
+ {
+ if (sfile.current != sfile.buffer)
+ printf ("%s\n", sfile.buffer);
+ free (sfile.buffer);
+ break;
+ }
}
else
{
- long j;
+ bfd_vma j;
- bytes = bytes_per_line;
- if (i + bytes > stop)
- bytes = stop - i;
+ octets = octets_per_line;
+ if (addr_offset + octets / opb > stop_offset)
+ octets = (stop_offset - addr_offset) * opb;
- for (j = i; j < i + bytes; ++j)
+ for (j = addr_offset * opb; j < addr_offset * opb + octets; ++j)
{
- if (isprint (data[j]))
- buf[j - i] = data[j];
+ if (ISPRINT (data[j]))
+ buf[j - addr_offset * opb] = data[j];
else
- buf[j - i] = '.';
+ buf[j - addr_offset * opb] = '.';
}
- buf[j - i] = '\0';
+ buf[j - addr_offset * opb] = '\0';
}
- if (! prefix_addresses || show_raw_insn)
+ if (prefix_addresses
+ ? show_raw_insn > 0
+ : show_raw_insn >= 0)
{
- long j;
+ bfd_vma j;
/* If ! prefix_addresses and ! wide_output, we print
- four bytes per line. */
- pb = bytes;
- if (pb > bytes_per_line && ! prefix_addresses && ! wide_output)
- pb = bytes_per_line;
+ octets_per_line octets per line. */
+ pb = octets;
+ if (pb > octets_per_line && ! prefix_addresses && ! wide_output)
+ pb = octets_per_line;
+
+ if (info->bytes_per_chunk)
+ bpc = info->bytes_per_chunk;
+ else
+ bpc = 1;
- for (j = i; j < i + pb; ++j)
+ for (j = addr_offset * opb; j < addr_offset * opb + pb; j += bpc)
{
- printf ("%02x", (unsigned) data[j]);
- putchar (' ');
+ int k;
+ if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE)
+ {
+ for (k = bpc - 1; k >= 0; k--)
+ printf ("%02x", (unsigned) data[j + k]);
+ putchar (' ');
+ }
+ else
+ {
+ for (k = 0; k < bpc; k++)
+ printf ("%02x", (unsigned) data[j + k]);
+ putchar (' ');
+ }
}
- for (; pb < bytes_per_line; ++pb)
- printf (" ");
+ for (; pb < octets_per_line; pb += bpc)
+ {
+ int k;
+
+ for (k = 0; k < bpc; k++)
+ printf (" ");
+ putchar (' ');
+ }
/* Separate raw data from instruction by extra space. */
if (insns)
printf (" ");
}
- printf ("%s", buf);
+ if (! insns)
+ printf ("%s", buf);
+ else
+ {
+ printf ("%s", sfile.buffer);
+ free (sfile.buffer);
+ }
- if (! prefix_addresses || show_raw_insn)
+ if (prefix_addresses
+ ? show_raw_insn > 0
+ : show_raw_insn >= 0)
{
- while (pb < bytes)
+ while (pb < octets)
{
- long j;
+ bfd_vma j;
char *s;
putchar ('\n');
- j = i + pb;
+ j = addr_offset * opb + pb;
- sprintf_vma (buf, section->vma + j);
+ bfd_sprintf_vma (aux->abfd, buf, section->vma + j / opb);
for (s = buf + skip_addr_chars; *s == '0'; s++)
*s = ' ';
if (*s == '\0')
*--s = '0';
printf ("%s:\t", buf + skip_addr_chars);
- pb += bytes_per_line;
- if (pb > bytes)
- pb = bytes;
- for (; j < i + pb; ++j)
+ pb += octets_per_line;
+ if (pb > octets)
+ pb = octets;
+ for (; j < addr_offset * opb + pb; j += bpc)
{
- printf ("%02x", (unsigned) data[j]);
- putchar (' ');
+ int k;
+
+ if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE)
+ {
+ for (k = bpc - 1; k >= 0; k--)
+ printf ("%02x", (unsigned) data[j + k]);
+ putchar (' ');
+ }
+ else
+ {
+ for (k = 0; k < bpc; k++)
+ printf ("%02x", (unsigned) data[j + k]);
+ putchar (' ');
+ }
}
}
}
need_nl = true;
}
- if (dump_reloc_info
- && (section->flags & SEC_RELOC) != 0)
+ if ((section->flags & SEC_RELOC) != 0
+#ifndef DISASSEMBLER_NEEDS_RELOCS
+ && dump_reloc_info
+#endif
+ )
{
while ((*relppp) < relppend
- && ((**relppp)->address >= (bfd_vma) i
- && (**relppp)->address < (bfd_vma) i + bytes))
+ && ((**relppp)->address >= (bfd_vma) addr_offset
+ && (**relppp)->address < (bfd_vma) addr_offset + octets / opb))
+#ifdef DISASSEMBLER_NEEDS_RELOCS
+ if (! dump_reloc_info)
+ ++(*relppp);
+ else
+#endif
{
arelent *q;
- const char *sym_name;
q = **relppp;
printf (": %s\t", q->howto->name);
- if (q->sym_ptr_ptr != NULL
- && *q->sym_ptr_ptr != NULL)
+ if (q->sym_ptr_ptr == NULL || *q->sym_ptr_ptr == NULL)
+ printf ("*unknown*");
+ else
{
+ const char *sym_name;
+
sym_name = bfd_asymbol_name (*q->sym_ptr_ptr);
- if (sym_name == NULL || *sym_name == '\0')
+ if (sym_name != NULL && *sym_name != '\0')
+ objdump_print_symname (aux->abfd, info, *q->sym_ptr_ptr);
+ else
{
asection *sym_sec;
sym_sec = bfd_get_section (*q->sym_ptr_ptr);
- sym_name = bfd_get_section_name (abfd, sym_sec);
+ sym_name = bfd_get_section_name (aux->abfd, sym_sec);
if (sym_name == NULL || *sym_name == '\0')
sym_name = "*unknown*";
+ printf ("%s", sym_name);
}
}
- else
- sym_name = "*unknown*";
-
- printf ("%s", sym_name);
if (q->addend)
{
if (need_nl)
printf ("\n");
- i += bytes;
+ addr_offset += octets / opb;
}
}
disassemble_data (abfd)
bfd *abfd;
{
- long i;
+ unsigned long addr_offset;
disassembler_ftype disassemble_fn;
struct disassemble_info disasm_info;
struct objdump_disasm_info aux;
asection *section;
+ unsigned int opb;
print_files = NULL;
prev_functionname = NULL;
aux.abfd = abfd;
aux.require_sec = false;
disasm_info.print_address_func = objdump_print_address;
+ disasm_info.symbol_at_address_func = objdump_symbol_at_address;
if (machine != (char *) NULL)
{
const bfd_arch_info_type *info = bfd_scan_arch (machine);
if (info == NULL)
{
- fprintf (stderr, "%s: Can't use supplied machine %s\n",
- program_name,
- machine);
- exit (1);
+ fatal (_("Can't use supplied machine %s"), machine);
}
abfd->arch_info = info;
}
disassemble_fn = disassembler (abfd);
if (!disassemble_fn)
{
- fprintf (stderr, "%s: Can't disassemble for architecture %s\n",
- program_name,
- bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
- exit (1);
+ non_fatal (_("Can't disassemble for architecture %s\n"),
+ bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
+ exit_status = 1;
+ return;
}
+ opb = bfd_octets_per_byte (abfd);
+
disasm_info.flavour = bfd_get_flavour (abfd);
disasm_info.arch = bfd_get_arch (abfd);
disasm_info.mach = bfd_get_mach (abfd);
+ disasm_info.disassembler_options = disassembler_options;
+ disasm_info.octets_per_byte = opb;
+
if (bfd_big_endian (abfd))
- disasm_info.endian = BFD_ENDIAN_BIG;
+ disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_BIG;
else if (bfd_little_endian (abfd))
- disasm_info.endian = BFD_ENDIAN_LITTLE;
+ disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE;
else
/* ??? Aborting here seems too drastic. We could default to big or little
instead. */
arelent **relbuf = NULL;
arelent **relpp = NULL;
arelent **relppend = NULL;
- long stop;
+ unsigned long stop_offset;
+ asymbol *sym = NULL;
+ long place = 0;
if ((section->flags & SEC_LOAD) == 0
|| (! disassemble_all
if (only != (char *) NULL && strcmp (only, section->name) != 0)
continue;
- if (dump_reloc_info
- && (section->flags & SEC_RELOC) != 0)
+ if ((section->flags & SEC_RELOC) != 0
+#ifndef DISASSEMBLER_NEEDS_RELOCS
+ && dump_reloc_info
+#endif
+ )
{
long relsize;
relpp = relbuf;
relppend = relpp + relcount;
+
+ /* Skip over the relocs belonging to addresses below the
+ start address. */
+ if (start_address != (bfd_vma) -1)
+ {
+ while (relpp < relppend
+ && (*relpp)->address < start_address)
+ ++relpp;
+ }
}
}
- printf ("Disassembly of section %s:\n", section->name);
+ printf (_("Disassembly of section %s:\n"), section->name);
datasize = bfd_get_section_size_before_reloc (section);
if (datasize == 0)
disasm_info.buffer = data;
disasm_info.buffer_vma = section->vma;
disasm_info.buffer_length = datasize;
+ disasm_info.section = section;
if (start_address == (bfd_vma) -1
|| start_address < disasm_info.buffer_vma)
- i = 0;
+ addr_offset = 0;
else
- i = start_address - disasm_info.buffer_vma;
+ addr_offset = start_address - disasm_info.buffer_vma;
if (stop_address == (bfd_vma) -1)
- stop = datasize;
+ stop_offset = datasize / opb;
else
{
if (stop_address < disasm_info.buffer_vma)
- stop = 0;
+ stop_offset = 0;
else
- stop = stop_address - disasm_info.buffer_vma;
- if (stop > disasm_info.buffer_length)
- stop = disasm_info.buffer_length;
+ stop_offset = stop_address - disasm_info.buffer_vma;
+ if (stop_offset > disasm_info.buffer_length / opb)
+ stop_offset = disasm_info.buffer_length / opb;
}
- if (prefix_addresses)
- disassemble_bytes (&disasm_info, disassemble_fn, true, data, i, stop,
- &relpp, relppend);
- else
+ sym = find_symbol_for_address (abfd, section, section->vma + addr_offset,
+ true, &place);
+
+ while (addr_offset < stop_offset)
{
- asymbol *sym;
- long place;
+ asymbol *nextsym;
+ unsigned long nextstop_offset;
+ boolean insns;
- sym = find_symbol_for_address (abfd, section, i, true, &place);
- ++place;
- while (i < stop)
+ if (sym != NULL && bfd_asymbol_value (sym) <= section->vma + addr_offset)
{
- asymbol *nextsym;
- long nextstop;
- boolean insns;
+ int x;
- disasm_info.symbol = sym;
+ for (x = place;
+ (x < sorted_symcount
+ && bfd_asymbol_value (sorted_syms[x]) <= section->vma + addr_offset);
+ ++x)
+ continue;
+ disasm_info.symbols = & sorted_syms[place];
+ disasm_info.num_symbols = x - place;
+ }
+ else
+ disasm_info.symbols = NULL;
+ if (! prefix_addresses)
+ {
printf ("\n");
objdump_print_addr_with_sym (abfd, section, sym,
- section->vma + i,
+ section->vma + addr_offset,
&disasm_info,
false);
printf (":\n");
+ }
- if (sym == NULL)
+ if (sym != NULL && bfd_asymbol_value (sym) > section->vma + addr_offset)
+ nextsym = sym;
+ else if (sym == NULL)
+ nextsym = NULL;
+ else
+ {
+ /* Search forward for the next appropriate symbol in
+ SECTION. Note that all the symbols are sorted
+ together into one big array, and that some sections
+ may have overlapping addresses. */
+ while (place < sorted_symcount
+ && (sorted_syms[place]->section != section
+ || (bfd_asymbol_value (sorted_syms[place])
+ <= bfd_asymbol_value (sym))))
+ ++place;
+ if (place >= sorted_symcount)
nextsym = NULL;
else
- {
- while (place < sorted_symcount
- && (sorted_syms[place]->section != section
- || (bfd_asymbol_value (sorted_syms[place])
- <= bfd_asymbol_value (sym))))
- ++place;
- if (place >= sorted_symcount)
- nextsym = NULL;
- else
- nextsym = sorted_syms[place];
- }
+ nextsym = sorted_syms[place];
+ }
- if (nextsym == NULL)
- nextstop = stop;
- else
- {
- nextstop = bfd_asymbol_value (nextsym) - section->vma;
- if (nextstop > stop)
- nextstop = stop;
- }
+ if (sym != NULL && bfd_asymbol_value (sym) > section->vma + addr_offset)
+ {
+ nextstop_offset = bfd_asymbol_value (sym) - section->vma;
+ if (nextstop_offset > stop_offset)
+ nextstop_offset = stop_offset;
+ }
+ else if (nextsym == NULL)
+ nextstop_offset = stop_offset;
+ else
+ {
+ nextstop_offset = bfd_asymbol_value (nextsym) - section->vma;
+ if (nextstop_offset > stop_offset)
+ nextstop_offset = stop_offset;
+ }
- /* If a symbol is explicitly marked as being an object
- rather than a function, just dump the bytes without
- disassembling them. */
- if (disassemble_all
- || sym == NULL
- || ((sym->flags & BSF_OBJECT) == 0
- && (strstr (bfd_asymbol_name (sym), "gnu_compiled")
- == NULL)
- && (strstr (bfd_asymbol_name (sym), "gcc2_compiled")
- == NULL))
- || (sym->flags & BSF_FUNCTION) != 0)
- insns = true;
- else
- insns = false;
+ /* If a symbol is explicitly marked as being an object
+ rather than a function, just dump the bytes without
+ disassembling them. */
+ if (disassemble_all
+ || sym == NULL
+ || bfd_asymbol_value (sym) > section->vma + addr_offset
+ || ((sym->flags & BSF_OBJECT) == 0
+ && (strstr (bfd_asymbol_name (sym), "gnu_compiled")
+ == NULL)
+ && (strstr (bfd_asymbol_name (sym), "gcc2_compiled")
+ == NULL))
+ || (sym->flags & BSF_FUNCTION) != 0)
+ insns = true;
+ else
+ insns = false;
- disassemble_bytes (&disasm_info, disassemble_fn, insns, data, i,
- nextstop, &relpp, relppend);
+ disassemble_bytes (&disasm_info, disassemble_fn, insns, data,
+ addr_offset, nextstop_offset, &relpp, relppend);
- i = nextstop;
- sym = nextsym;
- }
+ addr_offset = nextstop_offset;
+ sym = nextsym;
}
free (data);
static boolean
read_section_stabs (abfd, stabsect_name, strsect_name)
bfd *abfd;
- char *stabsect_name;
- char *strsect_name;
+ const char *stabsect_name;
+ const char *strsect_name;
{
asection *stabsect, *stabstrsect;
stabsect = bfd_get_section_by_name (abfd, stabsect_name);
if (0 == stabsect)
{
- printf ("No %s section present\n\n", stabsect_name);
+ printf (_("No %s section present\n\n"), stabsect_name);
return false;
}
stabstrsect = bfd_get_section_by_name (abfd, strsect_name);
if (0 == stabstrsect)
{
- fprintf (stderr, "%s: %s has no %s section\n", program_name,
- bfd_get_filename (abfd), strsect_name);
+ non_fatal (_("%s has no %s section"),
+ bfd_get_filename (abfd), strsect_name);
+ exit_status = 1;
return false;
}
-
+
stab_size = bfd_section_size (abfd, stabsect);
stabstr_size = bfd_section_size (abfd, stabstrsect);
stabs = (bfd_byte *) xmalloc (stab_size);
strtab = (char *) xmalloc (stabstr_size);
-
+
if (! bfd_get_section_contents (abfd, stabsect, (PTR) stabs, 0, stab_size))
{
- fprintf (stderr, "%s: Reading %s section of %s failed: %s\n",
- program_name, stabsect_name, bfd_get_filename (abfd),
- bfd_errmsg (bfd_get_error ()));
+ non_fatal (_("Reading %s section of %s failed: %s"),
+ stabsect_name, bfd_get_filename (abfd),
+ bfd_errmsg (bfd_get_error ()));
free (stabs);
free (strtab);
+ exit_status = 1;
return false;
}
if (! bfd_get_section_contents (abfd, stabstrsect, (PTR) strtab, 0,
stabstr_size))
{
- fprintf (stderr, "%s: Reading %s section of %s failed: %s\n",
- program_name, strsect_name, bfd_get_filename (abfd),
- bfd_errmsg (bfd_get_error ()));
+ non_fatal (_("Reading %s section of %s failed: %s\n"),
+ strsect_name, bfd_get_filename (abfd),
+ bfd_errmsg (bfd_get_error ()));
free (stabs);
free (strtab);
+ exit_status = 1;
return false;
}
static void
print_section_stabs (abfd, stabsect_name, strsect_name)
bfd *abfd;
- char *stabsect_name;
- char *strsect_name;
+ const char *stabsect_name;
+ const char *strsect_name ATTRIBUTE_UNUSED;
{
int i;
unsigned file_string_table_offset = 0, next_file_string_table_offset = 0;
stabp = stabs;
stabs_end = stabp + stab_size;
- printf ("Contents of %s section:\n\n", stabsect_name);
+ printf (_("Contents of %s section:\n\n"), stabsect_name);
printf ("Symnum n_type n_othr n_desc n_value n_strx String\n");
/* Loop through all symbols and print them.
printf ("\n%-6d ", i);
/* Either print the stab name, or, if unnamed, print its number
- again (makes consistent formatting for tools like awk). */
+ again (makes consistent formatting for tools like awk). */
name = bfd_get_stab_name (type);
if (name != NULL)
printf ("%-6s", name);
else
printf ("%-6d", type);
printf (" %-6d %-6d ", other, desc);
- printf_vma (value);
+ bfd_printf_vma (abfd, value);
printf (" %-6lu", strx);
/* Symbols with type == 0 (N_UNDF) specify the length of the
len = strlen (stabsect_name);
-/* If the prefix matches, and the files section name ends with a nul or a digit,
- then we match. Ie: we want either an exact match or a a section followed by
- a number. */
+ /* If the prefix matches, and the files section name ends with a
+ nul or a digit, then we match. I.e., we want either an exact
+ match or a section followed by a number. */
if (strncmp (stabsect_name, s->name, len) == 0
- && (s->name[len] == '\000' || isdigit (s->name[len])))
+ && (s->name[len] == '\000'
+ || ISDIGIT (s->name[len])))
{
if (read_section_stabs (abfd, s->name, strsect_name))
{
{
char *comma = "";
- printf ("architecture: %s, ",
+ printf (_("architecture: %s, "),
bfd_printable_arch_mach (bfd_get_arch (abfd),
bfd_get_mach (abfd)));
- printf ("flags 0x%08x:\n", abfd->flags);
+ printf (_("flags 0x%08x:\n"), abfd->flags);
#define PF(x, y) if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";}
PF (HAS_RELOC, "HAS_RELOC");
PF (WP_TEXT, "WP_TEXT");
PF (D_PAGED, "D_PAGED");
PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE");
- printf ("\nstart address 0x");
- printf_vma (abfd->start_address);
+ printf (_("\nstart address 0x"));
+ bfd_printf_vma (abfd, abfd->start_address);
printf ("\n");
}
\f
bfd_print_private_bfd_data (abfd, stdout);
}
+/* Dump selected contents of ABFD */
+
static void
-display_bfd (abfd)
+dump_bfd (abfd)
bfd *abfd;
{
- char **matching;
-
- if (!bfd_check_format_matches (abfd, bfd_object, &matching))
+ /* If we are adjusting section VMA's, change them all now. Changing
+ the BFD information is a hack. However, we must do it, or
+ bfd_find_nearest_line will not do the right thing. */
+ if (adjust_section_vma != 0)
{
- bfd_nonfatal (bfd_get_filename (abfd));
- if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ asection *s;
+
+ for (s = abfd->sections; s != NULL; s = s->next)
{
- list_matching_formats (matching);
- free (matching);
+ s->vma += adjust_section_vma;
+ s->lma += adjust_section_vma;
}
- return;
}
- printf ("\n%s: file format %s\n", bfd_get_filename (abfd),
+ printf (_("\n%s: file format %s\n"), bfd_get_filename (abfd),
abfd->xvec->name);
if (dump_ar_hdrs)
print_arelt_descr (stdout, abfd, true);
if (dhandle != NULL)
{
if (! print_debugging_info (stdout, dhandle))
- fprintf (stderr, "%s: printing debugging information failed\n",
- bfd_get_filename (abfd));
+ {
+ non_fatal (_("%s: printing debugging information failed"),
+ bfd_get_filename (abfd));
+ exit_status = 1;
+ }
}
}
if (syms)
}
static void
+display_bfd (abfd)
+ bfd *abfd;
+{
+ char **matching;
+
+ if (bfd_check_format_matches (abfd, bfd_object, &matching))
+ {
+ dump_bfd (abfd);
+ return;
+ }
+
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ {
+ nonfatal (bfd_get_filename (abfd));
+ list_matching_formats (matching);
+ free (matching);
+ return;
+ }
+
+ if (bfd_get_error () != bfd_error_file_not_recognized)
+ {
+ nonfatal (bfd_get_filename (abfd));
+ return;
+ }
+
+ if (bfd_check_format_matches (abfd, bfd_core, &matching))
+ {
+ dump_bfd (abfd);
+ return;
+ }
+
+ nonfatal (bfd_get_filename (abfd));
+
+ if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+ {
+ list_matching_formats (matching);
+ free (matching);
+ }
+}
+
+static void
display_file (filename, target)
char *filename;
char *target;
file = bfd_openr (filename, target);
if (file == NULL)
{
- bfd_nonfatal (filename);
+ nonfatal (filename);
return;
}
{
bfd *last_arfile = NULL;
- printf ("In archive %s:\n", bfd_get_filename (file));
+ printf (_("In archive %s:\n"), bfd_get_filename (file));
for (;;)
{
bfd_set_error (bfd_error_no_error);
if (arfile == NULL)
{
if (bfd_get_error () != bfd_error_no_more_archived_files)
- {
- bfd_nonfatal (bfd_get_filename (file));
- }
+ nonfatal (bfd_get_filename (file));
break;
}
asection *section;
bfd_byte *data = 0;
bfd_size_type datasize = 0;
- bfd_size_type i;
- bfd_size_type start, stop;
+ bfd_size_type addr_offset;
+ bfd_size_type start_offset, stop_offset;
+ unsigned int opb = bfd_octets_per_byte (abfd);
for (section = abfd->sections; section != NULL; section =
section->next)
{
if (section->flags & SEC_HAS_CONTENTS)
{
- printf ("Contents of section %s:\n", section->name);
+ printf (_("Contents of section %s:\n"), section->name);
if (bfd_section_size (abfd, section) == 0)
continue;
if (start_address == (bfd_vma) -1
|| start_address < section->vma)
- start = 0;
+ start_offset = 0;
else
- start = start_address - section->vma;
+ start_offset = start_address - section->vma;
if (stop_address == (bfd_vma) -1)
- stop = bfd_section_size (abfd, section);
+ stop_offset = bfd_section_size (abfd, section) / opb;
else
{
if (stop_address < section->vma)
- stop = 0;
+ stop_offset = 0;
else
- stop = stop_address - section->vma;
- if (stop > bfd_section_size (abfd, section))
- stop = bfd_section_size (abfd, section);
+ stop_offset = stop_address - section->vma;
+ if (stop_offset > bfd_section_size (abfd, section) / opb)
+ stop_offset = bfd_section_size (abfd, section) / opb;
}
- for (i = start; i < stop; i += onaline)
+ for (addr_offset = start_offset;
+ addr_offset < stop_offset; addr_offset += onaline)
{
bfd_size_type j;
- printf (" %04lx ", (unsigned long int) (i + section->vma));
- for (j = i; j < i + onaline; j++)
+ printf (" %04lx ", (unsigned long int)
+ (addr_offset + section->vma));
+ for (j = addr_offset * opb;
+ j < addr_offset * opb + onaline; j++)
{
- if (j < stop)
+ if (j < stop_offset * opb)
printf ("%02x", (unsigned) (data[j]));
else
printf (" ");
}
printf (" ");
- for (j = i; j < i + onaline; j++)
+ for (j = addr_offset; j < addr_offset * opb + onaline; j++)
{
- if (j >= stop)
+ if (j >= stop_offset * opb)
printf (" ");
else
- printf ("%c", isprint (data[j]) ? data[j] : '.');
+ printf ("%c", ISPRINT (data[j]) ? data[j] : '.');
}
putchar ('\n');
}
/* Should perhaps share code and display with nm? */
static void
dump_symbols (abfd, dynamic)
- bfd *abfd;
+ bfd *abfd ATTRIBUTE_UNUSED;
boolean dynamic;
{
asymbol **current;
{
if (*current)
{
- bfd *cur_bfd = bfd_asymbol_bfd(*current);
- if (cur_bfd)
+ bfd *cur_bfd = bfd_asymbol_bfd (*current);
+
+ if (cur_bfd != NULL)
{
- bfd_print_symbol (cur_bfd,
- stdout,
- *current, bfd_print_symbol_all);
+ const char *name;
+ char *alloc;
+
+ name = bfd_asymbol_name (*current);
+ alloc = NULL;
+ if (do_demangle && name != NULL && *name != '\0')
+ {
+ const char *n;
+
+ /* If we want to demangle the name, we demangle it
+ here, and temporarily clobber it while calling
+ bfd_print_symbol. FIXME: This is a gross hack. */
+
+ n = name;
+ if (bfd_get_symbol_leading_char (cur_bfd) == *n)
+ ++n;
+ alloc = cplus_demangle (n, DMGL_ANSI | DMGL_PARAMS);
+ if (alloc != NULL)
+ (*current)->name = alloc;
+ else
+ (*current)->name = n;
+ }
+
+ bfd_print_symbol (cur_bfd, stdout, *current,
+ bfd_print_symbol_all);
+
+ (*current)->name = name;
+ if (alloc != NULL)
+ free (alloc);
+
printf ("\n");
}
}
if (width == 0)
{
char buf[30];
- sprintf_vma (buf, (bfd_vma) -1);
+ bfd_sprintf_vma (abfd, buf, (bfd_vma) -1);
width = strlen (buf) - 7;
}
printf ("OFFSET %*s TYPE %*s VALUE \n", width, "", 12, "");
}
if (sym_name)
{
- printf_vma (q->address);
- printf (" %-16s %s",
- q->howto->name,
- sym_name);
+ bfd_printf_vma (abfd, q->address);
+ if (q->howto->name)
+ printf (" %-16s ", q->howto->name);
+ else
+ printf (" %-16d ", q->howto->type);
+ objdump_print_symname (abfd, (struct disassemble_info *) NULL,
+ *q->sym_ptr_ptr);
}
else
{
if (section_name == (CONST char *) NULL)
section_name = "*unknown*";
- printf_vma (q->address);
+ bfd_printf_vma (abfd, q->address);
printf (" %-16s [%s]",
q->howto->name,
section_name);
if (q->addend)
{
printf ("+0x");
- printf_vma (q->addend);
+ bfd_printf_vma (abfd, q->addend);
}
printf ("\n");
}
}
\f
/* The length of the longest architecture name + 1. */
-#define LONGEST_ARCH sizeof("rs6000:6000")
+#define LONGEST_ARCH sizeof("powerpc:common")
static const char *
endian_string (endian)
static void
display_target_list ()
{
- extern bfd_target *bfd_target_vector[];
+ extern const bfd_target *const *bfd_target_vector;
char *dummy_name;
int t;
- dummy_name = choose_temp_base ();
+ dummy_name = make_temp_file (NULL);
for (t = 0; bfd_target_vector[t]; t++)
{
- bfd_target *p = bfd_target_vector[t];
+ const bfd_target *p = bfd_target_vector[t];
bfd *abfd = bfd_openw (dummy_name, p->name);
int a;
if (abfd == NULL)
{
- bfd_nonfatal (dummy_name);
+ nonfatal (dummy_name);
continue;
}
if (! bfd_set_format (abfd, bfd_object))
{
if (bfd_get_error () != bfd_error_invalid_operation)
- bfd_nonfatal (p->name);
+ nonfatal (p->name);
+ bfd_close_all_done (abfd);
continue;
}
if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
printf (" %s\n",
bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
+ bfd_close_all_done (abfd);
}
unlink (dummy_name);
free (dummy_name);
int first;
int last;
{
- extern bfd_target *bfd_target_vector[];
+ extern const bfd_target *const *bfd_target_vector;
int t, a;
char *dummy_name;
printf ("%s ", bfd_target_vector[t]->name);
putchar ('\n');
- dummy_name = choose_temp_base ();
+ dummy_name = make_temp_file (NULL);
for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0)
{
bfd_printable_arch_mach (a, 0));
for (t = first; t < last && bfd_target_vector[t]; t++)
{
- bfd_target *p = bfd_target_vector[t];
+ const bfd_target *p = bfd_target_vector[t];
boolean ok = true;
bfd *abfd = bfd_openw (dummy_name, p->name);
if (abfd == NULL)
{
- bfd_nonfatal (p->name);
+ nonfatal (p->name);
ok = false;
}
if (! bfd_set_format (abfd, bfd_object))
{
if (bfd_get_error () != bfd_error_invalid_operation)
- bfd_nonfatal (p->name);
+ nonfatal (p->name);
ok = false;
}
}
putchar ('-');
putchar (' ');
}
+ if (abfd != NULL)
+ bfd_close_all_done (abfd);
}
putchar ('\n');
}
display_target_tables ()
{
int t, columns;
- extern bfd_target *bfd_target_vector[];
+ extern const bfd_target *const *bfd_target_vector;
char *colum;
- extern char *getenv ();
columns = 0;
colum = getenv ("COLUMNS");
static void
display_info ()
{
- printf ("BFD header file version %s\n", BFD_VERSION);
+ printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
display_target_list ();
display_target_tables ();
}
+int main PARAMS ((int, char **));
+
int
main (argc, argv)
int argc;
char *target = default_target;
boolean seenflag = false;
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+#if defined (HAVE_SETLOCALE)
+ setlocale (LC_CTYPE, "");
+#endif
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
program_name = *argv;
xmalloc_set_program_name (program_name);
START_PROGRESS (program_name, 0);
bfd_init ();
+ set_default_bfd_target ();
- while ((c = getopt_long (argc, argv, "pib:m:VdDlfahrRtTxsSj:wE:",
+ while ((c = getopt_long (argc, argv, "pib:m:M:VvCdDlfaHhrRtTxsSj:wE:zgG",
long_options, (int *) 0))
!= EOF)
{
- if (c != 'l' && c != OPTION_START_ADDRESS && c != OPTION_STOP_ADDRESS)
- seenflag = true;
switch (c)
{
case 0:
- break; /* we've been given a long option */
+ break; /* We've been given a long option. */
case 'm':
machine = optarg;
break;
+ case 'M':
+ disassembler_options = optarg;
+ break;
case 'j':
only = optarg;
break;
case 'l':
- with_line_numbers = 1;
+ with_line_numbers = true;
break;
case 'b':
target = optarg;
break;
+ case 'C':
+ do_demangle = true;
+ if (optarg != NULL)
+ {
+ enum demangling_styles style;
+
+ style = cplus_demangle_name_to_style (optarg);
+ if (style == unknown_demangling)
+ fatal (_("unknown demangling style `%s'"),
+ optarg);
+
+ cplus_demangle_set_style (style);
+ }
+ break;
+ case 'w':
+ wide_output = true;
+ break;
+ case OPTION_ADJUST_VMA:
+ adjust_section_vma = parse_vma (optarg, "--adjust-vma");
+ break;
+ case OPTION_START_ADDRESS:
+ start_address = parse_vma (optarg, "--start-address");
+ break;
+ case OPTION_STOP_ADDRESS:
+ stop_address = parse_vma (optarg, "--stop-address");
+ break;
+ case 'E':
+ if (strcmp (optarg, "B") == 0)
+ endian = BFD_ENDIAN_BIG;
+ else if (strcmp (optarg, "L") == 0)
+ endian = BFD_ENDIAN_LITTLE;
+ else
+ {
+ non_fatal (_("unrecognized -E option"));
+ usage (stderr, 1);
+ }
+ break;
+ case OPTION_ENDIAN:
+ if (strncmp (optarg, "big", strlen (optarg)) == 0)
+ endian = BFD_ENDIAN_BIG;
+ else if (strncmp (optarg, "little", strlen (optarg)) == 0)
+ endian = BFD_ENDIAN_LITTLE;
+ else
+ {
+ non_fatal (_("unrecognized --endian type `%s'"), optarg);
+ usage (stderr, 1);
+ }
+ break;
+
case 'f':
dump_file_header = true;
+ seenflag = true;
break;
case 'i':
formats_info = true;
+ seenflag = true;
break;
case 'p':
- dump_private_headers = 1;
+ dump_private_headers = true;
+ seenflag = true;
break;
case 'x':
- dump_private_headers = 1;
- dump_symtab = 1;
- dump_reloc_info = 1;
+ dump_private_headers = true;
+ dump_symtab = true;
+ dump_reloc_info = true;
dump_file_header = true;
- dump_ar_hdrs = 1;
- dump_section_headers = 1;
+ dump_ar_hdrs = true;
+ dump_section_headers = true;
+ seenflag = true;
break;
case 't':
- dump_symtab = 1;
+ dump_symtab = true;
+ seenflag = true;
break;
case 'T':
- dump_dynamic_symtab = 1;
+ dump_dynamic_symtab = true;
+ seenflag = true;
break;
case 'd':
disassemble = true;
+ seenflag = true;
+ break;
+ case 'z':
+ disassemble_zeroes = true;
break;
case 'D':
- disassemble = disassemble_all = true;
+ disassemble = true;
+ disassemble_all = true;
+ seenflag = true;
break;
case 'S':
disassemble = true;
with_source_code = true;
+ seenflag = true;
+ break;
+ case 'g':
+ dump_debugging = 1;
+ seenflag = true;
+ break;
+ case 'G':
+ dump_stab_section_info = true;
+ seenflag = true;
break;
case 's':
- dump_section_contents = 1;
+ dump_section_contents = true;
+ seenflag = true;
break;
case 'r':
- dump_reloc_info = 1;
+ dump_reloc_info = true;
+ seenflag = true;
break;
case 'R':
- dump_dynamic_reloc_info = 1;
+ dump_dynamic_reloc_info = true;
+ seenflag = true;
break;
case 'a':
- dump_ar_hdrs = 1;
+ dump_ar_hdrs = true;
+ seenflag = true;
break;
case 'h':
- dump_section_headers = 1;
+ dump_section_headers = true;
+ seenflag = true;
break;
case 'H':
usage (stdout, 0);
+ seenflag = true;
+ case 'v':
case 'V':
- show_version = 1;
- break;
- case 'w':
- wide_output = 1;
- break;
- case OPTION_START_ADDRESS:
- start_address = parse_vma (optarg, "--start-address");
- break;
- case OPTION_STOP_ADDRESS:
- stop_address = parse_vma (optarg, "--stop-address");
- break;
- case 'E':
- if (strcmp (optarg, "B") == 0)
- endian = BFD_ENDIAN_BIG;
- else if (strcmp (optarg, "L") == 0)
- endian = BFD_ENDIAN_LITTLE;
- else
- {
- fprintf (stderr, "%s: unrecognized -E option\n", program_name);
- usage (stderr, 1);
- }
- break;
- case OPTION_ENDIAN:
- if (strncmp (optarg, "big", strlen (optarg)) == 0)
- endian = BFD_ENDIAN_BIG;
- else if (strncmp (optarg, "little", strlen (optarg)) == 0)
- endian = BFD_ENDIAN_LITTLE;
- else
- {
- fprintf (stderr, "%s: unrecognized --endian type `%s'\n",
- program_name, optarg);
- usage (stderr, 1);
- }
+ show_version = true;
+ seenflag = true;
break;
+
default:
usage (stderr, 1);
}
print_version ("objdump");
if (seenflag == false)
- usage (stderr, 1);
+ usage (stderr, 2);
if (formats_info)
- {
- display_info ();
- }
+ display_info ();
else
{
if (optind == argc)
END_PROGRESS (program_name);
- return 0;
+ return exit_status;
}