From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 37844 invoked by alias); 7 Jul 2016 12:52:16 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 37760 invoked by uid 89); 7 Jul 2016 12:52:15 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.3 required=5.0 tests=BAYES_50,KAM_LOTSOFHASH,KAM_STOCKGEN,RP_MATCHES_RCVD,SPF_PASS autolearn=no version=3.3.2 spammy=BFD_ASSERT, root.type, bfd_assert, *htab X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 07 Jul 2016 12:52:03 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0679928 for ; Thu, 7 Jul 2016 05:53:02 -0700 (PDT) Received: from e105689-lin.cambridge.arm.com (e105689-lin.cambridge.arm.com [10.2.207.32]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A2E003F213; Thu, 7 Jul 2016 05:52:01 -0700 (PDT) Subject: Re: [RFC PATCH, binutils, ARM 11/11] Add support for stable secure gateway veneers addresses To: Thomas Preudhomme , binutils@sourceware.org References: <005601d13d58$522afb60$f680f220$@foss.arm.com> <1796369.8BmbsroDJA@e108577-lin> From: "Richard Earnshaw (lists)" Message-ID: <577E5070.3020606@arm.com> Date: Thu, 07 Jul 2016 12:52:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.8.0 MIME-Version: 1.0 In-Reply-To: <1796369.8BmbsroDJA@e108577-lin> Content-Type: text/plain; charset=iso-8859-15 Content-Transfer-Encoding: 8bit X-SW-Source: 2016-07/txt/msg00099.txt.bz2 On 04/04/16 15:22, Thomas Preudhomme wrote: > On Wednesday 23 December 2015 16:02:48 Thomas Preud'homme wrote: >> Hi, >> >> [Posting patch series as 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 allowing >> Secure Gateway veneers to have stable addresses when relinking a secure >> executable. >> >> ARM v8-M security extensions allow code running in a device to be divided >> into secure and non-secure code expected to be developed by independent >> (teams of) people. To allow updating the secure code without the need to >> relink the non-secure code against it, it is necessary for the toolchain to >> provide a way to fix the addresses of the secure gateway veneers that serve >> as entry points for non-secure code to call secure code. This is also a >> requirement [2] to claim support for ARM v8-M security extensions. >> >> This patch adds a --in-implib= option which, when used >> in conjunction of --cmse-implib will ensure that the veneers whose symbols >> are defined in the import library $in_implib_filename will remain at the >> same address in the executable. In the absence of a --out-implib option, >> the code will warn about new secure gateway veneers being created, >> otherwise these are allowed. >> >> >> [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 15 of >> ARM-ECM-0359818 [2] > > Please find an updated patch below. Comments inline. > > *** bfd/ChangeLog *** > > 2016-02-18 Thomas Preud'homme > > * bfd-in.h (bfd_elf32_arm_set_target_relocs): Add a new parameter for > the input import library bfd. > * bfd-in2.h: Regenerate. > * elf32-arm.c (struct elf32_arm_link_hash_table): New in_implib_bfd > and new_cmse_stub_offset fields. > (stub_hash_newfunc): Initialize stub_offset and stub_template_size to > -1. > (elf32_arm_add_stub): Likewise for stub_offset. > (arm_new_stubs_start_offset_ptr): New function. > (arm_build_one_stub): Only allocate a stub_offset if it is -1. Allow > empty veneers to have zero relocations. > (arm_size_one_stub): Only initialize stub size and template > information for non empty veneers. Do not update veneer section size > if veneer already has an offset. > (elf32_arm_create_stub): Return the stub entry pointer or NULL instead > of a boolean indicating success or failure. > (cmse_scan): Change stub_changed parameter into an integer pointer > parameter cmse_stub_created to count the number of stub created and > adapt to change of return value in elf32_arm_create_stub. > (cmse_entry_fct_p): New function. > (arm_list_new_cmse_stub): Likewise. > (set_cmse_veneer_addr_from_implib): Likewise. > (elf32_arm_size_stubs): Define cmse_stub_created, pass its address to > cmse_scan instead of that of cmse_stub_changed to compute the number > of stub created and use it to initialize stub_changed. Call > set_cmse_veneer_addr_from_implib after all cmse_scan. Adapt to change > of return value in elf32_arm_create_stub. Use > arm_stub_section_start_offset () if not NULL to initialize size of > secure gateway veneers section. Initialize stub_offset of Cortex-A8 > erratum fix to -1. Use ret to hold return value. > (elf32_arm_build_stubs): Use arm_stub_section_start_offset () if not > NULL to initialize size of secure gateway veneers section. Adapt > comment to stress the importance of zeroing veneer section content. > (bfd_elf32_arm_set_target_relocs): Add new in_implib_bfd parameter to > initialize eponymous field in struct elf32_arm_link_hash_table. > > > *** ld/ChangeLog *** > > 2016-02-18 Thomas Preud'homme > > * emultempl/armelf.em (in_implib_filename): Declare and initialize new > variable. > (arm_elf_create_output_section_statements): Open import input library > file for writing and pass resulting in_implib_bfd to > bfd_elf32_arm_set_target_relocs. > (PARSE_AND_LIST_PROLOGUE): Define OPTION_IN_IMPLIB option. > (PARSE_AND_LIST_LONGOPTS): Define --in-implib option. > (PARSE_AND_LIST_OPTIONS): Add help message for --in-implib option. > (PARSE_AND_LIST_ARGS_CASES): Handle new OPTION_IN_IMPLIB case. > * ld.texinfo (--cmse-implib): Update to mention --in-implib. > (--in-implib): Document new option. > * testsuite/ld-arm/arm-elf.exp > (Secure gateway import library generation): add --defsym VER=1 to gas > CLI. > (Secure gateway import library generation: errors): Likewise. > (Input secure gateway import library): New test. > (Input secure gateway import library: no output import library): > Likewise. > (Input secure gateway import library: earlier stub section base): > Likewise. > (Input secure gateway import library: later stub section base): > Likewise. > (Input secure gateway import library: veneer comeback): Likewise. > (Input secure gateway import library: entry function change): > Likewise. > * testsuite/ld-arm/cmse-implib.s: Add input import library testing. > * testsuite/ld-arm/cmse-implib.rd: Update accordingly. > * testsuite/ld-arm/cmse-new-implib.out: New file. > * testsuite/ld-arm/cmse-new-implib.rd: Likewise. > * testsuite/ld-arm/cmse-new-implib-no-output.out: Likewise. > * testsuite/ld-arm/cmse-new-earlier-later-implib.out: Likewise. > * testsuite/ld-arm/cmse-new-comeback-implib.rd: Likewise. > * testsuite/ld-arm/cmse-new-wrong-implib.out: Likewise. > > > diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h > index > 7e3483b9984b04c534e53f2f9026abf26d37592a..423c534a954c541e227e731e9256f08f9fa62014 > 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, int); > + bfd_arm_stm32l4xx_fix, int, int, int, int, int, int, bfd *); > > 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 > 55e1cdde2d0a899238a224c6915d20197b72f085..3a67fa637f5c709cddf3767496e4ac8796287765 > 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, int); > + bfd_arm_stm32l4xx_fix, int, int, int, int, int, int, bfd *); This is *only* one more parameter to this function, but it now takes 15, which seems excessive. Some redesign may be in order here... > > 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 > 0357fdab5cc77c3b0e983d1cb9b0285753bd5c65..be1d7224148f95bf097bb3fea63de2081f93aab9 > 100644 > --- a/bfd/elf32-arm.c > +++ b/bfd/elf32-arm.c > @@ -3127,6 +3127,10 @@ struct elf32_arm_link_hash_table > as per ARMv8-M Security Extensions. */ > int cmse_implib; > > + /* The import library whose symbols' address must remain stable in > + the import library generated. */ > + bfd *in_implib_bfd; > + > /* The index of the next unused R_ARM_TLS_DESC slot in .rel.plt. */ > bfd_vma next_tls_desc_index; > > @@ -3188,6 +3192,10 @@ struct elf32_arm_link_hash_table > /* Input stub section holding secure gateway veneers. */ > asection *cmse_stub_sec; > > + /* Offset in cmse_stub_sec where new SG veneers (not in input import > library) > + start to be allocated. */ > + bfd_vma new_cmse_stub_offset; > + > /* Number of elements in stub_group. */ > unsigned int top_id; > > @@ -3439,7 +3447,7 @@ stub_hash_newfunc (struct bfd_hash_entry *entry, > /* Initialize the local fields. */ > eh = (struct elf32_arm_stub_hash_entry *) entry; > eh->stub_sec = NULL; > - eh->stub_offset = 0; > + eh->stub_offset = (bfd_vma) -1; > eh->source_value = 0; > eh->target_value = 0; > eh->target_section = NULL; > @@ -3447,7 +3455,7 @@ stub_hash_newfunc (struct bfd_hash_entry *entry, > eh->stub_type = arm_stub_none; > eh->stub_size = 0; > eh->stub_template = NULL; > - eh->stub_template_size = 0; > + eh->stub_template_size = -1; > eh->h = NULL; > eh->id_sec = NULL; > eh->output_name = NULL; > @@ -4361,7 +4369,7 @@ elf32_arm_add_stub (const char *stub_name, asection > *section, > } > > stub_entry->stub_sec = stub_sec; > - stub_entry->stub_offset = 0; > + stub_entry->stub_offset = (bfd_vma) -1; > stub_entry->id_sec = link_sec; > > return stub_entry; > @@ -4525,6 +4533,46 @@ arm_dedicated_stub_section_padding (enum > elf32_arm_stub_type stub_type) > abort (); /* Should be unreachable. */ > } > > +/* If veneers of type STUB_TYPE should go in a dedicated output section, > + returns the address of the hash table field in HTAB holding the offset at > + which new veneers should be layed out in the stub section. */ > + > +static bfd_vma* > +arm_new_stubs_start_offset_ptr (struct elf32_arm_link_hash_table *htab, > + enum elf32_arm_stub_type stub_type) > +{ > + switch (stub_type) > + { > + case arm_stub_a8_veneer_b_cond: > + case arm_stub_a8_veneer_b: > + case arm_stub_a8_veneer_bl: > + case arm_stub_long_branch_any_any: > + case arm_stub_long_branch_v4t_arm_thumb: > + case arm_stub_long_branch_thumb_only: > + case arm_stub_long_branch_v4t_thumb_thumb: > + case arm_stub_long_branch_v4t_thumb_arm: > + case arm_stub_short_branch_v4t_thumb_arm: > + case arm_stub_long_branch_any_arm_pic: > + case arm_stub_long_branch_any_thumb_pic: > + case arm_stub_long_branch_v4t_thumb_thumb_pic: > + case arm_stub_long_branch_v4t_arm_thumb_pic: > + case arm_stub_long_branch_v4t_thumb_arm_pic: > + case arm_stub_long_branch_thumb_only_pic: > + case arm_stub_long_branch_any_tls_pic: > + case arm_stub_long_branch_v4t_thumb_tls_pic: > + case arm_stub_a8_veneer_blx: > + case arm_stub_long_branch_arm_nacl: > + case arm_stub_long_branch_arm_nacl_pic: > + return NULL; > + > + case arm_stub_cmse_branch_thumb_only: > + return &htab->new_cmse_stub_offset; > + > + default: > + abort (); /* Should be unreachable. */ > + } > +} > + > static bfd_boolean > arm_build_one_stub (struct bfd_hash_entry *gen_entry, > void * in_arg) > @@ -4544,6 +4592,7 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry, > int stub_reloc_idx[MAXRELOCS] = {-1, -1}; > int stub_reloc_offset[MAXRELOCS] = {0, 0}; > int nrelocs = 0; > + int just_allocated = 0; > > /* Massage our args to the form they really have. */ > stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry; > @@ -4560,8 +4609,12 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry, > /* We have to do less-strictly-aligned fixes last. */ > return TRUE; > > - /* Make a note of the offset within the stubs for this entry. */ > - stub_entry->stub_offset = stub_sec->size; > + /* Assign a slot at the end of section if none assigned yet. */ > + if (stub_entry->stub_offset == (bfd_vma) -1) > + { > + stub_entry->stub_offset = stub_sec->size; > + just_allocated = 1; > + } > loc = stub_sec->contents + stub_entry->stub_offset; > > stub_bfd = stub_sec->owner; > @@ -4635,7 +4688,8 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry, > } > } > > - stub_sec->size += size; > + if (just_allocated) > + stub_sec->size += size; > > /* Stub size has already been computed in arm_size_one_stub. Check > consistency. */ > @@ -4647,7 +4701,7 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry, > > /* Assume there is at least one and at most MAXRELOCS entries to relocate > in each stub. */ > - BFD_ASSERT (nrelocs != 0 && nrelocs <= MAXRELOCS); > + BFD_ASSERT (size == 0 || (nrelocs != 0 && nrelocs <= MAXRELOCS)); The comment no-longer matches the assert. Direct use of size is also confusing. It might be clearer if you create a new bool variable which is set to true iff size is zero and makes the code that follows easier to comprehend. > > for (i = 0; i < nrelocs; i++) > { > @@ -4749,9 +4803,17 @@ arm_size_one_stub (struct bfd_hash_entry *gen_entry, > size = find_stub_size_and_template (stub_entry->stub_type, > &template_sequence, > &template_size); > > - stub_entry->stub_size = size; > - stub_entry->stub_template = template_sequence; > - stub_entry->stub_template_size = template_size; > + /* Initialized to -1. Null size indicates a zeroed out veneer. */ Err, what's a zeroed out veneer? > + if (stub_entry->stub_template_size) > + { > + stub_entry->stub_size = size; > + stub_entry->stub_template = template_sequence; > + stub_entry->stub_template_size = template_size; > + } > + > + /* Already accounted for. */ > + if (stub_entry->stub_offset != (bfd_vma) -1) > + return TRUE; > > size = (size + 7) & ~7; > stub_entry->stub_sec->size += size; > @@ -5316,10 +5378,10 @@ cortex_a8_erratum_scan (bfd *input_bfd, > and *NEW_STUB is set to FALSE. Otherwise, *NEW_STUB is set to > TRUE and the stub entry is initialized. > > - Returns whether the stub could be successfully created or updated, or > FALSE > - if an error occured. */ > + Returns the stub that was created or updated, or NULL if an error > + occured. */ s/occured/occurred/ (at least according to my dictionary). > > -static bfd_boolean > +static struct elf32_arm_stub_hash_entry * > elf32_arm_create_stub (struct elf32_arm_link_hash_table *htab, > enum elf32_arm_stub_type stub_type, asection *section, > Elf_Internal_Rela *irela, asection *sym_sec, > @@ -5350,7 +5412,7 @@ elf32_arm_create_stub (struct elf32_arm_link_hash_table > *htab, > stub_name = elf32_arm_stub_name (id_sec, sym_sec, hash, irela, > stub_type); > if (!stub_name) > - return FALSE; > + return NULL; > } > > stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table, stub_name, > FALSE, > @@ -5361,7 +5423,7 @@ elf32_arm_create_stub (struct elf32_arm_link_hash_table > *htab, > if (!sym_claimed) > free (stub_name); > stub_entry->target_value = sym_value; > - return TRUE; > + return stub_entry; > } > > stub_entry = elf32_arm_add_stub (stub_name, section, htab, stub_type); > @@ -5369,7 +5431,7 @@ elf32_arm_create_stub (struct elf32_arm_link_hash_table > *htab, > { > if (!sym_claimed) > free (stub_name); > - return FALSE; > + return NULL; > } > > stub_entry->target_value = sym_value; > @@ -5390,7 +5452,7 @@ elf32_arm_create_stub (struct elf32_arm_link_hash_table > *htab, > if (stub_entry->output_name == NULL) > { > free (stub_name); > - return FALSE; > + return NULL; > } > > /* For historical reasons, use the existing names for ARM-to-Thumb and > @@ -5410,7 +5472,7 @@ elf32_arm_create_stub (struct elf32_arm_link_hash_table > *htab, > } > > *new_stub = TRUE; > - return TRUE; > + return stub_entry; > } > > /* Scan symbols in INPUT_BFD to identify secure entry functions needing a > @@ -5427,14 +5489,15 @@ elf32_arm_create_stub (struct > elf32_arm_link_hash_table *htab, > > OUT_ATTR gives the output attributes, SYM_HASHES the symbol index to hash > entry mapping while HTAB gives the name to hash entry mapping. > + *CMSE_STUB_CREATED is increased by the number of secure gateway veneer > + created. > > - If any secure gateway veneer is created, *STUB_CHANGED is set to TRUE. > The > - return value gives whether a stub failed to be allocated. */ > + The return value gives whether a stub failed to be allocated. */ > > static bfd_boolean > cmse_scan (bfd *input_bfd, struct elf32_arm_link_hash_table *htab, > obj_attribute *out_attr, struct elf_link_hash_entry **sym_hashes, > - bfd_boolean *stub_changed) > + int *cmse_stub_created) > { > const struct elf_backend_data *bed; > Elf_Internal_Shdr *symtab_hdr; > @@ -5445,7 +5508,8 @@ cmse_scan (bfd *input_bfd, struct > elf32_arm_link_hash_table *htab, > char *sym_name, *lsym_name; > bfd_vma sym_value; > asection *section; > - bfd_boolean is_v8m, new_stub, created_stub, cmse_invalid, ret = TRUE; > + struct elf32_arm_stub_hash_entry *stub_entry; > + bfd_boolean is_v8m, new_stub, cmse_invalid, ret = TRUE; > > bed = get_elf_backend_data (input_bfd); > symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; > @@ -5586,17 +5650,17 @@ cmse_scan (bfd *input_bfd, struct > elf32_arm_link_hash_table *htab, > if (!ret) > continue; > branch_type = ARM_GET_SYM_BRANCH_TYPE (hash->root.target_internal); > - created_stub > + stub_entry > = elf32_arm_create_stub (htab, arm_stub_cmse_branch_thumb_only, > NULL, NULL, section, hash, sym_name, > sym_value, branch_type, &new_stub); > > - if (!created_stub) > + if (stub_entry == NULL) > ret = FALSE; > else > { > BFD_ASSERT (new_stub); > - *stub_changed = TRUE; > + (*cmse_stub_created)++; > } > } > > @@ -5605,6 +5669,273 @@ cmse_scan (bfd *input_bfd, struct > elf32_arm_link_hash_table *htab, > return ret; > } > > +/* Return whether a symbol identified by its linker HASH entry is an entry s/an entry/a secure code entry/ Entry function is ambiguous. As a style point it's probably better to start with Return TRUE iff a symbol ... > + function, ie can be called from non secure code without using a veneer. > */ > + > +static bfd_boolean > +cmse_entry_fct_p (struct elf32_arm_link_hash_entry *hash) > +{ > + uint32_t first_insn; > + asection *section; > + file_ptr offset; > + bfd *abfd; > + > + /* Defined symbol of function type. */ > + if (hash->root.root.type != bfd_link_hash_defined > + && hash->root.root.type != bfd_link_hash_defweak) > + return FALSE; > + if (hash->root.type != STT_FUNC) > + return FALSE; > + > + /* Read first instruction. */ > + section = hash->root.root.u.def.section; > + abfd = section->owner; > + offset = hash->root.root.u.def.value - section->vma; > + if (!bfd_get_section_contents (abfd, section, &first_insn, offset, > + sizeof (first_insn))) > + return FALSE; > + > + /* Start by SG instruction. */ > + return first_insn == 0xe97fe97f; > +} > + > +/* Output the name (in symbol table) of the veneer GEN_ENTRY if it is a new > + secure gateway veneers (ie. the veneers was not in the input import > library) > + and there is no output import library (GEN_INFO->out_implib_bfd is NULL. > */ > + > +static bfd_boolean > +arm_list_new_cmse_stub (struct bfd_hash_entry *gen_entry, void *gen_info) > +{ > + struct elf32_arm_stub_hash_entry *stub_entry; > + struct bfd_link_info *info; > + > + /* Massage our args to the form they really have. */ > + stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry; > + info = (struct bfd_link_info *) gen_info; > + > + if (info->out_implib_bfd) > + return TRUE; > + > + if (stub_entry->stub_type != arm_stub_cmse_branch_thumb_only) > + return TRUE; > + > + if (stub_entry->stub_offset == (bfd_vma) -1) > + (*_bfd_error_handler) (" %s", stub_entry->output_name); > + > + return TRUE; > +} > + > +/* Set offset of secure gateway veneers so that their address remain identical Set the offset of each s g v so that *its* address remains... > + to the one in the input import library referred by HTAB->in_implib_bfd. A > + warning is issued for veneers that disappeared (present in input import > + library but absent from the executable being linked) or if new veneers > + appeared and there is no output import library (INFO->out_implib_bfd is > NULL > + and *CMSE_STUB_CREATED is bigger than the number of secure gateway veneers > + found in the input import library. > + > + The function returns whether an error occured. If no error occured, > + *CMSE_STUB_CREATED gives the number of SG veneers created by both > cmse_scan > + and this function and HTAB->new_cmse_stub_offset is set to the biggest > + veneer observed set for new veneers to be layed out after. */ > + > +static bfd_boolean > +set_cmse_veneer_addr_from_implib (struct bfd_link_info *info, > + struct elf32_arm_link_hash_table *htab, > + int *cmse_stub_created) > +{ > + long symsize; > + char *sym_name; > + flagword flags; > + long i, symcount; > + bfd *in_implib_bfd; > + asection *stub_out_sec; > + bfd_boolean ret = TRUE; > + Elf_Internal_Sym *intsym; > + const char *out_sec_name; > + bfd_size_type cmse_stub_size; > + asymbol **sympp = NULL, *sym; > + struct elf32_arm_link_hash_entry *hash; > + const insn_sequence *cmse_stub_template; > + struct elf32_arm_stub_hash_entry *stub_entry; > + int cmse_stub_template_size, new_cmse_stubs_created = *cmse_stub_created; > + bfd_vma veneer_value, stub_offset, next_cmse_stub_offset; > + bfd_vma cmse_stub_array_start = (bfd_vma) -1, cmse_stub_sec_vma = 0; > + > + /* No input secure gateway import library. */ > + if (!htab->in_implib_bfd) > + return TRUE; > + else if (!htab->cmse_implib) > + return FALSE; > + > + /* Get symbol table size. */ > + in_implib_bfd = htab->in_implib_bfd; > + symsize = bfd_get_symtab_upper_bound (in_implib_bfd); > + if (symsize < 0) > + return FALSE; > + > + /* Read in the input secure gateway import library's symbol table. */ > + sympp = (asymbol **) xmalloc (symsize); > + symcount = bfd_canonicalize_symtab (in_implib_bfd, sympp); > + if (symcount < 0) > + { > + ret = FALSE; > + goto free_sym_buf; > + } > + > + htab->new_cmse_stub_offset = 0; > + cmse_stub_size = > + find_stub_size_and_template (arm_stub_cmse_branch_thumb_only, > + &cmse_stub_template, > + &cmse_stub_template_size); > + out_sec_name = > + arm_dedicated_stub_output_section_name (arm_stub_cmse_branch_thumb_only); > + stub_out_sec = > + bfd_get_section_by_name (htab->obfd, out_sec_name); > + if (stub_out_sec != NULL) > + cmse_stub_sec_vma = stub_out_sec->vma; > + > + /* Set addresses of veneers mentionned in input secure gateway import > + library's symbol table. */ > + for (i = 0; i < symcount; i++) > + { > + sym = sympp[i]; > + flags = sym->flags; > + sym_name = (char *) bfd_asymbol_name (sym); > + intsym = &((elf_symbol_type *) sym)->internal_elf_sym; > + > + if (sym->section != bfd_abs_section_ptr > + || !(flags & (BSF_GLOBAL | BSF_WEAK)) > + || (flags & BSF_FUNCTION) != BSF_FUNCTION > + || (ARM_GET_SYM_BRANCH_TYPE (intsym->st_target_internal) > + != ST_BRANCH_TO_THUMB)) > + { > + (*_bfd_error_handler) (_("%B: invalid import library entry: `%s'."), > + in_implib_bfd, sym_name); > + (*_bfd_error_handler) (_("Symbol should be absolute, global and " > + "refer to Thumb functions.")); > + ret = FALSE; > + continue; > + } > + > + veneer_value = bfd_asymbol_value (sym); > + stub_offset = veneer_value - cmse_stub_sec_vma; > + stub_entry = arm_stub_hash_lookup (&htab->stub_hash_table, sym_name, > + FALSE, FALSE); > + hash = (struct elf32_arm_link_hash_entry *) > + elf_link_hash_lookup (&(htab)->root, sym_name, FALSE, FALSE, TRUE); > + > + /* Stub entry should have been created by cmse_scan or the symbol be of > + a secure function callable from non secure code. */ > + if (!stub_entry && !hash) > + { > + bfd_boolean new_stub; > + > + (*_bfd_error_handler) > + (_("Entry function `%s' disappeared from secure code."), sym_name); > + hash = (struct elf32_arm_link_hash_entry *) > + elf_link_hash_lookup (&(htab)->root, sym_name, TRUE, TRUE, TRUE); > + stub_entry > + = elf32_arm_create_stub (htab, arm_stub_cmse_branch_thumb_only, > + NULL, NULL, bfd_abs_section_ptr, hash, > + sym_name, veneer_value, > + ST_BRANCH_TO_THUMB, &new_stub); > + if (stub_entry == NULL) > + ret = FALSE; > + else > + { > + BFD_ASSERT (new_stub); > + new_cmse_stubs_created++; > + (*cmse_stub_created)++; > + } > + stub_entry->stub_template_size = stub_entry->stub_size = 0; > + stub_entry->stub_offset = stub_offset; > + } > + /* Symbol found is not callable from non secure code. */ > + else if (!stub_entry) > + { > + if (!cmse_entry_fct_p (hash)) > + { > + (*_bfd_error_handler) (_("`%s' refers to a non entry function."), > + sym_name); > + ret = FALSE; > + } > + continue; > + } > + else > + { > + /* Only stub for SG veneers should have been created. */ stubs > + BFD_ASSERT (stub_entry->stub_type == arm_stub_cmse_branch_thumb_only); > + > + /* Check visibility hasn't changed. */ > + if (!!(flags & BSF_GLOBAL) > + != (hash->root.root.type == bfd_link_hash_defined)) > + (*_bfd_error_handler) > + (_("%B: visibility of symbol `%s' has changed."), in_implib_bfd, > + sym_name); > + > + stub_entry->stub_offset = stub_offset; > + } > + > + /* Size should match that of a SG veneer. */ > + if (intsym->st_size != cmse_stub_size) > + { > + (*_bfd_error_handler) (_("%B: incorrect size for symbol `%s'."), > + in_implib_bfd, sym_name); > + ret = FALSE; > + } > + > + /* Previous veneer address is before current SG veneer section. */ > + if (veneer_value < cmse_stub_sec_vma) > + { > + /* Avoid offset underflow. */ > + if (stub_entry) > + stub_entry->stub_offset = 0; > + stub_offset = 0; > + ret = FALSE; > + } > + > + /* Complain if stub offset not a multiple of stub size. */ > + if (stub_offset % cmse_stub_size) > + { > + (*_bfd_error_handler) > + (_("Offset of veneer for entry function `%s' not a multiple of " > + "its size."), sym_name); > + ret = FALSE; > + } > + > + if (!ret) > + continue; > + > + new_cmse_stubs_created--; > + if (veneer_value < cmse_stub_array_start) > + cmse_stub_array_start = veneer_value; > + next_cmse_stub_offset = stub_offset + ((cmse_stub_size + 7) & ~7); > + if (next_cmse_stub_offset > htab->new_cmse_stub_offset) > + htab->new_cmse_stub_offset = next_cmse_stub_offset; > + } > + > + if (!info->out_implib_bfd && new_cmse_stubs_created != 0) > + { > + BFD_ASSERT (new_cmse_stubs_created > 0); > + (*_bfd_error_handler) > + (_("new entry function(s) introduced but no output import library " > + "specified:")); > + bfd_hash_traverse (&htab->stub_hash_table, arm_list_new_cmse_stub, > info); > + } > + > + if (cmse_stub_array_start != cmse_stub_sec_vma) > + { > + (*_bfd_error_handler) > + (_("Start address of `%s' is different from previous link."), > + out_sec_name); > + ret = FALSE; > + } > + > +free_sym_buf: > + free (sympp); > + return ret; > +} > + > /* Determine and set the size of the stub section for a final link. > > The basic idea here is to examine all the relocations looking for > @@ -5621,7 +5952,9 @@ elf32_arm_size_stubs (bfd *output_bfd, > unsigned int), > void (*layout_sections_again) (void)) > { > + bfd_boolean ret = TRUE; > obj_attribute *out_attr; > + int cmse_stub_created = 0; > bfd_size_type stub_group_size; > bfd_boolean m_profile, stubs_always_after_branch, first_veneer_scan = TRUE; > struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info); > @@ -5654,6 +5987,7 @@ elf32_arm_size_stubs (bfd *output_bfd, > > out_attr = elf_known_obj_attributes_proc (output_bfd); > m_profile = out_attr[Tag_CPU_arch_profile].i == 'M'; > + > /* The Cortex-A8 erratum fix depends on stubs not being in the same 4K page > as the first half of a 32-bit branch straddling two 4K pages. This is a > crude way of enforcing that. */ > @@ -5727,8 +6061,11 @@ elf32_arm_size_stubs (bfd *output_bfd, > > sym_hashes = elf_sym_hashes (input_bfd); > if (!cmse_scan (input_bfd, htab, out_attr, sym_hashes, > - &stub_changed)) > + &cmse_stub_created)) > goto error_ret_free_local; > + > + if (cmse_stub_created != 0) > + stub_changed = TRUE; > } > > /* Walk over each section attached to the input bfd. */ > @@ -5954,6 +6291,7 @@ elf32_arm_size_stubs (bfd *output_bfd, > do > { > bfd_boolean new_stub; > + struct elf32_arm_stub_hash_entry *stub_entry; > > /* Determine what (if any) linker stub is needed. */ > stub_type = arm_type_of_stub (info, section, irela, > @@ -5965,12 +6303,13 @@ elf32_arm_size_stubs (bfd *output_bfd, > > /* We've either created a stub for this reloc already, > or we are about to. */ > - created_stub = > + stub_entry = > elf32_arm_create_stub (htab, stub_type, section, irela, > sym_sec, hash, > (char *) sym_name, sym_value, > branch_type, &new_stub); > > + created_stub = stub_entry != NULL; > if (!created_stub || !new_stub) > { > if (!created_stub) > @@ -6044,6 +6383,11 @@ elf32_arm_size_stubs (bfd *output_bfd, > } > } > > + if (first_veneer_scan > + && !set_cmse_veneer_addr_from_implib (info, htab, > + &cmse_stub_created)) > + ret = FALSE; > + > if (prev_num_a8_fixes != num_a8_fixes) > stub_changed = TRUE; > > @@ -6063,6 +6407,23 @@ elf32_arm_size_stubs (bfd *output_bfd, > stub_sec->size = 0; > } > > + /* Append new SG veneers after those in input import library. */ ...after those already in the input... > + for (stub_type = arm_stub_none + 1; stub_type < max_stub_type; > + stub_type++) > + { > + bfd_vma *start_offset_p; > + asection **stub_sec_p; > + > + start_offset_p = arm_new_stubs_start_offset_ptr (htab, stub_type); > + stub_sec_p = arm_dedicated_stub_input_section_ptr (htab, stub_type); > + if (start_offset_p == NULL) > + continue; > + > + BFD_ASSERT (stub_sec_p != NULL); > + if (*stub_sec_p != NULL) > + (*stub_sec_p)->size = *start_offset_p; > + } > + > /* Compute stub section size, considering padding. */ > bfd_hash_traverse (&htab->stub_hash_table, arm_size_one_stub, htab); > for (stub_type = arm_stub_none + 1; stub_type < max_stub_type; > @@ -6131,7 +6492,7 @@ elf32_arm_size_stubs (bfd *output_bfd, > } > > stub_entry->stub_sec = stub_sec; > - stub_entry->stub_offset = 0; > + stub_entry->stub_offset = (bfd_vma) -1; > stub_entry->id_sec = link_sec; > stub_entry->stub_type = a8_fixes[i].stub_type; > stub_entry->source_value = a8_fixes[i].offset; > @@ -6159,7 +6520,7 @@ elf32_arm_size_stubs (bfd *output_bfd, > htab->a8_erratum_fixes = NULL; > htab->num_a8_erratum_fixes = 0; > } > - return TRUE; > + return ret; > > error_ret_free_local: > return FALSE; > @@ -6176,6 +6537,7 @@ elf32_arm_build_stubs (struct bfd_link_info *info) > { > asection *stub_sec; > struct bfd_hash_table *table; > + enum elf32_arm_stub_type stub_type; > struct elf32_arm_link_hash_table *htab; > > htab = elf32_arm_hash_table (info); > @@ -6193,14 +6555,33 @@ elf32_arm_build_stubs (struct bfd_link_info *info) > continue; > > /* Allocate memory to hold the linker stubs. Zeroing the stub sections > - must at least be done for stub section requiring padding. */ > + must at least be done for stub section requiring padding and for SG > + veneers to ensure that a non secure code branching to a removed SG > + veneer causes an error. */ > size = stub_sec->size; > stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, > size); > if (stub_sec->contents == NULL && size != 0) > return FALSE; > + > stub_sec->size = 0; > } > > + /* Append new SG veneers after those in input import library. */ As above. > + for (stub_type = arm_stub_none + 1; stub_type < max_stub_type; stub_type++) > + { > + bfd_vma *start_offset_p; > + asection **stub_sec_p; > + > + start_offset_p = arm_new_stubs_start_offset_ptr (htab, stub_type); > + stub_sec_p = arm_dedicated_stub_input_section_ptr (htab, stub_type); > + if (start_offset_p == NULL) > + continue; > + > + BFD_ASSERT (stub_sec_p != NULL); > + if (*stub_sec_p != NULL) > + (*stub_sec_p)->size = *start_offset_p; > + } > + > /* Build the stubs as directed by the stub hash table. */ > table = &htab->stub_hash_table; > bfd_hash_traverse (table, arm_build_one_stub, info); > @@ -8183,7 +8564,8 @@ 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 cmse_implib) > + int fix_arm1176, int cmse_implib, > + bfd *in_implib_bfd) > { > struct elf32_arm_link_hash_table *globals; > > @@ -8211,6 +8593,7 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd, > globals->fix_cortex_a8 = fix_cortex_a8; > globals->fix_arm1176 = fix_arm1176; > globals->cmse_implib = cmse_implib; > + globals->in_implib_bfd = in_implib_bfd; > > BFD_ASSERT (is_arm_elf (output_bfd)); > elf_arm_tdata (output_bfd)->no_enum_size_warning = no_enum_warn; > diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em > index > c21f6a82335a58a0ab37f3719c73c95e73e6211c..2346bb42444895605d10b7b7e21cca2dcaa38700 > 100644 > --- a/ld/emultempl/armelf.em > +++ b/ld/emultempl/armelf.em > @@ -43,6 +43,7 @@ static int pic_veneer = 0; > static int merge_exidx_entries = -1; > static int fix_arm1176 = 1; > static int cmse_implib = 0; > +static char *in_implib_filename = NULL; > > static void > gld${EMULATION_NAME}_before_parse (void) > @@ -498,6 +499,8 @@ gld${EMULATION_NAME}_finish (void) > static void > arm_elf_create_output_section_statements (void) > { > + bfd *in_implib_bfd; > + > if (strstr (bfd_get_target (link_info.output_bfd), "arm") == NULL) > { > /* The arm backend needs special fields in the output hash structure. > @@ -508,6 +511,20 @@ arm_elf_create_output_section_statements (void) > return; > } > > + if (in_implib_filename) > + { > + in_implib_bfd = bfd_openr (in_implib_filename, > + bfd_get_target (link_info.output_bfd)); > + > + if (in_implib_bfd == NULL) > + einfo ("%F%s: Can't open: %E\n", in_implib_filename); > + > + if (!bfd_check_format (in_implib_bfd, bfd_object)) > + einfo ("%F%s: Not a relocatable file: %E\n", in_implib_filename); > + } > + else > + in_implib_bfd = NULL; > + > bfd_elf32_arm_set_target_relocs (link_info.output_bfd, &link_info, > target1_is_rel, > target2_type, fix_v4bx, use_blx, > @@ -515,7 +532,7 @@ arm_elf_create_output_section_statements (void) > no_enum_size_warning, > no_wchar_size_warning, > pic_veneer, fix_cortex_a8, > - fix_arm1176, cmse_implib); > + fix_arm1176, cmse_implib, in_implib_bfd); > > stub_file = lang_add_input_file ("linker stubs", > lang_input_file_is_fake_enum, > @@ -585,6 +602,7 @@ PARSE_AND_LIST_PROLOGUE=' > #define OPTION_LONG_PLT 319 > #define OPTION_STM32L4XX_FIX 320 > #define OPTION_CMSE_IMPLIB 321 > +#define OPTION_IN_IMPLIB 322 > ' > > PARSE_AND_LIST_SHORTOPTS=p > @@ -612,6 +630,7 @@ PARSE_AND_LIST_LONGOPTS=' > { "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 }, > + { "in-implib", required_argument, NULL, OPTION_IN_IMPLIB }, > ' > > PARSE_AND_LIST_OPTIONS=' > @@ -634,6 +653,8 @@ PARSE_AND_LIST_OPTIONS=' > " 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, _(" --in-implib Import library whose symbols > address must\n" > + " remain stable\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\ > @@ -758,6 +779,10 @@ PARSE_AND_LIST_ARGS_CASES=' > case OPTION_CMSE_IMPLIB: > cmse_implib = 1; > break; > + > + case OPTION_IN_IMPLIB: > + in_implib_filename = optarg; > + break; > ' > > # We have our own before_allocation etc. functions, but they call > diff --git a/ld/ld.texinfo b/ld/ld.texinfo > index > 82b40355a698958d84b566c09901960370139b27..eda43065f42e28bc4793bd5df78e45bd21cc1817 > 100644 > --- a/ld/ld.texinfo > +++ b/ld/ld.texinfo > @@ -6817,6 +6817,18 @@ 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. > > +@kindex --in-implib=@var{file} > +@cindex Input import library > +The @samp{--in-implib=file} specifies an input import library whose symbols > +must keep the same address in the executable being produced. A warning is > +given if no @samp{--out-implib} is given but new symbols have been introduced > +in the executable that should be listed in its import library. Otherwise, if > +@samp{--out-implib} is specified, the symbols are silently added to the output I think 'silently' is unnecessary here. > +import library. A warning is also given if some symbols present in the input > +import library have disappeared from the executable. This option is only > +effective for Secure Gateway import libraries, ie. when @samp{--cmse-implib} > is > +specified. > + > @ifclear GENERIC > @lowersections > @end ifclear > diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp > index > da4bf7e0302de9f1c76bbacf8b64a9318d44c46a..f15a8d42f3d5a4f87f21df2b229e30a1143fe7ac > 100644 > --- a/ld/testsuite/ld-arm/arm-elf.exp > +++ b/ld/testsuite/ld-arm/arm-elf.exp > @@ -663,16 +663,53 @@ set armeabitests_nonacl { > "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" > + "-march=armv8-m.base -mthumb --defsym CHECK_ERRORS=1 --defsym VER=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" > + "-march=armv8-m.base -mthumb --defsym VER=1" > {cmse-implib.s} > {{readelf {-s tmpdir/cmse-implib.lib} cmse-implib.rd}} > "cmse-implib"} > + {"Input secure gateway import library" > + "--section-start .gnu.sgstubs=0x20000 --out-implib=tmpdir/cmse-new- > implib.lib --in-implib=tmpdir/cmse-implib.lib --cmse-implib" "" > + "-march=armv8-m.base -mthumb --defsym VER=2" > + {cmse-implib.s} > + {{ld cmse-new-implib.out} > + {readelf {-s tmpdir/cmse-new-implib.lib} cmse-new-implib.rd}} > + "cmse-new-implib"} > + {"Input secure gateway import library: no output import library" > + "--section-start .gnu.sgstubs=0x20000 --in-implib=tmpdir/cmse-implib.lib > --cmse-implib" "" > + "-march=armv8-m.base -mthumb --defsym VER=2" > + {cmse-implib.s} > + {{ld cmse-new-implib-no-output.out}} > + "cmse-new-implib-no-output"} > + {"Input secure gateway import library: earlier stub section base" > + "--section-start .gnu.sgstubs=0x19000 --out-implib=tmpdir/cmse-new- > earlier-implib.lib --in-implib=tmpdir/cmse-implib.lib --cmse-implib" "" > + "-march=armv8-m.base -mthumb --defsym VER=2" > + {cmse-implib.s} > + {{ld cmse-new-earlier-later-implib.out}} > + "cmse-new-earlier-implib"} > + {"Input secure gateway import library: later stub section base" > + "--section-start .gnu.sgstubs=0x30000 --out-implib=tmpdir/cmse-new- > later-implib.lib --in-implib=tmpdir/cmse-implib.lib --cmse-implib" "" > + "-march=armv8-m.base -mthumb --defsym VER=2" > + {cmse-implib.s} > + {{ld cmse-new-earlier-later-implib.out}} > + "cmse-new-later-implib"} > + {"Input secure gateway import library: veneer comeback" > + "--section-start .gnu.sgstubs=0x20000 --out-implib=tmpdir/cmse-new- > comeback-implib.lib --in-implib=tmpdir/cmse-implib.lib --cmse-implib" "" > + "-march=armv8-m.base -mthumb --defsym VER=3" > + {cmse-implib.s} > + {{readelf {-s tmpdir/cmse-new-comeback-implib.lib} cmse-new-comeback- > implib.rd}} > + "cmse-new-comeback-implib"} > + {"Input secure gateway import library: entry function change" > + "--section-start .gnu.sgstubs=0x20000 --out-implib=tmpdir/cmse-new- > wrong-implib.lib --in-implib=tmpdir/cmse-implib.lib --cmse-implib" "" > + "-march=armv8-m.base -mthumb --defsym VER=4" > + {cmse-implib.s} > + {{ld cmse-new-wrong-implib.out}} > + "cmse-new-wrong-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.s b/ld/testsuite/ld-arm/cmse- > implib.s > index > a42da63fffebe5322be83f278931754262b0f7ae..9dd783939891478351a5f7ccb1480980a77dca68 > 100644 > --- a/ld/testsuite/ld-arm/cmse-implib.s > +++ b/ld/testsuite/ld-arm/cmse-implib.s > @@ -20,12 +20,29 @@ __acle_se_\name: > .endm > > @ Valid setups for veneer generation > +.if (VER >= 2) > + entry exported_entry_veneer1, global > +.endif > +.if (VER != 4) > entry exported_entry_veneer2, global > +.else > + entry exported_entry_veneer2, weak > +.endif > +.if (VER != 2) > entry exported_entry_veneer3, global > +.endif > +.if (VER > 1) > + entry exported_entry_veneer4, global > +.endif > > @ Valid setup for entry function without veneer generation > entry exported_entry_fct1, global, sg > +.if (VER != 4) > entry exported_entry_fct2, global, sg > +.else > + @ Invalid setup for entry function without veneer generation > + entry exported_entry_fct2, global, nop > +.endif > > @ Normal symbol not exported to SG import library > .align 2 > diff --git a/ld/testsuite/ld-arm/cmse-new-comeback-implib.rd b/ld/testsuite/ld- > arm/cmse-new-comeback-implib.rd > new file mode 100644 > index > 0000000000000000000000000000000000000000..c88d9d5104244abc8ceba4d552e1ef0e400c37d1 > --- /dev/null > +++ b/ld/testsuite/ld-arm/cmse-new-comeback-implib.rd > @@ -0,0 +1,15 @@ > +File: tmpdir/cmse-new-.*implib.lib > + > +Symbol table '.symtab' contains 7 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: 00020011 8 FUNC GLOBAL DEFAULT ABS exported_entry_veneer4 > + 3: 00020019 8 FUNC GLOBAL DEFAULT ABS exported_entry_veneer1 > + 4: [0-9a-f]+ 6 FUNC GLOBAL DEFAULT ABS exported_entry_fct1 > + 5: 00020009 8 FUNC GLOBAL DEFAULT ABS exported_entry_veneer2 > + 6: [0-9a-f]+ 6 FUNC GLOBAL DEFAULT ABS exported_entry_fct2 > + > +File: tmpdir/cmse-new-.*implib > + > +#... > diff --git a/ld/testsuite/ld-arm/cmse-new-earlier-later-implib.out > b/ld/testsuite/ld-arm/cmse-new-earlier-later-implib.out > new file mode 100644 > index > 0000000000000000000000000000000000000000..b49ad0ac0770a17c39c2d119d1f0c5854a5bd8cc > --- /dev/null > +++ b/ld/testsuite/ld-arm/cmse-new-earlier-later-implib.out > @@ -0,0 +1,3 @@ > +.*: Entry function `exported_entry_veneer3' disappeared from secure code. > +.*: Start address of `.gnu.sgstubs' is different from previous link. > +.*: cannot size stub section: Invalid operation > diff --git a/ld/testsuite/ld-arm/cmse-new-implib-no-output.out > b/ld/testsuite/ld-arm/cmse-new-implib-no-output.out > new file mode 100644 > index > 0000000000000000000000000000000000000000..0590b71c844da3687b29b93797abda5172ab8d99 > --- /dev/null > +++ b/ld/testsuite/ld-arm/cmse-new-implib-no-output.out > @@ -0,0 +1,4 @@ > +.*: Entry function `exported_entry_veneer3' disappeared from secure code. > +.*: new entry function\(s\) introduced but no output import library specified: > +.*: exported_entry_veneer4 > +.*: exported_entry_veneer1 > diff --git a/ld/testsuite/ld-arm/cmse-new-implib.out b/ld/testsuite/ld- > arm/cmse-new-implib.out > new file mode 100644 > index > 0000000000000000000000000000000000000000..c8af2807e7c1a7eeb1fc156fbf4508cf7a7e932d > --- /dev/null > +++ b/ld/testsuite/ld-arm/cmse-new-implib.out > @@ -0,0 +1 @@ > +.*: Entry function `exported_entry_veneer3' disappeared from secure code. > diff --git a/ld/testsuite/ld-arm/cmse-new-implib.rd b/ld/testsuite/ld-arm/cmse- > new-implib.rd > new file mode 100644 > index > 0000000000000000000000000000000000000000..9ff0fd87937571f86f99ee940a91a3f67352242a > --- /dev/null > +++ b/ld/testsuite/ld-arm/cmse-new-implib.rd > @@ -0,0 +1,14 @@ > +File: tmpdir/cmse-new-.*implib.lib > + > +Symbol table '.symtab' contains 6 entries: > + Num: Value Size Type Bind Vis Ndx Name > + 0: 00000000 0 NOTYPE LOCAL DEFAULT UND > + 1: 00020011 8 FUNC GLOBAL DEFAULT ABS exported_entry_veneer4 > + 2: 00020019 8 FUNC GLOBAL DEFAULT ABS exported_entry_veneer1 > + 3: [0-9a-f]+ 6 FUNC GLOBAL DEFAULT ABS exported_entry_fct1 > + 4: 00020009 8 FUNC GLOBAL DEFAULT ABS exported_entry_veneer2 > + 5: [0-9a-f]+ 6 FUNC GLOBAL DEFAULT ABS exported_entry_fct2 > + > +File: tmpdir/cmse-new-.*implib > + > +#... > diff --git a/ld/testsuite/ld-arm/cmse-new-wrong-implib.out b/ld/testsuite/ld- > arm/cmse-new-wrong-implib.out > new file mode 100644 > index > 0000000000000000000000000000000000000000..2afe4078e78606d24f05dda6ff1c5e6a54d42512 > --- /dev/null > +++ b/ld/testsuite/ld-arm/cmse-new-wrong-implib.out > @@ -0,0 +1,3 @@ > +.*: .*: visibility of symbol `exported_entry_veneer2' has changed. > +.*: `exported_entry_fct2' refers to a non entry function. > +.*: cannot size stub section: Invalid operation > > > Is this ok for master branch? > > Best regards, > > Thomas >