+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.
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 *);
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 *);
/* 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;
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;
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;
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
#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
+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.
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)
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,
#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
{ "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='
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\
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
@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
{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" ""
--- /dev/null
+.*: .*: 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
+#...
--- /dev/null
+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
+
+#...
--- /dev/null
+ .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