2016-08-04 Thomas Preud'homme <thomas.preudhomme@arm.com>

bfd/
	* bfd-in.h (bfd_elf32_arm_set_target_relocs): Add one parameter.
	* bfd-in2.h: Regenerate.
	* elf32-arm.c (struct elf32_arm_link_hash_table): Declare new
	cmse_implib field.
	(bfd_elf32_arm_set_target_relocs): Add new parameter to initialize
	cmse_implib field in struct elf32_arm_link_hash_table.
	(elf32_arm_filter_cmse_symbols): New function.
	(elf32_arm_filter_implib_symbols): Likewise.
	(elf_backend_filter_implib_symbols): Define to
	elf32_arm_filter_implib_symbols.

ld/
	* emultempl/armelf.em (cmse_implib): Declare and define this new
	static variable.
	(arm_elf_create_output_section_statements): Add new cmse_implib
	parameter.
	(OPTION_CMSE_IMPLIB): Define macro.
	(PARSE_AND_LIST_LONGOPTS): Add entry for new --cmse-implib switch.
	(PARSE_AND_LIST_OPTIONS): Likewise.
	(PARSE_AND_LIST_ARGS_CASES): Handle OPTION_CMSE_IMPLIB case.
	* ld.texinfo (--cmse-implib): Document new option.
	* testsuite/ld-arm/arm-elf.exp
	(Secure gateway import library generation): New test.
	(Secure gateway import library generation: errors): Likewise.
	* testsuite/ld-arm/cmse-implib.s: New file.
	* testsuite/ld-arm/cmse-implib-errors.out: Likewise.
	* testsuite/ld-arm/cmse-implib.rd: Likewise.
This commit is contained in:
Thomas Preud'homme 2016-08-04 15:54:57 +01:00
parent 4ba2ef8fbe
commit 54ddd295b5
11 changed files with 236 additions and 4 deletions

View File

@ -1,3 +1,16 @@
2016-08-04 Thomas Preud'homme <thomas.preudhomme@arm.com>
* bfd-in.h (bfd_elf32_arm_set_target_relocs): Add one parameter.
* bfd-in2.h: Regenerate.
* elf32-arm.c (struct elf32_arm_link_hash_table): Declare new
cmse_implib field.
(bfd_elf32_arm_set_target_relocs): Add new parameter to initialize
cmse_implib field in struct elf32_arm_link_hash_table.
(elf32_arm_filter_cmse_symbols): New function.
(elf32_arm_filter_implib_symbols): Likewise.
(elf_backend_filter_implib_symbols): Define to
elf32_arm_filter_implib_symbols.
2016-08-04 Thomas Preud'homme <thomas.preudhomme@arm.com>
* elf32-arm.c (CMSE_PREFIX): Define macro.

View File

@ -902,7 +902,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation
void bfd_elf32_arm_set_target_relocs
(bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
bfd_arm_stm32l4xx_fix, int, int, int, int, int);
bfd_arm_stm32l4xx_fix, int, int, int, int, int, int);
extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
(bfd *, struct bfd_link_info *);

View File

@ -909,7 +909,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation
void bfd_elf32_arm_set_target_relocs
(bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
bfd_arm_stm32l4xx_fix, int, int, int, int, int);
bfd_arm_stm32l4xx_fix, int, int, int, int, int, int);
extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
(bfd *, struct bfd_link_info *);

View File

@ -3144,6 +3144,10 @@ struct elf32_arm_link_hash_table
/* True if the target uses REL relocations. */
int use_rel;
/* Nonzero if import library must be a secure gateway import library
as per ARMv8-M Security Extensions. */
int cmse_implib;
/* The index of the next unused R_ARM_TLS_DESC slot in .rel.plt. */
bfd_vma next_tls_desc_index;
@ -8307,7 +8311,7 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd,
bfd_arm_stm32l4xx_fix stm32l4xx_fix,
int no_enum_warn, int no_wchar_warn,
int pic_veneer, int fix_cortex_a8,
int fix_arm1176)
int fix_arm1176, int cmse_implib)
{
struct elf32_arm_link_hash_table *globals;
@ -8334,6 +8338,7 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd,
globals->pic_veneer = pic_veneer;
globals->fix_cortex_a8 = fix_cortex_a8;
globals->fix_arm1176 = fix_arm1176;
globals->cmse_implib = cmse_implib;
BFD_ASSERT (is_arm_elf (output_bfd));
elf_arm_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
@ -16854,6 +16859,95 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd,
return TRUE;
}
/* Filter normal symbols of CMSE entry functions of ABFD to include in
the import library. All SYMCOUNT symbols of ABFD can be examined
from their pointers in SYMS. Pointers of symbols to keep should be
stored continuously at the beginning of that array.
Returns the number of symbols to keep. */
static unsigned int
elf32_arm_filter_cmse_symbols (bfd *abfd ATTRIBUTE_UNUSED,
struct bfd_link_info *info,
asymbol **syms, long symcount)
{
size_t maxnamelen;
char *cmse_name;
long src_count, dst_count = 0;
struct elf32_arm_link_hash_table *htab;
htab = elf32_arm_hash_table (info);
if (!htab->stub_bfd || !htab->stub_bfd->sections)
symcount = 0;
maxnamelen = 128;
cmse_name = (char *) bfd_malloc (maxnamelen);
for (src_count = 0; src_count < symcount; src_count++)
{
struct elf32_arm_link_hash_entry *cmse_hash;
asymbol *sym;
flagword flags;
char *name;
size_t namelen;
sym = syms[src_count];
flags = sym->flags;
name = (char *) bfd_asymbol_name (sym);
if ((flags & BSF_FUNCTION) != BSF_FUNCTION)
continue;
if (!(flags & (BSF_GLOBAL | BSF_WEAK)))
continue;
namelen = strlen (name) + sizeof (CMSE_PREFIX) + 1;
if (namelen > maxnamelen)
{
cmse_name = (char *)
bfd_realloc (cmse_name, namelen);
maxnamelen = namelen;
}
snprintf (cmse_name, maxnamelen, "%s%s", CMSE_PREFIX, name);
cmse_hash = (struct elf32_arm_link_hash_entry *)
elf_link_hash_lookup (&(htab)->root, cmse_name, FALSE, FALSE, TRUE);
if (!cmse_hash
|| (cmse_hash->root.root.type != bfd_link_hash_defined
&& cmse_hash->root.root.type != bfd_link_hash_defweak)
|| cmse_hash->root.type != STT_FUNC)
continue;
if (!ARM_GET_SYM_CMSE_SPCL (cmse_hash->root.target_internal))
continue;
syms[dst_count++] = sym;
}
free (cmse_name);
syms[dst_count] = NULL;
return dst_count;
}
/* Filter symbols of ABFD to include in the import library. All
SYMCOUNT symbols of ABFD can be examined from their pointers in
SYMS. Pointers of symbols to keep should be stored continuously at
the beginning of that array.
Returns the number of symbols to keep. */
static unsigned int
elf32_arm_filter_implib_symbols (bfd *abfd ATTRIBUTE_UNUSED,
struct bfd_link_info *info,
asymbol **syms, long symcount)
{
struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (info);
if (globals->cmse_implib)
return elf32_arm_filter_cmse_symbols (abfd, info, syms, symcount);
else
return _bfd_elf_filter_global_symbols (abfd, info, syms, symcount);
}
/* Allocate target specific section data. */
static bfd_boolean
@ -18780,6 +18874,7 @@ elf32_arm_backend_symbol_processing (bfd *abfd, asymbol *sym)
#define elf_backend_modify_segment_map elf32_arm_modify_segment_map
#define elf_backend_additional_program_headers elf32_arm_additional_program_headers
#define elf_backend_output_arch_local_syms elf32_arm_output_arch_local_syms
#define elf_backend_filter_implib_symbols elf32_arm_filter_implib_symbols
#define elf_backend_begin_write_processing elf32_arm_begin_write_processing
#define elf_backend_add_symbol_hook elf32_arm_add_symbol_hook
#define elf_backend_count_additional_relocs elf32_arm_count_additional_relocs

View File

@ -1,3 +1,21 @@
2016-08-04 Thomas Preud'homme <thomas.preudhomme@arm.com>
* emultempl/armelf.em (cmse_implib): Declare and define this new
static variable.
(arm_elf_create_output_section_statements): Add new cmse_implib
parameter.
(OPTION_CMSE_IMPLIB): Define macro.
(PARSE_AND_LIST_LONGOPTS): Add entry for new --cmse-implib switch.
(PARSE_AND_LIST_OPTIONS): Likewise.
(PARSE_AND_LIST_ARGS_CASES): Handle OPTION_CMSE_IMPLIB case.
* ld.texinfo (--cmse-implib): Document new option.
* testsuite/ld-arm/arm-elf.exp
(Secure gateway import library generation): New test.
(Secure gateway import library generation: errors): Likewise.
* testsuite/ld-arm/cmse-implib.s: New file.
* testsuite/ld-arm/cmse-implib-errors.out: Likewise.
* testsuite/ld-arm/cmse-implib.rd: Likewise.
2016-08-04 Thomas Preud'homme <thomas.preudhomme@arm.com>
* ld.texinfo (Placement of SG veneers): New concept entry.

View File

@ -42,6 +42,7 @@ static int no_wchar_size_warning = 0;
static int pic_veneer = 0;
static int merge_exidx_entries = -1;
static int fix_arm1176 = 1;
static int cmse_implib = 0;
static void
gld${EMULATION_NAME}_before_parse (void)
@ -514,7 +515,7 @@ arm_elf_create_output_section_statements (void)
no_enum_size_warning,
no_wchar_size_warning,
pic_veneer, fix_cortex_a8,
fix_arm1176);
fix_arm1176, cmse_implib);
stub_file = lang_add_input_file ("linker stubs",
lang_input_file_is_fake_enum,
@ -583,6 +584,7 @@ PARSE_AND_LIST_PROLOGUE='
#define OPTION_NO_FIX_ARM1176 318
#define OPTION_LONG_PLT 319
#define OPTION_STM32L4XX_FIX 320
#define OPTION_CMSE_IMPLIB 321
'
PARSE_AND_LIST_SHORTOPTS=p
@ -609,6 +611,7 @@ PARSE_AND_LIST_LONGOPTS='
{ "fix-arm1176", no_argument, NULL, OPTION_FIX_ARM1176 },
{ "no-fix-arm1176", no_argument, NULL, OPTION_NO_FIX_ARM1176 },
{ "long-plt", no_argument, NULL, OPTION_LONG_PLT },
{ "cmse-implib", no_argument, NULL, OPTION_CMSE_IMPLIB },
'
PARSE_AND_LIST_OPTIONS='
@ -629,6 +632,8 @@ PARSE_AND_LIST_OPTIONS='
fprintf (file, _(" --pic-veneer Always generate PIC interworking veneers\n"));
fprintf (file, _(" --long-plt Generate long .plt entries\n"
" to handle large .plt/.got displacements\n"));
fprintf (file, _(" --cmse-implib Make import library to be a secure gateway import\n"
" library as per ARMv8-M Security Extensions\n"));
fprintf (file, _("\
--stub-group-size=N Maximum size of a group of input sections that\n\
can be handled by one stub section. A negative\n\
@ -749,6 +754,10 @@ PARSE_AND_LIST_ARGS_CASES='
case OPTION_LONG_PLT:
bfd_elf32_arm_use_long_plt ();
break;
case OPTION_CMSE_IMPLIB:
cmse_implib = 1;
break;
'
# We have our own before_allocation etc. functions, but they call

View File

@ -6859,6 +6859,13 @@ Its start address must be set, either with the command line option
@samp{--section-start} or in a linker script, to indicate where to place these
veneers in memory.
@kindex --cmse-implib
@cindex Secure gateway import library
The @samp{--cmse-implib} option requests that the import libraries
specified by the @samp{--out-implib} and @samp{--in-implib} options are
secure gateway import libraries, suitable for linking a non-secure
executable against secure code as per ARMv8-M Security Extensions.
@ifclear GENERIC
@lowersections
@end ifclear

View File

@ -668,6 +668,18 @@ set armeabitests_nonacl {
{objdump {-h -j .gnu.sgstubs} cmse-veneers.sd}
{nm {} cmse-veneers.rd}}
"cmse-veneers-mainline"}
{"Secure gateway import library generation: errors"
"--section-start .gnu.sgstubs=0x20000 --out-implib=tmpdir/cmse-implib.lib --cmse-implib" ""
"-march=armv8-m.base -mthumb --defsym CHECK_ERRORS=1"
{cmse-implib.s}
{{ld cmse-implib-errors.out}}
"cmse-implib"}
{"Secure gateway import library generation"
"--section-start .gnu.sgstubs=0x20000 --out-implib=tmpdir/cmse-implib.lib --cmse-implib" ""
"-march=armv8-m.base -mthumb"
{cmse-implib.s}
{{readelf {-s tmpdir/cmse-implib.lib} cmse-implib.rd}}
"cmse-implib"}
{"R_ARM_THM_JUMP19 Relocation veneers: Short"
"--section-start destsect=0x000108002 --section-start .text=0x8000" ""

View File

@ -0,0 +1,7 @@
.*: .*: absent standard symbol `not_exported_fct2'.
.*: .*: invalid special symbol `__acle_se_not_exported_pseudoentry_var'.
.*: It must be a global or weak function symbol.
.*: .*: invalid standard symbol `not_exported_pseudoentry_var'.
.*: It must be a global or weak function symbol.
.* cannot size stub section: Invalid operation
#...

View File

@ -0,0 +1,13 @@
File: tmpdir/cmse-implib.lib
Symbol table '.symtab' contains 5 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00020001 8 FUNC GLOBAL DEFAULT ABS exported_entry_veneer3
2: [0-9a-f]+ 6 FUNC GLOBAL DEFAULT ABS exported_entry_fct1
3: 00020009 8 FUNC GLOBAL DEFAULT ABS exported_entry_veneer2
4: [0-9a-f]+ 6 FUNC GLOBAL DEFAULT ABS exported_entry_fct2
File: tmpdir/cmse-implib
#...

View File

@ -0,0 +1,58 @@
.syntax unified
.text
.macro entry name, vis, entry_fct
.align 2
.\vis \name
.\vis __acle_se_\name
.thumb
.thumb_func
.type \name, %function
.type __acle_se_\name, %function
\name:
.ifnb \entry_fct
\entry_fct
.endif
__acle_se_\name:
nop
.size \name, .-\name
.size __acle_se_\name, .-__acle_se_\name
.endm
@ Valid setups for veneer generation
entry exported_entry_veneer2, global
entry exported_entry_veneer3, global
@ Valid setup for entry function without veneer generation
entry exported_entry_fct1, global, sg
entry exported_entry_fct2, global, sg
@ Normal symbol not exported to SG import library
.align 2
.global not_exported_fct1
.type not_exported_fct1, %function
not_exported_fct1:
nop
.size not_exported_fct1, .-not_exported_fct1
.ifdef CHECK_ERRORS
@ Invalid setups for export to SG import library
.align 2
.global __acle_se_not_exported_fct2
.type __acle_se_not_exported_fct2, %function
__acle_se_not_exported_fct2:
nop
.size __acle_se_not_exported_fct2, .-__acle_se_not_exported_fct2
.align 2
.global __acle_se_not_exported_pseudoentry_var
.global not_exported_pseudoentry_var
.data
.type __acle_se_not_exported_pseudoentry_var, %object
.type not_exported_pseudoentry_var, %object
.size not_exported_pseudoentry_var, 4
.size __acle_se_not_exported_pseudoentry_var, 4
__acle_se_not_exported_pseudoentry_var:
not_exported_pseudoentry_var:
.word 42
.endif