Add new field to disassemble_info structure: symbol_is_valid() and use it to

skip displaying arm elf mapping symbols in disassembly output.
This commit is contained in:
Nick Clifton 2003-11-14 15:12:44 +00:00
parent 0a90bcdd1e
commit 22a398e190
12 changed files with 170 additions and 60 deletions

View File

@ -1,3 +1,16 @@
2003-11-14 Nick Clifton <nickc@redhat.com>
* objdump.c (find_symbol_for_address): Change parameters so
that the entire disassemble_info structure is passed, not just
a few fields. Use the symbol_is_valid field to check the
validity of located symbols and continue searching if they are
not valid.
(objdump_print_addr): Alter parameters passed to
find_symbol_for_address.
(objdump_symbol_at_address): Likewise.
(disassemble_address): Likewise. Also use symbol_is_valid
function to check the validity of located symbols.
2003-11-13 Tobias Burnus <tobias.burnus@physik.fu-berlin.de>
* ar.c (open_inarch): Emit a warning when an archive is created

View File

@ -643,14 +643,14 @@ objdump_print_symname (bfd *abfd, struct disassemble_info *info,
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
@ -661,6 +661,9 @@ find_symbol_for_address (bfd *abfd, asection *sec, bfd_vma vma,
long min = 0;
long max = sorted_symcount;
long thisplace;
struct objdump_disasm_info * aux = (struct objdump_disasm_info *) info->application_data;
bfd * abfd = aux->abfd;
asection * sec = aux->sec;
unsigned int opb = bfd_octets_per_byte (abfd);
if (sorted_symcount < 1)
@ -704,7 +707,7 @@ find_symbol_for_address (bfd *abfd, asection *sec, bfd_vma vma,
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)
@ -749,15 +752,22 @@ find_symbol_for_address (bfd *abfd, asection *sec, bfd_vma vma,
}
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)
@ -819,7 +829,7 @@ static void
objdump_print_addr (bfd_vma vma, struct disassemble_info *info,
bfd_boolean skip_zeroes)
{
struct objdump_disasm_info *aux;
struct objdump_disasm_info * aux = (struct objdump_disasm_info *) info->application_data;
asymbol *sym;
if (sorted_symcount < 1)
@ -829,9 +839,7 @@ objdump_print_addr (bfd_vma vma, struct disassemble_info *info,
return;
}
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);
}
@ -850,16 +858,9 @@ objdump_print_address (bfd_vma vma, struct disassemble_info *info)
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));
}
@ -1627,6 +1628,7 @@ disassemble_section (bfd *abfd, asection *section, void *info)
bfd_get_section_contents (abfd, section, data, 0, datasize);
paux->sec = section;
paux->require_sec = TRUE;
pinfo->buffer = data;
pinfo->buffer_vma = section->vma;
pinfo->buffer_length = datasize;
@ -1659,8 +1661,7 @@ disassemble_section (bfd *abfd, asection *section, void *info)
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);
sym = find_symbol_for_address (section->vma + addr_offset, info, &place);
/* Disassemble a block of instructions up to the address associated with
the symbol we have just found. Then print the symbol and find the
@ -1668,81 +1669,81 @@ disassemble_section (bfd *abfd, asection *section, void *info)
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)
@ -1789,7 +1790,7 @@ disassemble_data (bfd *abfd)
/* 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;
@ -1845,6 +1846,9 @@ disassemble_data (bfd *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)

View File

@ -1,3 +1,13 @@
2003-11-14 Nick Clifton <nickc@redhat.com>
* gas/arm/arm7.d: Pass -D instead of -d to objdump in order to
display the contents of data fields in the .text section.
This change is necessary after the addition of arm elf mapping
symbol support to gas.
* gas/arm/pic.d: Expect addresses with function name offsets.
This change is necessary after the addition of arm elf mapping
symbol support to gas.
2003-11-13 Nick Clifton <nickc@redhat.com>
* gas/arm/mapping.s: New test: Source for ARM ELF mapping

View File

@ -1,4 +1,4 @@
#objdump: -dr --prefix-addresses --show-raw-insn
#objdump: -Dr --prefix-addresses --show-raw-insn
#name: ARM arm7t
#as: -mcpu=arm7t -EL

View File

@ -6,9 +6,9 @@
.*: +file format .*arm.*
Disassembly of section .text:
0x0+0 ebfffffe bl 0x0+0
00+0 <[^>]*> ebfffffe bl 00+0 <[^>]*>
0: R_ARM_PC24 foo
0x0+4 ebfffffe bl 0x0+4
00+4 <[^>]*> ebfffffe bl 00+4 <[^>]*>
4: R_ARM_PLT32 foo
\.\.\.
8: R_ARM_ABS32 sym

View File

@ -1,3 +1,14 @@
2003-11-14 Nick Clifton <nickc@redhat.com>
* dis-asm.h (struct disassemble_info): Add new field
'symbol_is_valid' which is a function which can tell the
disassembler to skip certain symbols as they should not be
displayed to the user.
(arm_symbol_is_valid): New prototype. This is the ARM
specific function for the symbol_is_valid field.
(generic_symbol_is_valid): New prototype. This is the default
function pointed to by the symbol_is_valid field.
2003-11-06 Bruno Rohee <bruno@rohee.com>
* hp-symtab.h: Fix "the the" typo.

View File

@ -130,6 +130,12 @@ typedef struct disassemble_info {
int (* symbol_at_address_func)
(bfd_vma addr, struct disassemble_info * info);
/* Function called to check if a SYMBOL is can be displayed to the user.
This is used by some ports that want to hide special symbols when
displaying debugging outout. */
bfd_boolean (* symbol_is_valid)
(asymbol *, struct disassemble_info * info);
/* These are for buffer_read_memory. */
bfd_byte *buffer;
bfd_vma buffer_vma;
@ -141,7 +147,7 @@ typedef struct disassemble_info {
the same value in order to get reasonable looking output. */
int bytes_per_line;
/* the next two variables control the way objdump displays the raw data */
/* The next two variables control the way objdump displays the raw data. */
/* For example, if bytes_per_line is 8 and bytes_per_chunk is 4, the */
/* output will look like this:
00: 00000000 00000000
@ -251,12 +257,16 @@ extern void print_arm_disassembler_options (FILE *);
extern void parse_arm_disassembler_option (char *);
extern int get_arm_regname_num_options (void);
extern int set_arm_regname_option (int);
extern int get_arm_regnames
(int, const char **, const char **, const char ***);
extern int get_arm_regnames (int, const char **, const char **, const char ***);
extern bfd_boolean arm_symbol_is_valid (asymbol *, struct disassemble_info *);
/* Fetch the disassembler for a given BFD, if that support is available. */
extern disassembler_ftype disassembler (bfd *);
/* Amend the disassemble_info structure as necessary for the target architecture.
Should only be called after initialising the info->arch field. */
extern void disassemble_init_for_target (struct disassemble_info * info);
/* Document any target specific options available from the disassembler. */
extern void disassembler_usage (FILE *);
@ -284,6 +294,10 @@ extern void generic_print_address
extern int generic_symbol_at_address
(bfd_vma, struct disassemble_info *);
/* Also always true. */
extern bfd_boolean generic_symbol_is_valid
(asymbol *, struct disassemble_info *);
/* Method to initialize a disassemble_info struct. This should be
called by all applications creating such a struct. */
extern void init_disassemble_info (struct disassemble_info *info, void *stream,

View File

@ -1,3 +1,15 @@
2003-11-14 Nick Clifton <nickc@redhat.com>
* dis-init.c (init_disassemble_info): Initialise
symbol_is_valid field.
* dis-buf.c (generic_symbol_is_valid): New function. Always
returns TRUE.
* arm-dis.c (arm_symbol_is_valid): New function. Return FALSE
for ARM ELF mapping symbols.
* disassemble.c (disassemble_init_for_target): Set
symbol_is_valid field to arm_symbol_is_valid of the target is
an ARM.
2003-11-05 H.J. Lu <hongjiu.lu@intel.com>
* m68k-opc.c (m68k_opcodes): Reorder "fmovel".

View File

@ -1145,6 +1145,23 @@ print_insn_thumb (pc, info, given)
abort ();
}
/* Disallow mapping symbols ($a, $b, $d, $t etc) from
being displayed in symbol relative addresses. */
bfd_boolean
arm_symbol_is_valid (asymbol * sym,
struct disassemble_info * info ATTRIBUTE_UNUSED)
{
const char * name;
if (sym == NULL)
return FALSE;
name = bfd_asymbol_name (sym);
return (name && *name != '$');
}
/* Parse an individual disassembler option. */
void

View File

@ -107,7 +107,7 @@ generic_strcat_address (addr, buf, len)
}
#endif
/* Just return the given address. */
/* Just return true. */
int
generic_symbol_at_address (addr, info)
@ -116,3 +116,12 @@ generic_symbol_at_address (addr, info)
{
return 1;
}
/* Just return TRUE. */
bfd_boolean
generic_symbol_is_valid (asymbol * sym ATTRIBUTE_UNUSED,
struct disassemble_info *info ATTRIBUTE_UNUSED)
{
return TRUE;
}

View File

@ -26,6 +26,7 @@ init_disassemble_info (struct disassemble_info *info, void *stream,
fprintf_ftype fprintf_func)
{
memset (info, 0, sizeof (*info));
info->flavour = bfd_target_unknown_flavour;
info->arch = bfd_arch_unknown;
info->endian = BFD_ENDIAN_UNKNOWN;
@ -36,6 +37,7 @@ init_disassemble_info (struct disassemble_info *info, void *stream,
info->memory_error_func = perror_memory;
info->print_address_func = generic_print_address;
info->symbol_at_address_func = generic_symbol_at_address;
info->symbol_is_valid = generic_symbol_is_valid;
info->display_endian = BFD_ENDIAN_UNKNOWN;
}

View File

@ -397,3 +397,21 @@ disassembler_usage (stream)
return;
}
void
disassemble_init_for_target (struct disassemble_info * info)
{
if (info == NULL)
return;
switch (info->arch)
{
#ifdef ARCH_arm
case bfd_arch_arm:
info->symbol_is_valid = arm_symbol_is_valid;
break;
#endif
default:
break;
}
}