This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Add new field to disassemble_info:
- From: Nick Clifton <nickc at redhat dot com>
- To: binutils at sources dot redhat dot com
- Date: Fri, 14 Nov 2003 15:10:28 +0000
- Subject: Add new field to disassemble_info:
Hi Guys
I am checking in my patch to add the target specific initialisation
function for the disassemble_info structure.
I am also going to check in the patch below which adds a new field
the disassemble_info structure called 'symbol_is_valid'. This is a
function which can be used to tell the disassembler if a symbol can
be shown in debugging output. The patch also adds code to objdump
to use this field and code to the arm disassembler to provide a
non-default implementation of the function which skips arm elf
mapping symbols.
Cheers
Nick
include/ChangeLog
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.
opcodes/ChangeLog
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.
binutils/ChangeLog
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.
gas/testsuite/ChangeLog
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.
Index: include/dis-asm.h
===================================================================
RCS file: /cvs/src/src/include/dis-asm.h,v
retrieving revision 1.45
diff -c -3 -p -r1.45 dis-asm.h
*** include/dis-asm.h 3 Sep 2003 23:43:17 -0000 1.45
--- include/dis-asm.h 14 Nov 2003 12:03:57 -0000
*************** typedef struct disassemble_info {
*** 130,135 ****
--- 130,141 ----
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;
*************** extern void print_arm_disassembler_optio
*** 251,262 ****
--- 257,268 ----
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 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 *);
*************** extern void generic_print_address
*** 284,289 ****
--- 294,303 ----
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,
Index: opcodes/dis-buf.c
===================================================================
RCS file: /cvs/src/src/opcodes/dis-buf.c,v
retrieving revision 1.7
diff -c -3 -p -r1.7 dis-buf.c
*** opcodes/dis-buf.c 9 Aug 2001 14:52:56 -0000 1.7
--- opcodes/dis-buf.c 14 Nov 2003 12:03:59 -0000
*************** generic_symbol_at_address (addr, info)
*** 115,118 ****
--- 115,127 ----
struct disassemble_info *info ATTRIBUTE_UNUSED;
{
return 1;
+ }
+
+ /* Just return TRUE. */
+
+ bfd_boolean
+ generic_symbol_is_valid (asymbol * sym ATTRIBUTE_UNUSED,
+ struct disassemble_info *info ATTRIBUTE_UNUSED)
+ {
+ return TRUE;
}
Index: opcodes/arm-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/arm-dis.c,v
retrieving revision 1.35
diff -c -3 -p -r1.35 arm-dis.c
*** opcodes/arm-dis.c 3 Nov 2003 14:47:22 -0000 1.35
--- opcodes/arm-dis.c 14 Nov 2003 12:03:59 -0000
*************** print_insn_thumb (pc, info, given)
*** 1145,1150 ****
--- 1145,1167 ----
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
Index: opcodes/dis-init.c
===================================================================
RCS file: /cvs/src/src/opcodes/dis-init.c,v
retrieving revision 1.1
diff -c -3 -p -r1.1 dis-init.c
*** opcodes/dis-init.c 3 Sep 2003 23:43:17 -0000 1.1
--- opcodes/dis-init.c 14 Nov 2003 12:03:59 -0000
*************** init_disassemble_info (struct disassembl
*************** init_disassemble_info (struct disassembl
*** 36,41 ****
--- 37,43 ----
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;
}
Index: opcodes/disassemble.c
===================================================================
RCS file: /cvs/src/src/opcodes/disassemble.c,v
retrieving revision 1.44
diff -c -3 -p -r1.44 disassemble.c
*** opcodes/disassemble.c 10 Oct 2003 22:13:49 -0000 1.44
--- opcodes/disassemble.c 14 Nov 2003 12:03:59 -0000
*************** disassembler_usage (stream)
*** 397,399 ****
--- 397,417 ----
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;
+ }
+ }
Index: binutils/objdump.c
===================================================================
RCS file: /cvs/src/src/binutils/objdump.c,v
retrieving revision 1.82
diff -c -3 -p -r1.82 objdump.c
*** binutils/objdump.c 11 Nov 2003 01:57:04 -0000 1.82
--- binutils/objdump.c 14 Nov 2003 12:03:50 -0000
*************** objdump_print_symname (bfd *abfd, struct
*** 643,656 ****
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. */
static asymbol *
! find_symbol_for_address (bfd *abfd, asection *sec, bfd_vma vma,
! bfd_boolean require_sec, 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
--- 643,656 ----
free (alloc);
}
! /* 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_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
*************** find_symbol_for_address (bfd *abfd, asec
*** 661,666 ****
--- 661,669 ----
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)
*************** find_symbol_for_address (bfd *abfd, asec
*** 704,710 ****
no way to tell what's desired without looking at the relocation
table. */
if (sorted_syms[thisplace]->section != sec
! && (require_sec
|| ((abfd->flags & HAS_RELOC) != 0
&& vma >= bfd_get_section_vma (abfd, sec)
&& vma < (bfd_get_section_vma (abfd, sec)
--- 707,713 ----
no way to tell what's desired without looking at the relocation
table. */
if (sorted_syms[thisplace]->section != sec
! && (aux->require_sec
|| ((abfd->flags & HAS_RELOC) != 0
&& vma >= bfd_get_section_vma (abfd, sec)
&& vma < (bfd_get_section_vma (abfd, sec)
*************** find_symbol_for_address (bfd *abfd, asec
*** 749,763 ****
}
if (sorted_syms[thisplace]->section != sec
! && (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;
! }
}
if (place != NULL)
--- 752,773 ----
}
if (sorted_syms[thisplace]->section != 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;
! }
!
! /* 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)
*************** static void
*** 819,825 ****
objdump_print_addr (bfd_vma vma, struct disassemble_info *info,
bfd_boolean skip_zeroes)
{
! struct objdump_disasm_info *aux;
asymbol *sym;
if (sorted_symcount < 1)
--- 829,835 ----
objdump_print_addr (bfd_vma vma, struct disassemble_info *info,
bfd_boolean skip_zeroes)
{
! struct objdump_disasm_info * aux = (struct objdump_disasm_info *) info->application_data;
asymbol *sym;
if (sorted_symcount < 1)
*************** objdump_print_addr (bfd_vma vma, struct
*** 829,837 ****
return;
}
! aux = (struct objdump_disasm_info *) info->application_data;
! sym = find_symbol_for_address (aux->abfd, aux->sec, vma, aux->require_sec,
! NULL);
objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, info,
skip_zeroes);
}
--- 839,845 ----
return;
}
! sym = find_symbol_for_address (vma, info, NULL);
objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, info,
skip_zeroes);
}
*************** objdump_print_address (bfd_vma vma, stru
*** 850,865 ****
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);
return (sym != NULL && (bfd_asymbol_value (sym) == vma));
}
--- 858,866 ----
static int
objdump_symbol_at_address (bfd_vma vma, struct disassemble_info * info)
{
asymbol * sym;
! sym = find_symbol_for_address (vma, info, NULL);
return (sym != NULL && (bfd_asymbol_value (sym) == vma));
}
*************** disassemble_section (bfd *abfd, asection
*** 1627,1632 ****
--- 1628,1634 ----
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;
*************** disassemble_section (bfd *abfd, asection
*** 1659,1666 ****
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);
/* Disassemble a block of instructions up to the address associated with
the symbol we have just found. Then print the symbol and find the
--- 1661,1667 ----
printf (_("Disassembly of section %s:\n"), section->name);
/* Find the nearest symbol forwards from our current position. */
! 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
*************** disassemble_section (bfd *abfd, asection
*** 1668,1748 ****
or we have reached the end of the address range we are interested in. */
while (addr_offset < stop_offset)
{
asymbol *nextsym;
unsigned long nextstop_offset;
bfd_boolean insns;
! if (sym != NULL
! && bfd_asymbol_value (sym) <= section->vma + addr_offset)
{
int x;
for (x = place;
(x < sorted_symcount
! && (bfd_asymbol_value (sorted_syms[x])
! <= section->vma + addr_offset));
++x)
continue;
! pinfo->symbols = & sorted_syms[place];
pinfo->num_symbols = x - place;
}
else
! pinfo->symbols = NULL;
if (! prefix_addresses)
{
pinfo->fprintf_func (pinfo->stream, "\n");
! objdump_print_addr_with_sym (abfd, section, sym,
! section->vma + addr_offset,
pinfo, FALSE);
pinfo->fprintf_func (pinfo->stream, ":\n");
}
! if (sym != NULL
! && bfd_asymbol_value (sym) > section->vma + addr_offset)
nextsym = sym;
else if (sym == NULL)
nextsym = NULL;
else
{
/* 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))))
++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;
! }
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;
! }
/* 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
|| ((sym->flags & BSF_OBJECT) == 0
&& (strstr (bfd_asymbol_name (sym), "gnu_compiled")
== NULL)
--- 1669,1749 ----
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;
! 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]) <= addr));
++x)
continue;
! pinfo->symbols = sorted_syms + place;
pinfo->num_symbols = x - place;
}
else
! {
! pinfo->symbols = NULL;
! pinfo->num_symbols = 0;
! }
if (! prefix_addresses)
{
pinfo->fprintf_func (pinfo->stream, "\n");
! objdump_print_addr_with_sym (abfd, section, sym, addr,
pinfo, FALSE);
pinfo->fprintf_func (pinfo->stream, ":\n");
}
! 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
! && ! 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) > 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;
/* 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) > addr
|| ((sym->flags & BSF_OBJECT) == 0
&& (strstr (bfd_asymbol_name (sym), "gnu_compiled")
== NULL)
*************** disassemble_data (bfd *abfd)
*** 1789,1795 ****
/* Sort the symbols into section and symbol order. */
qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
! init_disassemble_info (&disasm_info, stdout, fprintf);
disasm_info.application_data = (void *) &aux;
aux.abfd = abfd;
--- 1790,1796 ----
/* Sort the symbols into section and symbol order. */
qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
! init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf);
disasm_info.application_data = (void *) &aux;
aux.abfd = abfd;
*************** disassemble_data (bfd *abfd)
*** 1844,1849 ****
--- 1845,1853 ----
/* ??? Aborting here seems too drastic. We could default to big or little
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. */
Index: gas/testsuite/gas/arm/arm7t.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/arm7t.d,v
retrieving revision 1.10
diff -c -3 -p -r1.10 arm7t.d
*** gas/testsuite/gas/arm/arm7t.d 3 Nov 2003 14:47:37 -0000 1.10
--- gas/testsuite/gas/arm/arm7t.d 14 Nov 2003 12:03:55 -0000
***************
*** 1,4 ****
! #objdump: -dr --prefix-addresses --show-raw-insn
#name: ARM arm7t
#as: -mcpu=arm7t -EL
--- 1,4 ----
! #objdump: -Dr --prefix-addresses --show-raw-insn
#name: ARM arm7t
#as: -mcpu=arm7t -EL
Index: gas/testsuite/gas/arm/pic.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/pic.d,v
retrieving revision 1.4
diff -c -3 -p -r1.4 pic.d
*** gas/testsuite/gas/arm/pic.d 14 Aug 2003 17:11:08 -0000 1.4
--- gas/testsuite/gas/arm/pic.d 14 Nov 2003 12:03:55 -0000
***************
*** 6,14 ****
.*: +file format .*arm.*
Disassembly of section .text:
! 0x0+0 ebfffffe bl 0x0+0
0: R_ARM_PC24 foo
! 0x0+4 ebfffffe bl 0x0+4
4: R_ARM_PLT32 foo
\.\.\.
8: R_ARM_ABS32 sym
--- 6,14 ----
.*: +file format .*arm.*
Disassembly of section .text:
! 00+0 <[^>]*> ebfffffe bl 00+0 <[^>]*>
0: R_ARM_PC24 foo
! 00+4 <[^>]*> ebfffffe bl 00+4 <[^>]*>
4: R_ARM_PLT32 foo
\.\.\.
8: R_ARM_ABS32 sym