smallworld-re 1.0.3__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 +38 -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 +211 -57
  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.3.dist-info → smallworld_re-2.0.0.dist-info}/METADATA +74 -42
  297. smallworld_re-2.0.0.dist-info/RECORD +374 -0
  298. {smallworld_re-1.0.3.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.3.dist-info/RECORD +0 -166
  303. /smallworld/state/models/{posix.py → _posix.py} +0 -0
  304. {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/entry_points.txt +0 -0
  305. {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/licenses/LICENSE.txt +0 -0
  306. {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,674 @@
1
+ import locale
2
+
3
+ from .... import emulators, exceptions
4
+ from ..cstd import ArgumentType, CStdModel
5
+ from ..errno import ErrnoResolver
6
+ from .utils import (
7
+ MAX_STRLEN,
8
+ _emu_memcmp,
9
+ _emu_memcpy,
10
+ _emu_strlen,
11
+ _emu_strncat,
12
+ _emu_strncmp,
13
+ _emu_strncpy,
14
+ _emu_strnlen,
15
+ )
16
+
17
+
18
+ class Memcpy(CStdModel):
19
+ name = "memcpy"
20
+
21
+ # void *memcpy(void *restrict dst, const void *restrict src, size_t n);
22
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER, ArgumentType.SIZE_T]
23
+ return_type = ArgumentType.POINTER
24
+
25
+ def model(self, emulator: emulators.Emulator) -> None:
26
+ super().model(emulator)
27
+ dst = self.get_arg1(emulator)
28
+ src = self.get_arg2(emulator)
29
+ n = self.get_arg3(emulator)
30
+
31
+ assert isinstance(dst, int)
32
+ assert isinstance(src, int)
33
+ assert isinstance(n, int)
34
+
35
+ # FIXME: Does not actually mimic memcpy
36
+ # Will not clobber overlapping buffers
37
+ _emu_memcpy(emulator, dst, src, n)
38
+ self.set_return_value(emulator, dst)
39
+
40
+
41
+ class Memmove(CStdModel):
42
+ name = "memmove"
43
+
44
+ # void *memmove(void *restrict dst, const void *restrict src, size_t n);
45
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER, ArgumentType.SIZE_T]
46
+ return_type = ArgumentType.POINTER
47
+
48
+ def model(self, emulator: emulators.Emulator) -> None:
49
+ super().model(emulator)
50
+ dst = self.get_arg1(emulator)
51
+ src = self.get_arg2(emulator)
52
+ n = self.get_arg3(emulator)
53
+
54
+ assert isinstance(dst, int)
55
+ assert isinstance(src, int)
56
+ assert isinstance(n, int)
57
+
58
+ _emu_memcpy(emulator, dst, src, n)
59
+ self.set_return_value(emulator, dst)
60
+
61
+
62
+ class Strcpy(CStdModel):
63
+ name = "strcpy"
64
+
65
+ # char *strcpy(char *dst, const char *src);
66
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
67
+ return_type = ArgumentType.POINTER
68
+
69
+ def model(self, emulator: emulators.Emulator) -> None:
70
+ super().model(emulator)
71
+ dst = self.get_arg1(emulator)
72
+ src = self.get_arg2(emulator)
73
+
74
+ assert isinstance(dst, int)
75
+ assert isinstance(src, int)
76
+
77
+ n = _emu_strlen(emulator, src) + 1
78
+
79
+ _emu_memcpy(emulator, dst, src, n)
80
+ self.set_return_value(emulator, dst)
81
+
82
+
83
+ class Strncpy(CStdModel):
84
+ name = "strncpy"
85
+
86
+ # char *strcpy(char *dst, const char *src, size_t n);
87
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER, ArgumentType.SIZE_T]
88
+ return_type = ArgumentType.POINTER
89
+
90
+ def model(self, emulator: emulators.Emulator) -> None:
91
+ super().model(emulator)
92
+ dst = self.get_arg1(emulator)
93
+ src = self.get_arg2(emulator)
94
+ n = self.get_arg3(emulator)
95
+
96
+ assert isinstance(dst, int)
97
+ assert isinstance(src, int)
98
+ assert isinstance(n, int)
99
+
100
+ _emu_strncpy(emulator, dst, src, n)
101
+ self.set_return_value(emulator, dst)
102
+
103
+
104
+ class Strcat(CStdModel):
105
+ name = "strcat"
106
+
107
+ # char *strcat(char *restrict s1, const char *restrict s2);
108
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
109
+ return_type = ArgumentType.POINTER
110
+
111
+ def model(self, emulator: emulators.Emulator) -> None:
112
+ super().model(emulator)
113
+ dst = self.get_arg1(emulator)
114
+ src = self.get_arg2(emulator)
115
+
116
+ assert isinstance(dst, int)
117
+ assert isinstance(src, int)
118
+
119
+ _emu_strncat(emulator, dst, src, MAX_STRLEN)
120
+ self.set_return_value(emulator, dst)
121
+
122
+
123
+ class Strncat(CStdModel):
124
+ name = "strncat"
125
+
126
+ # char *strncat(char *restrict s1, const char *restrict s2, size_t n);
127
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER, ArgumentType.SIZE_T]
128
+ return_type = ArgumentType.POINTER
129
+
130
+ def model(self, emulator: emulators.Emulator) -> None:
131
+ super().model(emulator)
132
+ dst = self.get_arg1(emulator)
133
+ src = self.get_arg2(emulator)
134
+ n = self.get_arg3(emulator)
135
+
136
+ assert isinstance(dst, int)
137
+ assert isinstance(src, int)
138
+ assert isinstance(n, int)
139
+
140
+ _emu_strncat(emulator, dst, src, n)
141
+ self.set_return_value(emulator, dst)
142
+
143
+
144
+ class Memcmp(CStdModel):
145
+ name = "memcmp"
146
+
147
+ # int memcmp(const void *ptr1, const void *ptr2, size_t n);
148
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER, ArgumentType.SIZE_T]
149
+ return_type = ArgumentType.INT
150
+
151
+ def model(self, emulator: emulators.Emulator) -> None:
152
+ super().model(emulator)
153
+ ptr1 = self.get_arg1(emulator)
154
+ ptr2 = self.get_arg2(emulator)
155
+ n = self.get_arg3(emulator)
156
+
157
+ assert isinstance(ptr1, int)
158
+ assert isinstance(ptr2, int)
159
+ assert isinstance(n, int)
160
+
161
+ res = _emu_memcmp(emulator, ptr1, ptr2, n)
162
+ self.set_return_value(emulator, res)
163
+
164
+
165
+ class Strncmp(CStdModel):
166
+ name = "strncmp"
167
+
168
+ # int strncmp(const void *ptr1, const void *ptr2, size_t n);
169
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER, ArgumentType.SIZE_T]
170
+ return_type = ArgumentType.INT
171
+
172
+ def model(self, emulator: emulators.Emulator) -> None:
173
+ super().model(emulator)
174
+ # int strncmp(const char *ptr1, const char *ptr2, size_t n);
175
+ ptr1 = self.get_arg1(emulator)
176
+ ptr2 = self.get_arg2(emulator)
177
+ n = self.get_arg3(emulator)
178
+
179
+ assert isinstance(ptr1, int)
180
+ assert isinstance(ptr2, int)
181
+ assert isinstance(n, int)
182
+
183
+ res = _emu_strncmp(emulator, ptr1, ptr2, n)
184
+ self.set_return_value(emulator, res)
185
+
186
+
187
+ class Strcmp(CStdModel):
188
+ name = "strcmp"
189
+
190
+ # int strcmp(const void *ptr1, const void *ptr2);
191
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
192
+ return_type = ArgumentType.INT
193
+
194
+ def model(self, emulator: emulators.Emulator) -> None:
195
+ super().model(emulator)
196
+ # int strcmp(const char *ptr1, const char *ptr2);
197
+ ptr1 = self.get_arg1(emulator)
198
+ ptr2 = self.get_arg2(emulator)
199
+
200
+ assert isinstance(ptr1, int)
201
+ assert isinstance(ptr2, int)
202
+
203
+ res = _emu_strncmp(emulator, ptr1, ptr2, MAX_STRLEN)
204
+ self.set_return_value(emulator, res)
205
+
206
+
207
+ class Strcoll(CStdModel):
208
+ name = "strcoll"
209
+
210
+ # int strcoll(const void *ptr1, const void *ptr2);
211
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
212
+ return_type = ArgumentType.INT
213
+
214
+ # Won't respond to dynamic changes to the locale.
215
+ imprecise = True
216
+
217
+ def __init__(self, address: int):
218
+ super().__init__(address)
219
+ # NOTE: This requries extra configuration; set `locale` to the preferred locale.
220
+ # TODO: Think of a way to support dynamically-changing locales.
221
+ self.locale = ""
222
+
223
+ def model(self, emulator: emulators.Emulator) -> None:
224
+ super().model(emulator)
225
+ ptr1 = self.get_arg1(emulator)
226
+ ptr2 = self.get_arg2(emulator)
227
+
228
+ assert isinstance(ptr1, int)
229
+ assert isinstance(ptr2, int)
230
+
231
+ # TODO: This might be wrong if CTYPE is different
232
+ len1 = _emu_strlen(emulator, ptr1)
233
+ len2 = _emu_strlen(emulator, ptr2)
234
+
235
+ bytes1 = emulator.read_memory(ptr1, len1)
236
+ bytes2 = emulator.read_memory(ptr2, len2)
237
+
238
+ try:
239
+ # Risky. Inside this section, the locale will be different.
240
+ old_locale = locale.getlocale(category=locale.LC_COLLATE)
241
+ locale.setlocale(locale.LC_COLLATE, self.locale)
242
+ locale.setlocale(locale.LC_CTYPE, self.locale)
243
+
244
+ encoding = locale.getpreferredencoding()
245
+
246
+ str1 = bytes1.decode(encoding)
247
+ str2 = bytes2.decode(encoding)
248
+
249
+ res = locale.strcoll(str1, str2)
250
+
251
+ locale.setlocale(locale.LC_COLLATE, old_locale)
252
+ locale.setlocale(locale.LC_CTYPE, old_locale)
253
+ except Exception as e:
254
+ locale.setlocale(locale.LC_COLLATE, old_locale)
255
+ locale.setlocale(locale.LC_CTYPE, old_locale)
256
+ raise e
257
+
258
+ self.set_return_value(emulator, res)
259
+
260
+
261
+ class Strxfrm(CStdModel):
262
+ name = "strxfrm"
263
+
264
+ # size_t strxfrm(char *dst, const char *src, size_t n);
265
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER, ArgumentType.SIZE_T]
266
+ return_type = ArgumentType.SIZE_T
267
+
268
+ # Won't respond to dynamic changes to the locale.
269
+ imprecise = True
270
+
271
+ def __init__(self, address: int):
272
+ super().__init__(address)
273
+ # NOTE: This requries extra configuration; set `locale` to the preferred locale.
274
+ # TODO: Think of a way to support dynamically-changing locales.
275
+ self.locale = ""
276
+
277
+ def model(self, emulator: emulators.Emulator) -> None:
278
+ super().model(emulator)
279
+ dst = self.get_arg1(emulator)
280
+ src = self.get_arg2(emulator)
281
+ n = self.get_arg3(emulator)
282
+
283
+ assert isinstance(dst, int)
284
+ assert isinstance(src, int)
285
+ assert isinstance(n, int)
286
+
287
+ # TODO: This might be wrong if CTYPE is different
288
+ if n == 0:
289
+ n = _emu_strlen(emulator, src)
290
+ else:
291
+ n = _emu_strnlen(emulator, src, n)
292
+
293
+ self.set_return_value(emulator, n)
294
+
295
+ if dst == 0:
296
+ return
297
+
298
+ bytes1 = emulator.read_memory(src, n)
299
+
300
+ try:
301
+ # Risky. Inside this section, the locale will be different.
302
+ old_locale = locale.getlocale(category=locale.LC_COLLATE)
303
+ locale.setlocale(locale.LC_COLLATE, self.locale)
304
+ locale.setlocale(locale.LC_CTYPE, self.locale)
305
+
306
+ encoding = locale.getpreferredencoding()
307
+
308
+ str1 = bytes1.decode(encoding)
309
+
310
+ str2 = locale.strxfrm(str1)
311
+
312
+ bytes2 = str2.encode(encoding)
313
+
314
+ locale.setlocale(locale.LC_COLLATE, old_locale)
315
+ locale.setlocale(locale.LC_CTYPE, old_locale)
316
+ except Exception as e:
317
+ locale.setlocale(locale.LC_COLLATE, old_locale)
318
+ locale.setlocale(locale.LC_CTYPE, old_locale)
319
+ raise e
320
+
321
+ emulator.write_memory(dst, bytes2)
322
+
323
+
324
+ class Memchr(CStdModel):
325
+ name = "memchr"
326
+
327
+ # const void *memchr(const void *ptr, int value, size_t n);
328
+ argument_types = [ArgumentType.POINTER, ArgumentType.INT, ArgumentType.SIZE_T]
329
+ return_type = ArgumentType.SIZE_T
330
+
331
+ def model(self, emulator: emulators.Emulator) -> None:
332
+ super().model(emulator)
333
+ # const void *memchr(const void *ptr, int value, size_t n);
334
+ ptr = self.get_arg1(emulator)
335
+ val = self.get_arg2(emulator)
336
+ n = self.get_arg3(emulator)
337
+
338
+ assert isinstance(ptr, int)
339
+ assert isinstance(val, int)
340
+ assert isinstance(n, int)
341
+
342
+ data = emulator.read_memory(ptr, n)
343
+ for i in range(0, n):
344
+ if data[i] == val:
345
+ self.set_return_value(emulator, ptr + i)
346
+ return
347
+
348
+ self.set_return_value(emulator, 0)
349
+
350
+
351
+ class Strchr(CStdModel):
352
+ name = "strchr"
353
+
354
+ # const char *strchr(const char *ptr, int value);
355
+ argument_types = [ArgumentType.POINTER, ArgumentType.INT]
356
+ return_type = ArgumentType.POINTER
357
+
358
+ def model(self, emulator: emulators.Emulator) -> None:
359
+ super().model(emulator)
360
+ ptr = self.get_arg1(emulator)
361
+ val = self.get_arg2(emulator)
362
+
363
+ assert isinstance(ptr, int)
364
+ assert isinstance(val, int)
365
+
366
+ n = _emu_strlen(emulator, ptr)
367
+
368
+ data = emulator.read_memory(ptr, n)
369
+ for i in range(0, n):
370
+ if data[i] == val:
371
+ self.set_return_value(emulator, ptr + i)
372
+ return
373
+
374
+ self.set_return_value(emulator, 0)
375
+
376
+
377
+ class Strcspn(CStdModel):
378
+ name = "strcspn"
379
+
380
+ # size_t strcspn(const char *str1, const char *str2);
381
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
382
+ return_type = ArgumentType.SIZE_T
383
+
384
+ def model(self, emulator: emulators.Emulator) -> None:
385
+ super().model(emulator)
386
+ # size_t strcspn(const char *str1, const char *str2);
387
+ ptr1 = self.get_arg1(emulator)
388
+ ptr2 = self.get_arg2(emulator)
389
+
390
+ assert isinstance(ptr1, int)
391
+ assert isinstance(ptr2, int)
392
+
393
+ len1 = _emu_strlen(emulator, ptr1)
394
+ len2 = _emu_strlen(emulator, ptr2)
395
+
396
+ bytes1 = emulator.read_memory(ptr1, len1)
397
+ bytes2 = emulator.read_memory(ptr2, len2)
398
+
399
+ needles = {x for x in bytes2}
400
+
401
+ for i in range(0, len1):
402
+ if bytes1[i] in needles:
403
+ self.set_return_value(emulator, i)
404
+ return
405
+
406
+ self.set_return_value(emulator, len1)
407
+
408
+
409
+ class Strpbrk(CStdModel):
410
+ name = "strpbrk"
411
+
412
+ # const char *strpbrk(const char *str1, const char *str2);
413
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
414
+ return_type = ArgumentType.POINTER
415
+
416
+ def model(self, emulator: emulators.Emulator) -> None:
417
+ super().model(emulator)
418
+ ptr1 = self.get_arg1(emulator)
419
+ ptr2 = self.get_arg2(emulator)
420
+
421
+ assert isinstance(ptr1, int)
422
+ assert isinstance(ptr2, int)
423
+
424
+ len1 = _emu_strlen(emulator, ptr1)
425
+ len2 = _emu_strlen(emulator, ptr2)
426
+
427
+ bytes1 = emulator.read_memory(ptr1, len1)
428
+ bytes2 = emulator.read_memory(ptr2, len2)
429
+
430
+ needles = {x for x in bytes2}
431
+
432
+ for i in range(0, len1):
433
+ if bytes1[i] in needles:
434
+ self.set_return_value(emulator, ptr1 + i)
435
+ return
436
+
437
+ self.set_return_value(emulator, 0)
438
+
439
+
440
+ class Strrchr(CStdModel):
441
+ name = "strrchr"
442
+
443
+ # const char *strrchr(const char *ptr, int value);
444
+ argument_types = [ArgumentType.POINTER, ArgumentType.INT]
445
+ return_type = ArgumentType.POINTER
446
+
447
+ def model(self, emulator: emulators.Emulator) -> None:
448
+ super().model(emulator)
449
+ ptr = self.get_arg1(emulator)
450
+ val = self.get_arg2(emulator)
451
+
452
+ assert isinstance(ptr, int)
453
+ assert isinstance(val, int)
454
+
455
+ n = _emu_strlen(emulator, ptr)
456
+
457
+ data = emulator.read_memory(ptr, n)
458
+
459
+ for i in range(n - 1, -1, -1):
460
+ if data[i] == val:
461
+ self.set_return_value(emulator, ptr + i)
462
+ return
463
+
464
+ self.set_return_value(emulator, 0)
465
+
466
+
467
+ class Strspn(CStdModel):
468
+ name = "strspn"
469
+
470
+ # size_t strspn(const char *str1, const char *str2);
471
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
472
+ return_type = ArgumentType.SIZE_T
473
+
474
+ def model(self, emulator: emulators.Emulator) -> None:
475
+ super().model(emulator)
476
+ ptr1 = self.get_arg1(emulator)
477
+ ptr2 = self.get_arg2(emulator)
478
+
479
+ assert isinstance(ptr1, int)
480
+ assert isinstance(ptr2, int)
481
+
482
+ len1 = _emu_strlen(emulator, ptr1)
483
+ len2 = _emu_strlen(emulator, ptr2)
484
+
485
+ bytes1 = emulator.read_memory(ptr1, len1)
486
+ bytes2 = emulator.read_memory(ptr2, len2)
487
+
488
+ needles = {x for x in bytes2}
489
+
490
+ for i in range(0, len1):
491
+ if bytes1[i] not in needles:
492
+ self.set_return_value(emulator, i)
493
+ return
494
+
495
+ self.set_return_value(emulator, len1)
496
+
497
+
498
+ class Strstr(CStdModel):
499
+ name = "strstr"
500
+
501
+ # const char *strstr(const char *str1, const char *str2);
502
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
503
+ return_type = ArgumentType.POINTER
504
+
505
+ def model(self, emulator: emulators.Emulator) -> None:
506
+ super().model(emulator)
507
+ ptr1 = self.get_arg1(emulator)
508
+ ptr2 = self.get_arg2(emulator)
509
+
510
+ assert isinstance(ptr1, int)
511
+ assert isinstance(ptr2, int)
512
+
513
+ len1 = _emu_strlen(emulator, ptr1)
514
+ len2 = _emu_strlen(emulator, ptr2)
515
+
516
+ bytes1 = emulator.read_memory(ptr1, len1)
517
+ bytes2 = emulator.read_memory(ptr2, len2)
518
+
519
+ for i in range(0, len1):
520
+ if bytes1[i : i + len2] == bytes2:
521
+ self.set_return_value(emulator, ptr1 + i)
522
+ return
523
+
524
+ self.set_return_value(emulator, 0)
525
+
526
+
527
+ class Strtok(CStdModel):
528
+ name = "strtok"
529
+
530
+ # char *strtok(char *str, const char *delimiters);
531
+ argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
532
+ return_type = ArgumentType.POINTER
533
+
534
+ def __init__(self, address: int):
535
+ super().__init__(address)
536
+ self.ptr = 0
537
+
538
+ def model(self, emulator: emulators.Emulator) -> None:
539
+ super().model(emulator)
540
+ ptr1 = self.get_arg1(emulator)
541
+ ptr2 = self.get_arg2(emulator)
542
+
543
+ assert isinstance(ptr1, int)
544
+ assert isinstance(ptr2, int)
545
+
546
+ if ptr1 == 0:
547
+ if self.ptr == 0:
548
+ raise exceptions.EmulationError(
549
+ "strtok called with NULL when placeholder was NULL"
550
+ )
551
+ ptr1 = self.ptr
552
+
553
+ len1 = _emu_strlen(emulator, ptr1)
554
+ len2 = _emu_strlen(emulator, ptr2)
555
+
556
+ bytes1 = emulator.read_memory(ptr1, len1)
557
+ bytes2 = emulator.read_memory(ptr2, len2)
558
+
559
+ if len1 == 0:
560
+ # Empty string; we're out of tokens.
561
+ self.set_return_value(emulator, 0)
562
+ self.ptr = 0
563
+ return
564
+
565
+ # Non-empty string; we will have a token.
566
+ self.set_return_value(emulator, ptr1)
567
+
568
+ needles = {x for x in bytes2}
569
+ for i in range(0, len1):
570
+ if bytes1[i] in needles:
571
+ emulator.write_memory(ptr1 + i, b"\0")
572
+ self.ptr = ptr1 + i + 1
573
+ return
574
+
575
+ # Fall-through case; token lasts to end of string
576
+ self.ptr = ptr1 + len1
577
+
578
+
579
+ class Memset(CStdModel):
580
+ name = "memset"
581
+
582
+ # void *memset(void *ptr, int value, size_t num);
583
+ argument_types = [ArgumentType.POINTER, ArgumentType.INT, ArgumentType.SIZE_T]
584
+ return_type = ArgumentType.POINTER
585
+
586
+ def model(self, emulator: emulators.Emulator) -> None:
587
+ super().model(emulator)
588
+ ptr = self.get_arg1(emulator)
589
+ val = self.get_arg2(emulator)
590
+ n = self.get_arg3(emulator)
591
+
592
+ assert isinstance(ptr, int)
593
+ assert isinstance(val, int)
594
+ assert isinstance(n, int)
595
+
596
+ data = bytes([val & 0xFF]) * n
597
+ emulator.write_memory(ptr, data)
598
+
599
+ self.set_return_value(emulator, ptr)
600
+
601
+
602
+ class Strerror(CStdModel):
603
+ name = "strerror"
604
+
605
+ # const char *strerror(int errno);
606
+ argument_types = [ArgumentType.INT]
607
+ return_type = ArgumentType.POINTER
608
+
609
+ # Needs a string buffer for the description
610
+ static_space_required = 64
611
+
612
+ def model(self, emulator: emulators.Emulator) -> None:
613
+ super().model(emulator)
614
+
615
+ errno = self.get_arg1(emulator)
616
+
617
+ assert isinstance(errno, int)
618
+
619
+ resolver = ErrnoResolver.for_platform(self.platform, self.abi)
620
+
621
+ try:
622
+ description = resolver.get_description(errno)
623
+ except KeyError:
624
+ description = f"Unknown error {errno}"
625
+
626
+ descbytes = description.encode("utf-8") + b"\0"
627
+
628
+ assert len(descbytes) <= self.static_space_required
629
+ assert isinstance(self.static_buffer_address, int)
630
+ emulator.write_memory(self.static_buffer_address, descbytes)
631
+ self.set_return_value(emulator, self.static_buffer_address)
632
+
633
+
634
+ class Strlen(CStdModel):
635
+ name = "strlen"
636
+
637
+ # size_t strlen(const char *str);
638
+ argument_types = [ArgumentType.POINTER]
639
+ return_type = ArgumentType.SIZE_T
640
+
641
+ def model(self, emulator: emulators.Emulator) -> None:
642
+ super().model(emulator)
643
+ ptr = self.get_arg1(emulator)
644
+
645
+ assert isinstance(ptr, int)
646
+
647
+ res = _emu_strlen(emulator, ptr)
648
+ self.set_return_value(emulator, res)
649
+
650
+
651
+ __all__ = [
652
+ "Memcpy",
653
+ "Memmove",
654
+ "Strcpy",
655
+ "Strncpy",
656
+ "Strcat",
657
+ "Strncat",
658
+ "Memcmp",
659
+ "Strncmp",
660
+ "Strcmp",
661
+ "Strcoll",
662
+ "Strxfrm",
663
+ "Memchr",
664
+ "Strchr",
665
+ "Strcspn",
666
+ "Strpbrk",
667
+ "Strrchr",
668
+ "Strspn",
669
+ "Strstr",
670
+ "Strtok",
671
+ "Memset",
672
+ "Strerror",
673
+ "Strlen",
674
+ ]