Add new command line switch --thumb-entry.

This commit is contained in:
Nick Clifton 1999-06-21 03:30:32 +00:00
parent 74479bd3b9
commit 6f798e5c17
5 changed files with 173 additions and 3 deletions

View file

@ -1,3 +1,10 @@
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.
1999-06-20 H.J. Lu <hjl@gnu.org> 1999-06-20 H.J. Lu <hjl@gnu.org>
* configure.in (all_libpath): Accumulate across all enabled targets. * configure.in (all_libpath): Accumulate across all enabled targets.

View file

@ -44,17 +44,21 @@ static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
static int gld${EMULATION_NAME}_parse_args PARAMS((int, char **)); static int gld${EMULATION_NAME}_parse_args PARAMS((int, char **));
static void gld${EMULATION_NAME}_list_options PARAMS ((FILE *)); 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 /* If true, then interworking stubs which support calls to old, non-interworking
aware ARM code should be generated. */ aware ARM code should be generated. */
static int support_old_code = 0; static int support_old_code = 0;
static char * thumb_entry_symbol = NULL;
#define OPTION_SUPPORT_OLD_CODE 300 #define OPTION_SUPPORT_OLD_CODE 300
#define OPTION_THUMB_ENTRY 301
static struct option longopts[] = static struct option longopts[] =
{ {
{"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE}, {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
{"thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY},
{NULL, no_argument, NULL, 0} {NULL, no_argument, NULL, 0}
}; };
@ -63,6 +67,7 @@ gld${EMULATION_NAME}_list_options (file)
FILE * file; FILE * file;
{ {
fprintf (file, _(" --support-old-code Support interworking with old code\n")); 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 static int
@ -97,6 +102,10 @@ gld${EMULATION_NAME}_parse_args (argc, argv)
case OPTION_SUPPORT_OLD_CODE: case OPTION_SUPPORT_OLD_CODE:
support_old_code = 1; support_old_code = 1;
break; break;
case OPTION_THUMB_ENTRY:
thumb_entry_symbol = optarg;
break;
} }
return 1; return 1;
@ -146,6 +155,49 @@ gld${EMULATION_NAME}_after_open ()
} }
} }
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 * static char *
gld${EMULATION_NAME}_get_script (isfile) gld${EMULATION_NAME}_get_script (isfile)
int *isfile; int *isfile;
@ -214,7 +266,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
gld${EMULATION_NAME}_get_script, gld${EMULATION_NAME}_get_script,
"${EMULATION_NAME}", "${EMULATION_NAME}",
"${OUTPUT_FORMAT}", "${OUTPUT_FORMAT}",
NULL, /* finish */ gld${EMULATION_NAME}_finish, /* finish */
NULL, /* create output section statements */ NULL, /* create output section statements */
NULL, /* open dynamic archive */ NULL, /* open dynamic archive */
NULL, /* place orphan */ NULL, /* place orphan */

View file

@ -65,13 +65,18 @@ static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile)); static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
static int gld${EMULATION_NAME}_parse_args PARAMS((int, char **)); static int gld${EMULATION_NAME}_parse_args PARAMS((int, char **));
static void gld${EMULATION_NAME}_list_options PARAMS ((FILE *)); static void gld${EMULATION_NAME}_list_options PARAMS ((FILE *));
static void gld_${EMULATION_NAME}_finish PARAMS ((void));
static int no_pipeline_knowledge = 0; static int no_pipeline_knowledge = 0;
static char * thumb_entry_symbol = NULL;
#define OPTION_THUMB_ENTRY 301
static struct option longopts[] = static struct option longopts[] =
{ {
{ "no-pipeline-knowledge", no_argument, NULL, 'p'}, { "no-pipeline-knowledge", no_argument, NULL, 'p'},
{ "thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY},
{ NULL, no_argument, NULL, 0 } { NULL, no_argument, NULL, 0 }
}; };
@ -80,6 +85,7 @@ gld${EMULATION_NAME}_list_options (file)
FILE * file; FILE * file;
{ {
fprintf (file, _(" -p --no-pipeline-knowledge Stop the linker knowing about the pipeline length\n")); 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 static int
@ -114,6 +120,10 @@ gld${EMULATION_NAME}_parse_args (argc, argv)
case 'p': case 'p':
no_pipeline_knowledge = 1; no_pipeline_knowledge = 1;
break; break;
case OPTION_THUMB_ENTRY:
thumb_entry_symbol = optarg;
break;
} }
return 1; return 1;
@ -1136,6 +1146,49 @@ gld${EMULATION_NAME}_before_allocation ()
bfd_elf32_arm_allocate_interworking_sections (& link_info); 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 * static char *
gld${EMULATION_NAME}_get_script (isfile) gld${EMULATION_NAME}_get_script (isfile)
int *isfile; int *isfile;
@ -1204,7 +1257,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
gld${EMULATION_NAME}_get_script, gld${EMULATION_NAME}_get_script,
"${EMULATION_NAME}", "${EMULATION_NAME}",
"${OUTPUT_FORMAT}", "${OUTPUT_FORMAT}",
NULL, /* finish */ gld${EMULATION_NAME}_finish, /* finish */
NULL, /* create output section statements */ NULL, /* create output section statements */
gld${EMULATION_NAME}_open_dynamic_archive, gld${EMULATION_NAME}_open_dynamic_archive,
gld${EMULATION_NAME}_place_orphan, gld${EMULATION_NAME}_place_orphan,

View file

@ -74,10 +74,12 @@ static void gld${EMULATION_NAME}_place_section
PARAMS ((lang_statement_union_type *)); PARAMS ((lang_statement_union_type *));
static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *)); static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *));
static int gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **)); 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 struct internal_extra_pe_aouthdr pe;
static int dll; static int dll;
static int support_old_code = 0; static int support_old_code = 0;
static char * thumb_entry_symbol = NULL;
extern def_file *pe_def_file; extern def_file *pe_def_file;
static lang_assignment_statement_type *image_base_statement = 0; static lang_assignment_statement_type *image_base_statement = 0;
@ -126,6 +128,7 @@ gld_${EMULATION_NAME}_before_parse()
#define OPTION_ENABLE_STDCALL_FIXUP (OPTION_STDCALL_ALIASES + 1) #define OPTION_ENABLE_STDCALL_FIXUP (OPTION_STDCALL_ALIASES + 1)
#define OPTION_DISABLE_STDCALL_FIXUP (OPTION_ENABLE_STDCALL_FIXUP + 1) #define OPTION_DISABLE_STDCALL_FIXUP (OPTION_ENABLE_STDCALL_FIXUP + 1)
#define OPTION_IMPLIB_FILENAME (OPTION_DISABLE_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,6 +148,7 @@ static struct option longopts[] =
{"stack", required_argument, NULL, OPTION_STACK}, {"stack", required_argument, NULL, OPTION_STACK},
{"subsystem", required_argument, NULL, OPTION_SUBSYSTEM}, {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
{"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE}, {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
{"thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY},
#ifdef DLL_SUPPORT #ifdef DLL_SUPPORT
/* getopt allows abbreviations, so we do this to stop it from treating -o /* getopt allows abbreviations, so we do this to stop it from treating -o
as an abbreviation for this option */ as an abbreviation for this option */
@ -219,6 +223,7 @@ gld_${EMULATION_NAME}_list_options (file)
fprintf (file, _(" --stack <size> Set size of the initial stack\n")); fprintf (file, _(" --stack <size> Set size of the initial stack\n"));
fprintf (file, _(" --subsystem <name>[:<version>] Set required OS subsystem [& version]\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, _(" --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 #ifdef DLL_SUPPORT
fprintf (file, _(" --add-stdcall-alias Export symbols with and without @nn\n")); 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")); fprintf (file, _(" --disable-stdcall-fixup Don't link _sym to _sym@nn\n"));
@ -427,6 +432,9 @@ gld_${EMULATION_NAME}_parse_args(argc, argv)
case OPTION_SUPPORT_OLD_CODE: case OPTION_SUPPORT_OLD_CODE:
support_old_code = 1; support_old_code = 1;
break; break;
case OPTION_THUMB_ENTRY:
thumb_entry_symbol = optarg;
break;
#ifdef DLL_SUPPORT #ifdef DLL_SUPPORT
case OPTION_OUT_DEF: case OPTION_OUT_DEF:
pe_out_def_filename = xstrdup (optarg); pe_out_def_filename = xstrdup (optarg);
@ -884,6 +892,47 @@ gld_${EMULATION_NAME}_recognized_file(entry)
static void static void
gld_${EMULATION_NAME}_finish () 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 #ifdef DLL_SUPPORT
if (link_info.shared) if (link_info.shared)
{ {

View file

@ -3879,7 +3879,7 @@ not itself call any subroutines).
@section @code{ld}'s support for interworking between ARM and Thumb code @section @code{ld}'s support for interworking between ARM and Thumb code
@cindex ARM interworking support @cindex ARM interworking support
@cindex --support-old-code @kindex --support-old-code
For the ARM, @code{ld} will generate code stubs to allow functions calls 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 betweem ARM and Thumb code. These stubs only work with code that has
been compiled and assembled with the @samp{-mthumb-interwork} command been compiled and assembled with the @samp{-mthumb-interwork} command
@ -3891,6 +3891,15 @@ which will work with non-interworking aware ARM code. Note, however,
the linker does not support generating stubs for function calls to the linker does not support generating stubs for function calls to
non-interworking aware Thumb code. 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 @ifclear GENERIC
@lowersections @lowersections
@end ifclear @end ifclear