This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH, binutils, ARM 10/11, ping1] Add support for creating ARM v8-M secure extensions import libraries
- From: Thomas Preudhomme <thomas dot preudhomme at foss dot arm dot com>
- To: binutils at sourceware dot org
- Cc: richard dot earnshaw at arm dot com, nickc at redhat dot com
- Date: Wed, 18 May 2016 17:39:28 +0100
- Subject: Re: [PATCH, binutils, ARM 10/11, ping1] Add support for creating ARM v8-M secure extensions import libraries
- Authentication-results: sourceware.org; auth=none
- References: <005401d13d58$2ef59d80$8ce0d880$ at foss dot arm dot com> <4425036 dot gJq85AxEeD at e108577-lin>
[CCing Richard Earnshaw and Nick Clifton who reviewed previous ARMv8-M
patches]
Ping?
Best regards,
Thomas
On Tuesday 29 March 2016 15:46:12 Thomas Preudhomme wrote:
> On Wednesday 23 December 2015 16:01:50 Thomas Preud'homme wrote:
[Remove mention of RFC]
> >
> > This patch is part of a patch series to add support for ARMv8-M security
> > extension[1] to GNU ld. This specific patch adds support for creating
> > *Secure Gateway* import libraries.
> >
> > ARM v8-M security extensions require [3] a secure gateway import library
> > to
> > be generated for non-secure executable to link against entry points in
> > secure executable. Such an import library must contain all global function
> > symbols from the secure executable that have a corresponding special (ie
> > prefixed by "__acle_se_") symbol and these symbol should be made absolute.
> >
> > This patch adds support for generating such an import library. It reuses
> > the code to generate an import library by requiring the user to add an
> > extra --cmse-implib option for him/her to state the intent to create a
> > *secure gateway* import library.
> >
> >
> > [1] Software requirements for ARMv8-M security extension are described in
> > document ARM-ECM-0359818 [2] [2] Available on http://infocenter.arm.com in
> > Developer guides and articles > Software development > ARMÂv8-M Security
> > Extensions: Requirements on Development Tools [3] See requirement 9 of
> > ARM-ECM-0359818 [2]
>
> Please find an updated patch below.
>
> *** bfd/ChangeLog ***
>
> 2015-07-16 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.
>
>
> *** ld/ChangeLog ***
>
> 2016-02-17 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.
>
>
> diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
> index
> c66ce3bba1ad1d1ce670f7404e465834cbf43fb1..7e3483b9984b04c534e53f2f9026abf26d
> 37592a 100644
> --- a/bfd/bfd-in.h
> +++ b/bfd/bfd-in.h
> @@ -895,7 +895,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 *);
> diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
> index
> afaca4ef19e49cf9899952a84a90c60fcd3fc8dd..55e1cdde2d0a899238a224c6915d20197b
> 72f085 100644
> --- a/bfd/bfd-in2.h
> +++ b/bfd/bfd-in2.h
> @@ -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 *);
> diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
> index
> 126c30df9fbf5ee11020b9fa4efb59c61bc1c352..a8aee085bb80159d6877508a8eef044b05
> a8a4df 100644
> --- a/bfd/elf32-arm.c
> +++ b/bfd/elf32-arm.c
> @@ -3123,6 +3123,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;
>
> @@ -8179,7 +8183,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;
>
> @@ -8206,6 +8210,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;
> @@ -16692,6 +16697,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
> @@ -18480,6 +18574,7 @@ elf32_arm_count_additional_relocs (asection *sec)
> #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 diff
> --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
> index
> 6074824f72d6f607449000702e7c5945bfe412ef..c21f6a82335a58a0ab37f3719c73c95e73
> e6211c 100644
> --- a/ld/emultempl/armelf.em
> +++ b/ld/emultempl/armelf.em
> @@ -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
> diff --git a/ld/ld.texinfo b/ld/ld.texinfo
> index
> a2e864199ab21469fdf1e35364ad43ccbf1a3734..82b40355a698958d84b566c09901960370
> 139b27 100644
> --- a/ld/ld.texinfo
> +++ b/ld/ld.texinfo
> @@ -6810,6 +6810,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
> diff --git a/ld/testsuite/ld-arm/arm-elf.exp
> b/ld/testsuite/ld-arm/arm-elf.exp index
> d6e20504e45f4210a1af6a814fe48d30ff91f6fc..da4bf7e0302de9f1c76bbacf8b64a9318d
> 44c46a 100644
> --- a/ld/testsuite/ld-arm/arm-elf.exp
> +++ b/ld/testsuite/ld-arm/arm-elf.exp
> @@ -661,6 +661,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" ""
> diff --git a/ld/testsuite/ld-arm/cmse-implib-errors.out b/ld/testsuite/ld-
> arm/cmse-implib-errors.out
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..0026f6be97e682c963ac9cc462784c2cf3
> 4fd003 --- /dev/null
> +++ b/ld/testsuite/ld-arm/cmse-implib-errors.out
> @@ -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
> +#...
> diff --git a/ld/testsuite/ld-arm/cmse-implib.rd b/ld/testsuite/ld-arm/cmse-
> implib.rd
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..c5f7aef8c32bf5b4d693d98f9f9cdbae02
> 3861b5 --- /dev/null
> +++ b/ld/testsuite/ld-arm/cmse-implib.rd
> @@ -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
> +
> +#...
> diff --git a/ld/testsuite/ld-arm/cmse-implib.s b/ld/testsuite/ld-arm/cmse-
> implib.s
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..a42da63fffebe5322be83f278931754262
> b0f7ae --- /dev/null
> +++ b/ld/testsuite/ld-arm/cmse-implib.s
> @@ -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
>
>
> Is this ok for master branch?
>
> Best regards,
>
> Thomas