/* objdump.c -- dump information about an object file.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003
+ 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GNU Binutils.
processed in order by display_bfd(). If the file is an archive each
of its elements is processed in turn.
- 3. The file's target architecture and binary file format are determnined
+ 3. The file's target architecture and binary file format are determined
by bfd_check_format(). If they are recognised, then dump_bfd() is
called.
- 4. dump_bfd() in turn calls seperate functions to display the requested
- item(s) of infomation(s). For example dissasemble_data() is called if
- a disassmebly has been requested.
+ 4. dump_bfd() in turn calls separate functions to display the requested
+ item(s) of information(s). For example disassemble_data() is called if
+ a disassembly has been requested.
When disassembling the code loops through blocks of instructions bounded
- by symbols, calling dissassemble_bytes() on each block. The actual
+ by symbols, calling disassemble_bytes() on each block. The actual
disassembling is done by the libopcodes library, via a function pointer
supplied by the disassembler() function. */
#include "aout/aout64.h"
#ifdef NEED_DECLARATION_FPRINTF
-/* This is needed by INIT_DISASSEMBLE_INFO. */
+/* This is needed by init_disassemble_info(). */
extern int fprintf (FILE *, const char *, ...);
#endif
static char *default_target = NULL; /* Default at runtime. */
-/* The following variables are set based on arguments passed on command line. */
+/* The following variables are set based on arguments passed on the
+ command line. */
static int show_version = 0; /* Show the version number. */
static int dump_section_contents; /* -s */
static int dump_section_headers; /* -h */
static bfd_vma stop_address = (bfd_vma) -1; /* --stop-address */
static int dump_debugging; /* --debugging */
static int dump_debugging_tags; /* --debugging-tags */
+static int dump_special_syms = 0; /* --special-syms */
static bfd_vma adjust_section_vma = 0; /* --adjust-vma */
static int file_start_context = 0; /* --file-start-context */
static const char **include_paths;
static int include_path_count;
-/* Extra info to pass to the section disassembler and address printing function. */
+/* Extra info to pass to the section disassembler and address printing
+ function. */
struct objdump_disasm_info
{
bfd * abfd;
/* The dynamic symbol table. */
static asymbol **dynsyms;
+/* The synthetic symbol table. */
+static asymbol *synthsyms;
+static long synthcount = 0;
+
/* Number of symbols in `dynsyms'. */
static long dynsymcount = 0;
--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\
+ --special-syms Include special symbols in symbol dumps\n\
\n"));
list_supported_targets (program_name, stream);
list_supported_architectures (program_name, stream);
{"section-headers", no_argument, NULL, 'h'},
{"show-raw-insn", no_argument, &show_raw_insn, 1},
{"source", no_argument, NULL, 'S'},
+ {"special-syms", no_argument, &dump_special_syms, 1},
{"include", required_argument, NULL, 'I'},
{"stabs", no_argument, NULL, 'G'},
{"start-address", required_argument, NULL, OPTION_START_ADDRESS},
if ((section->flags & SEC_LINK_ONCE) != 0)
{
const char *ls;
+ struct coff_comdat_info *comdat;
switch (section->flags & SEC_LINK_DUPLICATES)
{
}
printf ("%s%s", comma, ls);
- if (section->comdat != NULL)
- printf (" (COMDAT %s %ld)", section->comdat->name,
- section->comdat->symbol);
+ comdat = bfd_coff_get_comdat_section (abfd, section);
+ if (comdat != NULL)
+ printf (" (COMDAT %s %ld)", comdat->name, comdat->symbol);
comma = ", ";
}
{
char buf[30];
char *p;
- struct objdump_disasm_info *aux
- = (struct objdump_disasm_info *) info->application_data;
+ struct objdump_disasm_info *aux;
+ aux = (struct objdump_disasm_info *) info->application_data;
bfd_sprintf_vma (aux->abfd, buf, vma);
if (! skip_zeroes)
p = buf;
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,
- then *PLACE is set to the index of the symbol in sorted_syms. */
+/* Locate a symbol given a bfd and a section (from INFO->application_data),
+ and a VMA. If INFO->application_data->require_sec is TRUE, then always
+ require the symbol to be in the section. Returns NULL if there is no
+ suitable symbol. If PLACE is not NULL, then *PLACE is set to the index
+ of the symbol in sorted_syms. */
static asymbol *
-find_symbol_for_address (bfd *abfd, asection *sec, bfd_vma vma,
- bfd_boolean require_sec, long *place)
+find_symbol_for_address (bfd_vma vma,
+ struct disassemble_info *info,
+ long *place)
{
/* @@ Would it speed things up to cache the last two symbols returned,
and maybe their address ranges? For many processors, only one memory
long min = 0;
long max = sorted_symcount;
long thisplace;
- unsigned int opb = bfd_octets_per_byte (abfd);
+ struct objdump_disasm_info *aux;
+ bfd *abfd;
+ asection *sec;
+ unsigned int opb;
if (sorted_symcount < 1)
return NULL;
+ aux = (struct objdump_disasm_info *) info->application_data;
+ abfd = aux->abfd;
+ sec = aux->sec;
+ opb = bfd_octets_per_byte (abfd);
+
/* Perform a binary search looking for the closest symbol to the
required value. We are searching the range (min, max]. */
while (min + 1 < max)
no way to tell what's desired without looking at the relocation
table. */
if (sorted_syms[thisplace]->section != sec
- && (require_sec
+ && (aux->require_sec
|| ((abfd->flags & HAS_RELOC) != 0
&& vma >= bfd_get_section_vma (abfd, sec)
&& vma < (bfd_get_section_vma (abfd, sec)
}
if (sorted_syms[thisplace]->section != sec
- && (require_sec
+ && (aux->require_sec
|| ((abfd->flags & HAS_RELOC) != 0
&& vma >= bfd_get_section_vma (abfd, sec)
&& vma < (bfd_get_section_vma (abfd, sec)
+ bfd_section_size (abfd, sec)))))
- {
- /* There is no suitable symbol. */
- return NULL;
- }
+ /* There is no suitable symbol. */
+ return NULL;
+ }
+
+ /* Give the target a chance to reject the symbol. */
+ while (! info->symbol_is_valid (sorted_syms [thisplace], info))
+ {
+ ++ thisplace;
+ if (thisplace >= sorted_symcount
+ || bfd_asymbol_value (sorted_syms [thisplace]) > vma)
+ return NULL;
}
if (place != NULL)
If SKIP_ZEROES is TRUE, don't output leading zeroes. */
static void
-objdump_print_addr (bfd_vma vma, struct disassemble_info *info,
+objdump_print_addr (bfd_vma vma,
+ struct disassemble_info *info,
bfd_boolean skip_zeroes)
{
struct objdump_disasm_info *aux;
}
aux = (struct objdump_disasm_info *) info->application_data;
- sym = find_symbol_for_address (aux->abfd, aux->sec, vma, aux->require_sec,
- NULL);
+ sym = find_symbol_for_address (vma, info, NULL);
objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, info,
skip_zeroes);
}
static int
objdump_symbol_at_address (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,
- NULL);
+ sym = find_symbol_for_address (vma, info, NULL);
return (sym != NULL && (bfd_asymbol_value (sym) == vma));
}
static unsigned int prev_line;
/* We keep a list of all files that we have seen when doing a
- dissassembly with source, so that we know how much of the file to
+ disassembly with source, so that we know how much of the file to
display. This can be important for inlined functions. */
struct print_file_list
}
}
-/* Show the line number, or the source line, in a dissassembly
+/* Show the line number, or the source line, in a disassembly
listing. */
static void
typedef struct
{
char *buffer;
- size_t size;
- char *current;
+ size_t pos;
+ size_t alloc;
} SFILE;
/* sprintf to a "stream". */
static int
objdump_sprintf (SFILE *f, const char *format, ...)
{
- char *buf;
size_t n;
va_list args;
- va_start (args, format);
-
- vasprintf (&buf, format, args);
-
- if (buf == NULL)
+ while (1)
{
+ size_t space = f->alloc - f->pos;
+
+ va_start (args, format);
+ n = vsnprintf (f->buffer + f->pos, space, format, args);
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;
+ if (space > n)
+ break;
+
+ f->alloc = (f->alloc + n) * 2;
+ f->buffer = xrealloc (f->buffer, f->alloc);
}
-
- memcpy (f->current, buf, n);
- f->current += n;
- f->current[0] = '\0';
-
- free (buf);
-
- va_end (args);
+ f->pos += n;
+
return n;
}
int skip_addr_chars;
bfd_vma addr_offset;
int opb = info->octets_per_byte;
+ SFILE sfile;
aux = (struct objdump_disasm_info *) info->application_data;
section = aux->sec;
+ sfile.alloc = 120;
+ sfile.buffer = xmalloc (sfile.alloc);
+ sfile.pos = 0;
+
if (insns)
octets_per_line = 4;
else
else
{
char buf[50];
- SFILE sfile;
int bpc = 0;
int pb = 0;
if (insns)
{
- sfile.size = 120;
- sfile.buffer = xmalloc (sfile.size);
- sfile.current = sfile.buffer;
+ sfile.pos = 0;
info->fprintf_func = (fprintf_ftype) objdump_sprintf;
info->stream = (FILE *) &sfile;
info->bytes_per_line = 0;
octets_per_line = info->bytes_per_line;
if (octets < 0)
{
- if (sfile.current != sfile.buffer)
+ if (sfile.pos)
printf ("%s\n", sfile.buffer);
- free (sfile.buffer);
break;
}
}
for (j = addr_offset * opb; j < addr_offset * opb + pb; j += bpc)
{
int k;
+
if (bpc > 1 && info->display_endian == BFD_ENDIAN_LITTLE)
{
for (k = bpc - 1; k >= 0; k--)
if (! insns)
printf ("%s", buf);
- else
- {
- printf ("%s", sfile.buffer);
- free (sfile.buffer);
- }
+ else if (sfile.pos)
+ printf ("%s", sfile.buffer);
if (prefix_addresses
? show_raw_insn > 0
else
printf ("\t\t\t");
- objdump_print_value (section->vma + q->address, info, TRUE);
+ objdump_print_value (section->vma - rel_offset + q->address,
+ info, TRUE);
printf (": %s\t", q->howto->name);
addr_offset += octets / opb;
}
+
+ free (sfile.buffer);
}
static void
disassemble_section (bfd *abfd, asection *section, void *info)
{
struct disassemble_info * pinfo = (struct disassemble_info *) info;
- struct objdump_disasm_info * paux = (struct objdump_disasm_info *) pinfo->application_data;
+ struct objdump_disasm_info * paux;
unsigned int opb = pinfo->octets_per_byte;
bfd_byte * data = NULL;
bfd_size_type datasize = 0;
code are not normally disassembled. */
if (! disassemble_all
&& only == NULL
- && (section->flags & SEC_CODE) == 0)
+ && ((section->flags & (SEC_CODE | SEC_HAS_CONTENTS))
+ != (SEC_CODE | SEC_HAS_CONTENTS)))
return;
if (! process_section_p (section))
return;
- datasize = bfd_get_section_size_before_reloc (section);
+ datasize = bfd_get_section_size (section);
if (datasize == 0)
return;
/* Decide which set of relocs to use. Load them if necessary. */
+ paux = (struct objdump_disasm_info *) pinfo->application_data;
if (paux->dynrelbuf)
{
rel_pp = paux->dynrelbuf;
rel_count = paux->dynrelcount;
/* Dynamic reloc addresses are absolute, non-dynamic are section
- relative. REL_OFFSET specifies the reloc address corresponnding
+ relative. REL_OFFSET specifies the reloc address corresponding
to the start of this section. */
- rel_offset = pinfo->buffer_vma;
+ rel_offset = section->vma;
}
else
{
printf (_("Disassembly of section %s:\n"), section->name);
/* Find the nearest symbol forwards from our current position. */
- sym = find_symbol_for_address (abfd, section, section->vma + addr_offset,
- TRUE, &place);
+ paux->require_sec = TRUE;
+ sym = find_symbol_for_address (section->vma + addr_offset, info, &place);
+ paux->require_sec = FALSE;
/* Disassemble a block of instructions up to the address associated with
the symbol we have just found. Then print the symbol and find the
or we have reached the end of the address range we are interested in. */
while (addr_offset < stop_offset)
{
+ bfd_vma addr;
asymbol *nextsym;
unsigned long nextstop_offset;
bfd_boolean insns;
- if (sym != NULL
- && bfd_asymbol_value (sym) <= section->vma + addr_offset)
+ addr = section->vma + addr_offset;
+
+ if (sym != NULL && bfd_asymbol_value (sym) <= addr)
{
int x;
for (x = place;
(x < sorted_symcount
- && (bfd_asymbol_value (sorted_syms[x])
- <= section->vma + addr_offset));
+ && (bfd_asymbol_value (sorted_syms[x]) <= addr));
++x)
continue;
- pinfo->symbols = & sorted_syms[place];
+ pinfo->symbols = sorted_syms + place;
pinfo->num_symbols = x - place;
}
else
- pinfo->symbols = NULL;
+ {
+ pinfo->symbols = NULL;
+ pinfo->num_symbols = 0;
+ }
if (! prefix_addresses)
{
pinfo->fprintf_func (pinfo->stream, "\n");
- objdump_print_addr_with_sym (abfd, section, sym,
- section->vma + addr_offset,
+ objdump_print_addr_with_sym (abfd, section, sym, addr,
pinfo, FALSE);
pinfo->fprintf_func (pinfo->stream, ":\n");
}
- if (sym != NULL
- && bfd_asymbol_value (sym) > section->vma + addr_offset)
+ if (sym != NULL && bfd_asymbol_value (sym) > addr)
nextsym = sym;
else if (sym == NULL)
nextsym = NULL;
else
{
+#define is_valid_next_sym(SYM) \
+ ((SYM)->section == section \
+ && (bfd_asymbol_value (SYM) > bfd_asymbol_value (sym)) \
+ && pinfo->symbol_is_valid (SYM, pinfo))
+
/* 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))))
+ && ! is_valid_next_sym (sorted_syms [place]))
++place;
+
if (place >= sorted_symcount)
nextsym = NULL;
else
nextsym = sorted_syms[place];
}
- 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;
- }
+ if (sym != NULL && bfd_asymbol_value (sym) > addr)
+ nextstop_offset = bfd_asymbol_value (sym) - section->vma;
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;
- }
+ 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
- || bfd_asymbol_value (sym) > section->vma + addr_offset
+ || bfd_asymbol_value (sym) > addr
|| ((sym->flags & BSF_OBJECT) == 0
&& (strstr (bfd_asymbol_name (sym), "gnu_compiled")
== NULL)
{
struct disassemble_info disasm_info;
struct objdump_disasm_info aux;
+ long i;
print_files = NULL;
prev_functionname = NULL;
/* We make a copy of syms to sort. We don't want to sort syms
because that will screw up the relocs. */
- sorted_syms = xmalloc (symcount * sizeof (asymbol *));
- memcpy (sorted_syms, syms, symcount * sizeof (asymbol *));
+ sorted_symcount = symcount ? symcount : dynsymcount;
+ sorted_syms = xmalloc ((sorted_symcount + synthcount) * sizeof (asymbol *));
+ memcpy (sorted_syms, symcount ? syms : dynsyms,
+ sorted_symcount * sizeof (asymbol *));
- sorted_symcount = remove_useless_symbols (sorted_syms, symcount);
+ sorted_symcount = remove_useless_symbols (sorted_syms, sorted_symcount);
+
+ for (i = 0; i < synthcount; ++i)
+ {
+ sorted_syms[sorted_symcount] = synthsyms + i;
+ ++sorted_symcount;
+ }
/* Sort the symbols into section and symbol order. */
qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
- INIT_DISASSEMBLE_INFO (disasm_info, stdout, fprintf);
+ init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf);
disasm_info.application_data = (void *) &aux;
aux.abfd = abfd;
instead. */
disasm_info.endian = BFD_ENDIAN_UNKNOWN;
+ /* Allow the target to customize the info structure. */
+ disassemble_init_for_target (& disasm_info);
+
/* Pre-load the dynamic relocs if we are going
to be dumping them along with the disassembly. */
if (dump_dynamic_reloc_info)
if (relsize > 0)
{
aux.dynrelbuf = xmalloc (relsize);
- aux.dynrelcount = bfd_canonicalize_dynamic_reloc (abfd, aux.dynrelbuf, dynsyms);
+ aux.dynrelcount = bfd_canonicalize_dynamic_reloc (abfd,
+ aux.dynrelbuf,
+ dynsyms);
if (aux.dynrelcount < 0)
bfd_fatal (bfd_get_filename (abfd));
/* Sort the relocs by address. */
- qsort (aux.dynrelbuf, aux.dynrelcount, sizeof (arelent *), compare_relocs);
+ qsort (aux.dynrelbuf, aux.dynrelcount, sizeof (arelent *),
+ compare_relocs);
}
}
free (sorted_syms);
}
\f
-/* Read ABFD's stabs section STABSECT_NAME into `stabs'
- and string table section STRSECT_NAME into `strtab'.
- If the section exists and was read, allocate the space and return TRUE.
- Otherwise return FALSE. */
+/* Read ABFD's stabs section STABSECT_NAME, and return a pointer to
+ it. Return NULL on failure. */
-static bfd_boolean
-read_section_stabs (bfd *abfd, const char *stabsect_name,
- const char *strsect_name)
+static char *
+read_section_stabs (bfd *abfd, const char *sect_name, bfd_size_type *size_ptr)
{
- asection *stabsect, *stabstrsect;
+ asection *stabsect;
+ bfd_size_type size;
+ char *contents;
- stabsect = bfd_get_section_by_name (abfd, stabsect_name);
+ stabsect = bfd_get_section_by_name (abfd, sect_name);
if (stabsect == NULL)
{
- printf (_("No %s section present\n\n"), stabsect_name);
+ printf (_("No %s section present\n\n"), sect_name);
return FALSE;
}
- stabstrsect = bfd_get_section_by_name (abfd, strsect_name);
- if (stabstrsect == NULL)
- {
- 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);
+ size = bfd_section_size (abfd, stabsect);
+ contents = xmalloc (size);
- stabs = xmalloc (stab_size);
- strtab = xmalloc (stabstr_size);
-
- if (! bfd_get_section_contents (abfd, stabsect, stabs, 0, stab_size))
+ if (! bfd_get_section_contents (abfd, stabsect, contents, 0, size))
{
non_fatal (_("Reading %s section of %s failed: %s"),
- stabsect_name, bfd_get_filename (abfd),
+ sect_name, bfd_get_filename (abfd),
bfd_errmsg (bfd_get_error ()));
- free (stabs);
- free (strtab);
+ free (contents);
exit_status = 1;
- return FALSE;
+ return NULL;
}
- if (! bfd_get_section_contents (abfd, stabstrsect, (void *) strtab, 0,
- stabstr_size))
- {
- 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;
- }
+ *size_ptr = size;
- return TRUE;
+ return contents;
}
/* Stabs entries use a 12 byte format:
using string table section STRSECT_NAME (in `strtab'). */
static void
-print_section_stabs (bfd *abfd, const char *stabsect_name)
+print_section_stabs (bfd *abfd,
+ const char *stabsect_name,
+ unsigned *string_offset_ptr)
{
int i;
unsigned file_string_table_offset = 0;
- unsigned next_file_string_table_offset = 0;
+ unsigned next_file_string_table_offset = *string_offset_ptr;
bfd_byte *stabp, *stabs_end;
stabp = stabs;
}
}
printf ("\n\n");
+ *string_offset_ptr = next_file_string_table_offset;
}
typedef struct
{
const char * section_name;
const char * string_section_name;
+ unsigned string_offset;
}
stab_section_names;
stab_section_names * sought = (stab_section_names *) names;
/* Check for section names for which stabsect_name is a prefix, to
- handle .stab0, etc. */
+ handle .stab.N, etc. */
len = strlen (sought->section_name);
/* If the prefix matches, and the files section name ends with a
match or a section followed by a number. */
if (strncmp (sought->section_name, section->name, len) == 0
&& (section->name[len] == 0
- || ISDIGIT (section->name[len])))
+ || (section->name[len] == '.' && ISDIGIT (section->name[len + 1]))))
{
- if (read_section_stabs (abfd, section->name, sought->string_section_name))
+ if (strtab == NULL)
+ strtab = read_section_stabs (abfd, sought->string_section_name,
+ &stabstr_size);
+
+ if (strtab)
{
- print_section_stabs (abfd, section->name);
- free (stabs);
- free (strtab);
+ stabs = read_section_stabs (abfd, section->name, &stab_size);
+ if (stabs)
+ print_section_stabs (abfd, section->name, &sought->string_offset);
}
}
}
s.section_name = stabsect_name;
s.string_section_name = strsect_name;
-
+ s.string_offset = 0;
+
bfd_map_over_sections (abfd, find_stabs_section, & s);
+
+ free (strtab);
+ strtab = NULL;
}
/* Dump the any sections containing stabs debugging information. */
bfd *cur_bfd;
if (*current == NULL)
- printf (_("no information for the %ld'th symbol"), count);
+ printf (_("no information for symbol number %ld\n"), count);
else if ((cur_bfd = bfd_asymbol_bfd (*current)) == NULL)
- printf (_("could not determine the type of the %ld'th symbol"),
+ printf (_("could not determine the type of symbol number %ld\n"),
count);
- else
+ else if (dump_special_syms
+ || !bfd_is_target_special_symbol (cur_bfd, *current))
{
const char *name = (*current)->name;
else
bfd_print_symbol (cur_bfd, stdout, *current,
bfd_print_symbol_all);
+ printf ("\n");
}
-
- printf ("\n");
current++;
}
printf ("\n\n");
}
static void
-dump_relocs_in_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
+dump_relocs_in_section (bfd *abfd,
+ asection *section,
+ void *dummy ATTRIBUTE_UNUSED)
{
arelent **relpp;
long relcount;
}
static void
-adjust_addresses (bfd *abfd ATTRIBUTE_UNUSED, asection *section, void *dummy ATTRIBUTE_UNUSED)
+adjust_addresses (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *section,
+ void *dummy ATTRIBUTE_UNUSED)
{
section->vma += adjust_section_vma;
section->lma += adjust_section_vma;
if (dump_symtab || dump_reloc_info || disassemble || dump_debugging)
syms = slurp_symtab (abfd);
- if (dump_dynamic_symtab || dump_dynamic_reloc_info)
+ if (dump_dynamic_symtab || dump_dynamic_reloc_info
+ || (disassemble && bfd_get_dynamic_symtab_upper_bound (abfd) > 0))
dynsyms = slurp_dynamic_symtab (abfd);
+ if (disassemble)
+ {
+ synthcount = bfd_get_synthetic_symtab (abfd, symcount, syms,
+ dynsymcount, dynsyms, &synthsyms);
+ if (synthcount < 0)
+ synthcount = 0;
+ }
if (dump_symtab)
dump_symbols (abfd, FALSE);
free (dynsyms);
dynsyms = NULL;
}
+
+ if (synthsyms)
+ {
+ free (synthsyms);
+ synthsyms = NULL;
+ }
+
+ symcount = 0;
+ dynsymcount = 0;
+ synthcount = 0;
}
static void
static void
display_file (char *filename, char *target)
{
- bfd *file, *arfile = NULL;
+ bfd *file;
+ bfd *arfile = NULL;
+
+ if (get_file_size (filename) < 1)
+ return;
file = bfd_openr (filename, target);
if (file == NULL)