This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [Patch, AArch64, LD/BFD] Cortex-A53 Erratum 835769 -- LD segfaults with unordered maps.
- From: Richard Earnshaw <rearnsha at arm dot com>
- To: Tejas Belagod <tejas dot belagod at arm dot com>, "binutils at sourceware dot org" <binutils at sourceware dot org>
- Cc: Marcus Shawcroft <Marcus dot Shawcroft at arm dot com>
- Date: Fri, 21 Nov 2014 13:39:58 +0000
- Subject: Re: [Patch, AArch64, LD/BFD] Cortex-A53 Erratum 835769 -- LD segfaults with unordered maps.
- Authentication-results: sourceware.org; auth=none
- References: <546F33D6 dot 9000806 at arm dot com>
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;
>