add reloc type and recipe for eBPF (#466)
authorFlier Lu <flier@users.noreply.github.com>
Mon, 17 Apr 2023 15:12:43 +0000 (23:12 +0800)
committerGitHub <noreply@github.com>
Mon, 17 Apr 2023 15:12:43 +0000 (08:12 -0700)
elftools/elf/enums.py
elftools/elf/relocation.py

index 6bcd4bb8a12d920f296fe03977bd4aee1258a965..c068a613b27cc84edc2373772c4d2859cf330d85 100644 (file)
@@ -820,6 +820,16 @@ ENUM_RELOC_TYPE_x64 = dict(
     _default_=Pass,
 )
 
+ENUM_RELOC_TYPE_BPF = dict(
+    R_BPF_NONE=0,
+    R_BPF_64_64=1,
+    R_BPF_64_ABS64=2,
+    R_BPF_64_ABS32=3,
+    R_BPF_64_NODYLD32=4,
+    R_BPF_64_32=10,
+    _default_=Pass,
+)
+
 # Sunw Syminfo Bound To special values
 ENUM_SUNW_SYMINFO_BOUNDTO = dict(
     SYMINFO_BT_SELF=0xffff,
index 4008e282960f39c45120beffb350f4c4ae861a55..0c4e754c790fb183dd41738e0c4a3c7157f358d9 100644 (file)
@@ -14,7 +14,7 @@ from .sections import Section
 from .enums import (
     ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64, ENUM_RELOC_TYPE_MIPS,
     ENUM_RELOC_TYPE_ARM, ENUM_RELOC_TYPE_AARCH64, ENUM_RELOC_TYPE_PPC64,
-    ENUM_D_TAG)
+    ENUM_RELOC_TYPE_BPF, ENUM_D_TAG)
 from ..construct import Container
 
 
@@ -253,6 +253,8 @@ class RelocationHandler(object):
             recipe = self._RELOCATION_RECIPES_AARCH64.get(reloc_type, None)
         elif self.elffile.get_machine_arch() == '64-bit PowerPC':
             recipe = self._RELOCATION_RECIPES_PPC64.get(reloc_type, None)
+        elif self.elffile.get_machine_arch() == 'Linux BPF - in-kernel virtual machine':
+            recipe = self._RELOCATION_RECIPES_EBPF.get(reloc_type, None)
 
         if recipe is None:
             raise ELFRelocationError(
@@ -319,6 +321,9 @@ class RelocationHandler(object):
     def _arm_reloc_calc_sym_plus_value_pcrel(value, sym_value, offset, addend=0):
         return sym_value // 4 + value - offset // 4
 
+    def _bpf_64_32_reloc_calc_sym_plus_addend(value, sym_value, offset, addend=0):
+        return (sym_value + addend) // 8 - 1
+
     _RELOCATION_RECIPES_ARM = {
         ENUM_RELOC_TYPE_ARM['R_ARM_ABS32']: _RELOCATION_RECIPE_TYPE(
             bytesize=4, has_addend=False,
@@ -381,4 +386,20 @@ class RelocationHandler(object):
             bytesize=4, has_addend=True, calc_func=_reloc_calc_sym_plus_addend),
     }
 
+    # https://www.kernel.org/doc/html/latest/bpf/llvm_reloc.html#different-relocation-types
+    _RELOCATION_RECIPES_EBPF = {
+        ENUM_RELOC_TYPE_BPF['R_BPF_NONE']: _RELOCATION_RECIPE_TYPE(
+            bytesize=8, has_addend=False, calc_func=_reloc_calc_identity),
+        ENUM_RELOC_TYPE_BPF['R_BPF_64_64']: _RELOCATION_RECIPE_TYPE(
+            bytesize=8, has_addend=False, calc_func=_reloc_calc_identity),
+        ENUM_RELOC_TYPE_BPF['R_BPF_64_32']: _RELOCATION_RECIPE_TYPE(
+            bytesize=8, has_addend=False, calc_func=_bpf_64_32_reloc_calc_sym_plus_addend),
+        ENUM_RELOC_TYPE_BPF['R_BPF_64_NODYLD32']: _RELOCATION_RECIPE_TYPE(
+            bytesize=4, has_addend=False, calc_func=_reloc_calc_identity),
+        ENUM_RELOC_TYPE_BPF['R_BPF_64_ABS64']: _RELOCATION_RECIPE_TYPE(
+            bytesize=8, has_addend=False, calc_func=_reloc_calc_identity),
+        ENUM_RELOC_TYPE_BPF['R_BPF_64_ABS32']: _RELOCATION_RECIPE_TYPE(
+            bytesize=4, has_addend=False, calc_func=_reloc_calc_identity),
+    }
+