/* objdump.c -- dump information about an object file.
- Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
Free Software Foundation, Inc.
This file is part of GNU Binutils.
/* 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;
static void
disassemble_bytes PARAMS ((struct disassemble_info *, disassembler_ftype,
- boolean, bfd_byte *, unsigned long, unsigned long,
+ boolean, bfd_byte *, bfd_vma, bfd_vma,
arelent ***, arelent **));
static void
int status;
{
fprintf (stream, _("\
-Usage: %s [-ahifCdDprRtTxsSlw] [-b bfdname] [-m machine] [-j section-name]\n\
+Usage: %s [-ahifCdDprRtTxsSlw] [-b bfdname] [-m machine] \n\
+ [-j section-name] [-M disassembler-options]\n\
[--archive-headers] [--target=bfdname] [--debugging] [--disassemble]\n\
[--disassemble-all] [--disassemble-zeroes] [--file-headers]\n\
[--section-headers] [--headers]\n\
{"demangle", no_argument, &do_demangle, 1},
{"disassemble", no_argument, NULL, 'd'},
{"disassemble-all", no_argument, NULL, 'D'},
+ {"disassembler-options", required_argument, NULL, 'M'},
{"disassemble-zeroes", no_argument, &disassemble_zeroes, 1},
{"dynamic-reloc", no_argument, NULL, 'R'},
{"dynamic-syms", no_argument, NULL, 'T'},
\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 = "";
PF (SEC_NEVER_LOAD, "NEVER_LOAD");
PF (SEC_EXCLUDE, "EXCLUDE");
PF (SEC_SORT_ENTRIES, "SORT_ENTRIES");
+ PF (SEC_SMALL_DATA, "SMALL_DATA");
+ PF (SEC_SHARED, "SHARED");
if ((section->flags & SEC_LINK_ONCE) != 0)
{
}
/* 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
+#ifdef ANSI_PROTOTYPES
objdump_sprintf (SFILE *f, const char *format, ...)
-{
- int n;
- va_list args;
-
- 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
+#endif
{
- int n;
+#ifndef ANSI_PROTOTYPES
SFILE *f;
const char *format;
+#endif
+ char *buf;
va_list args;
+ size_t n;
+#ifdef ANSI_PROTOTYPES
+ va_start (args, format);
+#else
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);
+#endif
+
+ vasprintf (&buf, format, args);
+
va_end (args);
+
+ if (buf == NULL)
+ {
+ fprintf (stderr, _("Out of virtual memory\n"));
+ exit (1);
+ }
+
+ 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);
+
return n;
}
-#endif
/* The number of zeroes we want to see before we start skipping them.
The number is arbitrarily chosen. */
disassembler_ftype disassemble_fn;
boolean insns;
bfd_byte *data;
- unsigned long start;
- unsigned long stop;
+ bfd_vma start;
+ bfd_vma stop;
arelent ***relppp;
arelent **relppend;
{
int bytes_per_line;
boolean done_dot;
int skip_addr_chars;
- unsigned long i;
+ bfd_vma i;
aux = (struct objdump_disasm_info *) info->application_data;
section = aux->sec;
i = start;
while (i < stop)
{
- unsigned long z;
- int bytes;
+ bfd_vma z;
+ int bytes = 0;
boolean need_nl = false;
/* If we see more than SKIP_ZEROES bytes of zeroes, we just
}
else
{
- char buf[1000];
+ char buf[50];
SFILE sfile;
int bpc = 0;
int pb = 0;
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;
info->bytes_per_chunk = 0;
- if ((*relppp < relppend) && ((**relppp)->address >= (bfd_vma) i &&
- (**relppp)->address < (bfd_vma) i + bytes))
+
+ /* FIXME: This is wrong. It tests the number of bytes
+ in the last instruction, not the current one. */
+ if (*relppp < relppend
+ && (**relppp)->address >= i
+ && (**relppp)->address < i + bytes)
info->flags = INSN_HAS_RELOC;
else
info->flags = 0;
+
bytes = (*disassemble_fn) (section->vma + i, 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;
+ {
+ 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)
? show_raw_insn > 0
: show_raw_insn >= 0)
{
- long j;
+ bfd_vma j;
/* If ! prefix_addresses and ! wide_output, we print
bytes_per_line bytes per line. */
printf (" ");
}
- printf ("%s", buf);
+ if (! insns)
+ printf ("%s", buf);
+ else
+ {
+ printf ("%s", sfile.buffer);
+ free (sfile.buffer);
+ }
if (prefix_addresses
? show_raw_insn > 0
{
while (pb < bytes)
{
- long j;
+ bfd_vma j;
char *s;
putchar ('\n');
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;
+
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. */
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;
+ }
}
}
print_section_stabs (abfd, stabsect_name, strsect_name)
bfd *abfd;
const char *stabsect_name;
- const char *strsect_name;
+ const char *strsect_name ATTRIBUTE_UNUSED;
{
int i;
unsigned file_string_table_offset = 0, next_file_string_table_offset = 0;
/* 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 (sym_name)
{
printf_vma (q->address);
- printf (" %-16s ", q->howto->name);
+ 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);
}
char *target = default_target;
boolean seenflag = false;
-#ifdef HAVE_SETLOCALE
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
setlocale (LC_MESSAGES, "");
#endif
bindtextdomain (PACKAGE, LOCALEDIR);
bfd_init ();
set_default_bfd_target ();
- while ((c = getopt_long (argc, argv, "pib:m:VCdDlfahrRtTxsSj:wE:",
+ while ((c = getopt_long (argc, argv, "pib:m:M:VCdDlfahrRtTxsSj:wE:",
long_options, (int *) 0))
!= EOF)
{
case 'm':
machine = optarg;
break;
+ case 'M':
+ disassembler_options = optarg;
+ break;
case 'j':
only = optarg;
break;