This is the mail archive of the binutils@sourceware.cygnus.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]

Patch: --thumb-entry command line switch


Hi Guys,

  Does anyone have any objections to my checking in the following
  patch ?

  It adds a new Thumb specific command line switch called
  --thumb-entry.  This switch behaves just like --entry, except that
  it also sets the bttom bit of the start address so that it will be
  entered in Thumb mode, not ARM mode.

Cheers
	Nick

 
1999-06-18  Nick Clifton  <nickc@cygnus.com>

	* emultempl/pe.em: Add new command line switch --thumb-entry.
	* emultempl/armelf.em: Add new command line switch --thumb-entry.
	* emultempl/armcoff.em: Add new command line switch --thumb-entry.
	* ld.texinfo: Document new ARM command line switch: --thumb-entry.	

Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/binutils/binutils/ld/ld.texinfo,v
retrieving revision 1.3
diff -p -r1.3 ld.texinfo
*** ld.texinfo	1999/06/14 01:40:24	1.3
--- ld.texinfo	1999/06/18 12:44:15
*************** not itself call any subroutines).
*** 3879,3885 ****
  @section @code{ld}'s support for interworking between ARM and Thumb code
  
  @cindex ARM interworking support
! @cindex --support-old-code
  For the ARM, @code{ld} will generate code stubs to allow functions calls
  betweem ARM and Thumb code.  These stubs only work with code that has
  been compiled and assembled with the @samp{-mthumb-interwork} command
--- 3879,3885 ----
  @section @code{ld}'s support for interworking between ARM and Thumb code
  
  @cindex ARM interworking support
! @kindex --support-old-code
  For the ARM, @code{ld} will generate code stubs to allow functions calls
  betweem ARM and Thumb code.  These stubs only work with code that has
  been compiled and assembled with the @samp{-mthumb-interwork} command
*************** given to the linker.  This will make it 
*** 3890,3895 ****
--- 3890,3904 ----
  which will work with non-interworking aware ARM code.  Note, however,
  the linker does not support generating stubs for function calls to
  non-interworking aware Thumb code.
+ 
+ @cindex thumb entry point
+ @cindex entry point, thumb
+ @kindex --thumb-entry=@var{entry}
+ The @samp{--thumb-entry} switch is a duplicate of the generic
+ @samp{--entry} switch, in that it sets the program's starting address.  
+ But it also sets the bottom bit of the address, so that it can be
+ branched to using a BX instruction, and the program will start
+ executing in Thumb mode straight away.
  
  @ifclear GENERIC
  @lowersections

Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/binutils/binutils/ld/emultempl/pe.em,v
retrieving revision 1.6
diff -p -r1.6 pe.em
*** pe.em	1999/06/12 14:00:03	1.6
--- pe.em	1999/06/18 12:44:15
*************** static void gld${EMULATION_NAME}_place_s
*** 74,83 ****
--- 74,85 ----
    PARAMS ((lang_statement_union_type *));
  static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *));
  static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **));
+ static void gld_${EMULATION_NAME}_finish PARAMS ((void));
  
  static struct internal_extra_pe_aouthdr pe;
  static int dll;
  static int support_old_code = 0;
+ static char * thumb_entry_symbol = NULL;
  extern def_file *pe_def_file;
  static lang_assignment_statement_type *image_base_statement = 0;
  
*************** gld_${EMULATION_NAME}_before_parse()
*** 126,131 ****
--- 128,134 ----
  #define OPTION_ENABLE_STDCALL_FIXUP	(OPTION_STDCALL_ALIASES + 1)
  #define OPTION_DISABLE_STDCALL_FIXUP	(OPTION_ENABLE_STDCALL_FIXUP + 1)
  #define OPTION_IMPLIB_FILENAME		(OPTION_DISABLE_STDCALL_FIXUP + 1)
+ #define OPTION_THUMB_ENTRY		(OPTION_IMPLIB_FILENAME + 1)
  
  static struct option longopts[] =
  {
*************** static struct option longopts[] =
*** 145,150 ****
--- 148,154 ----
    {"stack", required_argument, NULL, OPTION_STACK},
    {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
    {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
+   {"thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY},
  #ifdef DLL_SUPPORT
    /* getopt allows abbreviations, so we do this to stop it from treating -o
       as an abbreviation for this option */
*************** gld_${EMULATION_NAME}_list_options (file
*** 219,224 ****
--- 223,229 ----
    fprintf (file, _("  --stack <size>                     Set size of the initial stack\n"));
    fprintf (file, _("  --subsystem <name>[:<version>]     Set required OS subsystem [& version]\n"));
    fprintf (file, _("  --support-old-code                 Support interworking with old code\n"));
+   fprintf (file, _("  --thumb-entry=<symbol>             Set the entry point to be Thumb <symbol>\n"));
  #ifdef DLL_SUPPORT
    fprintf (file, _("  --add-stdcall-alias                Export symbols with and without @nn\n"));
    fprintf (file, _("  --disable-stdcall-fixup            Don't link _sym to _sym@nn\n"));
*************** gld_${EMULATION_NAME}_parse_args(argc, a
*** 427,432 ****
--- 432,440 ----
      case OPTION_SUPPORT_OLD_CODE:
        support_old_code = 1;
        break;
+     case OPTION_THUMB_ENTRY:
+       thumb_entry_symbol = optarg;
+       break;
  #ifdef DLL_SUPPORT
      case OPTION_OUT_DEF:
        pe_out_def_filename = xstrdup (optarg);
*************** gld_${EMULATION_NAME}_recognized_file(en
*** 884,889 ****
--- 892,938 ----
  static void
  gld_${EMULATION_NAME}_finish ()
  {
+ #if defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_epoc_pe)
+   struct bfd_link_hash_entry * h;
+ 
+   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 != NULL && entry_from_cmdline)
+ 	    einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
+ 		   thumb_entry_symbol, entry_symbol);
+ 	  entry_symbol = buffer;
+ 	}
+       else
+ 	einfo (_("%P: warning: connot find thumb start symbol %s\n"), thumb_entry_symbol);
+     }
+ #endif /* defined(TARGET_IS_armpe) || defined(TARGET_IS_arm_epoc_pe) */
+ 
  #ifdef DLL_SUPPORT
    if (link_info.shared)
      {

Index: ld/emultempl/armcoff.em
===================================================================
RCS file: /cvs/binutils/binutils/ld/emultempl/armcoff.em,v
retrieving revision 1.2
diff -p -r1.2 armcoff.em
*** armcoff.em	1999/05/28 10:53:04	1.2
--- armcoff.em	1999/06/18 12:44:16
*************** static void gld${EMULATION_NAME}_before_
*** 44,60 ****
--- 44,64 ----
  static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
  static int  gld${EMULATION_NAME}_parse_args PARAMS((int, char **));
  static void gld${EMULATION_NAME}_list_options PARAMS ((FILE *));
+ static void gld_${EMULATION_NAME}_finish PARAMS ((void));
  
  /* If true, then interworking stubs which support calls to old, non-interworking
     aware ARM code should be generated.  */
  
  static int support_old_code = 0;
+ static char * thumb_entry_symbol = NULL;
  
  #define OPTION_SUPPORT_OLD_CODE		300
+ #define OPTION_THUMB_ENTRY		301
  
  static struct option longopts[] =
  {
    {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
+   {"thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY},
    {NULL, no_argument, NULL, 0}
  };
  
*************** gld${EMULATION_NAME}_list_options (file)
*** 63,68 ****
--- 67,73 ----
       FILE * file;
  {
    fprintf (file, _("  --support-old-code   Support interworking with old code\n"));
+   fprintf (file, _("  --thumb-entry=<sym>  Set the entry point to be Thumb symbol <sym>\n"));
  }
  
  static int
*************** gld${EMULATION_NAME}_parse_args (argc, a
*** 97,102 ****
--- 102,111 ----
      case OPTION_SUPPORT_OLD_CODE:
        support_old_code = 1;
        break;
+ 
+     case OPTION_THUMB_ENTRY:
+       thumb_entry_symbol = optarg;
+       break;
      }
    
    return 1;
*************** gld${EMULATION_NAME}_after_open ()
*** 146,151 ****
--- 155,203 ----
      }
  }
  
+ static void
+ gld${EMULATION_NAME}_finish PARAMS((void))
+ {
+   struct bfd_link_hash_entry * h;
+ 
+   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 != NULL && entry_from_cmdline)
+ 	einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
+ 	       thumb_entry_symbol, entry_symbol);
+       entry_symbol = buffer;
+     }
+   else
+     einfo (_("%P: warning: connot find thumb start symbol %s\n"), thumb_entry_symbol);
+ }
+ 
  static char *
  gld${EMULATION_NAME}_get_script (isfile)
       int *isfile;
*************** struct ld_emulation_xfer_struct ld_${EMU
*** 214,220 ****
    gld${EMULATION_NAME}_get_script,
    "${EMULATION_NAME}",
    "${OUTPUT_FORMAT}",
!   NULL, /* finish */
    NULL, /* create output section statements */
    NULL, /* open dynamic archive */
    NULL, /* place orphan */
--- 266,272 ----
    gld${EMULATION_NAME}_get_script,
    "${EMULATION_NAME}",
    "${OUTPUT_FORMAT}",
!   gld${EMULATION_NAME}_finish, /* finish */
    NULL, /* create output section statements */
    NULL, /* open dynamic archive */
    NULL, /* place orphan */

Index: ld/emultempl/armelf.em
===================================================================
RCS file: /cvs/binutils/binutils/ld/emultempl/armelf.em,v
retrieving revision 1.4
diff -p -r1.4 armelf.em
*** armelf.em	1999/05/29 10:57:43	1.4
--- armelf.em	1999/06/18 12:44:16
*************** static void gld${EMULATION_NAME}_before_
*** 65,77 ****
--- 65,82 ----
  static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
  static int  gld${EMULATION_NAME}_parse_args PARAMS((int, char **));
  static void gld${EMULATION_NAME}_list_options PARAMS ((FILE *));
+ static void gld_${EMULATION_NAME}_finish PARAMS ((void));
  
  
  static int no_pipeline_knowledge = 0;
+ static char * thumb_entry_symbol = NULL;
  
+ #define OPTION_THUMB_ENTRY		301
+ 
  static struct option longopts[] =
  {
    { "no-pipeline-knowledge", no_argument, NULL, 'p'},
+   { "thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY},
    { NULL, no_argument, NULL, 0 }
  };
  
*************** gld${EMULATION_NAME}_list_options (file)
*** 80,85 ****
--- 85,91 ----
       FILE * file;
  {
    fprintf (file, _("  -p --no-pipeline-knowledge  Stop the linker knowing about the pipeline length\n"));
+   fprintf (file, _("     --thumb-entry=<sym>      Set the entry point to be Thumb symbol <sym>\n"));
  }
  
  static int
*************** gld${EMULATION_NAME}_parse_args (argc, a
*** 114,119 ****
--- 120,129 ----
      case 'p':
        no_pipeline_knowledge = 1;
        break;
+ 
+     case OPTION_THUMB_ENTRY:
+       thumb_entry_symbol = optarg;
+       break;
      }
    
    return 1;
*************** gld${EMULATION_NAME}_before_allocation (
*** 1130,1135 ****
--- 1140,1188 ----
    bfd_elf32_arm_allocate_interworking_sections (& link_info);
  }
  
+ static void
+ gld${EMULATION_NAME}_finish PARAMS((void))
+ {
+   struct bfd_link_hash_entry * h;
+ 
+   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 != NULL && entry_from_cmdline)
+ 	einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
+ 	       thumb_entry_symbol, entry_symbol);
+       entry_symbol = buffer;
+     }
+   else
+     einfo (_("%P: warning: connot find thumb start symbol %s\n"), thumb_entry_symbol);
+ }
+ 
  static char *
  gld${EMULATION_NAME}_get_script (isfile)
       int *isfile;
*************** struct ld_emulation_xfer_struct ld_${EMU
*** 1198,1204 ****
    gld${EMULATION_NAME}_get_script,
    "${EMULATION_NAME}",
    "${OUTPUT_FORMAT}",
!   NULL, /* finish */
    NULL, /* create output section statements */
    gld${EMULATION_NAME}_open_dynamic_archive,
    gld${EMULATION_NAME}_place_orphan,
--- 1251,1257 ----
    gld${EMULATION_NAME}_get_script,
    "${EMULATION_NAME}",
    "${OUTPUT_FORMAT}",
!   gld${EMULATION_NAME}_finish, /* finish */
    NULL, /* create output section statements */
    gld${EMULATION_NAME}_open_dynamic_archive,
    gld${EMULATION_NAME}_place_orphan,

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