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, ping] Add support for stable secure gateway veneers addresses


On 25/08/16 17:35, Thomas Preudhomme wrote:
> Hi Richard,
> 
> On 25/08/16 17:14, Richard Earnshaw (lists) wrote:
>> On 17/08/16 16:23, Thomas Preudhomme wrote:
>>> [Trying again with inline patch since previous attempt got flagged as
>>> spam]
>>>
>>
>> You're missing the ChangeLog entry, but I'll take it that it's still the
>> same as last time.
> 
> Sorry, I forgot to copy the message I sent with the patch in my first
> attempt. I paste it below and will wait that you confirm you are happy
> with the updated ChangeLog entries.
> 
> 

This is fine.

R.

> Sorry for the delay, got caught on other things. Please find an updated
> patch
> in attachment. All but one of your comments have been addressed, comment
> below
> on that one.
> 
> Updated ChangeLog entries are as follow:
> 
> *** 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-07-15  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.
>         * NEWS: Likewise.
>         * 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: not an SG input 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-implib-not-sg-in-implib.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.
> 
>>
>> OK.
>>
>> R.
>>
>>> diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
>>> index
>>> d33bb8267b12d9cd2c942d3c502e3e563e63d09f..f9bce9fd3ef778429ea9c1416ca2ffcab3f4e374
>>>
>>> 100644
>>> --- a/bfd/bfd-in.h
>>> +++ b/bfd/bfd-in.h
>>> @@ -894,7 +894,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
>>> cc8428a21d8ce3267420c76a4328fb6d433cd597..8b1d8a01adf529ee42ad6673c82a5028aed5774c
>>>
>>> 100644
>>> --- a/bfd/bfd-in2.h
>>> +++ b/bfd/bfd-in2.h
>>> @@ -901,7 +901,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/elf32-arm.c b/bfd/elf32-arm.c
>>> index
>>> 1eba21b42ddfaf3704860107e4fff36dbbc24d8d..539c2aacbd6b47b25288d3b3e691b90806863856
>>>
>>> 100644
>>> --- a/bfd/elf32-arm.c
>>> +++ b/bfd/elf32-arm.c
>>> @@ -3148,6 +3148,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;
>>>
>>> @@ -3209,6 +3213,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;
>>>
>>> @@ -3460,7 +3468,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;
>>> @@ -3468,7 +3476,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;
>>> @@ -4467,7 +4475,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;
>>> @@ -4633,11 +4641,31 @@ 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_cmse_branch_thumb_only:
>>> +      return &htab->new_cmse_stub_offset;
>>> +
>>> +    default:
>>> +      BFD_ASSERT (!arm_dedicated_stub_output_section_required
>>> (stub_type));
>>> +      return NULL;
>>> +    }
>>> +}
>>> +
>>>  static bfd_boolean
>>>  arm_build_one_stub (struct bfd_hash_entry *gen_entry,
>>>              void * in_arg)
>>>  {
>>>  #define MAXRELOCS 3
>>> +  bfd_boolean removed_sg_veneer;
>>>    struct elf32_arm_stub_hash_entry *stub_entry;
>>>    struct elf32_arm_link_hash_table *globals;
>>>    struct bfd_link_info *info;
>>> @@ -4652,6 +4680,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;
>>> @@ -4668,8 +4697,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;
>>> @@ -4743,7 +4776,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.  */
>>> @@ -4753,9 +4787,11 @@ arm_build_one_stub (struct bfd_hash_entry
>>> *gen_entry,
>>>    if (stub_entry->branch_type == ST_BRANCH_TO_THUMB)
>>>      sym_value |= 1;
>>>
>>> -  /* Assume there is at least one and at most MAXRELOCS entries to
>>> relocate
>>> -     in each stub.  */
>>> -  BFD_ASSERT (nrelocs != 0 && nrelocs <= MAXRELOCS);
>>> +  /* Assume non empty slots have at least one and at most MAXRELOCS
>>> entries
>>> +     to relocate in each stub.  */
>>> +  removed_sg_veneer =
>>> +    (size == 0 && stub_entry->stub_type ==
>>> arm_stub_cmse_branch_thumb_only);
>>> +  BFD_ASSERT (removed_sg_veneer || (nrelocs != 0 && nrelocs <=
>>> MAXRELOCS));
>>>
>>>    for (i = 0; i < nrelocs; i++)
>>>      {
>>> @@ -4857,9 +4893,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 an empty slot full of
>>> zeros.  */
>>> +  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;
>>> @@ -5424,10 +5468,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
>>> +   occurred.  */
>>>
>>> -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,
>>> @@ -5458,7 +5502,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,
>>> @@ -5469,7 +5513,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);
>>> @@ -5477,7 +5521,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;
>>> @@ -5498,7 +5542,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
>>> @@ -5518,7 +5562,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
>>> @@ -5537,14 +5581,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;
>>> @@ -5555,7 +5600,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;
>>> @@ -5700,17 +5746,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)++;
>>>      }
>>>      }
>>>
>>> @@ -5719,6 +5765,279 @@ cmse_scan (bfd *input_bfd, struct
>>> elf32_arm_link_hash_table *htab,
>>>    return ret;
>>>  }
>>>
>>> +/* Return TRUE iff a symbol identified by its linker HASH entry is a
>>> secure
>>> +   code entry 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 each secure gateway veneers so that its address remain
>>> +   identical 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 occurred.  If no error
>>> occurred,
>>> +   *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;
>>> +
>>> +  in_implib_bfd = htab->in_implib_bfd;
>>> +  if (!htab->cmse_implib)
>>> +    {
>>> +      (*_bfd_error_handler) (_("%B: --in-implib only supported for
>>> Secure "
>>> +                   "Gateway import libraries."), in_implib_bfd);
>>> +      return FALSE;
>>> +    }
>>> +
>>> +  /* Get symbol table size.  */
>>> +  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 stubs for SG veneers should have been created.  */
>>> +      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
>>> @@ -5735,7 +6054,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);
>>> @@ -5768,6 +6089,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.  */
>>> @@ -5841,8 +6163,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.  */
>>> @@ -6074,6 +6399,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,
>>> @@ -6085,12 +6411,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)
>>>              goto error_ret_free_internal;
>>>                else if (!new_stub)
>>> @@ -6172,6 +6499,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;
>>>
>>> @@ -6191,6 +6523,24 @@ elf32_arm_size_stubs (bfd *output_bfd,
>>>        stub_sec->size = 0;
>>>      }
>>>
>>> +      /* Add new SG veneers after those already in the input import
>>> +     library.  */
>>> +      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;
>>> @@ -6259,7 +6609,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;
>>> @@ -6287,7 +6637,7 @@ elf32_arm_size_stubs (bfd *output_bfd,
>>>        htab->a8_erratum_fixes = NULL;
>>>        htab->num_a8_erratum_fixes = 0;
>>>      }
>>> -  return TRUE;
>>> +  return ret;
>>>  }
>>>
>>>  /* Build all the stubs associated with the current output file.  The
>>> @@ -6301,6 +6651,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);
>>> @@ -6318,14 +6669,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;
>>>      }
>>>
>>> +  /* Add new SG veneers after those already in the input import
>>> library.  */
>>> +  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);
>>> @@ -8311,7 +8681,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;
>>>
>>> @@ -8339,6 +8710,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/NEWS b/ld/NEWS
>>> index
>>> 2a0b4ac704a088a24cfc1633785a50477513c4db..0f316bfcc248341200af14e5cb1a5c50787e9b1a
>>>
>>> 100644
>>> --- a/ld/NEWS
>>> +++ b/ld/NEWS
>>> @@ -2,6 +2,11 @@
>>>
>>>  Changes in 2.28:
>>>
>>> +* Add --in-implib=<infile> to the ARM linker to enable specifying a
>>> set of
>>> +  Secure Gateway veneers that must exist in the output import library
>>> specified
>>> +  by --out-implib=<outfile> and the address they must have.  As such,
>>> +  --in-implib is only supported in combination with --cmse-implib.
>>> +
>>>  * Extended the --out-implib=<file> option, previously restricted to
>>> x86 PE
>>>    targets, to any ELF based target.  This allows the generation of an
>>> import
>>>    library for an ELF executable, which can then be used by another
>>> application
>>> diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
>>> index
>>> c21f6a82335a58a0ab37f3719c73c95e73e6211c..2346bb42444895605d10b7b7e21cca2dcaa38700
>>>
>>> 100644
>>> --- a/ld/emultempl/armelf.em
>>> +++ b/ld/emultempl/armelf.em
>>> @@ -43,6 +43,7 @@ static int pic_veneer = 0;
>>>  static int merge_exidx_entries = -1;
>>>  static int fix_arm1176 = 1;
>>>  static int cmse_implib = 0;
>>> +static char *in_implib_filename = NULL;
>>>
>>>  static void
>>>  gld${EMULATION_NAME}_before_parse (void)
>>> @@ -498,6 +499,8 @@ gld${EMULATION_NAME}_finish (void)
>>>  static void
>>>  arm_elf_create_output_section_statements (void)
>>>  {
>>> +  bfd *in_implib_bfd;
>>> +
>>>    if (strstr (bfd_get_target (link_info.output_bfd), "arm") == NULL)
>>>      {
>>>        /* The arm backend needs special fields in the output hash
>>> structure.
>>> @@ -508,6 +511,20 @@ arm_elf_create_output_section_statements (void)
>>>        return;
>>>      }
>>>
>>> +  if (in_implib_filename)
>>> +    {
>>> +      in_implib_bfd = bfd_openr (in_implib_filename,
>>> +                 bfd_get_target (link_info.output_bfd));
>>> +
>>> +      if (in_implib_bfd == NULL)
>>> +    einfo ("%F%s: Can't open: %E\n", in_implib_filename);
>>> +
>>> +      if (!bfd_check_format (in_implib_bfd, bfd_object))
>>> +    einfo ("%F%s: Not a relocatable file: %E\n", in_implib_filename);
>>> +    }
>>> +  else
>>> +    in_implib_bfd = NULL;
>>> +
>>>    bfd_elf32_arm_set_target_relocs (link_info.output_bfd, &link_info,
>>>                     target1_is_rel,
>>>                     target2_type, fix_v4bx, use_blx,
>>> @@ -515,7 +532,7 @@ arm_elf_create_output_section_statements (void)
>>>                     no_enum_size_warning,
>>>                     no_wchar_size_warning,
>>>                     pic_veneer, fix_cortex_a8,
>>> -                   fix_arm1176, cmse_implib);
>>> +                   fix_arm1176, cmse_implib, in_implib_bfd);
>>>
>>>    stub_file = lang_add_input_file ("linker stubs",
>>>                      lang_input_file_is_fake_enum,
>>> @@ -585,6 +602,7 @@ PARSE_AND_LIST_PROLOGUE='
>>>  #define OPTION_LONG_PLT            319
>>>  #define OPTION_STM32L4XX_FIX        320
>>>  #define OPTION_CMSE_IMPLIB        321
>>> +#define OPTION_IN_IMPLIB        322
>>>  '
>>>
>>>  PARSE_AND_LIST_SHORTOPTS=p
>>> @@ -612,6 +630,7 @@ PARSE_AND_LIST_LONGOPTS='
>>>    { "no-fix-arm1176", no_argument, NULL, OPTION_NO_FIX_ARM1176 },
>>>    { "long-plt", no_argument, NULL, OPTION_LONG_PLT },
>>>    { "cmse-implib", no_argument, NULL, OPTION_CMSE_IMPLIB },
>>> +  { "in-implib", required_argument, NULL, OPTION_IN_IMPLIB },
>>>  '
>>>
>>>  PARSE_AND_LIST_OPTIONS='
>>> @@ -634,6 +653,8 @@ PARSE_AND_LIST_OPTIONS='
>>>             "                              to handle large .plt/.got
>>> displacements\n"));
>>>    fprintf (file, _("  --cmse-implib               Make import library
>>> to be a secure gateway import\n"
>>>                     "                                library as per
>>> ARMv8-M Security Extensions\n"));
>>> +  fprintf (file, _("  --in-implib                 Import library whose
>>> symbols address must\n"
>>> +                   "                                remain stable\n"));
>>>    fprintf (file, _("\
>>>    --stub-group-size=N         Maximum size of a group of input sections
>>> that\n\
>>>                                 can be handled by one stub section.  A
>>> negative\n\
>>> @@ -758,6 +779,10 @@ PARSE_AND_LIST_ARGS_CASES='
>>>     case OPTION_CMSE_IMPLIB:
>>>        cmse_implib = 1;
>>>        break;
>>> +
>>> +   case OPTION_IN_IMPLIB:
>>> +      in_implib_filename = optarg;
>>> +      break;
>>>  '
>>>
>>>  # We have our own before_allocation etc. functions, but they call
>>> diff --git a/ld/ld.texinfo b/ld/ld.texinfo
>>> index
>>> e6813f287fe5ce4c916bf93f48b2e9edbc336570..021385166887a2d2bd49bdba379e833b9c67d906
>>>
>>> 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.
>>>
>>> +@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 added to the output
>>> 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
>>> 55240854a24951194c8150581b8a40dd2910b5cb..24d0b4c72a91550bfa936cdbe4ab7fabbeecb6c5
>>>
>>> 100644
>>> --- a/ld/testsuite/ld-arm/arm-elf.exp
>>> +++ b/ld/testsuite/ld-arm/arm-elf.exp
>>> @@ -670,16 +670,59 @@ 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: not an SG input import
>>> library"
>>> +     "--section-start .gnu.sgstubs=0x20000
>>> --in-implib=tmpdir/cmse-implib.lib" ""
>>> +     "-march=armv8-m.base -mthumb --defsym VER=2"
>>> +     {cmse-implib.s}
>>> +     {{ld cmse-new-implib-not-sg-in-implib.out}}
>>> +     "cmse-new-implib-not-sg-in-implib"}
>>> +    {"Input secure gateway import library: earlier stub section base"
>>> +     "--section-start .gnu.sgstubs=0x19000
>>> --out-implib=tmpdir/cmse-new-earlier-implib.lib
>>> --in-implib=tmpdir/cmse-implib.lib --cmse-implib" ""
>>> +     "-march=armv8-m.base -mthumb --defsym VER=2"
>>> +     {cmse-implib.s}
>>> +     {{ld cmse-new-earlier-later-implib.out}}
>>> +     "cmse-new-earlier-implib"}
>>> +    {"Input secure gateway import library: later stub section base"
>>> +     "--section-start .gnu.sgstubs=0x30000
>>> --out-implib=tmpdir/cmse-new-later-implib.lib
>>> --in-implib=tmpdir/cmse-implib.lib --cmse-implib" ""
>>> +     "-march=armv8-m.base -mthumb --defsym VER=2"
>>> +     {cmse-implib.s}
>>> +     {{ld cmse-new-earlier-later-implib.out}}
>>> +     "cmse-new-later-implib"}
>>> +    {"Input secure gateway import library: veneer comeback"
>>> +     "--section-start .gnu.sgstubs=0x20000
>>> --out-implib=tmpdir/cmse-new-comeback-implib.lib
>>> --in-implib=tmpdir/cmse-implib.lib --cmse-implib" ""
>>> +     "-march=armv8-m.base -mthumb --defsym VER=3"
>>> +     {cmse-implib.s}
>>> +     {{readelf {-s tmpdir/cmse-new-comeback-implib.lib}
>>> cmse-new-comeback-implib.rd}}
>>> +     "cmse-new-comeback-implib"}
>>> +    {"Input secure gateway import library: entry function change"
>>> +     "--section-start .gnu.sgstubs=0x20000
>>> --out-implib=tmpdir/cmse-new-wrong-implib.lib
>>> --in-implib=tmpdir/cmse-implib.lib --cmse-implib" ""
>>> +     "-march=armv8-m.base -mthumb --defsym VER=4"
>>> +     {cmse-implib.s}
>>> +     {{ld cmse-new-wrong-implib.out}}
>>> +     "cmse-new-wrong-implib"}
>>>
>>>      {"R_ARM_THM_JUMP19 Relocation veneers: Short"
>>>       "--section-start destsect=0x000108002 --section-start
>>> .text=0x8000" ""
>>> diff --git a/ld/testsuite/ld-arm/cmse-implib.s
>>> b/ld/testsuite/ld-arm/cmse-implib.s
>>> index
>>> a42da63fffebe5322be83f278931754262b0f7ae..9dd783939891478351a5f7ccb1480980a77dca68
>>>
>>> 100644
>>> --- a/ld/testsuite/ld-arm/cmse-implib.s
>>> +++ b/ld/testsuite/ld-arm/cmse-implib.s
>>> @@ -20,12 +20,29 @@ __acle_se_\name:
>>>  .endm
>>>
>>>      @ Valid setups for veneer generation
>>> +.if (VER >= 2)
>>> +    entry exported_entry_veneer1, global
>>> +.endif
>>> +.if (VER != 4)
>>>      entry exported_entry_veneer2, global
>>> +.else
>>> +    entry exported_entry_veneer2, weak
>>> +.endif
>>> +.if (VER != 2)
>>>      entry exported_entry_veneer3, global
>>> +.endif
>>> +.if (VER > 1)
>>> +    entry exported_entry_veneer4, global
>>> +.endif
>>>
>>>      @ Valid setup for entry function without veneer generation
>>>      entry exported_entry_fct1, global, sg
>>> +.if (VER != 4)
>>>      entry exported_entry_fct2, global, sg
>>> +.else
>>> +    @ Invalid setup for entry function without veneer generation
>>> +    entry exported_entry_fct2, global, nop
>>> +.endif
>>>
>>>      @ Normal symbol not exported to SG import library
>>>      .align    2
>>> diff --git a/ld/testsuite/ld-arm/cmse-new-comeback-implib.rd
>>> b/ld/testsuite/ld-arm/cmse-new-comeback-implib.rd
>>> new file mode 100644
>>> index
>>> 0000000000000000000000000000000000000000..c88d9d5104244abc8ceba4d552e1ef0e400c37d1
>>>
>>>
>>> --- /dev/null
>>> +++ b/ld/testsuite/ld-arm/cmse-new-comeback-implib.rd
>>> @@ -0,0 +1,15 @@
>>> +File: tmpdir/cmse-new-.*implib.lib
>>> +
>>> +Symbol table '.symtab' contains 7 entries:
>>> +   Num:    Value  Size Type    Bind   Vis      Ndx Name
>>> +     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
>>> +     1: 00020001     8 FUNC    GLOBAL DEFAULT  ABS
>>> exported_entry_veneer3
>>> +     2: 00020011     8 FUNC    GLOBAL DEFAULT  ABS
>>> exported_entry_veneer4
>>> +     3: 00020019     8 FUNC    GLOBAL DEFAULT  ABS
>>> exported_entry_veneer1
>>> +     4: [0-9a-f]+     6 FUNC    GLOBAL DEFAULT  ABS exported_entry_fct1
>>> +     5: 00020009     8 FUNC    GLOBAL DEFAULT  ABS
>>> exported_entry_veneer2
>>> +     6: [0-9a-f]+     6 FUNC    GLOBAL DEFAULT  ABS exported_entry_fct2
>>> +
>>> +File: tmpdir/cmse-new-.*implib
>>> +
>>> +#...
>>> diff --git a/ld/testsuite/ld-arm/cmse-new-earlier-later-implib.out
>>> b/ld/testsuite/ld-arm/cmse-new-earlier-later-implib.out
>>> new file mode 100644
>>> index
>>> 0000000000000000000000000000000000000000..b49ad0ac0770a17c39c2d119d1f0c5854a5bd8cc
>>>
>>>
>>> --- /dev/null
>>> +++ b/ld/testsuite/ld-arm/cmse-new-earlier-later-implib.out
>>> @@ -0,0 +1,3 @@
>>> +.*: Entry function `exported_entry_veneer3' disappeared from secure
>>> code.
>>> +.*: Start address of `.gnu.sgstubs' is different from previous link.
>>> +.*: cannot size stub section: Invalid operation
>>> diff --git a/ld/testsuite/ld-arm/cmse-new-implib-no-output.out
>>> b/ld/testsuite/ld-arm/cmse-new-implib-no-output.out
>>> new file mode 100644
>>> index
>>> 0000000000000000000000000000000000000000..0590b71c844da3687b29b93797abda5172ab8d99
>>>
>>>
>>> --- /dev/null
>>> +++ b/ld/testsuite/ld-arm/cmse-new-implib-no-output.out
>>> @@ -0,0 +1,4 @@
>>> +.*: Entry function `exported_entry_veneer3' disappeared from secure
>>> code.
>>> +.*: new entry function\(s\) introduced but no output import library
>>> specified:
>>> +.*:   exported_entry_veneer4
>>> +.*:   exported_entry_veneer1
>>> diff --git a/ld/testsuite/ld-arm/cmse-new-implib-not-sg-in-implib.out
>>> b/ld/testsuite/ld-arm/cmse-new-implib-not-sg-in-implib.out
>>> new file mode 100644
>>> index
>>> 0000000000000000000000000000000000000000..c93c3fb97895286e05026b6eac696fa9de6c89f9
>>>
>>>
>>> --- /dev/null
>>> +++ b/ld/testsuite/ld-arm/cmse-new-implib-not-sg-in-implib.out
>>> @@ -0,0 +1,2 @@
>>> +.*: --in-implib only supported for Secure Gateway import libraries.
>>> +.*: cannot size stub section: Invalid operation
>>> diff --git a/ld/testsuite/ld-arm/cmse-new-implib.out
>>> b/ld/testsuite/ld-arm/cmse-new-implib.out
>>> new file mode 100644
>>> index
>>> 0000000000000000000000000000000000000000..c8af2807e7c1a7eeb1fc156fbf4508cf7a7e932d
>>>
>>>
>>> --- /dev/null
>>> +++ b/ld/testsuite/ld-arm/cmse-new-implib.out
>>> @@ -0,0 +1 @@
>>> +.*: Entry function `exported_entry_veneer3' disappeared from secure
>>> code.
>>> diff --git a/ld/testsuite/ld-arm/cmse-new-implib.rd
>>> b/ld/testsuite/ld-arm/cmse-new-implib.rd
>>> new file mode 100644
>>> index
>>> 0000000000000000000000000000000000000000..9ff0fd87937571f86f99ee940a91a3f67352242a
>>>
>>>
>>> --- /dev/null
>>> +++ b/ld/testsuite/ld-arm/cmse-new-implib.rd
>>> @@ -0,0 +1,14 @@
>>> +File: tmpdir/cmse-new-.*implib.lib
>>> +
>>> +Symbol table '.symtab' contains 6 entries:
>>> +   Num:    Value  Size Type    Bind   Vis      Ndx Name
>>> +     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
>>> +     1: 00020011     8 FUNC    GLOBAL DEFAULT  ABS
>>> exported_entry_veneer4
>>> +     2: 00020019     8 FUNC    GLOBAL DEFAULT  ABS
>>> exported_entry_veneer1
>>> +     3: [0-9a-f]+     6 FUNC    GLOBAL DEFAULT  ABS exported_entry_fct1
>>> +     4: 00020009     8 FUNC    GLOBAL DEFAULT  ABS
>>> exported_entry_veneer2
>>> +     5: [0-9a-f]+     6 FUNC    GLOBAL DEFAULT  ABS exported_entry_fct2
>>> +
>>> +File: tmpdir/cmse-new-.*implib
>>> +
>>> +#...
>>> diff --git a/ld/testsuite/ld-arm/cmse-new-wrong-implib.out
>>> b/ld/testsuite/ld-arm/cmse-new-wrong-implib.out
>>> new file mode 100644
>>> index
>>> 0000000000000000000000000000000000000000..2afe4078e78606d24f05dda6ff1c5e6a54d42512
>>>
>>>
>>> --- /dev/null
>>> +++ b/ld/testsuite/ld-arm/cmse-new-wrong-implib.out
>>> @@ -0,0 +1,3 @@
>>> +.*: .*: visibility of symbol `exported_entry_veneer2' has changed.
>>> +.*: `exported_entry_fct2' refers to a non entry function.
>>> +.*: cannot size stub section: Invalid operation
>>>
>>>
>>> On 17/08/16 16:12, Thomas Preudhomme wrote:
>>>> Ping?
>>>>
>>>> Best regards,
>>>>
>>>> Thomas
>>>>
>>>> On 05/08/16 09:47, Thomas Preudhomme wrote:
>>>>> Hi Richard,
>>>>>
>>>>> Sorry for the delay, got caught on other things. Please find an
>>>>> updated patch
>>>>> in attachment. All but one of your comments have been addressed,
>>>>> comment below
>>>>> on that one.
>>>>>
>>>>> Updated ChangeLog entries are as follow:
>>>>>
>>>>> *** 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-07-15  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.
>>>>>         * NEWS: Likewise.
>>>>>         * 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: not an SG input 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-implib-not-sg-in-implib.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.
>>>>>
>>>>> On Thursday 07 July 2016 13:52:00 you 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..423c534a954c541e227e731e9256f08f
>>>>>>>
>>>>>>>
>>>>>>> 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..3a67fa637f5c709cddf3767496e4ac87
>>>>>>>
>>>>>>>
>>>>>>> 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...
>>>>>
>>>>> Ok. I did a separate patch for this as I felt this was an independent
>>>>> change
>>>>> and would have made the patch even bigger. I'll post it soon.
>>>>>
>>>>> Best regards,
>>>>>
>>>>> Thomas
>>>>>
>>
> 


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