* bucomm.c (list_supported_targets): New function.
* bucomm.h (list_supported_targets): Declare. * ar.c (usage): Call list_supported_targets. * nm.c (usage): Likewise. * objcopy.c (copy_usage, strip_usage): Likewise. * objdump.c (usage): Likewise. * size.c (usage): Likewise. * strings.c (usage): Likewise. PR 6345.
This commit is contained in:
parent
c1d61903ec
commit
be1d162bb4
3 changed files with 350 additions and 134 deletions
|
@ -1,3 +1,45 @@
|
|||
Mon Mar 6 13:46:12 1995 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* bucomm.c (list_supported_targets): New function.
|
||||
* bucomm.h (list_supported_targets): Declare.
|
||||
* ar.c (usage): Call list_supported_targets.
|
||||
* nm.c (usage): Likewise.
|
||||
* objcopy.c (copy_usage, strip_usage): Likewise.
|
||||
* objdump.c (usage): Likewise.
|
||||
* size.c (usage): Likewise.
|
||||
* strings.c (usage): Likewise.
|
||||
|
||||
Tue Feb 28 15:13:58 1995 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* bucomm.c (print_arelt_descr): Cast st_size to long before
|
||||
passing it to fprintf.
|
||||
|
||||
Fri Feb 17 13:36:45 1995 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* objcopy.c (struct section_list): Add fields remove, set_flags,
|
||||
and flags. Change adjust from boolean to enum.
|
||||
(remove_sections): Remove static variable.
|
||||
(sections_removed): New static variable.
|
||||
(copy_options): Add --set-section-flags.
|
||||
(copy_usage): Mention --set-section-flags.
|
||||
(parse_flags): New static function.
|
||||
(find_section_list): New static function.
|
||||
(is_strip_symbol): Change return type from int to boolean.
|
||||
(is_strip_section): New static function.
|
||||
(filter_symbols): Call is_strip_section.
|
||||
(copy_object): When adding sections, check for specified flags or
|
||||
VMA. Call filter_symbols if any sections are being removed.
|
||||
(setup_section): Use find_section_list function rather than
|
||||
looking through remove_sections and adjust_sections. Handle
|
||||
--set-section-flags.
|
||||
(copy_section): Use find_section_list rather than looking through
|
||||
remove_sections.
|
||||
(strip_main): Use find_section_list instead of adding items to
|
||||
sections_removed.
|
||||
(copy_main): Use find_section_list instead of adding items to
|
||||
sections_removed and adjust_sections. Handle --set-section-flags.
|
||||
* binutils.texi, objcopy.1: Document --set-section-flags.
|
||||
|
||||
Tue Feb 14 18:03:03 1995 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* objdump.c (with_source_code): New global variable.
|
||||
|
|
|
@ -232,6 +232,7 @@ Usage: %s [-vVSgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-b byte]\n\
|
|||
[--strip-symbol symbol] [-N symbol] [--verbose]\n\
|
||||
[--version] [--help]\n\
|
||||
in-file [out-file]\n");
|
||||
list_supported_targets (program_name, stream);
|
||||
exit (exit_status);
|
||||
}
|
||||
|
||||
|
@ -247,6 +248,7 @@ Usage: %s [-vVsSgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-R section]\n\
|
|||
[--strip-symbol symbol] [-N symbol]\n\
|
||||
[--remove-section=section] [--verbose] [--version] [--help] file...\n",
|
||||
program_name);
|
||||
list_supported_targets (program_name, stream);
|
||||
exit (exit_status);
|
||||
}
|
||||
|
||||
|
@ -417,6 +419,12 @@ is_strip_section (abfd, sec)
|
|||
{
|
||||
struct section_list *p;
|
||||
|
||||
if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0
|
||||
&& (strip_symbols == strip_debug
|
||||
|| strip_symbols == strip_all
|
||||
|| discard_locals == locals_all))
|
||||
return true;
|
||||
|
||||
if (! sections_removed)
|
||||
return false;
|
||||
p = find_section_list (bfd_get_section_name (abfd, sec), false);
|
||||
|
|
|
@ -20,6 +20,7 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "getopt.h"
|
||||
#include "progress.h"
|
||||
#include "bucomm.h"
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
@ -48,6 +49,7 @@ int dump_reloc_info; /* -r */
|
|||
int dump_dynamic_reloc_info; /* -R */
|
||||
int dump_ar_hdrs; /* -a */
|
||||
int with_line_numbers; /* -l */
|
||||
boolean with_source_code; /* -S */
|
||||
int dump_stab_section_info; /* --stabs */
|
||||
boolean disassemble; /* -d */
|
||||
boolean disassemble_all; /* -D */
|
||||
|
@ -70,6 +72,12 @@ asymbol **syms;
|
|||
/* Number of symbols in `syms'. */
|
||||
long symcount = 0;
|
||||
|
||||
/* The sorted symbol table. */
|
||||
asymbol **sorted_syms;
|
||||
|
||||
/* Number of symbols in `sorted_syms'. */
|
||||
long sorted_symcount = 0;
|
||||
|
||||
/* The dynamic symbol table. */
|
||||
asymbol **dynsyms;
|
||||
|
||||
|
@ -101,6 +109,9 @@ display_bfd PARAMS ((bfd *abfd));
|
|||
|
||||
static void
|
||||
objdump_print_address PARAMS ((bfd_vma, struct disassemble_info *));
|
||||
|
||||
static void
|
||||
show_line PARAMS ((bfd *, asection *, bfd_vma));
|
||||
|
||||
void
|
||||
usage (stream, status)
|
||||
|
@ -108,15 +119,16 @@ usage (stream, status)
|
|||
int status;
|
||||
{
|
||||
fprintf (stream, "\
|
||||
Usage: %s [-ahifdDrRtTxsl] [-b bfdname] [-m machine] [-j section-name]\n\
|
||||
Usage: %s [-ahifdDrRtTxsSl] [-b bfdname] [-m machine] [-j section-name]\n\
|
||||
[--archive-headers] [--target=bfdname] [--disassemble]\n\
|
||||
[--disassemble-all] [--file-headers] [--section-headers] [--headers]\n\
|
||||
[--info] [--section=section-name] [--line-numbers]\n\
|
||||
[--info] [--section=section-name] [--line-numbers] [--source]\n\
|
||||
[--architecture=machine] [--reloc] [--full-contents] [--stabs]\n\
|
||||
[--syms] [--all-headers] [--dynamic-syms] [--dynamic-reloc]\n\
|
||||
[--version] [--help] objfile...\n\
|
||||
at least one option besides -l (--line-numbers) must be given\n",
|
||||
program_name);
|
||||
list_supported_targets (program_name, stream);
|
||||
exit (status);
|
||||
}
|
||||
|
||||
|
@ -138,6 +150,7 @@ static struct option long_options[]=
|
|||
{"reloc", no_argument, NULL, 'r'},
|
||||
{"section", required_argument, NULL, 'j'},
|
||||
{"section-headers", no_argument, NULL, 'h'},
|
||||
{"source", no_argument, NULL, 'S'},
|
||||
{"stabs", no_argument, &dump_stab_section_info, 1},
|
||||
{"syms", no_argument, NULL, 't'},
|
||||
{"target", required_argument, NULL, 'b'},
|
||||
|
@ -295,9 +308,9 @@ compare_symbols (ap, bp)
|
|||
const asymbol *a = *(const asymbol **)ap;
|
||||
const asymbol *b = *(const asymbol **)bp;
|
||||
|
||||
if (a->value > b->value)
|
||||
if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
|
||||
return 1;
|
||||
else if (a->value < b->value)
|
||||
else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
|
||||
return -1;
|
||||
|
||||
if (a->section > b->section)
|
||||
|
@ -341,16 +354,16 @@ objdump_print_address (vma, info)
|
|||
operand can be present at a time, so the 2-entry cache wouldn't be
|
||||
constantly churned by code doing heavy memory accesses. */
|
||||
|
||||
/* Indices in `syms'. */
|
||||
/* Indices in `sorted_syms'. */
|
||||
long min = 0;
|
||||
long max = symcount;
|
||||
long max = sorted_symcount;
|
||||
long thisplace;
|
||||
|
||||
bfd_signed_vma vardiff;
|
||||
|
||||
fprintf_vma (info->stream, vma);
|
||||
|
||||
if (symcount < 1)
|
||||
if (sorted_symcount < 1)
|
||||
return;
|
||||
|
||||
/* Perform a binary search looking for the closest symbol to the
|
||||
|
@ -360,9 +373,9 @@ objdump_print_address (vma, info)
|
|||
asymbol *sym;
|
||||
|
||||
thisplace = (max + min) / 2;
|
||||
sym = syms[thisplace];
|
||||
sym = sorted_syms[thisplace];
|
||||
|
||||
vardiff = sym->value - vma;
|
||||
vardiff = bfd_asymbol_value (sym) - vma;
|
||||
|
||||
if (vardiff > 0)
|
||||
max = thisplace;
|
||||
|
@ -382,27 +395,27 @@ objdump_print_address (vma, info)
|
|||
{
|
||||
/* If this symbol isn't global, search for one with the same value
|
||||
that is. */
|
||||
bfd_vma val = syms[thisplace]->value;
|
||||
bfd_vma val = bfd_asymbol_value (sorted_syms[thisplace]);
|
||||
long i;
|
||||
if (syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|
||||
if (sorted_syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|
||||
for (i = thisplace - 1; i >= 0; i--)
|
||||
{
|
||||
if (syms[i]->value == val
|
||||
&& (!(syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|
||||
|| ((syms[thisplace]->flags & BSF_DEBUGGING)
|
||||
&& !(syms[i]->flags & BSF_DEBUGGING))))
|
||||
if (bfd_asymbol_value (sorted_syms[i]) == val
|
||||
&& (!(sorted_syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|
||||
|| ((sorted_syms[thisplace]->flags & BSF_DEBUGGING)
|
||||
&& !(sorted_syms[i]->flags & BSF_DEBUGGING))))
|
||||
{
|
||||
thisplace = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|
||||
for (i = thisplace + 1; i < symcount; i++)
|
||||
if (sorted_syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|
||||
for (i = thisplace + 1; i < sorted_symcount; i++)
|
||||
{
|
||||
if (syms[i]->value == val
|
||||
&& (!(syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|
||||
|| ((syms[thisplace]->flags & BSF_DEBUGGING)
|
||||
&& !(syms[i]->flags & BSF_DEBUGGING))))
|
||||
if (bfd_asymbol_value (sorted_syms[i]) == val
|
||||
&& (!(sorted_syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|
||||
|| ((sorted_syms[thisplace]->flags & BSF_DEBUGGING)
|
||||
&& !(sorted_syms[i]->flags & BSF_DEBUGGING))))
|
||||
{
|
||||
thisplace = i;
|
||||
break;
|
||||
|
@ -422,35 +435,36 @@ objdump_print_address (vma, info)
|
|||
long i;
|
||||
|
||||
aux = (struct objdump_disasm_info *) info->application_data;
|
||||
if (syms[thisplace]->section != aux->sec
|
||||
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_get_section_size_before_reloc (aux->sec)))))
|
||||
{
|
||||
for (i = thisplace + 1; i < symcount; i++)
|
||||
for (i = thisplace + 1; i < sorted_symcount; i++)
|
||||
{
|
||||
if (syms[i]->value != syms[thisplace]->value)
|
||||
if (bfd_asymbol_value (sorted_syms[i])
|
||||
!= bfd_asymbol_value (sorted_syms[thisplace]))
|
||||
break;
|
||||
}
|
||||
--i;
|
||||
for (; i >= 0; i--)
|
||||
{
|
||||
if (syms[i]->section == aux->sec)
|
||||
if (sorted_syms[i]->section == aux->sec)
|
||||
{
|
||||
thisplace = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (syms[thisplace]->section != aux->sec)
|
||||
if (sorted_syms[thisplace]->section != aux->sec)
|
||||
{
|
||||
/* We didn't find a good symbol with a smaller value.
|
||||
Look for one with a larger value. */
|
||||
for (i = thisplace + 1; i < symcount; i++)
|
||||
for (i = thisplace + 1; i < sorted_symcount; i++)
|
||||
{
|
||||
if (syms[i]->section == aux->sec)
|
||||
if (sorted_syms[i]->section == aux->sec)
|
||||
{
|
||||
thisplace = i;
|
||||
break;
|
||||
|
@ -460,19 +474,19 @@ objdump_print_address (vma, info)
|
|||
}
|
||||
}
|
||||
|
||||
fprintf (info->stream, " <%s", syms[thisplace]->name);
|
||||
if (syms[thisplace]->value > vma)
|
||||
fprintf (info->stream, " <%s", sorted_syms[thisplace]->name);
|
||||
if (bfd_asymbol_value (sorted_syms[thisplace]) > vma)
|
||||
{
|
||||
char buf[30], *p = buf;
|
||||
sprintf_vma (buf, syms[thisplace]->value - vma);
|
||||
sprintf_vma (buf, bfd_asymbol_value (sorted_syms[thisplace]) - vma);
|
||||
while (*p == '0')
|
||||
p++;
|
||||
fprintf (info->stream, "-%s", p);
|
||||
}
|
||||
else if (vma > syms[thisplace]->value)
|
||||
else if (vma > bfd_asymbol_value (sorted_syms[thisplace]))
|
||||
{
|
||||
char buf[30], *p = buf;
|
||||
sprintf_vma (buf, vma - syms[thisplace]->value);
|
||||
sprintf_vma (buf, vma - bfd_asymbol_value (sorted_syms[thisplace]));
|
||||
while (*p == '0')
|
||||
p++;
|
||||
fprintf (info->stream, "+%s", p);
|
||||
|
@ -480,6 +494,205 @@ objdump_print_address (vma, info)
|
|||
fprintf (info->stream, ">");
|
||||
}
|
||||
|
||||
/* Hold the last function name and the last line number we displayed
|
||||
in a disassembly. */
|
||||
|
||||
static char *prev_functionname;
|
||||
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
|
||||
display. This can be important for inlined functions. */
|
||||
|
||||
struct print_file_list
|
||||
{
|
||||
struct print_file_list *next;
|
||||
char *filename;
|
||||
unsigned int line;
|
||||
FILE *f;
|
||||
};
|
||||
|
||||
static struct print_file_list *print_files;
|
||||
|
||||
/* The number of preceding context lines to show when we start
|
||||
displaying a file for the first time. */
|
||||
|
||||
#define SHOW_PRECEDING_CONTEXT_LINES (5)
|
||||
|
||||
/* Skip ahead to a given line in a file, optionally printing each
|
||||
line. */
|
||||
|
||||
static void
|
||||
skip_to_line PARAMS ((struct print_file_list *, unsigned int, boolean));
|
||||
|
||||
static void
|
||||
skip_to_line (p, line, show)
|
||||
struct print_file_list *p;
|
||||
unsigned int line;
|
||||
boolean show;
|
||||
{
|
||||
while (p->line < line)
|
||||
{
|
||||
char buf[100];
|
||||
|
||||
if (fgets (buf, sizeof buf, p->f) == NULL)
|
||||
{
|
||||
fclose (p->f);
|
||||
p->f = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (show)
|
||||
printf ("%s", buf);
|
||||
|
||||
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)
|
||||
bfd *abfd;
|
||||
asection *section;
|
||||
bfd_vma off;
|
||||
{
|
||||
CONST char *filename;
|
||||
CONST char *functionname;
|
||||
unsigned int line;
|
||||
|
||||
if (! with_line_numbers && ! with_source_code)
|
||||
return;
|
||||
|
||||
if (! bfd_find_nearest_line (abfd, section, syms, off, &filename,
|
||||
&functionname, &line))
|
||||
return;
|
||||
|
||||
if (filename != NULL && *filename == '\0')
|
||||
filename = NULL;
|
||||
if (functionname != NULL && *functionname == '\0')
|
||||
functionname = NULL;
|
||||
|
||||
if (with_line_numbers)
|
||||
{
|
||||
if (functionname != NULL
|
||||
&& (prev_functionname == NULL
|
||||
|| strcmp (functionname, prev_functionname) != 0))
|
||||
printf ("%s():\n", functionname);
|
||||
if (line > 0 && line != prev_line)
|
||||
printf ("%s:%u\n", filename == NULL ? "???" : filename, line);
|
||||
}
|
||||
|
||||
if (with_source_code
|
||||
&& filename != NULL
|
||||
&& line > 0)
|
||||
{
|
||||
struct print_file_list **pp, *p;
|
||||
|
||||
for (pp = &print_files; *pp != NULL; pp = &(*pp)->next)
|
||||
if (strcmp ((*pp)->filename, filename) == 0)
|
||||
break;
|
||||
p = *pp;
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
if (p != print_files)
|
||||
{
|
||||
int l;
|
||||
|
||||
/* We have reencountered a file name which we saw
|
||||
earlier. This implies that either we are dumping out
|
||||
code from an included file, or the same file was
|
||||
linked in more than once. There are two common cases
|
||||
of an included file: inline functions in a header
|
||||
file, and a bison or flex skeleton file. In the
|
||||
former case we want to just start printing (but we
|
||||
back up a few lines to give context); in the latter
|
||||
case we want to continue from where we left off. I
|
||||
can't think of a good way to distinguish the cases,
|
||||
so I used a heuristic based on the file name. */
|
||||
if (strcmp (p->filename + strlen (p->filename) - 2, ".h") != 0)
|
||||
l = p->line;
|
||||
else
|
||||
{
|
||||
l = line - SHOW_PRECEDING_CONTEXT_LINES;
|
||||
if (l <= 0)
|
||||
l = 1;
|
||||
}
|
||||
|
||||
if (p->f == NULL)
|
||||
{
|
||||
p->f = fopen (p->filename, "r");
|
||||
p->line = 0;
|
||||
}
|
||||
if (p->f != NULL)
|
||||
skip_to_line (p, l, false);
|
||||
|
||||
if (print_files->f != NULL)
|
||||
{
|
||||
fclose (print_files->f);
|
||||
print_files->f = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (p->f != NULL)
|
||||
{
|
||||
skip_to_line (p, line, true);
|
||||
*pp = p->next;
|
||||
p->next = print_files;
|
||||
print_files = p;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
f = fopen (filename, "r");
|
||||
if (f != NULL)
|
||||
{
|
||||
int l;
|
||||
|
||||
p = ((struct print_file_list *)
|
||||
xmalloc (sizeof (struct print_file_list)));
|
||||
p->filename = xmalloc (strlen (filename) + 1);
|
||||
strcpy (p->filename, filename);
|
||||
p->line = 0;
|
||||
p->f = f;
|
||||
|
||||
if (print_files != NULL && print_files->f != NULL)
|
||||
{
|
||||
fclose (print_files->f);
|
||||
print_files->f = NULL;
|
||||
}
|
||||
p->next = print_files;
|
||||
print_files = p;
|
||||
|
||||
l = line - SHOW_PRECEDING_CONTEXT_LINES;
|
||||
if (l <= 0)
|
||||
l = 1;
|
||||
skip_to_line (p, l, false);
|
||||
if (p->f != NULL)
|
||||
skip_to_line (p, line, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (functionname != NULL
|
||||
&& (prev_functionname == NULL
|
||||
|| strcmp (functionname, prev_functionname) != 0))
|
||||
{
|
||||
if (prev_functionname != NULL)
|
||||
free (prev_functionname);
|
||||
prev_functionname = xmalloc (strlen (functionname) + 1);
|
||||
strcpy (prev_functionname, functionname);
|
||||
}
|
||||
|
||||
if (line > 0 && line != prev_line)
|
||||
prev_line = line;
|
||||
}
|
||||
|
||||
void
|
||||
disassemble_data (abfd)
|
||||
bfd *abfd;
|
||||
|
@ -489,69 +702,22 @@ disassemble_data (abfd)
|
|||
disassembler_ftype disassemble_fn = 0; /* New style */
|
||||
struct disassemble_info disasm_info;
|
||||
struct objdump_disasm_info aux;
|
||||
|
||||
int prevline = 0;
|
||||
char *prev_function = NULL;
|
||||
|
||||
asection *section;
|
||||
|
||||
boolean done_dot = false;
|
||||
|
||||
/* If we are dumping relocation information, read the relocs for
|
||||
each section we are going to disassemble. We must do this before
|
||||
we sort the symbols. */
|
||||
if (dump_reloc_info)
|
||||
{
|
||||
for (section = abfd->sections;
|
||||
section != (asection *) NULL;
|
||||
section = section->next)
|
||||
{
|
||||
long relsize;
|
||||
arelent **relpp;
|
||||
print_files = NULL;
|
||||
prev_functionname = NULL;
|
||||
prev_line = -1;
|
||||
|
||||
if ((section->flags & SEC_LOAD) == 0
|
||||
|| (! disassemble_all
|
||||
&& only == NULL
|
||||
&& (section->flags & SEC_CODE) == 0))
|
||||
continue;
|
||||
if (only != (char *) NULL && strcmp (only, section->name) != 0)
|
||||
continue;
|
||||
if ((section->flags & SEC_RELOC) == 0)
|
||||
continue;
|
||||
/* We make a copy of syms to sort. We don't want to sort syms
|
||||
because that will screw up the relocs. */
|
||||
sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
|
||||
memcpy (sorted_syms, syms, symcount * sizeof (asymbol *));
|
||||
|
||||
/* We store the reloc information in the reloc_count and
|
||||
orelocation fields. */
|
||||
|
||||
relsize = bfd_get_reloc_upper_bound (abfd, section);
|
||||
if (relsize < 0)
|
||||
bfd_fatal (bfd_get_filename (abfd));
|
||||
|
||||
if (relsize == 0)
|
||||
section->reloc_count = 0;
|
||||
else
|
||||
{
|
||||
long relcount;
|
||||
|
||||
relpp = (arelent **) xmalloc (relsize);
|
||||
relcount = bfd_canonicalize_reloc (abfd, section, relpp, syms);
|
||||
if (relcount < 0)
|
||||
bfd_fatal (bfd_get_filename (abfd));
|
||||
section->reloc_count = relcount;
|
||||
section->orelocation = relpp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Replace symbol section relative values with abs values. */
|
||||
for (i = 0; i < symcount; i++)
|
||||
{
|
||||
syms[i]->value += syms[i]->section->vma;
|
||||
}
|
||||
|
||||
symcount = remove_useless_symbols (syms, symcount);
|
||||
sorted_symcount = remove_useless_symbols (sorted_syms, symcount);
|
||||
|
||||
/* Sort the symbols into section and symbol order */
|
||||
qsort (syms, symcount, sizeof (asymbol *), compare_symbols);
|
||||
qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
|
||||
|
||||
INIT_DISASSEMBLE_INFO(disasm_info, stdout);
|
||||
disasm_info.application_data = (PTR) &aux;
|
||||
|
@ -595,6 +761,7 @@ disassemble_data (abfd)
|
|||
{
|
||||
bfd_byte *data = NULL;
|
||||
bfd_size_type datasize = 0;
|
||||
arelent **relbuf = NULL;
|
||||
arelent **relpp = NULL;
|
||||
arelent **relppend = NULL;
|
||||
|
||||
|
@ -609,11 +776,27 @@ disassemble_data (abfd)
|
|||
if (dump_reloc_info
|
||||
&& (section->flags & SEC_RELOC) != 0)
|
||||
{
|
||||
/* Sort the relocs by address. */
|
||||
qsort (section->orelocation, section->reloc_count,
|
||||
sizeof (arelent *), compare_relocs);
|
||||
relpp = section->orelocation;
|
||||
relppend = relpp + section->reloc_count;
|
||||
long relsize;
|
||||
|
||||
relsize = bfd_get_reloc_upper_bound (abfd, section);
|
||||
if (relsize < 0)
|
||||
bfd_fatal (bfd_get_filename (abfd));
|
||||
|
||||
if (relsize > 0)
|
||||
{
|
||||
long relcount;
|
||||
|
||||
relbuf = (arelent **) xmalloc (relsize);
|
||||
relcount = bfd_canonicalize_reloc (abfd, section, relbuf, syms);
|
||||
if (relcount < 0)
|
||||
bfd_fatal (bfd_get_filename (abfd));
|
||||
|
||||
/* Sort the relocs by address. */
|
||||
qsort (relbuf, relcount, sizeof (arelent *), compare_relocs);
|
||||
|
||||
relpp = relbuf;
|
||||
relppend = relpp + relcount;
|
||||
}
|
||||
}
|
||||
|
||||
printf ("Disassembly of section %s:\n", section->name);
|
||||
|
@ -648,40 +831,8 @@ disassemble_data (abfd)
|
|||
else
|
||||
{
|
||||
done_dot = false;
|
||||
if (with_line_numbers)
|
||||
{
|
||||
CONST char *filename;
|
||||
CONST char *functionname;
|
||||
unsigned int line;
|
||||
|
||||
if (bfd_find_nearest_line (abfd,
|
||||
section,
|
||||
syms,
|
||||
section->vma + i,
|
||||
&filename,
|
||||
&functionname,
|
||||
&line))
|
||||
{
|
||||
if (functionname
|
||||
&& *functionname != '\0'
|
||||
&& (prev_function == NULL
|
||||
|| strcmp (functionname, prev_function) != 0))
|
||||
{
|
||||
printf ("%s():\n", functionname);
|
||||
if (prev_function != NULL)
|
||||
free (prev_function);
|
||||
prev_function = xmalloc (strlen (functionname) + 1);
|
||||
strcpy (prev_function, functionname);
|
||||
}
|
||||
if (!filename)
|
||||
filename = "???";
|
||||
if (line && line != prevline)
|
||||
{
|
||||
printf ("%s:%u\n", filename, line);
|
||||
prevline = line;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (with_line_numbers || with_source_code)
|
||||
show_line (abfd, section, i);
|
||||
aux.require_sec = true;
|
||||
objdump_print_address (section->vma + i, &disasm_info);
|
||||
aux.require_sec = false;
|
||||
|
@ -751,7 +902,10 @@ disassemble_data (abfd)
|
|||
|
||||
i += bytes;
|
||||
}
|
||||
|
||||
free (data);
|
||||
if (relbuf != NULL)
|
||||
free (relbuf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1026,8 +1180,6 @@ display_bfd (abfd)
|
|||
dump_dynamic_relocs (abfd);
|
||||
if (dump_section_contents)
|
||||
dump_data (abfd);
|
||||
/* Note that disassemble_data re-orders the syms table, but that is
|
||||
safe - as long as it is done last! */
|
||||
if (disassemble)
|
||||
disassemble_data (abfd);
|
||||
}
|
||||
|
@ -1229,7 +1381,6 @@ dump_relocs (abfd)
|
|||
else
|
||||
{
|
||||
relpp = (arelent **) xmalloc (relsize);
|
||||
/* Note that this must be done *before* we sort the syms table. */
|
||||
relcount = bfd_canonicalize_reloc (abfd, a, relpp, syms);
|
||||
if (relcount < 0)
|
||||
bfd_fatal (bfd_get_filename (abfd));
|
||||
|
@ -1350,6 +1501,10 @@ dump_reloc_set (abfd, relpp, relcount)
|
|||
/* The length of the longest architecture name + 1. */
|
||||
#define LONGEST_ARCH sizeof("rs6000:6000")
|
||||
|
||||
#ifndef L_tmpnam
|
||||
#define L_tmpnam 25
|
||||
#endif
|
||||
|
||||
/* List the targets that BFD is configured to support, each followed
|
||||
by its endianness and the architectures it supports. */
|
||||
|
||||
|
@ -1358,10 +1513,11 @@ display_target_list ()
|
|||
{
|
||||
extern char *tmpnam ();
|
||||
extern bfd_target *bfd_target_vector[];
|
||||
char tmparg[L_tmpnam];
|
||||
char *dummy_name;
|
||||
int t;
|
||||
|
||||
dummy_name = tmpnam ((char *) NULL);
|
||||
dummy_name = tmpnam (tmparg);
|
||||
for (t = 0; bfd_target_vector[t]; t++)
|
||||
{
|
||||
bfd_target *p = bfd_target_vector[t];
|
||||
|
@ -1404,6 +1560,7 @@ display_info_table (first, last)
|
|||
{
|
||||
extern bfd_target *bfd_target_vector[];
|
||||
extern char *tmpnam ();
|
||||
char tmparg[L_tmpnam];
|
||||
int t, a;
|
||||
char *dummy_name;
|
||||
|
||||
|
@ -1413,7 +1570,7 @@ display_info_table (first, last)
|
|||
printf ("%s ", bfd_target_vector[t]->name);
|
||||
putchar ('\n');
|
||||
|
||||
dummy_name = tmpnam ((char *) NULL);
|
||||
dummy_name = tmpnam (tmparg);
|
||||
for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
|
||||
if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0)
|
||||
{
|
||||
|
@ -1521,9 +1678,11 @@ main (argc, argv)
|
|||
program_name = *argv;
|
||||
xmalloc_set_program_name (program_name);
|
||||
|
||||
START_PROGRESS (program_name, 0);
|
||||
|
||||
bfd_init ();
|
||||
|
||||
while ((c = getopt_long (argc, argv, "ib:m:VdDlfahrRtTxsj:", long_options,
|
||||
while ((c = getopt_long (argc, argv, "ib:m:VdDlfahrRtTxsSj:", long_options,
|
||||
(int *) 0))
|
||||
!= EOF)
|
||||
{
|
||||
|
@ -1569,6 +1728,10 @@ main (argc, argv)
|
|||
case 'D':
|
||||
disassemble = disassemble_all = true;
|
||||
break;
|
||||
case 'S':
|
||||
disassemble = true;
|
||||
with_source_code = true;
|
||||
break;
|
||||
case 's':
|
||||
dump_section_contents = 1;
|
||||
break;
|
||||
|
@ -1615,5 +1778,8 @@ main (argc, argv)
|
|||
for (; optind < argc;)
|
||||
display_file (argv[optind++], target);
|
||||
}
|
||||
|
||||
END_PROGRESS (program_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue