From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 99442 invoked by alias); 18 May 2016 16:41:58 -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 96275 invoked by uid 89); 18 May 2016 16:41:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=2.1 required=5.0 tests=BAYES_50,KAM_LAZY_DOMAIN_SECURITY,KAM_LOTSOFHASH,KAM_STOCKGEN,RP_MATCHES_RCVD autolearn=no version=3.3.2 spammy=relocate, Gateway, Valid, sectionstart 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; Wed, 18 May 2016 16:41:44 +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 C2B552F; Wed, 18 May 2016 09:42:00 -0700 (PDT) Received: from e108577-lin.localnet (usa-sjc-imap-foss1.foss.arm.com [10.72.51.249]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 809153F253; Wed, 18 May 2016 09:41:42 -0700 (PDT) From: Thomas Preudhomme To: binutils@sourceware.org Cc: richard.earnshaw@arm.com, nickc@redhat.com Subject: Re: [PATCH, binutils, ARM 11/11] Add support for stable secure gateway veneers addresses Date: Wed, 18 May 2016 16:41:00 -0000 Message-ID: <1478317.JKN3veFDFN@e108577-lin> User-Agent: KMail/4.13.3 (Linux/3.13.0-85-generic; KDE/4.13.3; x86_64; ; ) In-Reply-To: <1796369.8BmbsroDJA@e108577-lin> References: <005601d13d58$522afb60$f680f220$@foss.arm.com> <1796369.8BmbsroDJA@e108577-lin> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" X-IsSubscribed: yes X-SW-Source: 2016-05/txt/msg00268.txt.bz2 [CCing Richard Earnshaw and Nick Clifton who reviewed previous ARMv8-M=20 patches] On Monday 04 April 2016 15:23 Thomas Preud'homme 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 suppo= rt=20 for > ARM v8-M security extensions. > > > > This patch adds a --in-implib=3D 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=C2=AEv8-M Security > > Extensions: Requirements on Development Tools [3] See requirement 15 > > of > > ARM-ECM-0359818 [2] >=20 > Please find an updated patch below. Please find an updated patch below, following the fix to the issue hilighte= d by=20 Christophe Lyon in patch 2/11 (Factor our stub creation in ARM backend). ChangeLog entries are unchanged: *** bfd/ChangeLog *** 2016-02-18 Thomas Preud'homme * bfd-in.h (bfd_elf32_arm_set_target_relocs): Add a new parameter f= or 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. All= ow 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 si= ze if veneer already has an offset. (elf32_arm_create_stub): Return the stub entry pointer or NULL inst= ead 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 cha= nge 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.=20 (arm_elf_create_output_section_statements): Open import input libra= ry 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=3D1 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.=20 (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):=20 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=20 d7f77d7650b8f4f23f2106c61c72fc238575d35a..140ddf463f6fffb00bace2f96b8365b71= c962152=20 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -895,7 +895,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocat= ion =20 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 *); =20 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=20 c7ba6427a5fd02a53a7bcbc042ac741456ddb213..b3db448d56ba850d998bcd21a4d9adc8a= eabdd2e=20 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -902,7 +902,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocat= ion =20 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 *); =20 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=20 1c9d97c4fa6af07a858d67f541e51fc49c4d40ee..d2a5de46b0819b7f1ad433507bfa86107= befc3c1=20 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -3128,6 +3128,10 @@ struct elf32_arm_link_hash_table as per ARMv8-M Security Extensions. */ int cmse_implib; =20 + /* 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; =20 @@ -3189,6 +3193,10 @@ struct elf32_arm_link_hash_table /* Input stub section holding secure gateway veneers. */ asection *cmse_stub_sec; =20 + /* Offset in cmse_stub_sec where new SG veneers (not in input import=20 library) + start to be allocated. */ + bfd_vma new_cmse_stub_offset; + /* Number of elements in stub_group. */ unsigned int top_id; =20 @@ -3440,7 +3448,7 @@ stub_hash_newfunc (struct bfd_hash_entry *entry, /* Initialize the local fields. */ eh =3D (struct elf32_arm_stub_hash_entry *) entry; eh->stub_sec =3D NULL; - eh->stub_offset =3D 0; + eh->stub_offset =3D (bfd_vma) -1; eh->source_value =3D 0; eh->target_value =3D 0; eh->target_section =3D NULL; @@ -3448,7 +3456,7 @@ stub_hash_newfunc (struct bfd_hash_entry *entry, eh->stub_type =3D arm_stub_none; eh->stub_size =3D 0; eh->stub_template =3D NULL; - eh->stub_template_size =3D 0; + eh->stub_template_size =3D -1; eh->h =3D NULL; eh->id_sec =3D NULL; eh->output_name =3D NULL; @@ -4362,7 +4370,7 @@ elf32_arm_add_stub (const char *stub_name, asection=20 *section, } =20 stub_entry->stub_sec =3D stub_sec; - stub_entry->stub_offset =3D 0; + stub_entry->stub_offset =3D (bfd_vma) -1; stub_entry->id_sec =3D link_sec; =20 return stub_entry; @@ -4526,6 +4534,46 @@ arm_dedicated_stub_section_padding (enum=20 elf32_arm_stub_type stub_type) abort (); /* Should be unreachable. */ } =20 +/* 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) @@ -4545,6 +4593,7 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry, int stub_reloc_idx[MAXRELOCS] =3D {-1, -1}; int stub_reloc_offset[MAXRELOCS] =3D {0, 0}; int nrelocs =3D 0; + int just_allocated =3D 0; =20 /* Massage our args to the form they really have. */ stub_entry =3D (struct elf32_arm_stub_hash_entry *) gen_entry; @@ -4561,8 +4610,12 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry, /* We have to do less-strictly-aligned fixes last. */ return TRUE; =20 - /* Make a note of the offset within the stubs for this entry. */ - stub_entry->stub_offset =3D stub_sec->size; + /* Assign a slot at the end of section if none assigned yet. */ + if (stub_entry->stub_offset =3D=3D (bfd_vma) -1) + { + stub_entry->stub_offset =3D stub_sec->size; + just_allocated =3D 1; + } loc =3D stub_sec->contents + stub_entry->stub_offset; =20 stub_bfd =3D stub_sec->owner; @@ -4636,7 +4689,8 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry, } } =20 - stub_sec->size +=3D size; + if (just_allocated) + stub_sec->size +=3D size; =20 /* Stub size has already been computed in arm_size_one_stub. Check consistency. */ @@ -4648,7 +4702,7 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry, =20 /* Assume there is at least one and at most MAXRELOCS entries to relocate in each stub. */ - BFD_ASSERT (nrelocs !=3D 0 && nrelocs <=3D MAXRELOCS); + BFD_ASSERT (size =3D=3D 0 || (nrelocs !=3D 0 && nrelocs <=3D MAXRELOCS)); =20 for (i =3D 0; i < nrelocs; i++) { @@ -4750,9 +4804,17 @@ arm_size_one_stub (struct bfd_hash_entry *gen_entry, size =3D find_stub_size_and_template (stub_entry->stub_type,=20 &template_sequence, &template_size); =20 - stub_entry->stub_size =3D size; - stub_entry->stub_template =3D template_sequence; - stub_entry->stub_template_size =3D template_size; + /* Initialized to -1. Null size indicates a zeroed out veneer. */ + if (stub_entry->stub_template_size) + { + stub_entry->stub_size =3D size; + stub_entry->stub_template =3D template_sequence; + stub_entry->stub_template_size =3D template_size; + } + + /* Already accounted for. */ + if (stub_entry->stub_offset !=3D (bfd_vma) -1) + return TRUE; =20 size =3D (size + 7) & ~7; stub_entry->stub_sec->size +=3D size; @@ -5317,10 +5379,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. =20 - Returns whether the stub could be successfully created or updated, or=20 FALSE - if an error occured. */ + Returns the stub that was created or updated, or NULL if an error + occured. */ =20 -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, @@ -5351,7 +5413,7 @@ elf32_arm_create_stub (struct elf32_arm_link_hash_tab= le=20 *htab, stub_name =3D elf32_arm_stub_name (id_sec, sym_sec, hash, irela, stub_type); if (!stub_name) - return FALSE; + return NULL; } =20 stub_entry =3D arm_stub_hash_lookup (&htab->stub_hash_table, stub_name,= =20 FALSE, @@ -5362,7 +5424,7 @@ elf32_arm_create_stub (struct elf32_arm_link_hash_tab= le=20 *htab, if (!sym_claimed) free (stub_name); stub_entry->target_value =3D sym_value; - return TRUE; + return stub_entry; } =20 stub_entry =3D elf32_arm_add_stub (stub_name, section, htab, stub_type); @@ -5370,7 +5432,7 @@ elf32_arm_create_stub (struct elf32_arm_link_hash_tab= le=20 *htab, { if (!sym_claimed) free (stub_name); - return FALSE; + return NULL; } =20 stub_entry->target_value =3D sym_value; @@ -5391,7 +5453,7 @@ elf32_arm_create_stub (struct elf32_arm_link_hash_tab= le=20 *htab, if (stub_entry->output_name =3D=3D NULL) { free (stub_name); - return FALSE; + return NULL; } =20 /* For historical reasons, use the existing names for ARM-to-Thumb a= nd @@ -5411,7 +5473,7 @@ elf32_arm_create_stub (struct elf32_arm_link_hash_tab= le=20 *htab, } =20 *new_stub =3D TRUE; - return TRUE; + return stub_entry; } =20 /* Scan symbols in INPUT_BFD to identify secure entry functions needing a @@ -5428,14 +5490,15 @@ elf32_arm_create_stub (struct=20 elf32_arm_link_hash_table *htab, =20 OUT_ATTR gives the output attributes, SYM_HASHES the symbol index to ha= sh entry mapping while HTAB gives the name to hash entry mapping. + *CMSE_STUB_CREATED is increased by the number of secure gateway veneer + created. =20 - If any secure gateway veneer is created, *STUB_CHANGED is set to TRUE.= =20=20 The - return value gives whether a stub failed to be allocated. */ + The return value gives whether a stub failed to be allocated. */ =20 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; @@ -5446,7 +5509,8 @@ cmse_scan (bfd *input_bfd, struct=20 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 =3D TRUE; + struct elf32_arm_stub_hash_entry *stub_entry; + bfd_boolean is_v8m, new_stub, cmse_invalid, ret =3D TRUE; =20 bed =3D get_elf_backend_data (input_bfd); symtab_hdr =3D &elf_tdata (input_bfd)->symtab_hdr; @@ -5587,17 +5651,17 @@ cmse_scan (bfd *input_bfd, struct=20 elf32_arm_link_hash_table *htab, if (!ret) continue; branch_type =3D ARM_GET_SYM_BRANCH_TYPE (hash->root.target_internal); - created_stub + stub_entry =3D elf32_arm_create_stub (htab, arm_stub_cmse_branch_thumb_only, NULL, NULL, section, hash, sym_name, sym_value, branch_type, &new_stub); =20 - if (!created_stub) + if (stub_entry =3D=3D NULL) ret =3D FALSE; else { BFD_ASSERT (new_stub); - *stub_changed =3D TRUE; + (*cmse_stub_created)++; } } =20 @@ -5606,6 +5670,273 @@ cmse_scan (bfd *input_bfd, struct=20 elf32_arm_link_hash_table *htab, return ret; } =20 +/* Return whether a symbol identified by its linker HASH entry is an entry + function, ie can be called from non secure code without using a veneer.= =20=20 */ + +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 !=3D bfd_link_hash_defined + && hash->root.root.type !=3D bfd_link_hash_defweak) + return FALSE; + if (hash->root.type !=3D STT_FUNC) + return FALSE; + + /* Read first instruction. */ + section =3D hash->root.root.u.def.section; + abfd =3D section->owner; + offset =3D 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 =3D=3D 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=20 library) + and there is no output import library (GEN_INFO->out_implib_bfd is NULL= .=20=20 */ + +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 =3D (struct elf32_arm_stub_hash_entry *) gen_entry; + info =3D (struct bfd_link_info *) gen_info; + + if (info->out_implib_bfd) + return TRUE; + + if (stub_entry->stub_type !=3D arm_stub_cmse_branch_thumb_only) + return TRUE; + + if (stub_entry->stub_offset =3D=3D (bfd_vma) -1) + (*_bfd_error_handler) (" %s", stub_entry->output_name); + + return TRUE; +} + +/* Set offset of secure gateway veneers so that their address remain ident= ical + 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= =20 NULL + and *CMSE_STUB_CREATED is bigger than the number of secure gateway vene= ers + 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=20 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 =3D TRUE; + Elf_Internal_Sym *intsym; + const char *out_sec_name; + bfd_size_type cmse_stub_size; + asymbol **sympp =3D 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 =3D *cmse_stub_creat= ed; + bfd_vma veneer_value, stub_offset, next_cmse_stub_offset; + bfd_vma cmse_stub_array_start =3D (bfd_vma) -1, cmse_stub_sec_vma =3D 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 =3D htab->in_implib_bfd; + symsize =3D 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 =3D (asymbol **) xmalloc (symsize); + symcount =3D bfd_canonicalize_symtab (in_implib_bfd, sympp); + if (symcount < 0) + { + ret =3D FALSE; + goto free_sym_buf; + } + + htab->new_cmse_stub_offset =3D 0; + cmse_stub_size =3D + find_stub_size_and_template (arm_stub_cmse_branch_thumb_only, + &cmse_stub_template, + &cmse_stub_template_size); + out_sec_name =3D + arm_dedicated_stub_output_section_name (arm_stub_cmse_branch_thumb_onl= y); + stub_out_sec =3D + bfd_get_section_by_name (htab->obfd, out_sec_name); + if (stub_out_sec !=3D NULL) + cmse_stub_sec_vma =3D stub_out_sec->vma; + + /* Set addresses of veneers mentionned in input secure gateway import + library's symbol table. */ + for (i =3D 0; i < symcount; i++) + { + sym =3D sympp[i]; + flags =3D sym->flags; + sym_name =3D (char *) bfd_asymbol_name (sym); + intsym =3D &((elf_symbol_type *) sym)->internal_elf_sym; + + if (sym->section !=3D bfd_abs_section_ptr + || !(flags & (BSF_GLOBAL | BSF_WEAK)) + || (flags & BSF_FUNCTION) !=3D BSF_FUNCTION + || (ARM_GET_SYM_BRANCH_TYPE (intsym->st_target_internal) + !=3D 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 =3D FALSE; + continue; + } + + veneer_value =3D bfd_asymbol_value (sym); + stub_offset =3D veneer_value - cmse_stub_sec_vma; + stub_entry =3D arm_stub_hash_lookup (&htab->stub_hash_table, sym_nam= e, + FALSE, FALSE); + hash =3D (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 =3D (struct elf32_arm_link_hash_entry *) + elf_link_hash_lookup (&(htab)->root, sym_name, TRUE, TRUE, TRUE); + stub_entry + =3D 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 =3D=3D NULL) + ret =3D FALSE; + else + { + BFD_ASSERT (new_stub); + new_cmse_stubs_created++; + (*cmse_stub_created)++; + } + stub_entry->stub_template_size =3D stub_entry->stub_size =3D 0; + stub_entry->stub_offset =3D 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 =3D FALSE; + } + continue; + } + else + { + /* Only stub for SG veneers should have been created. */ + BFD_ASSERT (stub_entry->stub_type =3D=3D arm_stub_cmse_branch_thumb_onl= y); + + /* Check visibility hasn't changed. */ + if (!!(flags & BSF_GLOBAL) + !=3D (hash->root.root.type =3D=3D bfd_link_hash_defined)) + (*_bfd_error_handler) + (_("%B: visibility of symbol `%s' has changed."), in_implib_bfd, + sym_name); + + stub_entry->stub_offset =3D stub_offset; + } + + /* Size should match that of a SG veneer. */ + if (intsym->st_size !=3D cmse_stub_size) + { + (*_bfd_error_handler) (_("%B: incorrect size for symbol `%s'."), + in_implib_bfd, sym_name); + ret =3D 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 =3D 0; + stub_offset =3D 0; + ret =3D 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 =3D FALSE; + } + + if (!ret) + continue; + + new_cmse_stubs_created--; + if (veneer_value < cmse_stub_array_start) + cmse_stub_array_start =3D veneer_value; + next_cmse_stub_offset =3D stub_offset + ((cmse_stub_size + 7) & ~7); + if (next_cmse_stub_offset > htab->new_cmse_stub_offset) + htab->new_cmse_stub_offset =3D next_cmse_stub_offset; + } + + if (!info->out_implib_bfd && new_cmse_stubs_created !=3D 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,=20 info); + } + + if (cmse_stub_array_start !=3D cmse_stub_sec_vma) + { + (*_bfd_error_handler) + (_("Start address of `%s' is different from previous link."), + out_sec_name); + ret =3D FALSE; + } + +free_sym_buf: + free (sympp); + return ret; +} + /* Determine and set the size of the stub section for a final link. =20 The basic idea here is to examine all the relocations looking for @@ -5622,7 +5953,9 @@ elf32_arm_size_stubs (bfd *output_bfd, unsigned int), void (*layout_sections_again) (void)) { + bfd_boolean ret =3D TRUE; obj_attribute *out_attr; + int cmse_stub_created =3D 0; bfd_size_type stub_group_size; bfd_boolean m_profile, stubs_always_after_branch, first_veneer_scan =3D = TRUE; struct elf32_arm_link_hash_table *htab =3D elf32_arm_hash_table (info); @@ -5655,6 +5988,7 @@ elf32_arm_size_stubs (bfd *output_bfd, =20 out_attr =3D elf_known_obj_attributes_proc (output_bfd); m_profile =3D out_attr[Tag_CPU_arch_profile].i =3D=3D 'M'; + /* The Cortex-A8 erratum fix depends on stubs not being in the same 4K p= age as the first half of a 32-bit branch straddling two 4K pages. This i= s a crude way of enforcing that. */ @@ -5728,8 +6062,11 @@ elf32_arm_size_stubs (bfd *output_bfd, =20 sym_hashes =3D 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 !=3D 0) + stub_changed =3D TRUE; } =20 /* Walk over each section attached to the input bfd. */ @@ -5961,6 +6298,7 @@ elf32_arm_size_stubs (bfd *output_bfd, do { bfd_boolean new_stub; + struct elf32_arm_stub_hash_entry *stub_entry; =20 /* Determine what (if any) linker stub is needed. */ stub_type =3D arm_type_of_stub (info, section, irela, @@ -5972,12 +6310,13 @@ elf32_arm_size_stubs (bfd *output_bfd, =20 /* We've either created a stub for this reloc already, or we are about to. */ - created_stub =3D + stub_entry =3D elf32_arm_create_stub (htab, stub_type, section, irela, sym_sec, hash, (char *) sym_name, sym_value, branch_type, &new_stub); =20 + created_stub =3D stub_entry !=3D NULL; if (!created_stub) goto error_ret_free_internal; else if (!new_stub) @@ -6050,6 +6389,11 @@ elf32_arm_size_stubs (bfd *output_bfd, } } =20 + if (first_veneer_scan + && !set_cmse_veneer_addr_from_implib (info, htab, + &cmse_stub_created)) + ret =3D FALSE; + if (prev_num_a8_fixes !=3D num_a8_fixes) stub_changed =3D TRUE; =20 @@ -6069,6 +6413,23 @@ elf32_arm_size_stubs (bfd *output_bfd, stub_sec->size =3D 0; } =20 + /* Append new SG veneers after those in input import library. */ + for (stub_type =3D arm_stub_none + 1; stub_type < max_stub_type; + stub_type++) + { + bfd_vma *start_offset_p; + asection **stub_sec_p; + + start_offset_p =3D arm_new_stubs_start_offset_ptr (htab, stub_type); + stub_sec_p =3D arm_dedicated_stub_input_section_ptr (htab, stub_type); + if (start_offset_p =3D=3D NULL) + continue; + + BFD_ASSERT (stub_sec_p !=3D NULL); + if (*stub_sec_p !=3D NULL) + (*stub_sec_p)->size =3D *start_offset_p; + } + /* Compute stub section size, considering padding. */ bfd_hash_traverse (&htab->stub_hash_table, arm_size_one_stub, htab); for (stub_type =3D arm_stub_none + 1; stub_type < max_stub_type; @@ -6137,7 +6498,7 @@ elf32_arm_size_stubs (bfd *output_bfd, } =20 stub_entry->stub_sec =3D stub_sec; - stub_entry->stub_offset =3D 0; + stub_entry->stub_offset =3D (bfd_vma) -1; stub_entry->id_sec =3D link_sec; stub_entry->stub_type =3D a8_fixes[i].stub_type; stub_entry->source_value =3D a8_fixes[i].offset; @@ -6165,7 +6526,7 @@ elf32_arm_size_stubs (bfd *output_bfd, htab->a8_erratum_fixes =3D NULL; htab->num_a8_erratum_fixes =3D 0; } - return TRUE; + return ret; } =20 /* Build all the stubs associated with the current output file. The @@ -6179,6 +6540,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; =20 htab =3D elf32_arm_hash_table (info); @@ -6196,14 +6558,33 @@ elf32_arm_build_stubs (struct bfd_link_info *info) continue; =20 /* Allocate memory to hold the linker stubs. Zeroing the stub secti= ons - 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 =3D stub_sec->size; stub_sec->contents =3D (unsigned char *) bfd_zalloc (htab->stub_bfd,= =20 size); if (stub_sec->contents =3D=3D NULL && size !=3D 0) return FALSE; + stub_sec->size =3D 0; } =20 + /* Append new SG veneers after those in input import library. */ + for (stub_type =3D arm_stub_none + 1; stub_type < max_stub_type; stub_ty= pe++) + { + bfd_vma *start_offset_p; + asection **stub_sec_p; + + start_offset_p =3D arm_new_stubs_start_offset_ptr (htab, stub_type); + stub_sec_p =3D arm_dedicated_stub_input_section_ptr (htab, stub_type= ); + if (start_offset_p =3D=3D NULL) + continue; + + BFD_ASSERT (stub_sec_p !=3D NULL); + if (*stub_sec_p !=3D NULL) + (*stub_sec_p)->size =3D *start_offset_p; + } + /* Build the stubs as directed by the stub hash table. */ table =3D &htab->stub_hash_table; bfd_hash_traverse (table, arm_build_one_stub, info); @@ -8189,7 +8570,8 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_b= fd, 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; =20 @@ -8217,6 +8599,7 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_b= fd, globals->fix_cortex_a8 =3D fix_cortex_a8; globals->fix_arm1176 =3D fix_arm1176; globals->cmse_implib =3D cmse_implib; + globals->in_implib_bfd =3D in_implib_bfd; =20 BFD_ASSERT (is_arm_elf (output_bfd)); elf_arm_tdata (output_bfd)->no_enum_size_warning =3D no_enum_warn; diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index=20 c21f6a82335a58a0ab37f3719c73c95e73e6211c..2346bb42444895605d10b7b7e21cca2dc= aa38700=20 100644 --- a/ld/emultempl/armelf.em +++ b/ld/emultempl/armelf.em @@ -43,6 +43,7 @@ static int pic_veneer =3D 0; static int merge_exidx_entries =3D -1; static int fix_arm1176 =3D 1; static int cmse_implib =3D 0; +static char *in_implib_filename =3D NULL; =20 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") =3D=3D NULL) { /* The arm backend needs special fields in the output hash structure. @@ -508,6 +511,20 @@ arm_elf_create_output_section_statements (void) return; } =20 + if (in_implib_filename) + { + in_implib_bfd =3D bfd_openr (in_implib_filename, + bfd_get_target (link_info.output_bfd)); + + if (in_implib_bfd =3D=3D 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 =3D 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); =20 stub_file =3D lang_add_input_file ("linker stubs", lang_input_file_is_fake_enum, @@ -585,6 +602,7 @@ PARSE_AND_LIST_PROLOGUE=3D' #define OPTION_LONG_PLT 319 #define OPTION_STM32L4XX_FIX 320 #define OPTION_CMSE_IMPLIB 321 +#define OPTION_IN_IMPLIB 322 ' =20 PARSE_AND_LIST_SHORTOPTS=3Dp @@ -612,6 +630,7 @@ PARSE_AND_LIST_LONGOPTS=3D' { "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 }, ' =20 PARSE_AND_LIST_OPTIONS=3D' @@ -634,6 +653,8 @@ PARSE_AND_LIST_OPTIONS=3D' " to handle large .plt/.got=20 displacements\n")); fprintf (file, _(" --cmse-implib Make import library to b= e a=20 secure gateway import\n" " library as per ARMv8-M= =20 Security Extensions\n")); + fprintf (file, _(" --in-implib Import library whose sym= bols=20 address must\n" + " remain stable\n")); fprintf (file, _("\ --stub-group-size=3DN Maximum size of a group of input sections= =20 that\n\ can be handled by one stub section. A=20 negative\n\ @@ -758,6 +779,10 @@ PARSE_AND_LIST_ARGS_CASES=3D' case OPTION_CMSE_IMPLIB: cmse_implib =3D 1; break; + + case OPTION_IN_IMPLIB: + in_implib_filename =3D optarg; + break; ' =20 # We have our own before_allocation etc. functions, but they call diff --git a/ld/ld.texinfo b/ld/ld.texinfo index=20 e6813f287fe5ce4c916bf93f48b2e9edbc336570..5994d2efc7a2406d0dcddbd2fe7eeefab= 910534a=20 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -6866,6 +6866,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. =20 +@kindex --in-implib=3D@var{file} +@cindex Input import library +The @samp{--in-implib=3Dfile} specifies an input import library whose symb= ols +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 introdu= ced +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 ou= tput +import library. A warning is also given if some symbols present in the in= put +import library have disappeared from the executable. This option is only +effective for Secure Gateway import libraries, ie. when @samp{--cmse-impli= b}=20 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=20 2efc047a63d6d5e3250a3259e01633394f102ac0..019f00abf6e43883c052a1b3f5f4d913f= 2dc0039=20 100644 --- a/ld/testsuite/ld-arm/arm-elf.exp +++ b/ld/testsuite/ld-arm/arm-elf.exp @@ -661,16 +661,53 @@ set armeabitests_nonacl { "cmse-veneers-mainline"} {"Secure gateway import library generation: errors" "--section-start .gnu.sgstubs=3D0x20000 --out-implib=3Dtmpdir/cmse- implib.lib --cmse-implib" "" - "-march=3Darmv8-m.base -mthumb --defsym CHECK_ERRORS=3D1" + "-march=3Darmv8-m.base -mthumb --defsym CHECK_ERRORS=3D1 --defsym VER= =3D1" {cmse-implib.s} {{ld cmse-implib-errors.out}} "cmse-implib"} {"Secure gateway import library generation" "--section-start .gnu.sgstubs=3D0x20000 --out-implib=3Dtmpdir/cmse- implib.lib --cmse-implib" "" - "-march=3Darmv8-m.base -mthumb" + "-march=3Darmv8-m.base -mthumb --defsym VER=3D1" {cmse-implib.s} {{readelf {-s tmpdir/cmse-implib.lib} cmse-implib.rd}} "cmse-implib"} + {"Input secure gateway import library" + "--section-start .gnu.sgstubs=3D0x20000 --out-implib=3Dtmpdir/cmse-ne= w- implib.lib --in-implib=3Dtmpdir/cmse-implib.lib --cmse-implib" "" + "-march=3Darmv8-m.base -mthumb --defsym VER=3D2" + {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=3D0x20000 --in-implib=3Dtmpdir/cmse-imp= lib.lib=20 --cmse-implib" "" + "-march=3Darmv8-m.base -mthumb --defsym VER=3D2" + {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=3D0x19000 --out-implib=3Dtmpdir/cmse-ne= w- earlier-implib.lib --in-implib=3Dtmpdir/cmse-implib.lib --cmse-implib" "" + "-march=3Darmv8-m.base -mthumb --defsym VER=3D2" + {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=3D0x30000 --out-implib=3Dtmpdir/cmse-ne= w- later-implib.lib --in-implib=3Dtmpdir/cmse-implib.lib --cmse-implib" "" + "-march=3Darmv8-m.base -mthumb --defsym VER=3D2" + {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=3D0x20000 --out-implib=3Dtmpdir/cmse-ne= w- comeback-implib.lib --in-implib=3Dtmpdir/cmse-implib.lib --cmse-implib" "" + "-march=3Darmv8-m.base -mthumb --defsym VER=3D3" + {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=3D0x20000 --out-implib=3Dtmpdir/cmse-ne= w- wrong-implib.lib --in-implib=3Dtmpdir/cmse-implib.lib --cmse-implib" "" + "-march=3Darmv8-m.base -mthumb --defsym VER=3D4" + {cmse-implib.s} + {{ld cmse-new-wrong-implib.out}} + "cmse-new-wrong-implib"} =20 {"R_ARM_THM_JUMP19 Relocation veneers: Short" "--section-start destsect=3D0x000108002 --section-start .text=3D0x800= 0" "" diff --git a/ld/testsuite/ld-arm/cmse-implib.s b/ld/testsuite/ld-arm/cmse- implib.s index=20 a42da63fffebe5322be83f278931754262b0f7ae..9dd783939891478351a5f7ccb1480980a= 77dca68=20 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 =20 @ Valid setups for veneer generation +.if (VER >=3D 2) + entry exported_entry_veneer1, global +.endif +.if (VER !=3D 4) entry exported_entry_veneer2, global +.else + entry exported_entry_veneer2, weak +.endif +.if (VER !=3D 2) entry exported_entry_veneer3, global +.endif +.if (VER > 1) + entry exported_entry_veneer4, global +.endif =20 @ Valid setup for entry function without veneer generation entry exported_entry_fct1, global, sg +.if (VER !=3D 4) entry exported_entry_fct2, global, sg +.else + @ Invalid setup for entry function without veneer generation + entry exported_entry_fct2, global, nop +.endif =20 @ 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=20 0000000000000000000000000000000000000000..c88d9d5104244abc8ceba4d552e1ef0e4= 00c37d1 --- /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=20 + 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=20 b/ld/testsuite/ld-arm/cmse-new-earlier-later-implib.out new file mode 100644 index=20 0000000000000000000000000000000000000000..b49ad0ac0770a17c39c2d119d1f0c5854= a5bd8cc --- /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=20 b/ld/testsuite/ld-arm/cmse-new-implib-no-output.out new file mode 100644 index=20 0000000000000000000000000000000000000000..0590b71c844da3687b29b93797abda517= 2ab8d99 --- /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 specif= ied: +.*: 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=20 0000000000000000000000000000000000000000..c8af2807e7c1a7eeb1fc156fbf4508cf7= a7e932d --- /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/c= mse- new-implib.rd new file mode 100644 index=20 0000000000000000000000000000000000000000..9ff0fd87937571f86f99ee940a91a3f67= 352242a --- /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=20 + 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/l= d- arm/cmse-new-wrong-implib.out new file mode 100644 index=20 0000000000000000000000000000000000000000..2afe4078e78606d24f05dda6ff1c5e6a5= 4d42512 --- /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 Best regards, Thomas