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.
Files changed (306) hide show
  1. smallworld/analyses/__init__.py +8 -0
  2. smallworld/analyses/analysis.py +8 -67
  3. smallworld/analyses/code_coverage.py +1 -2
  4. smallworld/analyses/colorizer.py +301 -534
  5. smallworld/analyses/colorizer_def_use.py +217 -0
  6. smallworld/analyses/colorizer_summary.py +173 -83
  7. smallworld/analyses/field_detection/field_analysis.py +7 -8
  8. smallworld/analyses/field_detection/hints.py +1 -1
  9. smallworld/analyses/field_detection/malloc.py +2 -2
  10. smallworld/analyses/trace_execution.py +160 -0
  11. smallworld/analyses/trace_execution_types.py +42 -0
  12. smallworld/analyses/unstable/angr/divergence.py +1 -2
  13. smallworld/analyses/unstable/angr/model.py +5 -6
  14. smallworld/analyses/unstable/angr_nwbt.py +3 -4
  15. smallworld/analyses/unstable/code_coverage.py +2 -3
  16. smallworld/analyses/unstable/code_reachable.py +2 -3
  17. smallworld/analyses/unstable/control_flow_tracer.py +2 -3
  18. smallworld/analyses/unstable/pointer_finder.py +2 -3
  19. smallworld/analyses/unstable/utils/tui.py +71 -0
  20. smallworld/emulators/__init__.py +3 -1
  21. smallworld/emulators/angr/angr.py +30 -9
  22. smallworld/emulators/angr/machdefs/__init__.py +2 -0
  23. smallworld/emulators/angr/machdefs/aarch64.py +1 -1
  24. smallworld/emulators/angr/machdefs/amd64.py +0 -4
  25. smallworld/emulators/angr/machdefs/arm.py +0 -2
  26. smallworld/emulators/angr/machdefs/i386.py +0 -2
  27. smallworld/emulators/angr/machdefs/loongarch.py +340 -0
  28. smallworld/emulators/angr/machdefs/machdef.py +1 -8
  29. smallworld/emulators/angr/machdefs/mips.py +0 -2
  30. smallworld/emulators/angr/machdefs/mips64.py +0 -2
  31. smallworld/emulators/angr/machdefs/ppc.py +1 -2
  32. smallworld/emulators/angr/machdefs/riscv.py +8 -10
  33. smallworld/emulators/angr/machdefs/xtensa.py +7 -4
  34. smallworld/emulators/emulator.py +22 -0
  35. smallworld/emulators/ghidra/__init__.py +37 -0
  36. smallworld/emulators/ghidra/ghidra.py +513 -0
  37. smallworld/emulators/ghidra/machdefs/__init__.py +31 -0
  38. smallworld/emulators/ghidra/machdefs/aarch64.py +289 -0
  39. smallworld/emulators/ghidra/machdefs/amd64.py +185 -0
  40. smallworld/emulators/ghidra/machdefs/arm.py +370 -0
  41. smallworld/emulators/ghidra/machdefs/i386.py +109 -0
  42. smallworld/emulators/ghidra/machdefs/loongarch.py +162 -0
  43. smallworld/emulators/ghidra/machdefs/machdef.py +81 -0
  44. smallworld/emulators/ghidra/machdefs/mips.py +163 -0
  45. smallworld/emulators/ghidra/machdefs/mips64.py +186 -0
  46. smallworld/emulators/ghidra/machdefs/ppc.py +98 -0
  47. smallworld/emulators/ghidra/machdefs/riscv.py +208 -0
  48. smallworld/emulators/ghidra/machdefs/xtensa.py +21 -0
  49. smallworld/emulators/ghidra/typing.py +28 -0
  50. smallworld/emulators/hookable.py +18 -4
  51. smallworld/emulators/panda/machdefs/__init__.py +2 -2
  52. smallworld/emulators/panda/machdefs/aarch64.py +186 -11
  53. smallworld/emulators/panda/machdefs/amd64.py +103 -11
  54. smallworld/emulators/panda/machdefs/arm.py +216 -20
  55. smallworld/emulators/panda/machdefs/i386.py +30 -7
  56. smallworld/emulators/panda/machdefs/machdef.py +9 -16
  57. smallworld/emulators/panda/machdefs/mips.py +49 -5
  58. smallworld/emulators/panda/machdefs/mips64.py +57 -5
  59. smallworld/emulators/panda/machdefs/ppc.py +38 -13
  60. smallworld/emulators/panda/panda.py +146 -44
  61. smallworld/emulators/unicorn/__init__.py +2 -0
  62. smallworld/emulators/unicorn/machdefs/aarch64.py +253 -264
  63. smallworld/emulators/unicorn/machdefs/amd64.py +254 -259
  64. smallworld/emulators/unicorn/machdefs/arm.py +200 -212
  65. smallworld/emulators/unicorn/machdefs/i386.py +84 -90
  66. smallworld/emulators/unicorn/machdefs/machdef.py +2 -23
  67. smallworld/emulators/unicorn/machdefs/mips.py +127 -135
  68. smallworld/emulators/unicorn/unicorn.py +52 -13
  69. smallworld/helpers.py +4 -19
  70. smallworld/hinting/hinting.py +22 -192
  71. smallworld/hinting/hints.py +50 -18
  72. smallworld/instructions/bsid.py +8 -8
  73. smallworld/logging.py +4 -2
  74. smallworld/platforms/__init__.py +12 -0
  75. smallworld/platforms/defs/__init__.py +36 -0
  76. smallworld/platforms/defs/aarch64.py +450 -0
  77. smallworld/platforms/defs/amd64.py +463 -0
  78. smallworld/platforms/defs/arm.py +519 -0
  79. smallworld/platforms/defs/i386.py +258 -0
  80. smallworld/platforms/defs/loongarch.py +270 -0
  81. smallworld/platforms/defs/mips.py +321 -0
  82. smallworld/platforms/defs/mips64.py +313 -0
  83. smallworld/platforms/defs/platformdef.py +97 -0
  84. smallworld/platforms/defs/powerpc.py +259 -0
  85. smallworld/platforms/defs/riscv.py +257 -0
  86. smallworld/platforms/defs/xtensa.py +96 -0
  87. smallworld/{platforms.py → platforms/platforms.py} +3 -0
  88. smallworld/state/cpus/__init__.py +2 -0
  89. smallworld/state/cpus/aarch64.py +0 -9
  90. smallworld/state/cpus/amd64.py +6 -28
  91. smallworld/state/cpus/arm.py +0 -11
  92. smallworld/state/cpus/cpu.py +0 -11
  93. smallworld/state/cpus/i386.py +0 -7
  94. smallworld/state/cpus/loongarch.py +299 -0
  95. smallworld/state/cpus/mips.py +4 -47
  96. smallworld/state/cpus/mips64.py +18 -58
  97. smallworld/state/cpus/powerpc.py +2 -9
  98. smallworld/state/cpus/riscv.py +1 -11
  99. smallworld/state/cpus/xtensa.py +0 -5
  100. smallworld/state/memory/code.py +44 -2
  101. smallworld/state/memory/elf/__init__.py +5 -1
  102. smallworld/state/memory/elf/coredump/__init__.py +3 -0
  103. smallworld/state/memory/elf/coredump/coredump.py +46 -0
  104. smallworld/state/memory/elf/coredump/prstatus/__init__.py +27 -0
  105. smallworld/state/memory/elf/coredump/prstatus/aarch64.py +46 -0
  106. smallworld/state/memory/elf/coredump/prstatus/amd64.py +40 -0
  107. smallworld/state/memory/elf/coredump/prstatus/arm.py +53 -0
  108. smallworld/state/memory/elf/coredump/prstatus/i386.py +30 -0
  109. smallworld/state/memory/elf/coredump/prstatus/mips.py +55 -0
  110. smallworld/state/memory/elf/coredump/prstatus/mips64.py +57 -0
  111. smallworld/state/memory/elf/coredump/prstatus/ppc.py +82 -0
  112. smallworld/state/memory/elf/coredump/prstatus/prstatus.py +129 -0
  113. smallworld/state/memory/elf/elf.py +225 -61
  114. smallworld/state/memory/elf/register_state.py +36 -0
  115. smallworld/state/memory/elf/rela/__init__.py +2 -0
  116. smallworld/state/memory/elf/rela/aarch64.py +3 -1
  117. smallworld/state/memory/elf/rela/amd64.py +4 -2
  118. smallworld/state/memory/elf/rela/arm.py +4 -2
  119. smallworld/state/memory/elf/rela/i386.py +4 -2
  120. smallworld/state/memory/elf/rela/loongarch.py +32 -0
  121. smallworld/state/memory/elf/rela/mips.py +39 -18
  122. smallworld/state/memory/elf/rela/ppc.py +31 -14
  123. smallworld/state/memory/elf/structs.py +3 -0
  124. smallworld/state/memory/heap.py +2 -2
  125. smallworld/state/memory/memory.py +18 -0
  126. smallworld/state/memory/pe/__init__.py +3 -0
  127. smallworld/state/memory/pe/pe.py +361 -0
  128. smallworld/state/memory/pe/structs.py +60 -0
  129. smallworld/state/memory/stack/__init__.py +2 -0
  130. smallworld/state/memory/stack/loongarch.py +26 -0
  131. smallworld/state/models/__init__.py +29 -2
  132. smallworld/state/models/aarch64/__init__.py +1 -0
  133. smallworld/state/models/aarch64/systemv/__init__.py +6 -0
  134. smallworld/state/models/aarch64/systemv/c99/__init__.py +12 -0
  135. smallworld/state/models/aarch64/systemv/c99/signal.py +16 -0
  136. smallworld/state/models/aarch64/systemv/c99/stdio.py +265 -0
  137. smallworld/state/models/aarch64/systemv/c99/stdlib.py +169 -0
  138. smallworld/state/models/aarch64/systemv/c99/string.py +139 -0
  139. smallworld/state/models/aarch64/systemv/c99/time.py +61 -0
  140. smallworld/state/models/aarch64/systemv/posix/__init__.py +6 -0
  141. smallworld/state/models/aarch64/systemv/posix/libgen.py +16 -0
  142. smallworld/state/models/aarch64/systemv/posix/signal.py +157 -0
  143. smallworld/state/models/aarch64/systemv/systemv.py +80 -0
  144. smallworld/state/models/amd64/__init__.py +1 -0
  145. smallworld/state/models/amd64/systemv/__init__.py +6 -0
  146. smallworld/state/models/amd64/systemv/c99/__init__.py +12 -0
  147. smallworld/state/models/amd64/systemv/c99/signal.py +16 -0
  148. smallworld/state/models/amd64/systemv/c99/stdio.py +265 -0
  149. smallworld/state/models/amd64/systemv/c99/stdlib.py +169 -0
  150. smallworld/state/models/amd64/systemv/c99/string.py +139 -0
  151. smallworld/state/models/amd64/systemv/c99/time.py +61 -0
  152. smallworld/state/models/amd64/systemv/posix/__init__.py +6 -0
  153. smallworld/state/models/amd64/systemv/posix/libgen.py +16 -0
  154. smallworld/state/models/amd64/systemv/posix/signal.py +157 -0
  155. smallworld/state/models/amd64/systemv/systemv.py +78 -0
  156. smallworld/state/models/armel/__init__.py +1 -0
  157. smallworld/state/models/armel/systemv/__init__.py +6 -0
  158. smallworld/state/models/armel/systemv/c99/__init__.py +12 -0
  159. smallworld/state/models/armel/systemv/c99/signal.py +16 -0
  160. smallworld/state/models/armel/systemv/c99/stdio.py +265 -0
  161. smallworld/state/models/armel/systemv/c99/stdlib.py +169 -0
  162. smallworld/state/models/armel/systemv/c99/string.py +139 -0
  163. smallworld/state/models/armel/systemv/c99/time.py +61 -0
  164. smallworld/state/models/armel/systemv/posix/__init__.py +6 -0
  165. smallworld/state/models/armel/systemv/posix/libgen.py +16 -0
  166. smallworld/state/models/armel/systemv/posix/signal.py +157 -0
  167. smallworld/state/models/armel/systemv/systemv.py +82 -0
  168. smallworld/state/models/armhf/__init__.py +1 -0
  169. smallworld/state/models/armhf/systemv/__init__.py +6 -0
  170. smallworld/state/models/armhf/systemv/c99/__init__.py +12 -0
  171. smallworld/state/models/armhf/systemv/c99/signal.py +16 -0
  172. smallworld/state/models/armhf/systemv/c99/stdio.py +265 -0
  173. smallworld/state/models/armhf/systemv/c99/stdlib.py +169 -0
  174. smallworld/state/models/armhf/systemv/c99/string.py +139 -0
  175. smallworld/state/models/armhf/systemv/c99/time.py +61 -0
  176. smallworld/state/models/armhf/systemv/posix/__init__.py +6 -0
  177. smallworld/state/models/armhf/systemv/posix/libgen.py +16 -0
  178. smallworld/state/models/armhf/systemv/posix/signal.py +157 -0
  179. smallworld/state/models/armhf/systemv/systemv.py +77 -0
  180. smallworld/state/models/c99/__init__.py +12 -0
  181. smallworld/state/models/c99/fmt_print.py +915 -0
  182. smallworld/state/models/c99/fmt_scan.py +864 -0
  183. smallworld/state/models/c99/math.py +362 -0
  184. smallworld/state/models/c99/signal.py +71 -0
  185. smallworld/state/models/c99/stdio.py +1305 -0
  186. smallworld/state/models/c99/stdlib.py +595 -0
  187. smallworld/state/models/c99/string.py +674 -0
  188. smallworld/state/models/c99/time.py +340 -0
  189. smallworld/state/models/c99/utils.py +89 -0
  190. smallworld/state/models/cstd.py +759 -0
  191. smallworld/state/models/errno.py +581 -0
  192. smallworld/state/models/filedesc.py +515 -0
  193. smallworld/state/models/i386/__init__.py +1 -0
  194. smallworld/state/models/i386/systemv/__init__.py +6 -0
  195. smallworld/state/models/i386/systemv/c99/__init__.py +12 -0
  196. smallworld/state/models/i386/systemv/c99/signal.py +16 -0
  197. smallworld/state/models/i386/systemv/c99/stdio.py +265 -0
  198. smallworld/state/models/i386/systemv/c99/stdlib.py +169 -0
  199. smallworld/state/models/i386/systemv/c99/string.py +139 -0
  200. smallworld/state/models/i386/systemv/c99/time.py +61 -0
  201. smallworld/state/models/i386/systemv/posix/__init__.py +6 -0
  202. smallworld/state/models/i386/systemv/posix/libgen.py +16 -0
  203. smallworld/state/models/i386/systemv/posix/signal.py +157 -0
  204. smallworld/state/models/i386/systemv/systemv.py +71 -0
  205. smallworld/state/models/loongarch64/__init__.py +1 -0
  206. smallworld/state/models/loongarch64/systemv/__init__.py +6 -0
  207. smallworld/state/models/loongarch64/systemv/c99/__init__.py +12 -0
  208. smallworld/state/models/loongarch64/systemv/c99/signal.py +16 -0
  209. smallworld/state/models/loongarch64/systemv/c99/stdio.py +265 -0
  210. smallworld/state/models/loongarch64/systemv/c99/stdlib.py +169 -0
  211. smallworld/state/models/loongarch64/systemv/c99/string.py +139 -0
  212. smallworld/state/models/loongarch64/systemv/c99/time.py +61 -0
  213. smallworld/state/models/loongarch64/systemv/posix/__init__.py +6 -0
  214. smallworld/state/models/loongarch64/systemv/posix/libgen.py +16 -0
  215. smallworld/state/models/loongarch64/systemv/posix/signal.py +157 -0
  216. smallworld/state/models/loongarch64/systemv/systemv.py +83 -0
  217. smallworld/state/models/mips/__init__.py +1 -0
  218. smallworld/state/models/mips/systemv/__init__.py +6 -0
  219. smallworld/state/models/mips/systemv/c99/__init__.py +12 -0
  220. smallworld/state/models/mips/systemv/c99/signal.py +16 -0
  221. smallworld/state/models/mips/systemv/c99/stdio.py +265 -0
  222. smallworld/state/models/mips/systemv/c99/stdlib.py +169 -0
  223. smallworld/state/models/mips/systemv/c99/string.py +139 -0
  224. smallworld/state/models/mips/systemv/c99/time.py +61 -0
  225. smallworld/state/models/mips/systemv/posix/__init__.py +6 -0
  226. smallworld/state/models/mips/systemv/posix/libgen.py +16 -0
  227. smallworld/state/models/mips/systemv/posix/signal.py +157 -0
  228. smallworld/state/models/mips/systemv/systemv.py +78 -0
  229. smallworld/state/models/mips64/__init__.py +1 -0
  230. smallworld/state/models/mips64/systemv/__init__.py +6 -0
  231. smallworld/state/models/mips64/systemv/c99/__init__.py +12 -0
  232. smallworld/state/models/mips64/systemv/c99/signal.py +16 -0
  233. smallworld/state/models/mips64/systemv/c99/stdio.py +265 -0
  234. smallworld/state/models/mips64/systemv/c99/stdlib.py +169 -0
  235. smallworld/state/models/mips64/systemv/c99/string.py +139 -0
  236. smallworld/state/models/mips64/systemv/c99/time.py +61 -0
  237. smallworld/state/models/mips64/systemv/posix/__init__.py +6 -0
  238. smallworld/state/models/mips64/systemv/posix/libgen.py +16 -0
  239. smallworld/state/models/mips64/systemv/posix/signal.py +157 -0
  240. smallworld/state/models/mips64/systemv/systemv.py +98 -0
  241. smallworld/state/models/mips64el/__init__.py +1 -0
  242. smallworld/state/models/mips64el/systemv/__init__.py +6 -0
  243. smallworld/state/models/mips64el/systemv/c99/__init__.py +12 -0
  244. smallworld/state/models/mips64el/systemv/c99/signal.py +16 -0
  245. smallworld/state/models/mips64el/systemv/c99/stdio.py +265 -0
  246. smallworld/state/models/mips64el/systemv/c99/stdlib.py +169 -0
  247. smallworld/state/models/mips64el/systemv/c99/string.py +139 -0
  248. smallworld/state/models/mips64el/systemv/c99/time.py +61 -0
  249. smallworld/state/models/mips64el/systemv/posix/__init__.py +6 -0
  250. smallworld/state/models/mips64el/systemv/posix/libgen.py +16 -0
  251. smallworld/state/models/mips64el/systemv/posix/signal.py +157 -0
  252. smallworld/state/models/mips64el/systemv/systemv.py +96 -0
  253. smallworld/state/models/mipsel/__init__.py +1 -0
  254. smallworld/state/models/mipsel/systemv/__init__.py +6 -0
  255. smallworld/state/models/mipsel/systemv/c99/__init__.py +12 -0
  256. smallworld/state/models/mipsel/systemv/c99/signal.py +16 -0
  257. smallworld/state/models/mipsel/systemv/c99/stdio.py +265 -0
  258. smallworld/state/models/mipsel/systemv/c99/stdlib.py +169 -0
  259. smallworld/state/models/mipsel/systemv/c99/string.py +139 -0
  260. smallworld/state/models/mipsel/systemv/c99/time.py +61 -0
  261. smallworld/state/models/mipsel/systemv/posix/__init__.py +6 -0
  262. smallworld/state/models/mipsel/systemv/posix/libgen.py +16 -0
  263. smallworld/state/models/mipsel/systemv/posix/signal.py +157 -0
  264. smallworld/state/models/mipsel/systemv/systemv.py +78 -0
  265. smallworld/state/models/model.py +27 -2
  266. smallworld/state/models/posix/__init__.py +6 -0
  267. smallworld/state/models/posix/libgen.py +123 -0
  268. smallworld/state/models/posix/signal.py +690 -0
  269. smallworld/state/models/powerpc/__init__.py +1 -0
  270. smallworld/state/models/powerpc/systemv/__init__.py +6 -0
  271. smallworld/state/models/powerpc/systemv/c99/__init__.py +12 -0
  272. smallworld/state/models/powerpc/systemv/c99/signal.py +16 -0
  273. smallworld/state/models/powerpc/systemv/c99/stdio.py +265 -0
  274. smallworld/state/models/powerpc/systemv/c99/stdlib.py +169 -0
  275. smallworld/state/models/powerpc/systemv/c99/string.py +139 -0
  276. smallworld/state/models/powerpc/systemv/c99/time.py +61 -0
  277. smallworld/state/models/powerpc/systemv/posix/__init__.py +6 -0
  278. smallworld/state/models/powerpc/systemv/posix/libgen.py +16 -0
  279. smallworld/state/models/powerpc/systemv/posix/signal.py +157 -0
  280. smallworld/state/models/powerpc/systemv/systemv.py +93 -0
  281. smallworld/state/models/riscv64/__init__.py +1 -0
  282. smallworld/state/models/riscv64/systemv/__init__.py +6 -0
  283. smallworld/state/models/riscv64/systemv/c99/__init__.py +12 -0
  284. smallworld/state/models/riscv64/systemv/c99/signal.py +16 -0
  285. smallworld/state/models/riscv64/systemv/c99/stdio.py +265 -0
  286. smallworld/state/models/riscv64/systemv/c99/stdlib.py +169 -0
  287. smallworld/state/models/riscv64/systemv/c99/string.py +139 -0
  288. smallworld/state/models/riscv64/systemv/c99/time.py +61 -0
  289. smallworld/state/models/riscv64/systemv/posix/__init__.py +6 -0
  290. smallworld/state/models/riscv64/systemv/posix/libgen.py +16 -0
  291. smallworld/state/models/riscv64/systemv/posix/signal.py +157 -0
  292. smallworld/state/models/riscv64/systemv/systemv.py +85 -0
  293. smallworld/state/state.py +65 -24
  294. smallworld/state/unstable/elf.py +16 -31
  295. smallworld/utils.py +6 -1
  296. {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info}/METADATA +76 -43
  297. smallworld_re-2.0.0.dist-info/RECORD +374 -0
  298. {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info}/WHEEL +1 -1
  299. smallworld/state/models/x86/__init__.py +0 -2
  300. smallworld/state/models/x86/microsoftcdecl.py +0 -35
  301. smallworld/state/models/x86/systemv.py +0 -240
  302. smallworld_re-1.0.2.dist-info/RECORD +0 -166
  303. /smallworld/state/models/{posix.py → _posix.py} +0 -0
  304. {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info}/entry_points.txt +0 -0
  305. {smallworld_re-1.0.2.dist-info → smallworld_re-2.0.0.dist-info/licenses}/LICENSE.txt +0 -0
  306. {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._symbols: typing.List[ElfSymbol] = list()
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
- hint = Hint(message="Program includes dynamic linking metadata")
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
- hint = Hint(message=f"Program specifies interpreter {interp!r}")
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
- hint = Hint(message="Program includes thread-local storage")
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
- hint = Hint(message="Program specifies stack permissions")
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
- hint = Hint(message="Program specifies RELRO data")
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
- hint = Hint(f"Unknown OS-specific program header: {phdr.type:08x}")
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
- hint = Hint(
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
- hint = Hint(f"Invalid program header: {phdr.type.value:08x}")
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
- raise ConfigurationError(f"Unknown ARM flags: {list(map(hex, flags))}")
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(f" f: [ {seg_start:012x} -> {seg_end:012x} ]")
393
- log.debug(f" m: [ {seg_addr:012x} -> {seg_addr + seg_size:012x} ]")
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
- seg_data += b"\0" * (seg_size - (seg_start - seg_end))
401
- elif len(seg_data) != seg_size:
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
- self._symbols.append(sym)
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
- # Find the GOT and the number of local entries
454
- gotoff = None
455
- gotsym = None
456
- local_gotno = None
457
- for dt in elf.dynamic_entries:
458
- if dt.tag.value == DT_MIPS_GOTSYM:
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._relas.append(rela)
537
+ self._dynamic_relas.append(rela)
494
538
 
495
539
  gotoff += gotent
496
540
 
497
- for r in elf.relocations:
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._relas.append(rela)
551
+ self._dynamic_relas.append(rela)
505
552
 
506
- def _get_symbols(self, name: typing.Union[str, int]) -> typing.List[ElfSymbol]:
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
- return [self._symbols[name]]
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
- syms = self._get_symbols(name)
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
- syms = self._get_symbols(name)
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, name: typing.Union[str, int], value: int, rebase: bool = True
630
+ self,
631
+ name: typing.Union[str, int, ElfSymbol],
632
+ value: int,
633
+ dynamic: bool = False,
634
+ rebase: bool = True,
543
635
  ) -> None:
544
- syms = self._get_symbols(name)
545
- if len(syms) > 1:
546
- raise ConfigurationError(f"Multiple syms named {name}")
547
- sym = syms[0]
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
+ )