This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]