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>
|
||||
|
||||
* 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 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}
|
||||
};
|
||||
|
||||
|
@ -63,6 +67,7 @@ gld${EMULATION_NAME}_list_options (file)
|
|||
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
|
||||
|
@ -97,6 +102,10 @@ gld${EMULATION_NAME}_parse_args (argc, argv)
|
|||
case OPTION_SUPPORT_OLD_CODE:
|
||||
support_old_code = 1;
|
||||
break;
|
||||
|
||||
case OPTION_THUMB_ENTRY:
|
||||
thumb_entry_symbol = optarg;
|
||||
break;
|
||||
}
|
||||
|
||||
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 *
|
||||
gld${EMULATION_NAME}_get_script (isfile)
|
||||
int *isfile;
|
||||
|
@ -214,7 +266,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
|
|||
gld${EMULATION_NAME}_get_script,
|
||||
"${EMULATION_NAME}",
|
||||
"${OUTPUT_FORMAT}",
|
||||
NULL, /* finish */
|
||||
gld${EMULATION_NAME}_finish, /* finish */
|
||||
NULL, /* create output section statements */
|
||||
NULL, /* open dynamic archive */
|
||||
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 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 }
|
||||
};
|
||||
|
||||
|
@ -80,6 +85,7 @@ gld${EMULATION_NAME}_list_options (file)
|
|||
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
|
||||
|
@ -114,6 +120,10 @@ gld${EMULATION_NAME}_parse_args (argc, argv)
|
|||
case 'p':
|
||||
no_pipeline_knowledge = 1;
|
||||
break;
|
||||
|
||||
case OPTION_THUMB_ENTRY:
|
||||
thumb_entry_symbol = optarg;
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -1136,6 +1146,49 @@ gld${EMULATION_NAME}_before_allocation ()
|
|||
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;
|
||||
|
@ -1204,7 +1257,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
|
|||
gld${EMULATION_NAME}_get_script,
|
||||
"${EMULATION_NAME}",
|
||||
"${OUTPUT_FORMAT}",
|
||||
NULL, /* finish */
|
||||
gld${EMULATION_NAME}_finish, /* finish */
|
||||
NULL, /* create output section statements */
|
||||
gld${EMULATION_NAME}_open_dynamic_archive,
|
||||
gld${EMULATION_NAME}_place_orphan,
|
||||
|
|
|
@ -74,10 +74,12 @@ static void gld${EMULATION_NAME}_place_section
|
|||
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;
|
||||
|
||||
|
@ -126,6 +128,7 @@ gld_${EMULATION_NAME}_before_parse()
|
|||
#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[] =
|
||||
{
|
||||
|
@ -145,6 +148,7 @@ static struct option longopts[] =
|
|||
{"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 */
|
||||
|
@ -219,6 +223,7 @@ gld_${EMULATION_NAME}_list_options (file)
|
|||
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"));
|
||||
|
@ -427,6 +432,9 @@ gld_${EMULATION_NAME}_parse_args(argc, argv)
|
|||
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);
|
||||
|
@ -884,6 +892,47 @@ gld_${EMULATION_NAME}_recognized_file(entry)
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -3879,7 +3879,7 @@ not itself call any subroutines).
|
|||
@section @code{ld}'s support for interworking between ARM and Thumb code
|
||||
|
||||
@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
|
||||
betweem ARM and Thumb code. These stubs only work with code that has
|
||||
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
|
||||
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
|
||||
@end ifclear
|
||||
|
|
Loading…
Reference in a new issue