This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
Patch: --thumb-entry command line switch
- To: binutils@sourceware.cygnus.com
- Subject: Patch: --thumb-entry command line switch
- From: Nick Clifton <nickc@cygnus.com>
- Date: Fri, 18 Jun 1999 13:44:55 +0100
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,