[PATCH, arm] Support for Thumb init/fini entry points

Adam Nemet anemet@Lnxw.COM
Mon Aug 12 22:52:00 GMT 2002


Hi,

Since it seems that my Thumb PLT patch has to wait until the EABI spec
gets released, I separated the init/fini part that does not have any
ABI implications.

The idea is that I set the last bit of DT_INIT/FINI if the function is
of type STT_ARM_TFUNC.  If this is acceptable we could probably do the
same thing for the entry point and then --thumb-entry would become
just an alias for --entry.

It was regtested together with the PLT patch on arm-elf.

Please apply if OK.
Adam

bfd/ChangeLog:
2002-08-12  Adam Nemet  <anemet@lnxw.com>

	* elflink.h (elf_bfd_final_link): Allow numbers in
	link_info.{init,fini}_function.

ld/ChangeLog:
2002-08-12  Adam Nemet  <anemet@lnxw.com>

	* emultempl/armelf.em: Include elf-bfd.h and elf/arm.h.
	(arm_elf_finish): Set the last bit of DT_INIT and DT_FINI
	depending on the type of the function.

Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.177
diff -c -p -r1.177 elflink.h
*** bfd/elflink.h	16 Jul 2002 12:31:35 -0000	1.177
--- bfd/elflink.h	17 Jul 2002 22:30:28 -0000
*************** elf_bfd_final_link (abfd, info)
*** 5662,5667 ****
--- 5662,5681 ----
  
  		    elf_swap_dyn_out (dynobj, &dyn, dyncon);
  		  }
+ 		else
+ 		  {
+ 		    bfd_vma val;
+ 		    CONST char *send;
+ 
+ 		    /* We couldn't find the entry symbol.  Try parsing it as a
+ 		       number.  */
+ 		    val = bfd_scan_vma (name, &send, 0);
+ 		    if (*send == '\0')
+ 		      {
+ 			dyn.d_un.d_val = val;
+ 			elf_swap_dyn_out (dynobj, &dyn, dyncon);
+ 		      }
+ 		  }
  	      }
  	      break;
  
Index: ld/emultempl/armelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/armelf.em,v
retrieving revision 1.27
diff -c -p -r1.27 armelf.em
*** ld/emultempl/armelf.em	1 Jul 2002 08:07:31 -0000	1.27
--- ld/emultempl/armelf.em	17 Jul 2002 22:30:28 -0000
***************
*** 24,33 ****
  #
  cat >>e${EMULATION_NAME}.c <<EOF
  
  static int no_pipeline_knowledge = 0;
  static char *thumb_entry_symbol = NULL;
  static bfd *bfd_for_interwork;
! 
  
  static void
  gld${EMULATION_NAME}_before_parse ()
--- 24,36 ----
  #
  cat >>e${EMULATION_NAME}.c <<EOF
  
+ #include "elf-bfd.h"
+ #include "elf/arm.h"
+ 
  static int no_pipeline_knowledge = 0;
  static char *thumb_entry_symbol = NULL;
  static bfd *bfd_for_interwork;
*************** static void
*** 138,185 ****
  arm_elf_finish ()
  {
    struct bfd_link_hash_entry * h;
  
    /* Call the elf32.em routine.  */
    gld${EMULATION_NAME}_finish ();
  
!   if (thumb_entry_symbol == NULL)
!     return;
!   
!   h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol,
! 			    false, false, true);
  
    if (h != (struct bfd_link_hash_entry *) NULL
        && (h->type == bfd_link_hash_defined
  	  || h->type == bfd_link_hash_defweak)
        && h->u.def.section->output_section != NULL)
      {
        static char buffer[32];
        bfd_vma val;
!       
!       /* Special procesing is required for a Thumb entry symbol.  The
! 	 bottom bit of its address must be set.  */
        val = (h->u.def.value
  	     + bfd_get_section_vma (output_bfd,
  				    h->u.def.section->output_section)
  	     + h->u.def.section->output_offset);
!       
        val |= 1;
  
!       /* Now convert this value into a string and store it in entry_symbol
!          where the lang_finish() function will pick it up.  */
        buffer[0] = '0';
        buffer[1] = 'x';
!       
        sprintf_vma (buffer + 2, val);
  
!       if (entry_symbol.name != NULL && entry_from_cmdline)
! 	einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
! 	       thumb_entry_symbol, entry_symbol.name);
!       entry_symbol.name = buffer;
      }
-   else
-     einfo (_("%P: warning: connot find thumb start symbol %s\n"),
- 	   thumb_entry_symbol);
  }
  
  EOF
--- 142,256 ----
  arm_elf_finish ()
  {
    struct bfd_link_hash_entry * h;
+   struct elf_link_hash_entry * eh;
  
    /* Call the elf32.em routine.  */
    gld${EMULATION_NAME}_finish ();
  
!   if (thumb_entry_symbol != NULL)
!     {
!       h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol,
! 				false, false, true);
! 
!       if (h != (struct bfd_link_hash_entry *) NULL
! 	  && (h->type == bfd_link_hash_defined
! 	      || h->type == bfd_link_hash_defweak)
! 	  && h->u.def.section->output_section != NULL)
! 	{
! 	  static char buffer[32];
! 	  bfd_vma val;
!       
! 	  /* Special procesing is required for a Thumb entry symbol.  The
! 	     bottom bit of its address must be set.  */
! 	  val = (h->u.def.value
! 		 + bfd_get_section_vma (output_bfd,
! 					h->u.def.section->output_section)
! 		 + h->u.def.section->output_offset);
!       
! 	  val |= 1;
! 
! 	  /* Now convert this value into a string and store it in entry_symbol
! 	     where the lang_finish() function will pick it up.  */
! 	  buffer[0] = '0';
! 	  buffer[1] = 'x';
!       
! 	  sprintf_vma (buffer + 2, val);
! 
! 	  if (entry_symbol.name != NULL && entry_from_cmdline)
! 	    einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
! 		   thumb_entry_symbol, entry_symbol.name);
! 	  entry_symbol.name = buffer;
! 	}
!       else
! 	einfo (_("%P: warning: connot find thumb start symbol %s\n"),
! 	       thumb_entry_symbol);
!     }
! 
!   /* If init is a Thumb function set the LSB.  */
!   h = bfd_link_hash_lookup (link_info.hash, link_info.init_function, false,
! 			    false, true);
!   eh = (struct elf_link_hash_entry *)h;
  
    if (h != (struct bfd_link_hash_entry *) NULL
        && (h->type == bfd_link_hash_defined
  	  || h->type == bfd_link_hash_defweak)
+       && ELF_ST_TYPE (eh->type) == STT_ARM_TFUNC
        && h->u.def.section->output_section != NULL)
      {
        static char buffer[32];
        bfd_vma val;
! 
!       /* Special procesing is required for a Thumb symbol.  The bottom
! 	 bit of its address must be set.  */
        val = (h->u.def.value
  	     + bfd_get_section_vma (output_bfd,
  				    h->u.def.section->output_section)
  	     + h->u.def.section->output_offset);
! 
        val |= 1;
  
!       /* Now convert this value into a string and store it in
! 	 init_function where the elf_bfd_final_link() function will
! 	 pick it up.  */
        buffer[0] = '0';
        buffer[1] = 'x';
! 
        sprintf_vma (buffer + 2, val);
+       link_info.init_function = buffer;
+     }
+ 
+   /* If fini is a Thumb function set the LSB.  */
+   h = bfd_link_hash_lookup (link_info.hash, link_info.fini_function, false,
+ 			    false, true);
+   eh = (struct elf_link_hash_entry *)h;
  
!   if (h != (struct bfd_link_hash_entry *) NULL
!       && (h->type == bfd_link_hash_defined
! 	  || h->type == bfd_link_hash_defweak)
!       && ELF_ST_TYPE (eh->type) == STT_ARM_TFUNC
!       && h->u.def.section->output_section != NULL)
!     {
!       static char buffer[32];
!       bfd_vma val;
! 
!       /* Special procesing is required for a Thumb symbol.  The bottom
! 	 bit of its address must be set.  */
!       val = (h->u.def.value
! 	     + bfd_get_section_vma (output_bfd,
! 				    h->u.def.section->output_section)
! 	     + h->u.def.section->output_offset);
! 
!       val |= 1;
! 
!       /* Now convert this value into a string and store it in
! 	 fini_function where the elf_bfd_final_link() function will
! 	 pick it up.  */
!       buffer[0] = '0';
!       buffer[1] = 'x';
! 
!       sprintf_vma (buffer + 2, val);
!       link_info.fini_function = buffer;
      }
  }
  
  EOF



More information about the Binutils mailing list