[Patch, AArch64, LD/BFD] Cortex-A53 Erratum 835769 -- LD segfaults with unordered maps.

Tejas Belagod tejas.belagod@arm.com
Fri Nov 21 12:44:00 GMT 2014


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.
-------------- next part --------------
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;


More information about the Binutils mailing list