This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC PATCH, binutils, ARM 11/11] Add support for stable secure gateway veneers addresses


Sorry please ignore that. I'll post an updated version soon. The patch no 
longer works when rebased on latest master branch. I already have a fix for 
that but realized it also misses a ld/NEWS entry.

Best regards,

Thomas

On Thursday 14 July 2016 10:30:52 Thomas Preudhomme wrote:
> Hi Richard,
> 
> How about this updated patch? I left the following issue for a follow-up
> 
> patch:
> > > diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
> > > index
> > > 55e1cdde2d0a899238a224c6915d20197b72f085..3a67fa637f5c709cddf3767496e4ac
> > > 87
> > > 96287765 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...
> 
> ChangeLog entries are:
> 
> *** bfd/ChangeLog ***
> 
> 2016-07-08  Thomas Preud'homme  <thomas.preudhomme@arm.com>
> 
>         * 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 SG 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  <thomas.preudhomme@arm.com>
> 
>         * 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.
> 
> 
> Patch is in attachment. Is this ok for trunk?
> 
> Best regards,
> 
> Thomas
> 
> On Thursday 07 July 2016 13:52:00 Richard Earnshaw wrote:
> > 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=<in_implib_filename> 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  <thomas.preudhomme@arm.com>
> > > 
> > >         * 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  <thomas.preudhomme@arm.com>
> > > 
> > >         * 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..423c534a954c541e227e731e9256f0
> > > 8f
> > > 9fa62014 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..3a67fa637f5c709cddf3767496e4ac
> > > 87
> > > 96287765 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..be1d7224148f95bf097bb3fea63de2
> > > 08
> > > 1f93aab9 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..2346bb42444895605d10b7b7e21cca
> > > 2d
> > > caa38700 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..eda43065f42e28bc4793bd5df78e45
> > > bd
> > > 21cc1817 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..f15a8d42f3d5a4f87f21df2b229e30
> > > a1
> > > 143fe7ac 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..9dd783939891478351a5f7ccb14809
> > > 80
> > > a77dca68 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..c88d9d5104244abc8ceba4d552e1ef
> > > 0e
> > > 400c37d1 --- /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..b49ad0ac0770a17c39c2d119d1f0c5
> > > 85
> > > 4a5bd8cc --- /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..0590b71c844da3687b29b93797abda
> > > 51
> > > 72ab8d99 --- /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..c8af2807e7c1a7eeb1fc156fbf4508
> > > cf
> > > 7a7e932d --- /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..9ff0fd87937571f86f99ee940a91a3
> > > f6
> > > 7352242a --- /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..2afe4078e78606d24f05dda6ff1c5e
> > > 6a
> > > 54d42512 --- /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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]