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:
parent
4ba2ef8fbe
commit
54ddd295b5
11 changed files with 236 additions and 4 deletions
|
@ -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.
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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
|
||||
|
|
18
ld/ChangeLog
18
ld/ChangeLog
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" ""
|
||||
|
|
7
ld/testsuite/ld-arm/cmse-implib-errors.out
Normal file
7
ld/testsuite/ld-arm/cmse-implib-errors.out
Normal 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
|
||||
#...
|
13
ld/testsuite/ld-arm/cmse-implib.rd
Normal file
13
ld/testsuite/ld-arm/cmse-implib.rd
Normal 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
|
||||
|
||||
#...
|
58
ld/testsuite/ld-arm/cmse-implib.s
Normal file
58
ld/testsuite/ld-arm/cmse-implib.s
Normal 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
|
Loading…
Add table
Reference in a new issue