Add new command line switch --thumb-entry.
This commit is contained in:
parent
74479bd3b9
commit
6f798e5c17
5 changed files with 173 additions and 3 deletions
|
@ -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.
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue