initial support for aarch64 little endian (#318)
authorNick Desaulniers <nickdesaulniers@users.noreply.github.com>
Tue, 9 Jun 2020 12:53:08 +0000 (05:53 -0700)
committerGitHub <noreply@github.com>
Tue, 9 Jun 2020 12:53:08 +0000 (05:53 -0700)
See also:
https://static.docs.arm.com/ihi0056/b/IHI0056B_aaelf64.pdf
for relocation types and
https://developer.arm.com/docs/ihi0057/c/dwarf-for-the-arm-64-bit-architecture-aarch64-abi-2018q4
for DWARF register names.

Issue #317
Link: https://github.com/ClangBuiltLinux/frame-larger-than/issues/4
Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
elftools/dwarf/descriptions.py
elftools/elf/relocation.py
test/testfiles_for_readelf/aarch64-relocs-le.o.elf [new file with mode: 0644]
test/testfiles_for_readelf/aarch64-relocs.c [new file with mode: 0644]

index c3fa0788df96aab5073706b4d9d96d04f72c1680..e5c8c26bfcf69de552be3ef22fb1c284c4f3e40c 100644 (file)
@@ -159,6 +159,8 @@ def describe_reg_name(regnum, machine_arch=None, default=True):
         return _REG_NAMES_x86[regnum]
     elif machine_arch == 'x64':
         return _REG_NAMES_x64[regnum]
+    elif machine_arch == 'AArch64':
+        return _REG_NAMES_AArch64[regnum]
     elif default:
         return 'r%s' % regnum
     else:
@@ -528,6 +530,14 @@ _REG_NAMES_x64 = [
     'mxcsr', 'fcw', 'fsw'
 ]
 
+# https://developer.arm.com/docs/ihi0057/c/dwarf-for-the-arm-64-bit-architecture-aarch64-abi-2018q4#id24
+_REG_NAMES_AArch64 = [
+    'x0', 'x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7', 'x8', 'x9',
+    'x10', 'x11', 'x12', 'x13', 'x14', 'x15', 'x16', 'x17', 'x18', 'x19',
+    'x20', 'x21', 'x22', 'x23', 'x24', 'x25', 'x26', 'x27', 'x28', 'x29',
+    'x30', 'sp'
+]
+
 
 class ExprDumper(object):
     """ A dumper for DWARF expressions that dumps a textual
index be0316532f38fad1fdbbb7d9bbae6067474e91c9..427a56f41856af9f4568dac2a3913f4b9f84eb0d 100644 (file)
@@ -12,7 +12,8 @@ from ..common.exceptions import ELFRelocationError
 from ..common.utils import elf_assert, struct_parse
 from .sections import Section
 from .enums import (
-    ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64, ENUM_RELOC_TYPE_MIPS, ENUM_RELOC_TYPE_ARM, ENUM_D_TAG)
+    ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64, ENUM_RELOC_TYPE_MIPS,
+    ENUM_RELOC_TYPE_ARM, ENUM_RELOC_TYPE_AARCH64, ENUM_D_TAG)
 
 
 class Relocation(object):
@@ -172,6 +173,8 @@ class RelocationHandler(object):
                 raise ELFRelocationError(
                     'Unexpected RELA relocation for ARM: %s' % reloc)
             recipe = self._RELOCATION_RECIPES_ARM.get(reloc_type, None)
+        elif self.elffile.get_machine_arch() == 'AArch64':
+            recipe = self._RELOCATION_RECIPES_AARCH64.get(reloc_type, None)
 
         if recipe is None:
             raise ELFRelocationError(
@@ -247,6 +250,16 @@ class RelocationHandler(object):
             calc_func=_arm_reloc_calc_sym_plus_value_pcrel),
     }
 
+    _RELOCATION_RECIPES_AARCH64 = {
+        ENUM_RELOC_TYPE_AARCH64['R_AARCH64_ABS64']: _RELOCATION_RECIPE_TYPE(
+            bytesize=8, has_addend=True, calc_func=_reloc_calc_sym_plus_addend),
+        ENUM_RELOC_TYPE_AARCH64['R_AARCH64_ABS32']: _RELOCATION_RECIPE_TYPE(
+            bytesize=4, has_addend=True, calc_func=_reloc_calc_sym_plus_addend),
+        ENUM_RELOC_TYPE_AARCH64['R_AARCH64_PREL32']: _RELOCATION_RECIPE_TYPE(
+            bytesize=4, has_addend=True,
+            calc_func=_reloc_calc_sym_plus_addend_pcrel),
+    }
+
     # https://dmz-portal.mips.com/wiki/MIPS_relocation_types
     _RELOCATION_RECIPES_MIPS = {
         ENUM_RELOC_TYPE_MIPS['R_MIPS_NONE']: _RELOCATION_RECIPE_TYPE(
diff --git a/test/testfiles_for_readelf/aarch64-relocs-le.o.elf b/test/testfiles_for_readelf/aarch64-relocs-le.o.elf
new file mode 100644 (file)
index 0000000..3f74d22
Binary files /dev/null and b/test/testfiles_for_readelf/aarch64-relocs-le.o.elf differ
diff --git a/test/testfiles_for_readelf/aarch64-relocs.c b/test/testfiles_for_readelf/aarch64-relocs.c
new file mode 100644 (file)
index 0000000..c78a562
--- /dev/null
@@ -0,0 +1,16 @@
+/* This source was compiled for aarch64 (little endian).
+   aarch64-linux-gnu-gcc -c -o aarch64-relocs-le.o.elf aarch64-relocs.c -g
+*/
+
+extern struct {
+  int i, j;
+} data;
+
+extern int bar (void);
+
+int
+foo (int a)
+{
+  data.i += a;
+  data.j -= bar();
+}