forked from Imagelibrary/binutils-gdb
* 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:
@@ -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>
|
Tue Feb 14 18:03:03 1995 Ian Lance Taylor <ian@cygnus.com>
|
||||||
|
|
||||||
* objdump.c (with_source_code): New global variable.
|
* 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\
|
[--strip-symbol symbol] [-N symbol] [--verbose]\n\
|
||||||
[--version] [--help]\n\
|
[--version] [--help]\n\
|
||||||
in-file [out-file]\n");
|
in-file [out-file]\n");
|
||||||
|
list_supported_targets (program_name, stream);
|
||||||
exit (exit_status);
|
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\
|
[--strip-symbol symbol] [-N symbol]\n\
|
||||||
[--remove-section=section] [--verbose] [--version] [--help] file...\n",
|
[--remove-section=section] [--verbose] [--version] [--help] file...\n",
|
||||||
program_name);
|
program_name);
|
||||||
|
list_supported_targets (program_name, stream);
|
||||||
exit (exit_status);
|
exit (exit_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,6 +419,12 @@ is_strip_section (abfd, sec)
|
|||||||
{
|
{
|
||||||
struct section_list *p;
|
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)
|
if (! sections_removed)
|
||||||
return false;
|
return false;
|
||||||
p = find_section_list (bfd_get_section_name (abfd, sec), 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 "bfd.h"
|
||||||
#include "sysdep.h"
|
#include "sysdep.h"
|
||||||
#include "getopt.h"
|
#include "getopt.h"
|
||||||
|
#include "progress.h"
|
||||||
#include "bucomm.h"
|
#include "bucomm.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -48,6 +49,7 @@ int dump_reloc_info; /* -r */
|
|||||||
int dump_dynamic_reloc_info; /* -R */
|
int dump_dynamic_reloc_info; /* -R */
|
||||||
int dump_ar_hdrs; /* -a */
|
int dump_ar_hdrs; /* -a */
|
||||||
int with_line_numbers; /* -l */
|
int with_line_numbers; /* -l */
|
||||||
|
boolean with_source_code; /* -S */
|
||||||
int dump_stab_section_info; /* --stabs */
|
int dump_stab_section_info; /* --stabs */
|
||||||
boolean disassemble; /* -d */
|
boolean disassemble; /* -d */
|
||||||
boolean disassemble_all; /* -D */
|
boolean disassemble_all; /* -D */
|
||||||
@@ -70,6 +72,12 @@ asymbol **syms;
|
|||||||
/* Number of symbols in `syms'. */
|
/* Number of symbols in `syms'. */
|
||||||
long symcount = 0;
|
long symcount = 0;
|
||||||
|
|
||||||
|
/* The sorted symbol table. */
|
||||||
|
asymbol **sorted_syms;
|
||||||
|
|
||||||
|
/* Number of symbols in `sorted_syms'. */
|
||||||
|
long sorted_symcount = 0;
|
||||||
|
|
||||||
/* The dynamic symbol table. */
|
/* The dynamic symbol table. */
|
||||||
asymbol **dynsyms;
|
asymbol **dynsyms;
|
||||||
|
|
||||||
@@ -101,6 +109,9 @@ display_bfd PARAMS ((bfd *abfd));
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
objdump_print_address PARAMS ((bfd_vma, struct disassemble_info *));
|
objdump_print_address PARAMS ((bfd_vma, struct disassemble_info *));
|
||||||
|
|
||||||
|
static void
|
||||||
|
show_line PARAMS ((bfd *, asection *, bfd_vma));
|
||||||
|
|
||||||
void
|
void
|
||||||
usage (stream, status)
|
usage (stream, status)
|
||||||
@@ -108,15 +119,16 @@ usage (stream, status)
|
|||||||
int status;
|
int status;
|
||||||
{
|
{
|
||||||
fprintf (stream, "\
|
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\
|
[--archive-headers] [--target=bfdname] [--disassemble]\n\
|
||||||
[--disassemble-all] [--file-headers] [--section-headers] [--headers]\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\
|
[--architecture=machine] [--reloc] [--full-contents] [--stabs]\n\
|
||||||
[--syms] [--all-headers] [--dynamic-syms] [--dynamic-reloc]\n\
|
[--syms] [--all-headers] [--dynamic-syms] [--dynamic-reloc]\n\
|
||||||
[--version] [--help] objfile...\n\
|
[--version] [--help] objfile...\n\
|
||||||
at least one option besides -l (--line-numbers) must be given\n",
|
at least one option besides -l (--line-numbers) must be given\n",
|
||||||
program_name);
|
program_name);
|
||||||
|
list_supported_targets (program_name, stream);
|
||||||
exit (status);
|
exit (status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +150,7 @@ static struct option long_options[]=
|
|||||||
{"reloc", no_argument, NULL, 'r'},
|
{"reloc", no_argument, NULL, 'r'},
|
||||||
{"section", required_argument, NULL, 'j'},
|
{"section", required_argument, NULL, 'j'},
|
||||||
{"section-headers", no_argument, NULL, 'h'},
|
{"section-headers", no_argument, NULL, 'h'},
|
||||||
|
{"source", no_argument, NULL, 'S'},
|
||||||
{"stabs", no_argument, &dump_stab_section_info, 1},
|
{"stabs", no_argument, &dump_stab_section_info, 1},
|
||||||
{"syms", no_argument, NULL, 't'},
|
{"syms", no_argument, NULL, 't'},
|
||||||
{"target", required_argument, NULL, 'b'},
|
{"target", required_argument, NULL, 'b'},
|
||||||
@@ -295,9 +308,9 @@ compare_symbols (ap, bp)
|
|||||||
const asymbol *a = *(const asymbol **)ap;
|
const asymbol *a = *(const asymbol **)ap;
|
||||||
const asymbol *b = *(const asymbol **)bp;
|
const asymbol *b = *(const asymbol **)bp;
|
||||||
|
|
||||||
if (a->value > b->value)
|
if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
|
||||||
return 1;
|
return 1;
|
||||||
else if (a->value < b->value)
|
else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (a->section > b->section)
|
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
|
operand can be present at a time, so the 2-entry cache wouldn't be
|
||||||
constantly churned by code doing heavy memory accesses. */
|
constantly churned by code doing heavy memory accesses. */
|
||||||
|
|
||||||
/* Indices in `syms'. */
|
/* Indices in `sorted_syms'. */
|
||||||
long min = 0;
|
long min = 0;
|
||||||
long max = symcount;
|
long max = sorted_symcount;
|
||||||
long thisplace;
|
long thisplace;
|
||||||
|
|
||||||
bfd_signed_vma vardiff;
|
bfd_signed_vma vardiff;
|
||||||
|
|
||||||
fprintf_vma (info->stream, vma);
|
fprintf_vma (info->stream, vma);
|
||||||
|
|
||||||
if (symcount < 1)
|
if (sorted_symcount < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Perform a binary search looking for the closest symbol to the
|
/* Perform a binary search looking for the closest symbol to the
|
||||||
@@ -360,9 +373,9 @@ objdump_print_address (vma, info)
|
|||||||
asymbol *sym;
|
asymbol *sym;
|
||||||
|
|
||||||
thisplace = (max + min) / 2;
|
thisplace = (max + min) / 2;
|
||||||
sym = syms[thisplace];
|
sym = sorted_syms[thisplace];
|
||||||
|
|
||||||
vardiff = sym->value - vma;
|
vardiff = bfd_asymbol_value (sym) - vma;
|
||||||
|
|
||||||
if (vardiff > 0)
|
if (vardiff > 0)
|
||||||
max = thisplace;
|
max = thisplace;
|
||||||
@@ -382,27 +395,27 @@ objdump_print_address (vma, info)
|
|||||||
{
|
{
|
||||||
/* If this symbol isn't global, search for one with the same value
|
/* If this symbol isn't global, search for one with the same value
|
||||||
that is. */
|
that is. */
|
||||||
bfd_vma val = syms[thisplace]->value;
|
bfd_vma val = bfd_asymbol_value (sorted_syms[thisplace]);
|
||||||
long i;
|
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--)
|
for (i = thisplace - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (syms[i]->value == val
|
if (bfd_asymbol_value (sorted_syms[i]) == val
|
||||||
&& (!(syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|
&& (!(sorted_syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|
||||||
|| ((syms[thisplace]->flags & BSF_DEBUGGING)
|
|| ((sorted_syms[thisplace]->flags & BSF_DEBUGGING)
|
||||||
&& !(syms[i]->flags & BSF_DEBUGGING))))
|
&& !(sorted_syms[i]->flags & BSF_DEBUGGING))))
|
||||||
{
|
{
|
||||||
thisplace = i;
|
thisplace = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|
if (sorted_syms[thisplace]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|
||||||
for (i = thisplace + 1; i < symcount; i++)
|
for (i = thisplace + 1; i < sorted_symcount; i++)
|
||||||
{
|
{
|
||||||
if (syms[i]->value == val
|
if (bfd_asymbol_value (sorted_syms[i]) == val
|
||||||
&& (!(syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|
&& (!(sorted_syms[i]->flags & (BSF_LOCAL|BSF_DEBUGGING))
|
||||||
|| ((syms[thisplace]->flags & BSF_DEBUGGING)
|
|| ((sorted_syms[thisplace]->flags & BSF_DEBUGGING)
|
||||||
&& !(syms[i]->flags & BSF_DEBUGGING))))
|
&& !(sorted_syms[i]->flags & BSF_DEBUGGING))))
|
||||||
{
|
{
|
||||||
thisplace = i;
|
thisplace = i;
|
||||||
break;
|
break;
|
||||||
@@ -422,35 +435,36 @@ objdump_print_address (vma, info)
|
|||||||
long i;
|
long i;
|
||||||
|
|
||||||
aux = (struct objdump_disasm_info *) info->application_data;
|
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->require_sec
|
||||||
|| ((aux->abfd->flags & HAS_RELOC) != 0
|
|| ((aux->abfd->flags & HAS_RELOC) != 0
|
||||||
&& vma >= bfd_get_section_vma (aux->abfd, aux->sec)
|
&& vma >= bfd_get_section_vma (aux->abfd, aux->sec)
|
||||||
&& 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_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;
|
break;
|
||||||
}
|
}
|
||||||
--i;
|
--i;
|
||||||
for (; i >= 0; i--)
|
for (; i >= 0; i--)
|
||||||
{
|
{
|
||||||
if (syms[i]->section == aux->sec)
|
if (sorted_syms[i]->section == aux->sec)
|
||||||
{
|
{
|
||||||
thisplace = i;
|
thisplace = i;
|
||||||
break;
|
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.
|
/* We didn't find a good symbol with a smaller value.
|
||||||
Look for one with a larger 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;
|
thisplace = i;
|
||||||
break;
|
break;
|
||||||
@@ -460,19 +474,19 @@ objdump_print_address (vma, info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (info->stream, " <%s", syms[thisplace]->name);
|
fprintf (info->stream, " <%s", sorted_syms[thisplace]->name);
|
||||||
if (syms[thisplace]->value > vma)
|
if (bfd_asymbol_value (sorted_syms[thisplace]) > vma)
|
||||||
{
|
{
|
||||||
char buf[30], *p = buf;
|
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')
|
while (*p == '0')
|
||||||
p++;
|
p++;
|
||||||
fprintf (info->stream, "-%s", 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;
|
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')
|
while (*p == '0')
|
||||||
p++;
|
p++;
|
||||||
fprintf (info->stream, "+%s", p);
|
fprintf (info->stream, "+%s", p);
|
||||||
@@ -480,6 +494,205 @@ objdump_print_address (vma, info)
|
|||||||
fprintf (info->stream, ">");
|
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
|
void
|
||||||
disassemble_data (abfd)
|
disassemble_data (abfd)
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
@@ -489,69 +702,22 @@ disassemble_data (abfd)
|
|||||||
disassembler_ftype disassemble_fn = 0; /* New style */
|
disassembler_ftype disassemble_fn = 0; /* New style */
|
||||||
struct disassemble_info disasm_info;
|
struct disassemble_info disasm_info;
|
||||||
struct objdump_disasm_info aux;
|
struct objdump_disasm_info aux;
|
||||||
|
|
||||||
int prevline = 0;
|
|
||||||
char *prev_function = NULL;
|
|
||||||
|
|
||||||
asection *section;
|
asection *section;
|
||||||
|
|
||||||
boolean done_dot = false;
|
boolean done_dot = false;
|
||||||
|
|
||||||
/* If we are dumping relocation information, read the relocs for
|
print_files = NULL;
|
||||||
each section we are going to disassemble. We must do this before
|
prev_functionname = NULL;
|
||||||
we sort the symbols. */
|
prev_line = -1;
|
||||||
if (dump_reloc_info)
|
|
||||||
{
|
|
||||||
for (section = abfd->sections;
|
|
||||||
section != (asection *) NULL;
|
|
||||||
section = section->next)
|
|
||||||
{
|
|
||||||
long relsize;
|
|
||||||
arelent **relpp;
|
|
||||||
|
|
||||||
if ((section->flags & SEC_LOAD) == 0
|
/* We make a copy of syms to sort. We don't want to sort syms
|
||||||
|| (! disassemble_all
|
because that will screw up the relocs. */
|
||||||
&& only == NULL
|
sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
|
||||||
&& (section->flags & SEC_CODE) == 0))
|
memcpy (sorted_syms, syms, symcount * sizeof (asymbol *));
|
||||||
continue;
|
|
||||||
if (only != (char *) NULL && strcmp (only, section->name) != 0)
|
|
||||||
continue;
|
|
||||||
if ((section->flags & SEC_RELOC) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* We store the reloc information in the reloc_count and
|
sorted_symcount = remove_useless_symbols (sorted_syms, symcount);
|
||||||
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);
|
|
||||||
|
|
||||||
/* Sort the symbols into section and symbol order */
|
/* 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);
|
INIT_DISASSEMBLE_INFO(disasm_info, stdout);
|
||||||
disasm_info.application_data = (PTR) &aux;
|
disasm_info.application_data = (PTR) &aux;
|
||||||
@@ -595,6 +761,7 @@ disassemble_data (abfd)
|
|||||||
{
|
{
|
||||||
bfd_byte *data = NULL;
|
bfd_byte *data = NULL;
|
||||||
bfd_size_type datasize = 0;
|
bfd_size_type datasize = 0;
|
||||||
|
arelent **relbuf = NULL;
|
||||||
arelent **relpp = NULL;
|
arelent **relpp = NULL;
|
||||||
arelent **relppend = NULL;
|
arelent **relppend = NULL;
|
||||||
|
|
||||||
@@ -609,11 +776,27 @@ disassemble_data (abfd)
|
|||||||
if (dump_reloc_info
|
if (dump_reloc_info
|
||||||
&& (section->flags & SEC_RELOC) != 0)
|
&& (section->flags & SEC_RELOC) != 0)
|
||||||
{
|
{
|
||||||
/* Sort the relocs by address. */
|
long relsize;
|
||||||
qsort (section->orelocation, section->reloc_count,
|
|
||||||
sizeof (arelent *), compare_relocs);
|
relsize = bfd_get_reloc_upper_bound (abfd, section);
|
||||||
relpp = section->orelocation;
|
if (relsize < 0)
|
||||||
relppend = relpp + section->reloc_count;
|
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);
|
printf ("Disassembly of section %s:\n", section->name);
|
||||||
@@ -648,40 +831,8 @@ disassemble_data (abfd)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
done_dot = false;
|
done_dot = false;
|
||||||
if (with_line_numbers)
|
if (with_line_numbers || with_source_code)
|
||||||
{
|
show_line (abfd, section, i);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
aux.require_sec = true;
|
aux.require_sec = true;
|
||||||
objdump_print_address (section->vma + i, &disasm_info);
|
objdump_print_address (section->vma + i, &disasm_info);
|
||||||
aux.require_sec = false;
|
aux.require_sec = false;
|
||||||
@@ -751,7 +902,10 @@ disassemble_data (abfd)
|
|||||||
|
|
||||||
i += bytes;
|
i += bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
free (data);
|
free (data);
|
||||||
|
if (relbuf != NULL)
|
||||||
|
free (relbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1026,8 +1180,6 @@ display_bfd (abfd)
|
|||||||
dump_dynamic_relocs (abfd);
|
dump_dynamic_relocs (abfd);
|
||||||
if (dump_section_contents)
|
if (dump_section_contents)
|
||||||
dump_data (abfd);
|
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)
|
if (disassemble)
|
||||||
disassemble_data (abfd);
|
disassemble_data (abfd);
|
||||||
}
|
}
|
||||||
@@ -1229,7 +1381,6 @@ dump_relocs (abfd)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
relpp = (arelent **) xmalloc (relsize);
|
relpp = (arelent **) xmalloc (relsize);
|
||||||
/* Note that this must be done *before* we sort the syms table. */
|
|
||||||
relcount = bfd_canonicalize_reloc (abfd, a, relpp, syms);
|
relcount = bfd_canonicalize_reloc (abfd, a, relpp, syms);
|
||||||
if (relcount < 0)
|
if (relcount < 0)
|
||||||
bfd_fatal (bfd_get_filename (abfd));
|
bfd_fatal (bfd_get_filename (abfd));
|
||||||
@@ -1350,6 +1501,10 @@ dump_reloc_set (abfd, relpp, relcount)
|
|||||||
/* The length of the longest architecture name + 1. */
|
/* The length of the longest architecture name + 1. */
|
||||||
#define LONGEST_ARCH sizeof("rs6000:6000")
|
#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
|
/* List the targets that BFD is configured to support, each followed
|
||||||
by its endianness and the architectures it supports. */
|
by its endianness and the architectures it supports. */
|
||||||
|
|
||||||
@@ -1358,10 +1513,11 @@ display_target_list ()
|
|||||||
{
|
{
|
||||||
extern char *tmpnam ();
|
extern char *tmpnam ();
|
||||||
extern bfd_target *bfd_target_vector[];
|
extern bfd_target *bfd_target_vector[];
|
||||||
|
char tmparg[L_tmpnam];
|
||||||
char *dummy_name;
|
char *dummy_name;
|
||||||
int t;
|
int t;
|
||||||
|
|
||||||
dummy_name = tmpnam ((char *) NULL);
|
dummy_name = tmpnam (tmparg);
|
||||||
for (t = 0; bfd_target_vector[t]; t++)
|
for (t = 0; bfd_target_vector[t]; t++)
|
||||||
{
|
{
|
||||||
bfd_target *p = bfd_target_vector[t];
|
bfd_target *p = bfd_target_vector[t];
|
||||||
@@ -1404,6 +1560,7 @@ display_info_table (first, last)
|
|||||||
{
|
{
|
||||||
extern bfd_target *bfd_target_vector[];
|
extern bfd_target *bfd_target_vector[];
|
||||||
extern char *tmpnam ();
|
extern char *tmpnam ();
|
||||||
|
char tmparg[L_tmpnam];
|
||||||
int t, a;
|
int t, a;
|
||||||
char *dummy_name;
|
char *dummy_name;
|
||||||
|
|
||||||
@@ -1413,7 +1570,7 @@ display_info_table (first, last)
|
|||||||
printf ("%s ", bfd_target_vector[t]->name);
|
printf ("%s ", bfd_target_vector[t]->name);
|
||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
|
|
||||||
dummy_name = tmpnam ((char *) NULL);
|
dummy_name = tmpnam (tmparg);
|
||||||
for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
|
for (a = (int) bfd_arch_obscure + 1; a < (int) bfd_arch_last; a++)
|
||||||
if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0)
|
if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0)
|
||||||
{
|
{
|
||||||
@@ -1521,9 +1678,11 @@ main (argc, argv)
|
|||||||
program_name = *argv;
|
program_name = *argv;
|
||||||
xmalloc_set_program_name (program_name);
|
xmalloc_set_program_name (program_name);
|
||||||
|
|
||||||
|
START_PROGRESS (program_name, 0);
|
||||||
|
|
||||||
bfd_init ();
|
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))
|
(int *) 0))
|
||||||
!= EOF)
|
!= EOF)
|
||||||
{
|
{
|
||||||
@@ -1569,6 +1728,10 @@ main (argc, argv)
|
|||||||
case 'D':
|
case 'D':
|
||||||
disassemble = disassemble_all = true;
|
disassemble = disassemble_all = true;
|
||||||
break;
|
break;
|
||||||
|
case 'S':
|
||||||
|
disassemble = true;
|
||||||
|
with_source_code = true;
|
||||||
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
dump_section_contents = 1;
|
dump_section_contents = 1;
|
||||||
break;
|
break;
|
||||||
@@ -1615,5 +1778,8 @@ main (argc, argv)
|
|||||||
for (; optind < argc;)
|
for (; optind < argc;)
|
||||||
display_file (argv[optind++], target);
|
display_file (argv[optind++], target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
END_PROGRESS (program_name);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user