smallworld-re 1.0.2__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- smallworld/analyses/__init__.py +8 -0
- smallworld/analyses/analysis.py +8 -67
- smallworld/analyses/code_coverage.py +1 -2
- smallworld/analyses/colorizer.py +301 -534
- smallworld/analyses/colorizer_def_use.py +217 -0
- smallworld/analyses/colorizer_summary.py +173 -83
- smallworld/analyses/field_detection/field_analysis.py +7 -8
- smallworld/analyses/field_detection/hints.py +1 -1
- smallworld/analyses/field_detection/malloc.py +2 -2
- smallworld/analyses/trace_execution.py +160 -0
- smallworld/analyses/trace_execution_types.py +42 -0
- smallworld/analyses/unstable/angr/divergence.py +1 -2
- smallworld/analyses/unstable/angr/model.py +5 -6
- smallworld/analyses/unstable/angr_nwbt.py +3 -4
- smallworld/analyses/unstable/code_coverage.py +2 -3
- smallworld/analyses/unstable/code_reachable.py +2 -3
- smallworld/analyses/unstable/control_flow_tracer.py +2 -3
- smallworld/analyses/unstable/pointer_finder.py +2 -3
- smallworld/analyses/unstable/utils/tui.py +71 -0
- smallworld/emulators/__init__.py +3 -1
- smallworld/emulators/angr/angr.py +30 -9
- smallworld/emulators/angr/machdefs/__init__.py +2 -0
- smallworld/emulators/angr/machdefs/aarch64.py +1 -1
- smallworld/emulators/angr/machdefs/amd64.py +0 -4
- smallworld/emulators/angr/machdefs/arm.py +0 -2
- smallworld/emulators/angr/machdefs/i386.py +0 -2
- smallworld/emulators/angr/machdefs/loongarch.py +340 -0
- smallworld/emulators/angr/machdefs/machdef.py +1 -8
- smallworld/emulators/angr/machdefs/mips.py +0 -2
- smallworld/emulators/angr/machdefs/mips64.py +0 -2
- smallworld/emulators/angr/machdefs/ppc.py +1 -2
- smallworld/emulators/angr/machdefs/riscv.py +8 -10
- smallworld/emulators/angr/machdefs/xtensa.py +7 -4
- smallworld/emulators/emulator.py +22 -0
- smallworld/emulators/ghidra/__init__.py +37 -0
- smallworld/emulators/ghidra/ghidra.py +513 -0
- smallworld/emulators/ghidra/machdefs/__init__.py +31 -0
- smallworld/emulators/ghidra/machdefs/aarch64.py +289 -0
- smallworld/emulators/ghidra/machdefs/amd64.py +185 -0
- smallworld/emulators/ghidra/machdefs/arm.py +370 -0
- smallworld/emulators/ghidra/machdefs/i386.py +109 -0
- smallworld/emulators/ghidra/machdefs/loongarch.py +162 -0
- smallworld/emulators/ghidra/machdefs/machdef.py +81 -0
- smallworld/emulators/ghidra/machdefs/mips.py +163 -0
- smallworld/emulators/ghidra/machdefs/mips64.py +186 -0
- smallworld/emulators/ghidra/machdefs/ppc.py +98 -0
- smallworld/emulators/ghidra/machdefs/riscv.py +208 -0
- smallworld/emulators/ghidra/machdefs/xtensa.py +21 -0
- smallworld/emulators/ghidra/typing.py +28 -0
- smallworld/emulators/hookable.py +18 -4
- smallworld/emulators/panda/machdefs/__init__.py +2 -2
- smallworld/emulators/panda/machdefs/aarch64.py +186 -11
- smallworld/emulators/panda/machdefs/amd64.py +103 -11
- smallworld/emulators/panda/machdefs/arm.py +216 -20
- smallworld/emulators/panda/machdefs/i386.py +30 -7
- smallworld/emulators/panda/machdefs/machdef.py +9 -16
- smallworld/emulators/panda/machdefs/mips.py +49 -5
- smallworld/emulators/panda/machdefs/mips64.py +57 -5
- smallworld/emulators/panda/machdefs/ppc.py +38 -13
- smallworld/emulators/panda/panda.py +146 -44
- smallworld/emulators/unicorn/__init__.py +2 -0
- smallworld/emulators/unicorn/machdefs/aarch64.py +253 -264
- smallworld/emulators/unicorn/machdefs/amd64.py +254 -259
- smallworld/emulators/unicorn/machdefs/arm.py +200 -212
- smallworld/emulators/unicorn/machdefs/i386.py +84 -90
- smallworld/emulators/unicorn/machdefs/machdef.py +2 -23
- smallworld/emulators/unicorn/machdefs/mips.py +127 -135
- smallworld/emulators/unicorn/unicorn.py +52 -13
- smallworld/helpers.py +4 -19
- smallworld/hinting/hinting.py +22 -192
- smallworld/hinting/hints.py +50 -18
- smallworld/instructions/bsid.py +8 -8
- smallworld/logging.py +4 -2
- smallworld/platforms/__init__.py +12 -0
- smallworld/platforms/defs/__init__.py +36 -0
- smallworld/platforms/defs/aarch64.py +450 -0
- smallworld/platforms/defs/amd64.py +463 -0
- smallworld/platforms/defs/arm.py +519 -0
- smallworld/platforms/defs/i386.py +258 -0
- smallworld/platforms/defs/loongarch.py +270 -0
- smallworld/platforms/defs/mips.py +321 -0
- smallworld/platforms/defs/mips64.py +313 -0
- smallworld/platforms/defs/platformdef.py +97 -0
- smallworld/platforms/defs/powerpc.py +259 -0
- smallworld/platforms/defs/riscv.py +257 -0
- smallworld/platforms/defs/xtensa.py +96 -0
- smallworld/{platforms.py → platforms/platforms.py} +3 -0
- smallworld/state/cpus/__init__.py +2 -0
- smallworld/state/cpus/aarch64.py +0 -9
- smallworld/state/cpus/amd64.py +6 -28
- smallworld/state/cpus/arm.py +0 -11
- smallworld/state/cpus/cpu.py +0 -11
- smallworld/state/cpus/i386.py +0 -7
- smallworld/state/cpus/loongarch.py +299 -0
- smallworld/state/cpus/mips.py +4 -47
- smallworld/state/cpus/mips64.py +18 -58
- smallworld/state/cpus/powerpc.py +2 -9
- smallworld/state/cpus/riscv.py +1 -11
- smallworld/state/cpus/xtensa.py +0 -5
- smallworld/state/memory/code.py +44 -2
- smallworld/state/memory/elf/__init__.py +5 -1
- smallworld/state/memory/elf/coredump/__init__.py +3 -0
- smallworld/state/memory/elf/coredump/coredump.py +46 -0
- smallworld/state/memory/elf/coredump/prstatus/__init__.py +27 -0
- smallworld/state/memory/elf/coredump/prstatus/aarch64.py +46 -0
- smallworld/state/memory/elf/coredump/prstatus/amd64.py +40 -0
- smallworld/state/memory/elf/coredump/prstatus/arm.py +53 -0
- smallworld/state/memory/elf/coredump/prstatus/i386.py +30 -0
- smallworld/state/memory/elf/coredump/prstatus/mips.py +55 -0
- smallworld/state/memory/elf/coredump/prstatus/mips64.py +57 -0
- smallworld/state/memory/elf/coredump/prstatus/ppc.py +82 -0
- smallworld/state/memory/elf/coredump/prstatus/prstatus.py +129 -0
- smallworld/state/memory/elf/elf.py +225 -61
- smallworld/state/memory/elf/register_state.py +36 -0
- smallworld/state/memory/elf/rela/__init__.py +2 -0
- smallworld/state/memory/elf/rela/aarch64.py +3 -1
- smallworld/state/memory/elf/rela/amd64.py +4 -2
- smallworld/state/memory/elf/rela/arm.py +4 -2
- smallworld/state/memory/elf/rela/i386.py +4 -2
- smallworld/state/memory/elf/rela/loongarch.py +32 -0
- smallworld/state/memory/elf/rela/mips.py +39 -18
- smallworld/state/memory/elf/rela/ppc.py +31 -14
- smallworld/state/memory/elf/structs.py +3 -0
- smallworld/state/memory/heap.py +2 -2
- smallworld/state/memory/memory.py +18 -0
- smallworld/state/memory/pe/__init__.py +3 -0
- smallworld/state/memory/pe/pe.py +361 -0
- smallworld/state/memory/pe/structs.py +60 -0
- smallworld/state/memory/stack/__init__.py +2 -0
- smallworld/state/memory/stack/loongarch.py +26 -0
- smallworld/state/models/__init__.py +29 -2
- smallworld/state/models/aarch64/__init__.py +1 -0
- smallworld/state/models/aarch64/systemv/__init__.py +6 -0
- smallworld/state/models/aarch64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/aarch64/systemv/c99/signal.py +16 -0
- smallworld/state/models/aarch64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/aarch64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/aarch64/systemv/c99/string.py +139 -0
- smallworld/state/models/aarch64/systemv/c99/time.py +61 -0
- smallworld/state/models/aarch64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/aarch64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/aarch64/systemv/posix/signal.py +157 -0
- smallworld/state/models/aarch64/systemv/systemv.py +80 -0
- smallworld/state/models/amd64/__init__.py +1 -0
- smallworld/state/models/amd64/systemv/__init__.py +6 -0
- smallworld/state/models/amd64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/amd64/systemv/c99/signal.py +16 -0
- smallworld/state/models/amd64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/amd64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/amd64/systemv/c99/string.py +139 -0
- smallworld/state/models/amd64/systemv/c99/time.py +61 -0
- smallworld/state/models/amd64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/amd64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/amd64/systemv/posix/signal.py +157 -0
- smallworld/state/models/amd64/systemv/systemv.py +78 -0
- smallworld/state/models/armel/__init__.py +1 -0
- smallworld/state/models/armel/systemv/__init__.py +6 -0
- smallworld/state/models/armel/systemv/c99/__init__.py +12 -0
- smallworld/state/models/armel/systemv/c99/signal.py +16 -0
- smallworld/state/models/armel/systemv/c99/stdio.py +265 -0
- smallworld/state/models/armel/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/armel/systemv/c99/string.py +139 -0
- smallworld/state/models/armel/systemv/c99/time.py +61 -0
- smallworld/state/models/armel/systemv/posix/__init__.py +6 -0
- smallworld/state/models/armel/systemv/posix/libgen.py +16 -0
- smallworld/state/models/armel/systemv/posix/signal.py +157 -0
- smallworld/state/models/armel/systemv/systemv.py +82 -0
- smallworld/state/models/armhf/__init__.py +1 -0
- smallworld/state/models/armhf/systemv/__init__.py +6 -0
- smallworld/state/models/armhf/systemv/c99/__init__.py +12 -0
- smallworld/state/models/armhf/systemv/c99/signal.py +16 -0
- smallworld/state/models/armhf/systemv/c99/stdio.py +265 -0
- smallworld/state/models/armhf/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/armhf/systemv/c99/string.py +139 -0
- smallworld/state/models/armhf/systemv/c99/time.py +61 -0
- smallworld/state/models/armhf/systemv/posix/__init__.py +6 -0
- smallworld/state/models/armhf/systemv/posix/libgen.py +16 -0
- smallworld/state/models/armhf/systemv/posix/signal.py +157 -0
- smallworld/state/models/armhf/systemv/systemv.py +77 -0
- smallworld/state/models/c99/__init__.py +12 -0
- smallworld/state/models/c99/fmt_print.py +915 -0
- smallworld/state/models/c99/fmt_scan.py +864 -0
- smallworld/state/models/c99/math.py +362 -0
- smallworld/state/models/c99/signal.py +71 -0
- smallworld/state/models/c99/stdio.py +1305 -0
- smallworld/state/models/c99/stdlib.py +595 -0
- smallworld/state/models/c99/string.py +674 -0
- smallworld/state/models/c99/time.py +340 -0
- smallworld/state/models/c99/utils.py +89 -0
- smallworld/state/models/cstd.py +759 -0
- smallworld/state/models/errno.py +581 -0
- smallworld/state/models/filedesc.py +515 -0
- smallworld/state/models/i386/__init__.py +1 -0
- smallworld/state/models/i386/systemv/__init__.py +6 -0
- smallworld/state/models/i386/systemv/c99/__init__.py +12 -0
- smallworld/state/models/i386/systemv/c99/signal.py +16 -0
- smallworld/state/models/i386/systemv/c99/stdio.py +265 -0
- smallworld/state/models/i386/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/i386/systemv/c99/string.py +139 -0
- smallworld/state/models/i386/systemv/c99/time.py +61 -0
- smallworld/state/models/i386/systemv/posix/__init__.py +6 -0
- smallworld/state/models/i386/systemv/posix/libgen.py +16 -0
- smallworld/state/models/i386/systemv/posix/signal.py +157 -0
- smallworld/state/models/i386/systemv/systemv.py +71 -0
- smallworld/state/models/loongarch64/__init__.py +1 -0
- smallworld/state/models/loongarch64/systemv/__init__.py +6 -0
- smallworld/state/models/loongarch64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/loongarch64/systemv/c99/signal.py +16 -0
- smallworld/state/models/loongarch64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/loongarch64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/loongarch64/systemv/c99/string.py +139 -0
- smallworld/state/models/loongarch64/systemv/c99/time.py +61 -0
- smallworld/state/models/loongarch64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/loongarch64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/loongarch64/systemv/posix/signal.py +157 -0
- smallworld/state/models/loongarch64/systemv/systemv.py +83 -0
- smallworld/state/models/mips/__init__.py +1 -0
- smallworld/state/models/mips/systemv/__init__.py +6 -0
- smallworld/state/models/mips/systemv/c99/__init__.py +12 -0
- smallworld/state/models/mips/systemv/c99/signal.py +16 -0
- smallworld/state/models/mips/systemv/c99/stdio.py +265 -0
- smallworld/state/models/mips/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/mips/systemv/c99/string.py +139 -0
- smallworld/state/models/mips/systemv/c99/time.py +61 -0
- smallworld/state/models/mips/systemv/posix/__init__.py +6 -0
- smallworld/state/models/mips/systemv/posix/libgen.py +16 -0
- smallworld/state/models/mips/systemv/posix/signal.py +157 -0
- smallworld/state/models/mips/systemv/systemv.py +78 -0
- smallworld/state/models/mips64/__init__.py +1 -0
- smallworld/state/models/mips64/systemv/__init__.py +6 -0
- smallworld/state/models/mips64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/mips64/systemv/c99/signal.py +16 -0
- smallworld/state/models/mips64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/mips64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/mips64/systemv/c99/string.py +139 -0
- smallworld/state/models/mips64/systemv/c99/time.py +61 -0
- smallworld/state/models/mips64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/mips64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/mips64/systemv/posix/signal.py +157 -0
- smallworld/state/models/mips64/systemv/systemv.py +98 -0
- smallworld/state/models/mips64el/__init__.py +1 -0
- smallworld/state/models/mips64el/systemv/__init__.py +6 -0
- smallworld/state/models/mips64el/systemv/c99/__init__.py +12 -0
- smallworld/state/models/mips64el/systemv/c99/signal.py +16 -0
- smallworld/state/models/mips64el/systemv/c99/stdio.py +265 -0
- smallworld/state/models/mips64el/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/mips64el/systemv/c99/string.py +139 -0
- smallworld/state/models/mips64el/systemv/c99/time.py +61 -0
- smallworld/state/models/mips64el/systemv/posix/__init__.py +6 -0
- smallworld/state/models/mips64el/systemv/posix/libgen.py +16 -0
- smallworld/state/models/mips64el/systemv/posix/signal.py +157 -0
- smallworld/state/models/mips64el/systemv/systemv.py +96 -0
- smallworld/state/models/mipsel/__init__.py +1 -0
- smallworld/state/models/mipsel/systemv/__init__.py +6 -0
- smallworld/state/models/mipsel/systemv/c99/__init__.py +12 -0
- smallworld/state/models/mipsel/systemv/c99/signal.py +16 -0
- smallworld/state/models/mipsel/systemv/c99/stdio.py +265 -0
- smallworld/state/models/mipsel/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/mipsel/systemv/c99/string.py +139 -0
- smallworld/state/models/mipsel/systemv/c99/time.py +61 -0
- smallworld/state/models/mipsel/systemv/posix/__init__.py +6 -0
- smallworld/state/models/mipsel/systemv/posix/libgen.py +16 -0
- smallworld/state/models/mipsel/systemv/posix/signal.py +157 -0
- smallworld/state/models/mipsel/systemv/systemv.py +78 -0
- smallworld/state/models/model.py +27 -2
- smallworld/state/models/posix/__init__.py +6 -0
- smallworld/state/models/posix/libgen.py +123 -0
- smallworld/state/models/posix/signal.py +690 -0
- smallworld/state/models/powerpc/__init__.py +1 -0
- smallworld/state/models/powerpc/systemv/__init__.py +6 -0
- smallworld/state/models/powerpc/systemv/c99/__init__.py +12 -0
- smallworld/state/models/powerpc/systemv/c99/signal.py +16 -0
- smallworld/state/models/powerpc/systemv/c99/stdio.py +265 -0
- smallworld/state/models/powerpc/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/powerpc/systemv/c99/string.py +139 -0
- smallworld/state/models/powerpc/systemv/c99/time.py +61 -0
- smallworld/state/models/powerpc/systemv/posix/__init__.py +6 -0
- smallworld/state/models/powerpc/systemv/posix/libgen.py +16 -0
- smallworld/state/models/powerpc/systemv/posix/signal.py +157 -0
- smallworld/state/models/powerpc/systemv/systemv.py +93 -0
- smallworld/state/models/riscv64/__init__.py +1 -0
- smallworld/state/models/riscv64/systemv/__init__.py +6 -0
- smallworld/state/models/riscv64/systemv/c99/__init__.py +12 -0
- smallworld/state/models/riscv64/systemv/c99/signal.py +16 -0
- smallworld/state/models/riscv64/systemv/c99/stdio.py +265 -0
- smallworld/state/models/riscv64/systemv/c99/stdlib.py +169 -0
- smallworld/state/models/riscv64/systemv/c99/string.py +139 -0
- smallworld/state/models/riscv64/systemv/c99/time.py +61 -0
- smallworld/state/models/riscv64/systemv/posix/__init__.py +6 -0
- smallworld/state/models/riscv64/systemv/posix/libgen.py +16 -0
- smallworld/state/models/riscv64/systemv/posix/signal.py +157 -0
- smallworld/state/models/riscv64/systemv/systemv.py +85 -0
- smallworld/state/state.py +65 -24
- smallworld/state/unstable/elf.py +16 -31
- smallworld/utils.py +6 -1
- {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info}/METADATA +76 -43
- smallworld_re-2.0.0.dist-info/RECORD +374 -0
- {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info}/WHEEL +1 -1
- smallworld/state/models/x86/__init__.py +0 -2
- smallworld/state/models/x86/microsoftcdecl.py +0 -35
- smallworld/state/models/x86/systemv.py +0 -240
- smallworld_re-1.0.2.dist-info/RECORD +0 -166
- /smallworld/state/models/{posix.py → _posix.py} +0 -0
- {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info}/entry_points.txt +0 -0
- {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info/licenses}/LICENSE.txt +0 -0
- {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info}/top_level.txt +0 -0
@@ -4,7 +4,6 @@ import typing
|
|
4
4
|
import lief
|
5
5
|
|
6
6
|
from ....exceptions import ConfigurationError
|
7
|
-
from ....hinting import Hint, get_hinter
|
8
7
|
from ....platforms import Architecture, Byteorder, Platform
|
9
8
|
from ....utils import RangeCollection
|
10
9
|
from ...state import BytesValue
|
@@ -13,7 +12,6 @@ from .rela import ElfRelocator
|
|
13
12
|
from .structs import ElfRela, ElfSymbol
|
14
13
|
|
15
14
|
log = logging.getLogger(__name__)
|
16
|
-
hinter = get_hinter(__name__)
|
17
15
|
|
18
16
|
# ELF machine values
|
19
17
|
# See /usr/include/elf.h for the complete list
|
@@ -26,6 +24,7 @@ EM_X86_64 = 62 # AMD/Intel x86-64
|
|
26
24
|
EM_XTENSA = 94 # Xtensa
|
27
25
|
EM_AARCH64 = 183 # ARM v9, or AARCH64
|
28
26
|
EM_RISCV = 243 # RISC-V
|
27
|
+
EM_LOONGARCH = 258 # LoongArch
|
29
28
|
|
30
29
|
# ARM-specific flag values
|
31
30
|
EF_ARM_VFP_FLOAT = 0x400
|
@@ -99,10 +98,19 @@ class ElfExecutable(Executable):
|
|
99
98
|
self._user_base = user_base
|
100
99
|
self._file_base = 0
|
101
100
|
|
101
|
+
# Lief struct.
|
102
|
+
# We can't keep it around forever, since it's not copyable.
|
103
|
+
self._elf: typing.Optional[typing.Any] = None
|
104
|
+
|
105
|
+
# Initialize dynamic tag info
|
106
|
+
self._dtags: typing.Dict[int, int] = dict()
|
107
|
+
|
102
108
|
# Initialize symbol info
|
103
|
-
self.
|
109
|
+
self._dynamic_symbols: typing.List[ElfSymbol] = list()
|
110
|
+
self._static_symbols: typing.List[ElfSymbol] = list()
|
111
|
+
self._dynamic_relas: typing.List[ElfRela] = list()
|
112
|
+
self._static_relas: typing.List[ElfRela] = list()
|
104
113
|
self._syms_by_name: typing.Dict[str, typing.List[ElfSymbol]] = dict()
|
105
|
-
self._relas: typing.List[ElfRela] = list()
|
106
114
|
self._relocator: typing.Optional[ElfRelocator] = None
|
107
115
|
|
108
116
|
# Read the entire image out of the file.
|
@@ -121,6 +129,9 @@ class ElfExecutable(Executable):
|
|
121
129
|
if elf is None:
|
122
130
|
raise ConfigurationError("Failed parsing ELF")
|
123
131
|
|
132
|
+
# Save the lief struct
|
133
|
+
self._elf = elf
|
134
|
+
|
124
135
|
# Extract the file header
|
125
136
|
ehdr = elf.header
|
126
137
|
if ehdr is None:
|
@@ -169,15 +180,13 @@ class ElfExecutable(Executable):
|
|
169
180
|
elif phdr.type == PT_DYNAMIC:
|
170
181
|
# Dynamic linking metadata.
|
171
182
|
# This ELF needs dynamic linking
|
172
|
-
|
173
|
-
hinter.info(hint)
|
183
|
+
log.info("Program includes dynamic linking metadata")
|
174
184
|
elif phdr.type == PT_INTERP:
|
175
185
|
# Program interpreter
|
176
186
|
# This completely changes how program loading works.
|
177
187
|
# Whether you care is a different matter.
|
178
188
|
interp = image[phdr.file_offset : phdr.file_offset + phdr.physical_size]
|
179
|
-
|
180
|
-
hinter.info(hint)
|
189
|
+
log.info(f"Program specifies interpreter {interp!r}")
|
181
190
|
elif phdr.type == PT_NOTE:
|
182
191
|
# Auxiliary information
|
183
192
|
# Possibly useful for comparing machine/OS type.
|
@@ -189,8 +198,7 @@ class ElfExecutable(Executable):
|
|
189
198
|
elif phdr.type == PT_TLS:
|
190
199
|
# TLS Segment
|
191
200
|
# Your analysis is about to get nasty :(
|
192
|
-
|
193
|
-
hinter.info(hint)
|
201
|
+
log.info("Program includes thread-local storage")
|
194
202
|
elif phdr.type == PT_GNU_EH_FRAME:
|
195
203
|
# Exception handler frame.
|
196
204
|
# GCC puts one of these in everything. Do we care?
|
@@ -198,13 +206,11 @@ class ElfExecutable(Executable):
|
|
198
206
|
elif phdr.type == PT_GNU_STACK:
|
199
207
|
# Stack executability
|
200
208
|
# If this is missing, assume executable stack
|
201
|
-
|
202
|
-
hinter.info(hint)
|
209
|
+
log.info("Program specifies stack permissions")
|
203
210
|
elif phdr.type == PT_GNU_RELRO:
|
204
211
|
# Read-only after relocation
|
205
212
|
# Only the dynamic linker should write this data.
|
206
|
-
|
207
|
-
hinter.info(hint)
|
213
|
+
log.info("Program specifies RELRO data")
|
208
214
|
elif phdr.type == PT_GNU_PROPERTY:
|
209
215
|
# GNU property segment
|
210
216
|
# Contains extra metadata which I'm not sure anything uses
|
@@ -213,21 +219,18 @@ class ElfExecutable(Executable):
|
|
213
219
|
# Unknown OS-specific program header
|
214
220
|
# Either this is a weird ISA that extends the generic GNU ABI,
|
215
221
|
# or this isn't a Linux ELF.
|
216
|
-
|
217
|
-
hinter.warn(hint)
|
222
|
+
log.warn(f"Unknown OS-specific program header: {phdr.type:08x}")
|
218
223
|
elif phdr.type >= PT_LOPROC and phdr.type <= PT_HIPROC:
|
219
224
|
# Unknown machine-specific program header
|
220
225
|
# This is probably a non-Intel ISA.
|
221
226
|
# Most of these are harmless, serving to tell the RTLD
|
222
227
|
# where to find machine-specific metadata
|
223
|
-
|
228
|
+
log.warn(
|
224
229
|
f"Unknown machine-specific program header: {phdr.type.value:08x}"
|
225
230
|
)
|
226
|
-
hinter.warn(hint)
|
227
231
|
else:
|
228
232
|
# Unknown program header outside the allowed custom ranges
|
229
|
-
|
230
|
-
hinter.warn(hint)
|
233
|
+
log.warn(f"Invalid program header: {phdr.type.value:08x}")
|
231
234
|
|
232
235
|
# Compute the final total capacity
|
233
236
|
for offset, value in self.items():
|
@@ -258,6 +261,9 @@ class ElfExecutable(Executable):
|
|
258
261
|
# Or this is PowerPC64 and the entrypoint is gibberish
|
259
262
|
self.entrypoint = None
|
260
263
|
|
264
|
+
# Organize dynamic tags
|
265
|
+
self._extract_dtags(elf)
|
266
|
+
|
261
267
|
# Organize symbols for later relocation
|
262
268
|
self._extract_symbols(elf)
|
263
269
|
|
@@ -296,7 +302,24 @@ class ElfExecutable(Executable):
|
|
296
302
|
# This is ARMv7a, as built by gcc.
|
297
303
|
architecture = Architecture.ARM_V7A
|
298
304
|
else:
|
299
|
-
|
305
|
+
# The file might be a core dump or some uncommon flavor of ARM.
|
306
|
+
# Fallback to a default if flags are missing.
|
307
|
+
log.warning(
|
308
|
+
f"No recognized ARM flags found. flags={list(map(hex, flags))}, "
|
309
|
+
"defaulting to ARM_V7A."
|
310
|
+
)
|
311
|
+
architecture = Architecture.ARM_V7A
|
312
|
+
elif elf.header.machine_type.value == EM_LOONGARCH:
|
313
|
+
if elf.header.identity_class.value == 1:
|
314
|
+
# 32-bit elf
|
315
|
+
raise ConfigurationError("LoongArch32 not supported")
|
316
|
+
elif elf.header.identity_class.value == 2:
|
317
|
+
# 64-bit elf
|
318
|
+
architecture = Architecture.LOONGARCH64
|
319
|
+
else:
|
320
|
+
raise ConfigurationError(
|
321
|
+
f"Unknown value of ei_class: {hex(elf.header.identity_class.value)}"
|
322
|
+
)
|
300
323
|
elif elf.header.machine_type.value == EM_MIPS:
|
301
324
|
# Some kind of mips.
|
302
325
|
# TODO: There are more parameters than just word size
|
@@ -368,6 +391,7 @@ class ElfExecutable(Executable):
|
|
368
391
|
# File base is defined.
|
369
392
|
# We (probably) cannot move the image without problems.
|
370
393
|
raise ConfigurationError("Base address defined for fixed-position ELF")
|
394
|
+
log.info(f"Address: {self.address:x}")
|
371
395
|
|
372
396
|
def _rebase_file(self, val: int):
|
373
397
|
# Rebase an offset from file-relative to image-relative
|
@@ -389,16 +413,22 @@ class ElfExecutable(Executable):
|
|
389
413
|
seg_size = self._page_align(phdr.virtual_size + (phdr.file_offset - seg_start))
|
390
414
|
|
391
415
|
log.debug("Mapping: ")
|
392
|
-
log.debug(
|
393
|
-
|
416
|
+
log.debug(
|
417
|
+
f" f: [ {seg_start:012x} -> {seg_end:012x} ] ( {seg_end - seg_start:x} bytes )"
|
418
|
+
)
|
419
|
+
log.debug(
|
420
|
+
f" m: [ {seg_addr:012x} -> {seg_addr + seg_size:012x} ] ( {seg_size:x} bytes )"
|
421
|
+
)
|
394
422
|
|
395
423
|
# Extract segment data
|
396
424
|
seg_data = image[seg_start:seg_end]
|
397
425
|
if len(seg_data) < seg_size:
|
398
426
|
# Segment is shorter than is available from the file;
|
399
427
|
# this will get zero-padded.
|
400
|
-
|
401
|
-
|
428
|
+
pad_size = seg_size - len(seg_data)
|
429
|
+
log.debug(f"Padding segment by {pad_size} bytes")
|
430
|
+
seg_data += b"\0" * pad_size
|
431
|
+
if len(seg_data) != seg_size:
|
402
432
|
raise ConfigurationError(
|
403
433
|
f"Expected segment of size {seg_size}, but got {len(seg_data)}"
|
404
434
|
)
|
@@ -408,8 +438,15 @@ class ElfExecutable(Executable):
|
|
408
438
|
|
409
439
|
# Add the segment to the memory map
|
410
440
|
seg_value = BytesValue(seg_data, None)
|
441
|
+
assert (
|
442
|
+
seg_value._size == seg_size
|
443
|
+
), f"Expected {seg_size:x} bytes, got {seg_value._size:x}"
|
411
444
|
self[seg_addr - self.address] = seg_value
|
412
445
|
|
446
|
+
def _extract_dtags(self, elf):
|
447
|
+
for dt in elf.dynamic_entries:
|
448
|
+
self._dtags[dt.tag.value] = dt.value
|
449
|
+
|
413
450
|
def _extract_symbols(self, elf):
|
414
451
|
lief_to_elf = dict()
|
415
452
|
|
@@ -425,9 +462,21 @@ class ElfExecutable(Executable):
|
|
425
462
|
# Relative symbols will be relative to the load address
|
426
463
|
baseaddr = self.address
|
427
464
|
|
465
|
+
dynsyms = set(elf.dynamic_symbols)
|
466
|
+
idx = 0
|
467
|
+
dynamic = True
|
428
468
|
for s in elf.symbols:
|
469
|
+
# Lief lets you access dynamic symbols separately,
|
470
|
+
# but you need to access static symbols through
|
471
|
+
# the list of all symbols
|
472
|
+
if dynamic and s not in dynsyms:
|
473
|
+
idx = 0
|
474
|
+
dynamic = False
|
475
|
+
|
429
476
|
# Build a symbol
|
430
477
|
sym = ElfSymbol(
|
478
|
+
idx=idx,
|
479
|
+
dynamic=dynamic,
|
431
480
|
name=s.name,
|
432
481
|
type=s.type.value,
|
433
482
|
bind=s.binding.value,
|
@@ -436,9 +485,14 @@ class ElfExecutable(Executable):
|
|
436
485
|
value=s.value,
|
437
486
|
size=s.size,
|
438
487
|
baseaddr=baseaddr,
|
488
|
+
defined=(s.shndx != 0),
|
439
489
|
)
|
440
490
|
# Save the sym, and temporarily tie it to its lief partner
|
441
|
-
|
491
|
+
if dynamic:
|
492
|
+
self._dynamic_symbols.append(sym)
|
493
|
+
else:
|
494
|
+
self._static_symbols.append(sym)
|
495
|
+
|
442
496
|
self._syms_by_name.setdefault(sym.name, list()).append(sym)
|
443
497
|
lief_to_elf[s] = sym
|
444
498
|
|
@@ -449,30 +503,20 @@ class ElfExecutable(Executable):
|
|
449
503
|
# All MIPS dynamic symbols have an implicit rela.
|
450
504
|
# MIPS dynamic symbols always have a GOT entry;
|
451
505
|
# to save space, the ABI just assumes that the rela exists
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
gotsym = dt.value
|
460
|
-
if dt.tag.value == DT_MIPS_LOCAL_GOTNO:
|
461
|
-
local_gotno = dt.value
|
462
|
-
if dt.tag.value == DT_PLTGOT:
|
463
|
-
gotoff = dt.value
|
464
|
-
if (
|
465
|
-
local_gotno is not None
|
466
|
-
and gotsym is not None
|
467
|
-
and gotoff is not None
|
468
|
-
):
|
469
|
-
break
|
470
|
-
|
471
|
-
if local_gotno is None or gotoff is None or gotsym is None:
|
472
|
-
log.error("MIPS binary missing got information")
|
506
|
+
if (
|
507
|
+
DT_MIPS_GOTSYM not in self._dtags
|
508
|
+
or DT_MIPS_LOCAL_GOTNO not in self._dtags
|
509
|
+
or DT_PLTGOT not in self._dtags
|
510
|
+
):
|
511
|
+
# GOT is missing... not sure what's up.
|
512
|
+
log.error("MIPS binary missing GOT information")
|
473
513
|
else:
|
474
514
|
# We found the GOT info; we're actually a dynamic binary
|
475
515
|
# Figure out the GOT entry size based on arch
|
516
|
+
gotsym = self._dtags[DT_MIPS_GOTSYM]
|
517
|
+
local_gotno = self._dtags[DT_MIPS_LOCAL_GOTNO]
|
518
|
+
gotoff = self._dtags[DT_PLTGOT]
|
519
|
+
|
476
520
|
if self.platform.architecture == Architecture.MIPS32:
|
477
521
|
gotent = 4
|
478
522
|
rela_type = R_MIPS_32
|
@@ -490,20 +534,35 @@ class ElfExecutable(Executable):
|
|
490
534
|
sym = lief_to_elf[s]
|
491
535
|
rela = ElfRela(offset=gotoff, type=rela_type, symbol=sym, addend=0)
|
492
536
|
sym.relas.append(rela)
|
493
|
-
self.
|
537
|
+
self._dynamic_relas.append(rela)
|
494
538
|
|
495
539
|
gotoff += gotent
|
496
540
|
|
497
|
-
for r in elf.
|
541
|
+
for r in list(elf.dynamic_relocations) + list(elf.pltgot_relocations):
|
498
542
|
# Build a rela, and tie it to its symbol
|
543
|
+
# TODO: some relas have no symbols. Live with it.
|
544
|
+
if r.symbol is None:
|
545
|
+
continue
|
499
546
|
sym = lief_to_elf[r.symbol]
|
500
547
|
rela = ElfRela(
|
501
548
|
offset=r.address + baseaddr, type=r.type, symbol=sym, addend=r.addend
|
502
549
|
)
|
503
550
|
sym.relas.append(rela)
|
504
|
-
self.
|
551
|
+
self._dynamic_relas.append(rela)
|
505
552
|
|
506
|
-
|
553
|
+
for r in elf.object_relocations:
|
554
|
+
if r.symbol is None:
|
555
|
+
continue
|
556
|
+
sym = lief_to_elf[r.symbol]
|
557
|
+
rela = ElfRela(
|
558
|
+
offset=r.address + baseaddr, type=r.type, symbol=sym, addend=r.addend
|
559
|
+
)
|
560
|
+
sym.relas.append(rela)
|
561
|
+
self._static_relas.append(rela)
|
562
|
+
|
563
|
+
def _get_symbols(
|
564
|
+
self, name: typing.Union[str, int], dynamic: bool
|
565
|
+
) -> typing.List[ElfSymbol]:
|
507
566
|
if isinstance(name, str):
|
508
567
|
# Caller wants to look up a symbol by name
|
509
568
|
if name not in self._syms_by_name:
|
@@ -512,14 +571,30 @@ class ElfExecutable(Executable):
|
|
512
571
|
syms = self._syms_by_name[name]
|
513
572
|
return list(syms)
|
514
573
|
elif isinstance(name, int):
|
515
|
-
|
574
|
+
if dynamic:
|
575
|
+
return [self._dynamic_symbols[name]]
|
576
|
+
else:
|
577
|
+
return [self._static_symbols[name]]
|
516
578
|
else:
|
517
579
|
raise TypeError("Symbols must be specified by str names or int indexes")
|
518
580
|
|
519
581
|
def get_symbol_value(
|
520
|
-
self, name: typing.Union[str, int], rebase: bool = True
|
582
|
+
self, name: typing.Union[str, int], dynamic: bool = False, rebase: bool = True
|
521
583
|
) -> int:
|
522
|
-
|
584
|
+
"""Get the value for a symbol
|
585
|
+
|
586
|
+
The value of a symbol is usually an address or offset,
|
587
|
+
although the precise meaning can vary a little.
|
588
|
+
|
589
|
+
Arguments:
|
590
|
+
name: The name of the symbol, or its index into the symbol table
|
591
|
+
dynamic: If specified by index, whether to look in the static or dynamic symbol table
|
592
|
+
rebase: Whether the recorded value is relative to the base address of this ELF.
|
593
|
+
|
594
|
+
Returns:
|
595
|
+
The integer value of this symbol
|
596
|
+
"""
|
597
|
+
syms = self._get_symbols(name, dynamic)
|
523
598
|
if len(syms) > 1:
|
524
599
|
for sym in syms:
|
525
600
|
if sym.value != syms[0].value and sym.baseaddr != syms[0].baseaddr:
|
@@ -530,8 +605,21 @@ class ElfExecutable(Executable):
|
|
530
605
|
val += syms[0].baseaddr
|
531
606
|
return val
|
532
607
|
|
533
|
-
def get_symbol_size(self, name: typing.Union[str, int]):
|
534
|
-
|
608
|
+
def get_symbol_size(self, name: typing.Union[str, int], dynamic: bool = False):
|
609
|
+
"""Get the size for a symbol
|
610
|
+
|
611
|
+
If a symbol references a function or a data structure,
|
612
|
+
this will hold its size in bytes
|
613
|
+
|
614
|
+
Arguments:
|
615
|
+
name: The name of the symbol, or its index into the symbol table
|
616
|
+
dynamic: If specified by index, whether to look in the static or dynamic symbol table
|
617
|
+
rebase: Whether the recorded value is relative to the base address of this ELF.
|
618
|
+
|
619
|
+
Returns:
|
620
|
+
The size of this symbol
|
621
|
+
"""
|
622
|
+
syms = self._get_symbols(name, dynamic)
|
535
623
|
if len(syms) > 1:
|
536
624
|
for sym in syms:
|
537
625
|
if sym.size != syms[0].size:
|
@@ -539,12 +627,31 @@ class ElfExecutable(Executable):
|
|
539
627
|
return syms[0].size
|
540
628
|
|
541
629
|
def update_symbol_value(
|
542
|
-
self,
|
630
|
+
self,
|
631
|
+
name: typing.Union[str, int, ElfSymbol],
|
632
|
+
value: int,
|
633
|
+
dynamic: bool = False,
|
634
|
+
rebase: bool = True,
|
543
635
|
) -> None:
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
636
|
+
"""Update the value of a symbol
|
637
|
+
|
638
|
+
This will alter the value of the symbol,
|
639
|
+
and also propagate that updated value according to any associated relocations.
|
640
|
+
|
641
|
+
Arguments:
|
642
|
+
name: The name of the symbol, its index into the symbol table, or a specific symbol object
|
643
|
+
value: The new value for the symbol
|
644
|
+
dynamic: If specified by index, whether to look in the static or dynamic symbol table
|
645
|
+
rebase: Whether the recorded value is relative to the base address of this ELF.
|
646
|
+
"""
|
647
|
+
|
648
|
+
if isinstance(name, ElfSymbol):
|
649
|
+
sym = name
|
650
|
+
else:
|
651
|
+
syms = self._get_symbols(name, dynamic)
|
652
|
+
if len(syms) > 1:
|
653
|
+
raise ConfigurationError(f"Multiple syms named {name}")
|
654
|
+
sym = syms[0]
|
548
655
|
|
549
656
|
if rebase:
|
550
657
|
# Value provided is absolute; rebase it to the symbol's base address
|
@@ -553,12 +660,69 @@ class ElfExecutable(Executable):
|
|
553
660
|
# Update the value
|
554
661
|
sym.value = value
|
555
662
|
|
663
|
+
# Mark this symbol as defined
|
664
|
+
sym.defined = True
|
665
|
+
|
556
666
|
if self._relocator is not None:
|
557
667
|
for rela in sym.relas:
|
558
668
|
# Relocate!
|
669
|
+
log.info(f"Relocating {rela}")
|
559
670
|
self._relocator.relocate(self, rela)
|
560
671
|
else:
|
561
672
|
log.error(f"No platform defined; cannot relocate {name}!")
|
562
673
|
|
674
|
+
def link_elf(self, elf: "ElfExecutable", dynamic: bool = True) -> None:
|
675
|
+
"""Link one ELF against another
|
676
|
+
|
677
|
+
This roughly mimics the ELF linker;
|
678
|
+
it looks for undefined symbols in the current file,
|
679
|
+
and tries to populate their values from matching defined symbols
|
680
|
+
from another file.
|
681
|
+
|
682
|
+
Arguments:
|
683
|
+
elf: The ELF from which to draw symbol values
|
684
|
+
dynamic: Whether to link static or dynamic symbols
|
685
|
+
"""
|
686
|
+
if dynamic:
|
687
|
+
# Relocate rela.dyn and rela.plt
|
688
|
+
relas = self._dynamic_relas
|
689
|
+
else:
|
690
|
+
# relocate static relocations
|
691
|
+
relas = self._static_relas
|
692
|
+
|
693
|
+
for rela in relas:
|
694
|
+
my_sym = rela.symbol
|
695
|
+
if my_sym.name == "":
|
696
|
+
# This isn't a real symbol
|
697
|
+
continue
|
698
|
+
if my_sym.defined:
|
699
|
+
# This is a defined symbol
|
700
|
+
continue
|
701
|
+
|
702
|
+
try:
|
703
|
+
o_syms = elf._get_symbols(my_sym.name, dynamic)
|
704
|
+
except ConfigurationError:
|
705
|
+
continue
|
706
|
+
|
707
|
+
o_syms = list(filter(lambda x: x.defined, o_syms))
|
708
|
+
if len(o_syms) == 0:
|
709
|
+
continue
|
710
|
+
|
711
|
+
if len(set(map(lambda x: x.value, o_syms))) > 1:
|
712
|
+
# Catch multiple symbols
|
713
|
+
# If they all have the same value, we don't care.
|
714
|
+
log.warning(f"Multiple symbols for {my_sym.name}")
|
715
|
+
continue
|
716
|
+
|
717
|
+
o_sym = o_syms[0]
|
718
|
+
self.update_symbol_value(my_sym, o_sym.value + o_sym.baseaddr, rebase=True)
|
719
|
+
|
720
|
+
def __getstate__(self):
|
721
|
+
# Override the default pickling mechanism.
|
722
|
+
# We can't save any lief data through a copy.
|
723
|
+
state = self.__dict__.copy()
|
724
|
+
state["_elf"] = None
|
725
|
+
return state
|
726
|
+
|
563
727
|
|
564
728
|
__all__ = ["ElfExecutable"]
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class RegisterState:
|
2
|
+
def __init__(self, registers: dict, pc: int, sp: int, status: int, arch: str):
|
3
|
+
self.arch = arch
|
4
|
+
self.pc = pc
|
5
|
+
self.sp = sp
|
6
|
+
self.status = status
|
7
|
+
|
8
|
+
# The rest of the registers
|
9
|
+
self._registers = registers
|
10
|
+
|
11
|
+
def __getattr__(self, name: str):
|
12
|
+
if name in self._registers:
|
13
|
+
return self._registers[name]
|
14
|
+
|
15
|
+
raise AttributeError(f"No register named '{name}' in this core dump.")
|
16
|
+
|
17
|
+
def __setattr__(self, name: str, value):
|
18
|
+
if name.startswith("_") or name in ("arch", "pc", "sp", "status"):
|
19
|
+
super().__setattr__(name, value)
|
20
|
+
else:
|
21
|
+
if hasattr(self, "_registers") and (name in self._registers):
|
22
|
+
self._registers[name] = value
|
23
|
+
else:
|
24
|
+
super().__setattr__(name, value)
|
25
|
+
|
26
|
+
def apply_to_cpu(self, cpu):
|
27
|
+
"""
|
28
|
+
Set the CPU registers from this RegisterState object.
|
29
|
+
"""
|
30
|
+
cpu.pc.set(self.pc)
|
31
|
+
cpu.sp.set(self.sp)
|
32
|
+
|
33
|
+
for reg_name, reg_val in self._registers.items():
|
34
|
+
reg_name_lower = reg_name.lower()
|
35
|
+
if hasattr(cpu, reg_name_lower):
|
36
|
+
getattr(cpu, reg_name_lower).set(reg_val)
|
@@ -8,6 +8,7 @@ from .arm import (
|
|
8
8
|
Armv7RElfRelocator,
|
9
9
|
)
|
10
10
|
from .i386 import I386ElfRelocator
|
11
|
+
from .loongarch import LoongArch64ElfRelocator
|
11
12
|
from .mips import MIPSELElfRelocator, MIPSElfRelocator
|
12
13
|
from .ppc import PowerPCElfRelocator
|
13
14
|
from .rela import ElfRelocator
|
@@ -23,6 +24,7 @@ __all__ = [
|
|
23
24
|
"Armv7MElfRelocator",
|
24
25
|
"Armv7RElfRelocator",
|
25
26
|
"I386ElfRelocator",
|
27
|
+
"LoongArch64ElfRelocator",
|
26
28
|
"MIPSElfRelocator",
|
27
29
|
"MIPSELElfRelocator",
|
28
30
|
"PowerPCElfRelocator",
|
@@ -3,6 +3,7 @@ from .....exceptions import ConfigurationError
|
|
3
3
|
from ..structs import ElfRela
|
4
4
|
from .rela import ElfRelocator
|
5
5
|
|
6
|
+
R_AARCH64_ABS64 = 257 # Direct 64-bit
|
6
7
|
R_AARCH64_GLOB_DAT = 1025 # Create GOT entry
|
7
8
|
R_AARCH64_JUMP_SLOT = 1026 # Create PLT entry
|
8
9
|
R_AARCH64_RELATIVE = 1027 # Adjust by program base
|
@@ -17,11 +18,12 @@ class AArch64ElfRelocator(ElfRelocator):
|
|
17
18
|
rela.type == R_AARCH64_GLOB_DAT
|
18
19
|
or rela.type == R_AARCH64_JUMP_SLOT
|
19
20
|
or rela.type == R_AARCH64_RELATIVE
|
21
|
+
or rela.type == R_AARCH64_ABS64
|
20
22
|
):
|
21
23
|
# Different semantics, all behave the same
|
22
24
|
val = rela.symbol.value + rela.symbol.baseaddr + rela.addend
|
23
25
|
return val.to_bytes(8, "little")
|
24
26
|
else:
|
25
27
|
raise ConfigurationError(
|
26
|
-
"Unknown relocation type for {rela.symbol.name}: {rela.type}"
|
28
|
+
f"Unknown relocation type for {rela.symbol.name}: {rela.type}"
|
27
29
|
)
|
@@ -3,6 +3,7 @@ from .....exceptions import ConfigurationError
|
|
3
3
|
from ..structs import ElfRela
|
4
4
|
from .rela import ElfRelocator
|
5
5
|
|
6
|
+
R_X86_64_64 = 1 # Direct 64-bit
|
6
7
|
R_X86_64_GLOB_DAT = 6 # Create GOT entry
|
7
8
|
R_X86_64_JUMP_SLOT = 7 # Create PLT entry
|
8
9
|
R_X86_64_RELATIVE = 8 # Adjust by program base
|
@@ -18,15 +19,16 @@ class AMD64ElfRelocator(ElfRelocator):
|
|
18
19
|
rela.type == R_X86_64_GLOB_DAT
|
19
20
|
or rela.type == R_X86_64_JUMP_SLOT
|
20
21
|
or rela.type == R_X86_64_RELATIVE
|
22
|
+
or rela.type == R_X86_64_64
|
21
23
|
):
|
22
24
|
# Different semantics, all behave the same
|
23
25
|
val = rela.symbol.value + rela.symbol.baseaddr + rela.addend
|
24
26
|
return val.to_bytes(8, "little")
|
25
27
|
elif rela.type >= 0 and rela.type < R_X86_64_NUM:
|
26
28
|
raise ConfigurationError(
|
27
|
-
"Valid, but unsupported relocation for {rela.symbol.name}: {rela.type}"
|
29
|
+
f"Valid, but unsupported relocation for {rela.symbol.name}: {rela.type}"
|
28
30
|
)
|
29
31
|
else:
|
30
32
|
raise ConfigurationError(
|
31
|
-
"Invalid relocation type for {rela.symbol.name}: {rela.type}"
|
33
|
+
f"Invalid relocation type for {rela.symbol.name}: {rela.type}"
|
32
34
|
)
|
@@ -3,6 +3,7 @@ from .....exceptions import ConfigurationError
|
|
3
3
|
from ..structs import ElfRela
|
4
4
|
from .rela import ElfRelocator
|
5
5
|
|
6
|
+
R_ARM_ABS32 = 2 # Direct 32-bit
|
6
7
|
R_ARM_GLOB_DAT = 21 # Create GOT entry
|
7
8
|
R_ARM_JUMP_SLOT = 22 # Create PLT entry
|
8
9
|
R_ARM_RELATIVE = 23 # Adjust by program base
|
@@ -17,17 +18,18 @@ class ArmElfRelocator(ElfRelocator):
|
|
17
18
|
rela.type == R_ARM_GLOB_DAT
|
18
19
|
or rela.type == R_ARM_JUMP_SLOT
|
19
20
|
or rela.type == R_ARM_RELATIVE
|
21
|
+
or rela.type == R_ARM_ABS32
|
20
22
|
):
|
21
23
|
# Different semantics, all behave the same
|
22
24
|
val = rela.symbol.value + rela.symbol.baseaddr + rela.addend
|
23
25
|
return val.to_bytes(4, "little")
|
24
26
|
elif rela.type >= 0 and rela.type < R_ARM_NUM:
|
25
27
|
raise ConfigurationError(
|
26
|
-
"Valid, but unsupported relocation for {rela.symbol.name}: {rela.type}"
|
28
|
+
f"Valid, but unsupported relocation for {rela.symbol.name}: {rela.type}"
|
27
29
|
)
|
28
30
|
else:
|
29
31
|
raise ConfigurationError(
|
30
|
-
"Invalid relocation type for {rela.symbol.name}: {rela.type}"
|
32
|
+
f"Invalid relocation type for {rela.symbol.name}: {rela.type}"
|
31
33
|
)
|
32
34
|
|
33
35
|
|
@@ -3,6 +3,7 @@ from .....exceptions import ConfigurationError
|
|
3
3
|
from ..structs import ElfRela
|
4
4
|
from .rela import ElfRelocator
|
5
5
|
|
6
|
+
R_386_32 = 1 # Direct 32-bit
|
6
7
|
R_386_GLOB_DAT = 6 # Create GOT entry
|
7
8
|
R_386_JUMP_SLOT = 7 # Create PLT entry
|
8
9
|
R_386_RELATIVE = 8 # Adjust by program base
|
@@ -18,15 +19,16 @@ class I386ElfRelocator(ElfRelocator):
|
|
18
19
|
rela.type == R_386_GLOB_DAT
|
19
20
|
or rela.type == R_386_JUMP_SLOT
|
20
21
|
or rela.type == R_386_RELATIVE
|
22
|
+
or rela.type == R_386_32
|
21
23
|
):
|
22
24
|
# Different semantics, all behave the same
|
23
25
|
val = rela.symbol.value + rela.symbol.baseaddr + rela.addend
|
24
26
|
return val.to_bytes(4, "little")
|
25
27
|
elif rela.type >= 0 and rela.type < R_386_NUM:
|
26
28
|
raise ConfigurationError(
|
27
|
-
"Valid, but unsupported relocation for {rela.symbol.name}: {rela.type}"
|
29
|
+
f"Valid, but unsupported relocation for {rela.symbol.name}: {rela.type}"
|
28
30
|
)
|
29
31
|
else:
|
30
32
|
raise ConfigurationError(
|
31
|
-
"Invalid relocation type for {rela.symbol.name}: {rela.type}"
|
33
|
+
f"Invalid relocation type for {rela.symbol.name}: {rela.type}"
|
32
34
|
)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
from ..... import platforms
|
2
|
+
from .....exceptions import ConfigurationError
|
3
|
+
from ..structs import ElfRela
|
4
|
+
from .rela import ElfRelocator
|
5
|
+
|
6
|
+
R_LARCH_64 = 2 # Direct 64-bit
|
7
|
+
R_LARCH_RELATIVE = 4 # Adjust by program base
|
8
|
+
R_LARCH_JUMP_SLOT = 5 # Create PLT entry
|
9
|
+
R_LARCH_NUM = 127 # This and higher aren't valid
|
10
|
+
|
11
|
+
|
12
|
+
class LoongArch64ElfRelocator(ElfRelocator):
|
13
|
+
arch = platforms.Architecture.LOONGARCH64
|
14
|
+
byteorder = platforms.Byteorder.LITTLE
|
15
|
+
|
16
|
+
def _compute_value(self, rela: ElfRela):
|
17
|
+
if (
|
18
|
+
rela.type == R_LARCH_JUMP_SLOT
|
19
|
+
or rela.type == R_LARCH_RELATIVE
|
20
|
+
or rela.type == R_LARCH_64
|
21
|
+
):
|
22
|
+
# Different semantics, all behave the same
|
23
|
+
val = rela.symbol.value + rela.symbol.baseaddr + rela.addend
|
24
|
+
return val.to_bytes(8, "little")
|
25
|
+
elif rela.type >= 0 and rela.type < R_LARCH_NUM:
|
26
|
+
raise ConfigurationError(
|
27
|
+
f"Valid, but unsupported relocation for {rela.symbol.name}: {rela.type}"
|
28
|
+
)
|
29
|
+
else:
|
30
|
+
raise ConfigurationError(
|
31
|
+
f"Invalid relocation type for {rela.symbol.name}: {rela.type}"
|
32
|
+
)
|