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: [Patch, AArch64, LD/BFD] Cortex-A53 Erratum 835769 -- LD segfaults with unordered maps.


On 21/11/14 12:45, Tejas Belagod wrote:
> Hi,
> 
> The BFD/LD patch for Cortex-A53 erratum 
> 835769(https://sourceware.org/ml/binutils/2014-10/msg00199.html) does 
> not handle a particular case of the AArch64 ELF ABI where mapping 
> symbols are allowed to be unordered in the symbol table(not in address 
> order). The unordering causes section maps to be traversed with 
> incorrect span boundaries(in the erratum scanning function) which causes 
> memory faults. The attached patch fixes this issue by ordering the 
> section maps by their 'vma' before starting to traverse them.
> 
> While this is not an issue with a the GNU toolchain, it is a potential 
> issue with Clang/LLVM. We have observed atleast one case where LLVM 
> generates an ELF object with mapping symbols unordered in the symbol 
> table and causes a fault. We have been unable to construct a test case 
> with the GNU toolchain. We have verified by manual inspection the 
> correctness of the traversal with this patch for an LLVM-generated ELF 
> object which triggered this issue. This patch has been bootstrapped on 
> aarch64-linux and regressed.
> 
> OK for trunk, 2.24 and 2.25?
> 
> Thanks,
> Tejas.
> 
> Changelog:
> 
> 2014-11-21  Tejas Belagod  <tejas.belagod@arm.com>
> 
> 	* elfnn-aarch64.c (erratum_835769_scan): Sort map list.
> 	(elf_aarch64_compare_mapping): New.
> 

OK.

R.

> 
> a_53-erratum-224-8-1.txt
> 
> 
> diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
> index 9fc734f..b9952d2 100644
> --- a/bfd/elfnn-aarch64.c
> +++ b/bfd/elfnn-aarch64.c
> @@ -2936,6 +2936,29 @@ aarch64_erratum_sequence (uint32_t insn_1, uint32_t insn_2)
>    return FALSE;
>  }
>  
> +/* Used to order a list of mapping symbols by address.  */
> +
> +static int
> +elf_aarch64_compare_mapping (const void *a, const void *b)
> +{
> +  const elf_aarch64_section_map *amap = (const elf_aarch64_section_map *) a;
> +  const elf_aarch64_section_map *bmap = (const elf_aarch64_section_map *) b;
> +
> +  if (amap->vma > bmap->vma)
> +    return 1;
> +  else if (amap->vma < bmap->vma)
> +    return -1;
> +  else if (amap->type > bmap->type)
> +    /* Ensure results do not depend on the host qsort for objects with
> +       multiple mapping symbols at the same address by sorting on type
> +       after vma.  */
> +    return 1;
> +  else if (amap->type < bmap->type)
> +    return -1;
> +  else
> +    return 0;
> +}
> +
>  static bfd_boolean
>  erratum_835769_scan (bfd *input_bfd,
>  		     struct bfd_link_info *info,
> @@ -2973,6 +2996,10 @@ erratum_835769_scan (bfd *input_bfd,
>  	return TRUE;
>  
>        sec_data = elf_aarch64_section_data (section);
> +
> +      qsort (sec_data->map, sec_data->mapcount,
> +	     sizeof (elf_aarch64_section_map), elf_aarch64_compare_mapping);
> +
>        for (span = 0; span < sec_data->mapcount; span++)
>  	{
>  	  unsigned int span_start = sec_data->map[span].vma;
> 



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