#include "getopt.h"
#include "progress.h"
#include "bucomm.h"
+#include <sys/types.h>
#include <stdio.h>
#include <ctype.h>
#include "dis-asm.h"
static void
display_bfd PARAMS ((bfd *abfd));
+static void
+objdump_print_value PARAMS ((bfd_vma, FILE *));
+
static void
objdump_print_address PARAMS ((bfd_vma, struct disassemble_info *));
if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
{
printf ("No symbols in \"%s\".\n", bfd_get_filename (abfd));
+ symcount = 0;
return NULL;
}
{
fprintf (stderr, "%s: %s: not a dynamic object\n",
program_name, bfd_get_filename (abfd));
+ dynsymcount = 0;
return NULL;
}
{
const asymbol *a = *(const asymbol **)ap;
const asymbol *b = *(const asymbol **)bp;
+ const char *an, *bn;
+ size_t anl, bnl;
+ boolean af, bf;
if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
return 1;
return 1;
else if (a->section < b->section)
return -1;
+
+ an = bfd_asymbol_name (a);
+ bn = bfd_asymbol_name (b);
+ anl = strlen (an);
+ bnl = strlen (bn);
+
+ /* The symbols gnu_compiled and gcc2_compiled convey no real
+ information, so put them after other symbols with the same value. */
+
+ af = (strstr (an, "gnu_compiled") != NULL
+ || strstr (an, "gcc2_compiled") != NULL);
+ bf = (strstr (bn, "gnu_compiled") != NULL
+ || strstr (bn, "gcc2_compiled") != NULL);
+
+ if (af && ! bf)
+ return 1;
+ if (! af && bf)
+ return -1;
+
+ /* We use a heuristic for the file name, to try to sort it after
+ more useful symbols. It may not work on non Unix systems, but it
+ doesn't really matter; the only difference is precisely which
+ symbol names get printed. */
+
+#define file_symbol(s, sn, snl) \
+ (((s)->flags & BSF_FILE) != 0 \
+ || ((sn)[(snl) - 2] == '.' \
+ && ((sn)[(snl) - 1] == 'o' \
+ || (sn)[(snl) - 1] == 'a')))
+
+ af = file_symbol (a, an, anl);
+ bf = file_symbol (b, bn, bnl);
+
+ if (af && ! bf)
+ return 1;
+ if (! af && bf)
+ return -1;
+
return 0;
}
return 0;
}
+/* Print VMA to STREAM with no leading zeroes. */
+
+static void
+objdump_print_value (vma, stream)
+ bfd_vma vma;
+ FILE *stream;
+{
+ char buf[30];
+ char *p;
+
+ sprintf_vma (buf, vma);
+ for (p = buf; *p == '0'; ++p)
+ ;
+ fprintf (stream, "%s", p);
+}
+
/* Print VMA symbolically to INFO if possible. */
static void
/* The symbol we want is now in min, the low end of the range we
were searching. */
thisplace = min;
+ while (thisplace > 0
+ && (bfd_asymbol_value (sorted_syms[thisplace])
+ == bfd_asymbol_value (sorted_syms[thisplace - 1])))
+ --thisplace;
{
/* If this symbol isn't global, search for one with the same value
|| ((aux->abfd->flags & HAS_RELOC) != 0
&& vma >= bfd_get_section_vma (aux->abfd, aux->sec)
&& vma < (bfd_get_section_vma (aux->abfd, aux->sec)
- + bfd_get_section_size_before_reloc (aux->sec)))))
+ + bfd_section_size (aux->abfd, aux->sec)))))
{
for (i = thisplace + 1; i < sorted_symcount; i++)
{
--i;
for (; i >= 0; i--)
{
- if (sorted_syms[i]->section == aux->sec)
+ if (sorted_syms[i]->section == aux->sec
+ && (i == 0
+ || sorted_syms[i - 1]->section != aux->sec
+ || (bfd_asymbol_value (sorted_syms[i])
+ != bfd_asymbol_value (sorted_syms[i - 1]))))
{
thisplace = i;
break;
}
}
}
+
+ if (sorted_syms[thisplace]->section != aux->sec
+ && (aux->require_sec
+ || ((aux->abfd->flags & HAS_RELOC) != 0
+ && vma >= bfd_get_section_vma (aux->abfd, aux->sec)
+ && vma < (bfd_get_section_vma (aux->abfd, aux->sec)
+ + bfd_section_size (aux->abfd, aux->sec)))))
+ {
+ bfd_vma secaddr;
+
+ fprintf (info->stream, " <%s",
+ bfd_get_section_name (aux->abfd, aux->sec));
+ secaddr = bfd_get_section_vma (aux->abfd, aux->sec);
+ if (vma < secaddr)
+ {
+ fprintf (info->stream, "-");
+ objdump_print_value (secaddr - vma, info->stream);
+ }
+ else if (vma > secaddr)
+ {
+ fprintf (info->stream, "+");
+ objdump_print_value (vma - secaddr, info->stream);
+ }
+ fprintf (info->stream, ">");
+ return;
+ }
}
}
fprintf (info->stream, " <%s", sorted_syms[thisplace]->name);
if (bfd_asymbol_value (sorted_syms[thisplace]) > vma)
{
- char buf[30], *p = buf;
- sprintf_vma (buf, bfd_asymbol_value (sorted_syms[thisplace]) - vma);
- while (*p == '0')
- p++;
- fprintf (info->stream, "-%s", p);
+ fprintf (info->stream, "-");
+ objdump_print_value (bfd_asymbol_value (sorted_syms[thisplace]) - vma,
+ info->stream);
}
else if (vma > bfd_asymbol_value (sorted_syms[thisplace]))
{
- char buf[30], *p = buf;
- sprintf_vma (buf, vma - bfd_asymbol_value (sorted_syms[thisplace]));
- while (*p == '0')
- p++;
- fprintf (info->stream, "+%s", p);
+ fprintf (info->stream, "+");
+ objdump_print_value (vma - bfd_asymbol_value (sorted_syms[thisplace]),
+ info->stream);
}
fprintf (info->stream, ">");
}
bfd *abfd;
{
long i;
- unsigned int (*print) () = 0; /* Old style */
disassembler_ftype disassemble_fn = 0; /* New style */
struct disassemble_info disasm_info;
struct objdump_disasm_info aux;
if (machine != (char *) NULL)
{
- bfd_arch_info_type *info = bfd_scan_arch (machine);
+ const bfd_arch_info_type *info = bfd_scan_arch (machine);
if (info == NULL)
{
fprintf (stderr, "%s: Can't use supplied machine %s\n",
abfd->arch_info = info;
}
- /* See if we can disassemble using bfd. */
-
- if (abfd->arch_info->disassemble)
+ disassemble_fn = disassembler (abfd);
+ if (!disassemble_fn)
{
- print = abfd->arch_info->disassemble;
- }
- else
- {
- 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);
- }
+ fprintf (stderr, "%s: Can't disassemble for architecture %s\n",
+ program_name,
+ bfd_printable_arch_mach (bfd_get_arch (abfd), 0));
+ exit (1);
}
for (section = abfd->sections;
aux.require_sec = false;
putchar (' ');
- if (disassemble_fn)
- {
- /* New style */
- bytes = (*disassemble_fn) (section->vma + i, &disasm_info);
- if (bytes < 0)
- break;
- }
- else
- {
- /* Old style */
- bytes = print (section->vma + i, data + i, stdout);
- }
+ bytes = (*disassemble_fn) (section->vma + i, &disasm_info);
+ if (bytes < 0)
+ break;
+
if (!wide_output)
putchar ('\n');
else
if (relbuf != NULL)
free (relbuf);
}
+ free (sorted_syms);
}
\f
dump_data (abfd);
if (disassemble)
disassemble_data (abfd);
+ if (syms)
+ {
+ free (syms);
+ syms = NULL;
+ }
+ if (dynsyms)
+ {
+ free (dynsyms);
+ dynsyms = NULL;
+ }
}
static void
else if ((a->flags & SEC_RELOC) == 0)
continue;
- printf ("RELOCATION RECORDS FOR [%s]:", a->name);
-
relsize = bfd_get_reloc_upper_bound (abfd, a);
if (relsize < 0)
bfd_fatal (bfd_get_filename (abfd));
+ printf ("RELOCATION RECORDS FOR [%s]:", a->name);
+
if (relsize == 0)
{
printf (" (none)\n\n");
arelent **relpp;
long relcount;
- printf ("DYNAMIC RELOCATION RECORDS");
-
relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
if (relsize < 0)
bfd_fatal (bfd_get_filename (abfd));
+ printf ("DYNAMIC RELOCATION RECORDS");
+
if (relsize == 0)
{
printf (" (none)\n\n");