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.
- 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 +38 -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 +211 -57
- 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.3.dist-info → smallworld_re-2.0.0.dist-info}/METADATA +74 -42
- smallworld_re-2.0.0.dist-info/RECORD +374 -0
- {smallworld_re-1.0.3.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.3.dist-info/RECORD +0 -166
- /smallworld/state/models/{posix.py → _posix.py} +0 -0
- {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/entry_points.txt +0 -0
- {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/licenses/LICENSE.txt +0 -0
- {smallworld_re-1.0.3.dist-info → smallworld_re-2.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1305 @@
|
|
1
|
+
import random
|
2
|
+
import string
|
3
|
+
import typing
|
4
|
+
|
5
|
+
from .... import emulators, exceptions
|
6
|
+
from ....platforms import Byteorder
|
7
|
+
from ..cstd import ArgumentType, CStdModel
|
8
|
+
from ..filedesc import FDIOError, FileDescriptorManager
|
9
|
+
from .fmt_print import parse_printf_format
|
10
|
+
from .fmt_scan import FileIntake, StringIntake, handle_scanf_format
|
11
|
+
from .utils import _emu_strlen
|
12
|
+
|
13
|
+
|
14
|
+
class StdioModel(CStdModel):
|
15
|
+
def __init__(self, address: int):
|
16
|
+
super().__init__(address)
|
17
|
+
self._fdmgr = FileDescriptorManager.for_platform(self.platform, self.abi)
|
18
|
+
|
19
|
+
def _parse_mode(self, mode: str) -> typing.Tuple[bool, bool, bool, bool, bool]:
|
20
|
+
readable = False
|
21
|
+
writable = False
|
22
|
+
create = False
|
23
|
+
truncate = False
|
24
|
+
append = True
|
25
|
+
if mode in ("r", "rb"):
|
26
|
+
# - Open for reading
|
27
|
+
# - Fails if doesn't exist
|
28
|
+
# - Cursor starts at zero
|
29
|
+
readable = True
|
30
|
+
elif mode in ("r+", "r+b"):
|
31
|
+
# - Open for reading and writing
|
32
|
+
# - Fails if doesn't exist
|
33
|
+
# - Cursor starts at zero
|
34
|
+
readable = True
|
35
|
+
writable = True
|
36
|
+
elif mode in ("w", "wb"):
|
37
|
+
# - Open for writing
|
38
|
+
# - Creates if doesn't exist
|
39
|
+
# - Truncates if exists
|
40
|
+
# - Cursor starts at zero
|
41
|
+
writable = True
|
42
|
+
create = True
|
43
|
+
truncate = True
|
44
|
+
elif mode in ("w+", "w+b"):
|
45
|
+
# - Open for reading and writing
|
46
|
+
# - Creates if doesn't exist
|
47
|
+
# - Truncates if exists
|
48
|
+
# - Cursor starts at zero
|
49
|
+
readable = True
|
50
|
+
writable = True
|
51
|
+
create = True
|
52
|
+
truncate = True
|
53
|
+
elif mode in ("a", "ab"):
|
54
|
+
# - Open for writing
|
55
|
+
# - Creates if doesn't exist
|
56
|
+
# - Cursor starts at end
|
57
|
+
writable = True
|
58
|
+
create = True
|
59
|
+
append = True
|
60
|
+
elif mode in ("a+", "a+b"):
|
61
|
+
# - Open for reading and writing
|
62
|
+
# - Creates if doesn't exist
|
63
|
+
# - Start is unspecified; glibc does the beginning
|
64
|
+
readable = True
|
65
|
+
writable = True
|
66
|
+
create = True
|
67
|
+
else:
|
68
|
+
raise FDIOError(f"Unknown mode {mode}")
|
69
|
+
|
70
|
+
return (readable, writable, create, truncate, append)
|
71
|
+
|
72
|
+
def _generate_tmpnam(self):
|
73
|
+
# TODO: Doesn't actually test uniqueness
|
74
|
+
search = string.ascii_letters + "0123456789"
|
75
|
+
|
76
|
+
out = "/tmp/file"
|
77
|
+
for i in range(0, 6):
|
78
|
+
out += search[random.randint(0, len(search) - 1)]
|
79
|
+
|
80
|
+
return out
|
81
|
+
|
82
|
+
|
83
|
+
class Fclose(StdioModel):
|
84
|
+
name = "fclose"
|
85
|
+
|
86
|
+
# int fclose(FILE *file);
|
87
|
+
argument_types = [ArgumentType.POINTER]
|
88
|
+
return_type = ArgumentType.INT
|
89
|
+
|
90
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
91
|
+
super().model(emulator)
|
92
|
+
ptr = self.get_arg1(emulator)
|
93
|
+
|
94
|
+
assert isinstance(ptr, int)
|
95
|
+
|
96
|
+
try:
|
97
|
+
fd = self._fdmgr.filestar_to_fd(ptr)
|
98
|
+
self._fdmgr.close(fd)
|
99
|
+
self.set_return_value(emulator, 0)
|
100
|
+
except FDIOError:
|
101
|
+
self.set_return_value(emulator, -1)
|
102
|
+
|
103
|
+
|
104
|
+
class Feof(StdioModel):
|
105
|
+
name = "feof"
|
106
|
+
|
107
|
+
# int feof(FILE *file);
|
108
|
+
argument_types = [ArgumentType.POINTER]
|
109
|
+
return_type = ArgumentType.INT
|
110
|
+
|
111
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
112
|
+
super().model(emulator)
|
113
|
+
|
114
|
+
filestar = self.get_arg1(emulator)
|
115
|
+
|
116
|
+
assert isinstance(filestar, int)
|
117
|
+
|
118
|
+
try:
|
119
|
+
fd = self._fdmgr.filestar_to_fd(filestar)
|
120
|
+
file = self._fdmgr.get(fd)
|
121
|
+
except FDIOError:
|
122
|
+
print(f"Failed looking up filestar {filestar:x}")
|
123
|
+
self.set_return_value(emulator, -1)
|
124
|
+
return
|
125
|
+
|
126
|
+
print(f"EOF: {file.eof}")
|
127
|
+
self.set_return_value(emulator, 1 if file.eof else 0)
|
128
|
+
|
129
|
+
|
130
|
+
class Ferror(StdioModel):
|
131
|
+
name = "ferror"
|
132
|
+
|
133
|
+
# int ferror(FILE *file);
|
134
|
+
argument_types = [ArgumentType.POINTER]
|
135
|
+
return_type = ArgumentType.INT
|
136
|
+
|
137
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
138
|
+
super().model(emulator)
|
139
|
+
|
140
|
+
# We never have errors.
|
141
|
+
self.set_return_value(emulator, 0)
|
142
|
+
|
143
|
+
|
144
|
+
class Clearerr(StdioModel):
|
145
|
+
name = "clearerr"
|
146
|
+
|
147
|
+
# void clearerr(FILE *file);
|
148
|
+
argument_types = [ArgumentType.POINTER]
|
149
|
+
return_type = ArgumentType.VOID
|
150
|
+
|
151
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
152
|
+
super().model(emulator)
|
153
|
+
|
154
|
+
filestar = self.get_arg1(emulator)
|
155
|
+
|
156
|
+
assert isinstance(filestar, int)
|
157
|
+
|
158
|
+
try:
|
159
|
+
fd = self._fdmgr.filestar_to_fd(filestar)
|
160
|
+
file = self._fdmgr.get(fd)
|
161
|
+
except FDIOError:
|
162
|
+
print(f"Failed looking up filestar {filestar:x}")
|
163
|
+
self.set_return_value(emulator, -1)
|
164
|
+
return
|
165
|
+
|
166
|
+
file.eof = False
|
167
|
+
|
168
|
+
|
169
|
+
class Fflush(StdioModel):
|
170
|
+
name = "fflush"
|
171
|
+
|
172
|
+
# int fflush(FILE *file);
|
173
|
+
argument_types = [ArgumentType.POINTER]
|
174
|
+
return_type = ArgumentType.INT
|
175
|
+
|
176
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
177
|
+
super().model(emulator)
|
178
|
+
# TODO: If you want to model something more interesting here, we can talk.
|
179
|
+
self.set_return_value(emulator, 0)
|
180
|
+
|
181
|
+
|
182
|
+
class Fgetc(StdioModel):
|
183
|
+
name = "fgetc"
|
184
|
+
|
185
|
+
# int fgetc(FILE *file);
|
186
|
+
argument_types = [ArgumentType.POINTER]
|
187
|
+
return_type = ArgumentType.INT
|
188
|
+
|
189
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
190
|
+
super().model(emulator)
|
191
|
+
|
192
|
+
filestar = self.get_arg1(emulator)
|
193
|
+
|
194
|
+
assert isinstance(filestar, int)
|
195
|
+
|
196
|
+
try:
|
197
|
+
fd = self._fdmgr.filestar_to_fd(filestar)
|
198
|
+
file = self._fdmgr.get(fd)
|
199
|
+
except FDIOError:
|
200
|
+
print(f"Failed looking up filestar {filestar:x}")
|
201
|
+
self.set_return_value(emulator, -1)
|
202
|
+
return
|
203
|
+
|
204
|
+
try:
|
205
|
+
data = file.read(1, ungetc=True)
|
206
|
+
except Exception as e:
|
207
|
+
print(f"Failed reading from {file.name}: {e}")
|
208
|
+
raise e
|
209
|
+
|
210
|
+
print(f"Returning {data[0]:x}")
|
211
|
+
self.set_return_value(emulator, data[0])
|
212
|
+
|
213
|
+
|
214
|
+
class Fgets(StdioModel):
|
215
|
+
name = "fgets"
|
216
|
+
|
217
|
+
# char *fgets(char *dst, size_t size, FILE *file);
|
218
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.SIZE_T, ArgumentType.POINTER]
|
219
|
+
return_type = ArgumentType.POINTER
|
220
|
+
|
221
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
222
|
+
super().model(emulator)
|
223
|
+
|
224
|
+
dst = self.get_arg1(emulator)
|
225
|
+
size = self.get_arg2(emulator)
|
226
|
+
filestar = self.get_arg3(emulator)
|
227
|
+
|
228
|
+
assert isinstance(dst, int)
|
229
|
+
assert isinstance(size, int)
|
230
|
+
assert isinstance(filestar, int)
|
231
|
+
|
232
|
+
try:
|
233
|
+
fd = self._fdmgr.filestar_to_fd(filestar)
|
234
|
+
file = self._fdmgr.get(fd)
|
235
|
+
except FDIOError:
|
236
|
+
self.set_return_value(emulator, 0)
|
237
|
+
return
|
238
|
+
|
239
|
+
data = file.read_string(size)
|
240
|
+
emulator.write_memory(dst, data)
|
241
|
+
self.set_return_value(emulator, dst)
|
242
|
+
|
243
|
+
|
244
|
+
class Fopen(StdioModel):
|
245
|
+
name = "fopen"
|
246
|
+
|
247
|
+
# FILE *fopen(const char *path, const char *mode);
|
248
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
|
249
|
+
return_type = ArgumentType.POINTER
|
250
|
+
|
251
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
252
|
+
super().model(emulator)
|
253
|
+
ptr1 = self.get_arg1(emulator)
|
254
|
+
ptr2 = self.get_arg2(emulator)
|
255
|
+
|
256
|
+
assert isinstance(ptr1, int)
|
257
|
+
assert isinstance(ptr2, int)
|
258
|
+
|
259
|
+
len1 = _emu_strlen(emulator, ptr1)
|
260
|
+
len2 = _emu_strlen(emulator, ptr2)
|
261
|
+
|
262
|
+
bytes1 = emulator.read_memory(ptr1, len1)
|
263
|
+
bytes2 = emulator.read_memory(ptr2, len2)
|
264
|
+
|
265
|
+
filepath = bytes1.decode("utf-8")
|
266
|
+
filemode = bytes2.decode("utf-8")
|
267
|
+
|
268
|
+
# FIXME: Not all files are seekable.
|
269
|
+
# For now, assume this one is.
|
270
|
+
seekable = True
|
271
|
+
|
272
|
+
try:
|
273
|
+
readable, writable, create, truncate, append = self._parse_mode(filemode)
|
274
|
+
fd = self._fdmgr.open(
|
275
|
+
filepath,
|
276
|
+
readable=readable,
|
277
|
+
writable=writable,
|
278
|
+
create=create,
|
279
|
+
truncate=truncate,
|
280
|
+
append=append,
|
281
|
+
seekable=seekable,
|
282
|
+
)
|
283
|
+
except FDIOError:
|
284
|
+
self.set_return_value(emulator, 0)
|
285
|
+
return
|
286
|
+
|
287
|
+
filestar = self._fdmgr.fd_to_filestar(fd)
|
288
|
+
self.set_return_value(emulator, filestar)
|
289
|
+
|
290
|
+
|
291
|
+
class Freopen(StdioModel):
|
292
|
+
name = "freopen"
|
293
|
+
|
294
|
+
# FILE *freopen(const char *filename, const char *mode, FILE *stream);
|
295
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
|
296
|
+
return_type = ArgumentType.POINTER
|
297
|
+
|
298
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
299
|
+
super().model(emulator)
|
300
|
+
|
301
|
+
name = self.get_arg1(emulator)
|
302
|
+
mode = self.get_arg2(emulator)
|
303
|
+
filestar = self.get_arg3(emulator)
|
304
|
+
|
305
|
+
assert isinstance(name, int)
|
306
|
+
assert isinstance(mode, int)
|
307
|
+
assert isinstance(filestar, int)
|
308
|
+
|
309
|
+
len2 = _emu_strlen(emulator, mode)
|
310
|
+
|
311
|
+
bytes2 = emulator.read_memory(mode, len2)
|
312
|
+
|
313
|
+
filemode = bytes2.decode("utf-8")
|
314
|
+
|
315
|
+
# FIXME: Not all files are seekable.
|
316
|
+
# For now, assume this one is.
|
317
|
+
seekable = True
|
318
|
+
|
319
|
+
# Reset the access mode on the file
|
320
|
+
try:
|
321
|
+
fd = self._fdmgr.filestar_to_fd(filestar)
|
322
|
+
file = self._fdmgr.get(fd)
|
323
|
+
readable, writable, _, _, _ = self._parse_mode(filemode)
|
324
|
+
except FDIOError:
|
325
|
+
self.set_return_value(emulator, 0)
|
326
|
+
return
|
327
|
+
|
328
|
+
file.readable = readable
|
329
|
+
file.writable = writable
|
330
|
+
file.seekable = seekable
|
331
|
+
|
332
|
+
# Redirect the file if name is not NULL
|
333
|
+
if name != 0:
|
334
|
+
len1 = _emu_strlen(emulator, name)
|
335
|
+
bytes1 = emulator.read_memory(name, len1)
|
336
|
+
filepath = bytes1.decode("utf-8")
|
337
|
+
|
338
|
+
file.name = filepath
|
339
|
+
|
340
|
+
self.set_return_value(emulator, filestar)
|
341
|
+
|
342
|
+
|
343
|
+
class Fprintf(StdioModel):
|
344
|
+
name = "fprintf"
|
345
|
+
|
346
|
+
# int fprintf(FILE *file, const char *fmt, ...);
|
347
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
|
348
|
+
return_type = ArgumentType.INT
|
349
|
+
|
350
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
351
|
+
super().model(emulator)
|
352
|
+
|
353
|
+
filestar = self.get_arg1(emulator)
|
354
|
+
fmt_addr = self.get_arg2(emulator)
|
355
|
+
|
356
|
+
assert isinstance(fmt_addr, int)
|
357
|
+
|
358
|
+
fmt_len = _emu_strlen(emulator, fmt_addr)
|
359
|
+
fmt_bytes = emulator.read_memory(fmt_addr, fmt_len)
|
360
|
+
fmt = fmt_bytes.decode("utf-8")
|
361
|
+
|
362
|
+
output = parse_printf_format(self, fmt, emulator)
|
363
|
+
output_bytes = output.encode("utf-8")
|
364
|
+
|
365
|
+
try:
|
366
|
+
fd = self._fdmgr.filestar_to_fd(filestar)
|
367
|
+
file = self._fdmgr.get(fd)
|
368
|
+
except FDIOError:
|
369
|
+
self.set_return_value(emulator, -1)
|
370
|
+
return
|
371
|
+
|
372
|
+
file.write(output_bytes)
|
373
|
+
|
374
|
+
self.set_return_value(emulator, len(output_bytes))
|
375
|
+
|
376
|
+
|
377
|
+
class Fputc(StdioModel):
|
378
|
+
name = "fputc"
|
379
|
+
|
380
|
+
# int fputc(int c, FILE *file);
|
381
|
+
argument_types = [ArgumentType.INT, ArgumentType.POINTER]
|
382
|
+
return_type = ArgumentType.INT
|
383
|
+
|
384
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
385
|
+
super().model(emulator)
|
386
|
+
|
387
|
+
char = self.get_arg1(emulator)
|
388
|
+
filestar = self.get_arg2(emulator)
|
389
|
+
|
390
|
+
assert isinstance(char, int)
|
391
|
+
assert isinstance(filestar, int)
|
392
|
+
|
393
|
+
try:
|
394
|
+
fd = self._fdmgr.filestar_to_fd(filestar)
|
395
|
+
file = self._fdmgr.get(fd)
|
396
|
+
except FDIOError:
|
397
|
+
self.set_return_value(emulator, -1)
|
398
|
+
return
|
399
|
+
|
400
|
+
file.write(bytes([char]))
|
401
|
+
|
402
|
+
self.set_return_value(emulator, char)
|
403
|
+
|
404
|
+
|
405
|
+
class Fputs(StdioModel):
|
406
|
+
name = "fputs"
|
407
|
+
|
408
|
+
# int fputs(const char *str, FILE *file);
|
409
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
|
410
|
+
return_type = ArgumentType.INT
|
411
|
+
|
412
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
413
|
+
super().model(emulator)
|
414
|
+
|
415
|
+
ptr = self.get_arg1(emulator)
|
416
|
+
filestar = self.get_arg2(emulator)
|
417
|
+
|
418
|
+
assert isinstance(ptr, int)
|
419
|
+
assert isinstance(filestar, int)
|
420
|
+
|
421
|
+
strlen = _emu_strlen(emulator, ptr)
|
422
|
+
strbytes = emulator.read_memory(ptr, strlen)
|
423
|
+
|
424
|
+
try:
|
425
|
+
fd = self._fdmgr.filestar_to_fd(filestar)
|
426
|
+
file = self._fdmgr.get(fd)
|
427
|
+
except FDIOError:
|
428
|
+
self.set_return_value(emulator, -1)
|
429
|
+
return
|
430
|
+
|
431
|
+
file.write(strbytes)
|
432
|
+
|
433
|
+
self.set_return_value(emulator, 0)
|
434
|
+
|
435
|
+
|
436
|
+
class Fread(StdioModel):
|
437
|
+
name = "fread"
|
438
|
+
|
439
|
+
# size_t fread(void *dst, size_t size, size_t amt, FILE *file);
|
440
|
+
argument_types = [
|
441
|
+
ArgumentType.POINTER,
|
442
|
+
ArgumentType.SIZE_T,
|
443
|
+
ArgumentType.SIZE_T,
|
444
|
+
ArgumentType.POINTER,
|
445
|
+
]
|
446
|
+
return_type = ArgumentType.SIZE_T
|
447
|
+
|
448
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
449
|
+
super().model(emulator)
|
450
|
+
|
451
|
+
dst = self.get_arg1(emulator)
|
452
|
+
size = self.get_arg2(emulator)
|
453
|
+
amt = self.get_arg3(emulator)
|
454
|
+
filestar = self.get_arg4(emulator)
|
455
|
+
|
456
|
+
assert isinstance(dst, int)
|
457
|
+
assert isinstance(size, int)
|
458
|
+
assert isinstance(amt, int)
|
459
|
+
assert isinstance(filestar, int)
|
460
|
+
|
461
|
+
try:
|
462
|
+
fd = self._fdmgr.filestar_to_fd(filestar)
|
463
|
+
file = self._fdmgr.get(fd)
|
464
|
+
except FDIOError:
|
465
|
+
self.set_return_value(emulator, -1)
|
466
|
+
return
|
467
|
+
|
468
|
+
i = 0
|
469
|
+
for i in range(0, amt):
|
470
|
+
data = file.read(size)
|
471
|
+
if len(data) != size:
|
472
|
+
file.cursor -= len(data)
|
473
|
+
break
|
474
|
+
|
475
|
+
emulator.write_memory(dst, data)
|
476
|
+
dst += size
|
477
|
+
|
478
|
+
self.set_return_value(emulator, i)
|
479
|
+
|
480
|
+
|
481
|
+
class Fscanf(StdioModel):
|
482
|
+
name = "fscanf"
|
483
|
+
|
484
|
+
# int fscanf(FILE *, const char *fmt, ...);
|
485
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
|
486
|
+
return_type = ArgumentType.INT
|
487
|
+
|
488
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
489
|
+
super().model(emulator)
|
490
|
+
|
491
|
+
filestar = self.get_arg1(emulator)
|
492
|
+
fmt_addr = self.get_arg2(emulator)
|
493
|
+
|
494
|
+
assert isinstance(filestar, int)
|
495
|
+
assert isinstance(fmt_addr, int)
|
496
|
+
|
497
|
+
fmt_len = _emu_strlen(emulator, fmt_addr)
|
498
|
+
fmt_bytes = emulator.read_memory(fmt_addr, fmt_len)
|
499
|
+
fmt = fmt_bytes.decode("utf-8")
|
500
|
+
|
501
|
+
try:
|
502
|
+
fd = self._fdmgr.filestar_to_fd(filestar)
|
503
|
+
file = self._fdmgr.get(fd)
|
504
|
+
except FDIOError:
|
505
|
+
self.set_return_value(emulator, -1)
|
506
|
+
return
|
507
|
+
|
508
|
+
intake = FileIntake(file)
|
509
|
+
|
510
|
+
res = handle_scanf_format(self, intake, fmt, emulator)
|
511
|
+
|
512
|
+
self.set_return_value(emulator, res)
|
513
|
+
|
514
|
+
|
515
|
+
class Fseek(StdioModel):
|
516
|
+
name = "fseek"
|
517
|
+
|
518
|
+
# int fseek(FILE *file, long int offset, int origin);
|
519
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.LONG, ArgumentType.INT]
|
520
|
+
return_type = ArgumentType.INT
|
521
|
+
|
522
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
523
|
+
super().model(emulator)
|
524
|
+
|
525
|
+
filestar = self.get_arg1(emulator)
|
526
|
+
offset = self.get_arg2(emulator)
|
527
|
+
origin = self.get_arg3(emulator)
|
528
|
+
|
529
|
+
assert isinstance(filestar, int)
|
530
|
+
assert isinstance(offset, int)
|
531
|
+
assert isinstance(offset, int)
|
532
|
+
|
533
|
+
try:
|
534
|
+
fd = self._fdmgr.filestar_to_fd(filestar)
|
535
|
+
file = self._fdmgr.get(fd)
|
536
|
+
except FDIOError:
|
537
|
+
self.set_return_value(emulator, -1)
|
538
|
+
return
|
539
|
+
|
540
|
+
pos = file.seek(offset, origin)
|
541
|
+
self.set_return_value(emulator, pos)
|
542
|
+
|
543
|
+
|
544
|
+
class Ftell(StdioModel):
|
545
|
+
name = "ftell"
|
546
|
+
|
547
|
+
# long ftell(FILE *file);
|
548
|
+
argument_types = [ArgumentType.POINTER]
|
549
|
+
return_type = ArgumentType.LONG
|
550
|
+
|
551
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
552
|
+
super().model(emulator)
|
553
|
+
filestar = self.get_arg1(emulator)
|
554
|
+
|
555
|
+
assert isinstance(filestar, int)
|
556
|
+
|
557
|
+
try:
|
558
|
+
fd = self._fdmgr.filestar_to_fd(filestar)
|
559
|
+
file = self._fdmgr.get(fd)
|
560
|
+
except FDIOError:
|
561
|
+
self.set_return_value(emulator, -1)
|
562
|
+
|
563
|
+
self.set_return_value(emulator, file.cursor)
|
564
|
+
|
565
|
+
|
566
|
+
class Fgetpos(StdioModel):
|
567
|
+
name = "fgetpos"
|
568
|
+
|
569
|
+
# int fgetpos(FILE *file, fpos_t *pos);
|
570
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
|
571
|
+
return_type = ArgumentType.INT
|
572
|
+
|
573
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
574
|
+
super().model(emulator)
|
575
|
+
|
576
|
+
filestar = self.get_arg1(emulator)
|
577
|
+
ptr = self.get_arg2(emulator)
|
578
|
+
|
579
|
+
assert isinstance(filestar, int)
|
580
|
+
assert isinstance(ptr, int)
|
581
|
+
|
582
|
+
try:
|
583
|
+
fd = self._fdmgr.filestar_to_fd(filestar)
|
584
|
+
file = self._fdmgr.get(fd)
|
585
|
+
except FDIOError:
|
586
|
+
self.set_return_value(emulator, -1)
|
587
|
+
|
588
|
+
# Okay, this is a pain.
|
589
|
+
# fpos_t is platform-specific.
|
590
|
+
# On GNU Linux, it's always a struct, and always
|
591
|
+
# at least eight bytes.
|
592
|
+
# One fieldis the offset. No idea what the other is.
|
593
|
+
#
|
594
|
+
# If you read from inside this, I grump at you.
|
595
|
+
|
596
|
+
if self.platform.byteorder == Byteorder.LITTLE:
|
597
|
+
data = file.cursor.to_bytes(8, "little")
|
598
|
+
elif self.platform.byteorder == Byteorder.BIG:
|
599
|
+
data = file.cursor.to_bytes(8, "big")
|
600
|
+
else:
|
601
|
+
raise exceptions.ConfigurationError(
|
602
|
+
f"Can't encode int for byteorder {self.platform.byteorder}"
|
603
|
+
)
|
604
|
+
|
605
|
+
emulator.write_memory(ptr, data)
|
606
|
+
self.set_return_value(emulator, 0)
|
607
|
+
|
608
|
+
|
609
|
+
class Fsetpos(StdioModel):
|
610
|
+
name = "fsetpos"
|
611
|
+
|
612
|
+
# int ftell(FILE *file, fpos_t *pos);
|
613
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
|
614
|
+
return_type = ArgumentType.INT
|
615
|
+
|
616
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
617
|
+
super().model(emulator)
|
618
|
+
|
619
|
+
filestar = self.get_arg1(emulator)
|
620
|
+
ptr = self.get_arg2(emulator)
|
621
|
+
|
622
|
+
assert isinstance(filestar, int)
|
623
|
+
assert isinstance(ptr, int)
|
624
|
+
|
625
|
+
try:
|
626
|
+
fd = self._fdmgr.filestar_to_fd(filestar)
|
627
|
+
file = self._fdmgr.get(fd)
|
628
|
+
except FDIOError:
|
629
|
+
self.set_return_value(emulator, -1)
|
630
|
+
|
631
|
+
# Okay, this is a pain.
|
632
|
+
# fpos_t is platform-specific.
|
633
|
+
# On GNU Linux, it's always a struct, and always
|
634
|
+
# at least eight bytes.
|
635
|
+
# One fieldis the offset. No idea what the other is.
|
636
|
+
#
|
637
|
+
# If you read from inside this, I grump at you.
|
638
|
+
|
639
|
+
data = emulator.read_memory(ptr, 8)
|
640
|
+
|
641
|
+
if self.platform.byteorder == Byteorder.LITTLE:
|
642
|
+
pos = int.from_bytes(data, "little")
|
643
|
+
elif self.platform.byteorder == Byteorder.BIG:
|
644
|
+
pos = int.from_bytes(data, "big")
|
645
|
+
else:
|
646
|
+
raise exceptions.ConfigurationError(
|
647
|
+
f"Can't encode int for byteorder {self.platform.byteorder}"
|
648
|
+
)
|
649
|
+
|
650
|
+
file.seek(pos, 0)
|
651
|
+
self.set_return_value(emulator, 0)
|
652
|
+
|
653
|
+
|
654
|
+
class Fwrite(StdioModel):
|
655
|
+
name = "fwrite"
|
656
|
+
|
657
|
+
# int fwrite(void *src, size_t size, size_t amt, FILE *file);
|
658
|
+
argument_types = [
|
659
|
+
ArgumentType.POINTER,
|
660
|
+
ArgumentType.SIZE_T,
|
661
|
+
ArgumentType.SIZE_T,
|
662
|
+
ArgumentType.POINTER,
|
663
|
+
]
|
664
|
+
return_type = ArgumentType.SIZE_T
|
665
|
+
|
666
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
667
|
+
super().model(emulator)
|
668
|
+
|
669
|
+
src = self.get_arg1(emulator)
|
670
|
+
size = self.get_arg2(emulator)
|
671
|
+
amt = self.get_arg3(emulator)
|
672
|
+
filestar = self.get_arg4(emulator)
|
673
|
+
|
674
|
+
assert isinstance(src, int)
|
675
|
+
assert isinstance(size, int)
|
676
|
+
assert isinstance(amt, int)
|
677
|
+
assert isinstance(filestar, int)
|
678
|
+
|
679
|
+
try:
|
680
|
+
fd = self._fdmgr.filestar_to_fd(filestar)
|
681
|
+
file = self._fdmgr.get(fd)
|
682
|
+
|
683
|
+
data = emulator.read_memory(src, size * amt)
|
684
|
+
file.write(data)
|
685
|
+
except FDIOError:
|
686
|
+
self.set_return_value(emulator, -1)
|
687
|
+
return
|
688
|
+
|
689
|
+
self.set_return_value(emulator, amt)
|
690
|
+
|
691
|
+
|
692
|
+
class Getc(Fgetc):
|
693
|
+
name = "getc"
|
694
|
+
|
695
|
+
# NOTE: getc and fgetc behave the same.
|
696
|
+
# getc may actually be a macro for fgetc
|
697
|
+
|
698
|
+
|
699
|
+
class Ungetc(StdioModel):
|
700
|
+
name = "ungetc"
|
701
|
+
|
702
|
+
# int ungetc(int c, FILE *file);
|
703
|
+
argument_types = [ArgumentType.INT, ArgumentType.POINTER]
|
704
|
+
return_type = ArgumentType.INT
|
705
|
+
|
706
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
707
|
+
super().model(emulator)
|
708
|
+
|
709
|
+
char = self.get_arg1(emulator)
|
710
|
+
filestar = self.get_arg2(emulator)
|
711
|
+
|
712
|
+
assert isinstance(char, int)
|
713
|
+
assert isinstance(char, int)
|
714
|
+
|
715
|
+
try:
|
716
|
+
fd = self._fdmgr.filestar_to_fd(filestar)
|
717
|
+
file = self._fdmgr.get(fd)
|
718
|
+
file.ungetc(char)
|
719
|
+
except FDIOError:
|
720
|
+
self.set_return_value(emulator, -1)
|
721
|
+
return
|
722
|
+
|
723
|
+
self.set_return_value(emulator, char)
|
724
|
+
|
725
|
+
|
726
|
+
class Getchar(StdioModel):
|
727
|
+
name = "getchar"
|
728
|
+
|
729
|
+
# int getchar(void);
|
730
|
+
argument_types = []
|
731
|
+
return_type = ArgumentType.INT
|
732
|
+
|
733
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
734
|
+
super().model(emulator)
|
735
|
+
|
736
|
+
# Use stdin
|
737
|
+
# TODO: If someone changes the struct pointed to by stdin, we're in trouble.
|
738
|
+
fd = 0
|
739
|
+
|
740
|
+
try:
|
741
|
+
file = self._fdmgr.get(fd)
|
742
|
+
except FDIOError:
|
743
|
+
self.set_return_value(emulator, -1)
|
744
|
+
|
745
|
+
data = file.read(1, ungetc=True)
|
746
|
+
|
747
|
+
self.set_return_value(emulator, data[0])
|
748
|
+
|
749
|
+
|
750
|
+
class Gets(StdioModel):
|
751
|
+
name = "gets"
|
752
|
+
|
753
|
+
# char *fgets(char *dst);
|
754
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.SIZE_T, ArgumentType.POINTER]
|
755
|
+
return_type = ArgumentType.POINTER
|
756
|
+
|
757
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
758
|
+
super().model(emulator)
|
759
|
+
|
760
|
+
dst = self.get_arg1(emulator)
|
761
|
+
|
762
|
+
assert isinstance(dst, int)
|
763
|
+
|
764
|
+
try:
|
765
|
+
fd = 0
|
766
|
+
file = self._fdmgr.get(fd)
|
767
|
+
except FDIOError:
|
768
|
+
self.set_return_value(emulator, 0)
|
769
|
+
return
|
770
|
+
|
771
|
+
data = file.read_string()
|
772
|
+
emulator.write_memory(dst, data)
|
773
|
+
self.set_return_value(emulator, dst)
|
774
|
+
|
775
|
+
|
776
|
+
class Printf(StdioModel):
|
777
|
+
name = "printf"
|
778
|
+
|
779
|
+
# int printf(const char *fmt, ...);
|
780
|
+
argument_types = [ArgumentType.POINTER]
|
781
|
+
return_type = ArgumentType.INT
|
782
|
+
|
783
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
784
|
+
super().model(emulator)
|
785
|
+
|
786
|
+
fmt_addr = self.get_arg1(emulator)
|
787
|
+
|
788
|
+
assert isinstance(fmt_addr, int)
|
789
|
+
|
790
|
+
fmt_len = _emu_strlen(emulator, fmt_addr)
|
791
|
+
fmt_bytes = emulator.read_memory(fmt_addr, fmt_len)
|
792
|
+
fmt = fmt_bytes.decode("utf-8")
|
793
|
+
|
794
|
+
output = parse_printf_format(self, fmt, emulator)
|
795
|
+
output_bytes = output.encode("utf-8")
|
796
|
+
|
797
|
+
fd = 1
|
798
|
+
try:
|
799
|
+
file = self._fdmgr.get(fd)
|
800
|
+
except FDIOError:
|
801
|
+
self.set_return_value(emulator, -1)
|
802
|
+
return
|
803
|
+
|
804
|
+
file.write(output_bytes)
|
805
|
+
|
806
|
+
self.set_return_value(emulator, len(output_bytes))
|
807
|
+
|
808
|
+
|
809
|
+
class Putc(Fputc):
|
810
|
+
name = "putc"
|
811
|
+
|
812
|
+
# NOTE: fputc and putc behave the same.
|
813
|
+
# putc may actually be a macro for fputc.
|
814
|
+
|
815
|
+
|
816
|
+
class Putchar(StdioModel):
|
817
|
+
name = "putchar"
|
818
|
+
|
819
|
+
# int putchar(int c);
|
820
|
+
argument_types = [ArgumentType.INT]
|
821
|
+
return_type = ArgumentType.INT
|
822
|
+
|
823
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
824
|
+
super().model(emulator)
|
825
|
+
|
826
|
+
char = self.get_arg1(emulator)
|
827
|
+
|
828
|
+
assert isinstance(char, int)
|
829
|
+
|
830
|
+
# Use stdout
|
831
|
+
# TODO: If someone changes the FILE * in stdout, we're in trouble.
|
832
|
+
fd = 1
|
833
|
+
|
834
|
+
try:
|
835
|
+
file = self._fdmgr.get(fd)
|
836
|
+
except FDIOError:
|
837
|
+
self.set_return_value(emulator, -1)
|
838
|
+
return
|
839
|
+
|
840
|
+
file.write(bytes([char]))
|
841
|
+
|
842
|
+
self.set_return_value(emulator, char)
|
843
|
+
|
844
|
+
|
845
|
+
class Puts(StdioModel):
|
846
|
+
name = "puts"
|
847
|
+
|
848
|
+
# int puts(const char *s);
|
849
|
+
argument_types = [ArgumentType.POINTER]
|
850
|
+
return_type = ArgumentType.INT
|
851
|
+
|
852
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
853
|
+
super().model(emulator)
|
854
|
+
|
855
|
+
ptr = self.get_arg1(emulator)
|
856
|
+
|
857
|
+
assert isinstance(ptr, int)
|
858
|
+
|
859
|
+
size = _emu_strlen(emulator, ptr)
|
860
|
+
|
861
|
+
data = emulator.read_memory(ptr, size)
|
862
|
+
|
863
|
+
# Use stdout
|
864
|
+
# TODO: If someone changes the FILE * in stdout, we're in trouble.
|
865
|
+
fd = 1
|
866
|
+
|
867
|
+
try:
|
868
|
+
file = self._fdmgr.get(fd)
|
869
|
+
except FDIOError:
|
870
|
+
self.set_return_value(emulator, -1)
|
871
|
+
return
|
872
|
+
|
873
|
+
file.write(data)
|
874
|
+
file.write(b"\n")
|
875
|
+
|
876
|
+
self.set_return_value(emulator, 0)
|
877
|
+
|
878
|
+
|
879
|
+
class Remove(StdioModel):
|
880
|
+
name = "remove"
|
881
|
+
|
882
|
+
# int remove(const char *path);
|
883
|
+
argument_types = [ArgumentType.POINTER]
|
884
|
+
return_type = ArgumentType.INT
|
885
|
+
|
886
|
+
# No file system; just returns true
|
887
|
+
imprecise = True
|
888
|
+
|
889
|
+
def __init__(self, address: int):
|
890
|
+
self._allow_imprecise = False
|
891
|
+
super().__init__(address)
|
892
|
+
|
893
|
+
@property
|
894
|
+
def allow_imprecise(self) -> bool:
|
895
|
+
return self._allow_imprecise or self._fdmgr.model_fs
|
896
|
+
|
897
|
+
@allow_imprecise.setter
|
898
|
+
def allow_imprecise(self, val: bool) -> None:
|
899
|
+
self._allow_imprecise = val
|
900
|
+
|
901
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
902
|
+
super().model(emulator)
|
903
|
+
|
904
|
+
ptr = self.get_arg1(emulator)
|
905
|
+
|
906
|
+
assert isinstance(ptr, int)
|
907
|
+
|
908
|
+
size = _emu_strlen(emulator, ptr)
|
909
|
+
|
910
|
+
data = emulator.read_memory(ptr, size)
|
911
|
+
|
912
|
+
name = data.decode("utf-8")
|
913
|
+
|
914
|
+
if self._fdmgr.remove(name):
|
915
|
+
self.set_return_value(emulator, 0)
|
916
|
+
else:
|
917
|
+
self.set_return_value(emulator, -1)
|
918
|
+
|
919
|
+
|
920
|
+
class Rename(StdioModel):
|
921
|
+
name = "rename"
|
922
|
+
|
923
|
+
# int rename(const char *oldpath, const char *newpath);
|
924
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
|
925
|
+
return_type = ArgumentType.INT
|
926
|
+
|
927
|
+
# No file system; just returns true
|
928
|
+
imprecise = True
|
929
|
+
|
930
|
+
def __init__(self, address: int):
|
931
|
+
self._allow_imprecise = False
|
932
|
+
super().__init__(address)
|
933
|
+
|
934
|
+
@property
|
935
|
+
def allow_imprecise(self) -> bool:
|
936
|
+
return self._allow_imprecise or self._fdmgr.model_fs
|
937
|
+
|
938
|
+
@allow_imprecise.setter
|
939
|
+
def allow_imprecise(self, val: bool) -> None:
|
940
|
+
self._allow_imprecise = val
|
941
|
+
|
942
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
943
|
+
super().model(emulator)
|
944
|
+
|
945
|
+
oldptr = self.get_arg1(emulator)
|
946
|
+
newptr = self.get_arg2(emulator)
|
947
|
+
|
948
|
+
assert isinstance(oldptr, int)
|
949
|
+
assert isinstance(newptr, int)
|
950
|
+
|
951
|
+
oldsize = _emu_strlen(emulator, oldptr)
|
952
|
+
newsize = _emu_strlen(emulator, newptr)
|
953
|
+
|
954
|
+
olddata = emulator.read_memory(oldptr, oldsize)
|
955
|
+
newdata = emulator.read_memory(newptr, newsize)
|
956
|
+
|
957
|
+
old = olddata.decode("utf-8")
|
958
|
+
new = newdata.decode("utf-8")
|
959
|
+
|
960
|
+
try:
|
961
|
+
self._fdmgr.rename(old, new)
|
962
|
+
self.set_return_value(emulator, 0)
|
963
|
+
except FDIOError:
|
964
|
+
self.set_return_value(emulator, -1)
|
965
|
+
|
966
|
+
|
967
|
+
class Rewind(StdioModel):
|
968
|
+
name = "rewind"
|
969
|
+
|
970
|
+
# void rewind(FILE *file);
|
971
|
+
argument_types = [ArgumentType.POINTER]
|
972
|
+
return_type = ArgumentType.VOID
|
973
|
+
|
974
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
975
|
+
super().model(emulator)
|
976
|
+
|
977
|
+
filestar = self.get_arg1(emulator)
|
978
|
+
|
979
|
+
assert isinstance(filestar, int)
|
980
|
+
|
981
|
+
try:
|
982
|
+
fd = self._fdmgr.filestar_to_fd(filestar)
|
983
|
+
file = self._fdmgr.get(fd)
|
984
|
+
except FDIOError:
|
985
|
+
return
|
986
|
+
|
987
|
+
file.cursor = 0
|
988
|
+
|
989
|
+
|
990
|
+
class Scanf(StdioModel):
|
991
|
+
name = "scanf"
|
992
|
+
|
993
|
+
# int scanf(const char *fmt, ...);
|
994
|
+
argument_types = [ArgumentType.POINTER]
|
995
|
+
return_type = ArgumentType.INT
|
996
|
+
|
997
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
998
|
+
super().model(emulator)
|
999
|
+
|
1000
|
+
fmt_addr = self.get_arg1(emulator)
|
1001
|
+
|
1002
|
+
assert isinstance(fmt_addr, int)
|
1003
|
+
|
1004
|
+
fmt_len = _emu_strlen(emulator, fmt_addr)
|
1005
|
+
fmt_bytes = emulator.read_memory(fmt_addr, fmt_len)
|
1006
|
+
fmt = fmt_bytes.decode("utf-8")
|
1007
|
+
|
1008
|
+
try:
|
1009
|
+
fd = 0
|
1010
|
+
file = self._fdmgr.get(fd)
|
1011
|
+
except FDIOError:
|
1012
|
+
self.set_return_value(emulator, -1)
|
1013
|
+
return
|
1014
|
+
|
1015
|
+
intake = FileIntake(file)
|
1016
|
+
|
1017
|
+
res = handle_scanf_format(self, intake, fmt, emulator)
|
1018
|
+
|
1019
|
+
self.set_return_value(emulator, res)
|
1020
|
+
|
1021
|
+
|
1022
|
+
class Snprintf(StdioModel):
|
1023
|
+
name = "snprintf"
|
1024
|
+
|
1025
|
+
# int snprintf(char *dst, size_t size, const char *fmt, ...);
|
1026
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.SIZE_T, ArgumentType.POINTER]
|
1027
|
+
return_type = ArgumentType.INT
|
1028
|
+
|
1029
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
1030
|
+
super().model(emulator)
|
1031
|
+
|
1032
|
+
buf_addr = self.get_arg1(emulator)
|
1033
|
+
size = self.get_arg2(emulator)
|
1034
|
+
fmt_addr = self.get_arg3(emulator)
|
1035
|
+
|
1036
|
+
assert isinstance(buf_addr, int)
|
1037
|
+
assert isinstance(size, int)
|
1038
|
+
assert isinstance(fmt_addr, int)
|
1039
|
+
|
1040
|
+
fmt_len = _emu_strlen(emulator, fmt_addr)
|
1041
|
+
fmt_bytes = emulator.read_memory(fmt_addr, fmt_len)
|
1042
|
+
fmt = fmt_bytes.decode("utf-8")
|
1043
|
+
|
1044
|
+
output = parse_printf_format(self, fmt, emulator)
|
1045
|
+
output_bytes = output.encode("utf-8")
|
1046
|
+
output_bytes += b"\0"
|
1047
|
+
|
1048
|
+
trunc_bytes = output_bytes
|
1049
|
+
if len(trunc_bytes) > size:
|
1050
|
+
trunc_bytes = trunc_bytes[: size - 1]
|
1051
|
+
trunc_bytes += b"\0"
|
1052
|
+
|
1053
|
+
if buf_addr != 0:
|
1054
|
+
emulator.write_memory(buf_addr, output_bytes)
|
1055
|
+
|
1056
|
+
self.set_return_value(emulator, len(output_bytes) - 1)
|
1057
|
+
|
1058
|
+
|
1059
|
+
class Sprintf(StdioModel):
|
1060
|
+
name = "sprintf"
|
1061
|
+
|
1062
|
+
# int sprintf(char *dst, const char *fmt, ...);
|
1063
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
|
1064
|
+
return_type = ArgumentType.INT
|
1065
|
+
|
1066
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
1067
|
+
super().model(emulator)
|
1068
|
+
|
1069
|
+
buf_addr = self.get_arg1(emulator)
|
1070
|
+
fmt_addr = self.get_arg2(emulator)
|
1071
|
+
|
1072
|
+
assert isinstance(buf_addr, int)
|
1073
|
+
assert isinstance(fmt_addr, int)
|
1074
|
+
|
1075
|
+
fmt_len = _emu_strlen(emulator, fmt_addr)
|
1076
|
+
fmt_bytes = emulator.read_memory(fmt_addr, fmt_len)
|
1077
|
+
fmt = fmt_bytes.decode("utf-8")
|
1078
|
+
|
1079
|
+
output = parse_printf_format(self, fmt, emulator)
|
1080
|
+
output_bytes = output.encode("utf-8")
|
1081
|
+
output_bytes += b"\0"
|
1082
|
+
|
1083
|
+
if buf_addr != 0:
|
1084
|
+
emulator.write_memory(buf_addr, output_bytes)
|
1085
|
+
|
1086
|
+
self.set_return_value(emulator, len(output_bytes) - 1)
|
1087
|
+
|
1088
|
+
|
1089
|
+
class Sscanf(StdioModel):
|
1090
|
+
name = "sscanf"
|
1091
|
+
|
1092
|
+
# int sscanf(const char *src, const char *fmt, ...);
|
1093
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
|
1094
|
+
return_type = ArgumentType.INT
|
1095
|
+
|
1096
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
1097
|
+
super().model(emulator)
|
1098
|
+
|
1099
|
+
src_addr = self.get_arg1(emulator)
|
1100
|
+
fmt_addr = self.get_arg2(emulator)
|
1101
|
+
|
1102
|
+
assert isinstance(src_addr, int)
|
1103
|
+
assert isinstance(fmt_addr, int)
|
1104
|
+
|
1105
|
+
fmt_len = _emu_strlen(emulator, fmt_addr)
|
1106
|
+
fmt_bytes = emulator.read_memory(fmt_addr, fmt_len)
|
1107
|
+
fmt = fmt_bytes.decode("utf-8")
|
1108
|
+
|
1109
|
+
intake = StringIntake(src_addr, emulator)
|
1110
|
+
|
1111
|
+
res = handle_scanf_format(self, intake, fmt, emulator)
|
1112
|
+
|
1113
|
+
self.set_return_value(emulator, res)
|
1114
|
+
|
1115
|
+
|
1116
|
+
class Tmpfile(StdioModel):
|
1117
|
+
name = "tmpfile"
|
1118
|
+
|
1119
|
+
# FILE *tmpfile(void);
|
1120
|
+
argument_types = []
|
1121
|
+
return_type = ArgumentType.POINTER
|
1122
|
+
|
1123
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
1124
|
+
super().model(emulator)
|
1125
|
+
|
1126
|
+
name = self._generate_tmpnam()
|
1127
|
+
|
1128
|
+
try:
|
1129
|
+
fd = self._fdmgr.open(
|
1130
|
+
name,
|
1131
|
+
readable=True,
|
1132
|
+
writable=True,
|
1133
|
+
create=True,
|
1134
|
+
truncate=False,
|
1135
|
+
append=False,
|
1136
|
+
seekable=True,
|
1137
|
+
)
|
1138
|
+
except FDIOError:
|
1139
|
+
self.set_return_value(emulator, 0)
|
1140
|
+
return
|
1141
|
+
|
1142
|
+
filestar = self._fdmgr.fd_to_filestar(fd)
|
1143
|
+
self.set_return_value(emulator, filestar)
|
1144
|
+
|
1145
|
+
|
1146
|
+
class Tmpnam(StdioModel):
|
1147
|
+
name = "tmpnam"
|
1148
|
+
|
1149
|
+
# char *tmpnam(char *name);
|
1150
|
+
argument_types = [ArgumentType.POINTER]
|
1151
|
+
return_type = ArgumentType.POINTER
|
1152
|
+
|
1153
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
1154
|
+
super().model(emulator)
|
1155
|
+
|
1156
|
+
ptr = self.get_arg1(emulator)
|
1157
|
+
|
1158
|
+
assert isinstance(ptr, int)
|
1159
|
+
|
1160
|
+
if ptr == 0:
|
1161
|
+
raise NotImplementedError("Using tmpnam internal buffer not supported")
|
1162
|
+
|
1163
|
+
name = self._generate_tmpnam().encode("utf-8")
|
1164
|
+
|
1165
|
+
emulator.write_memory(ptr, name)
|
1166
|
+
|
1167
|
+
self.set_return_value(emulator, ptr)
|
1168
|
+
|
1169
|
+
|
1170
|
+
class Vfprintf(StdioModel):
|
1171
|
+
name = "vfprintf"
|
1172
|
+
|
1173
|
+
# int vfprintf(FILE *stream, const char *fmt, va_list args);
|
1174
|
+
# TODO: Figure out how to decode a va_list
|
1175
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
|
1176
|
+
return_type = ArgumentType.INT
|
1177
|
+
|
1178
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
1179
|
+
super().model(emulator)
|
1180
|
+
raise NotImplementedError()
|
1181
|
+
|
1182
|
+
|
1183
|
+
class Vfscanf(StdioModel):
|
1184
|
+
name = "vfscanf"
|
1185
|
+
|
1186
|
+
# int vfscanf(FILE *stream, const char *fmt, va_list args);
|
1187
|
+
# TODO: Figure out how to decode a va_list
|
1188
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
|
1189
|
+
return_type = ArgumentType.INT
|
1190
|
+
|
1191
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
1192
|
+
super().model(emulator)
|
1193
|
+
raise NotImplementedError()
|
1194
|
+
|
1195
|
+
|
1196
|
+
class Vprintf(StdioModel):
|
1197
|
+
name = "vprintf"
|
1198
|
+
|
1199
|
+
# int vprintf(const char *fmt, va_list args);
|
1200
|
+
# TODO: Figure out how to decode a va_list
|
1201
|
+
argument_types = [ArgumentType.POINTER]
|
1202
|
+
return_type = ArgumentType.INT
|
1203
|
+
|
1204
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
1205
|
+
super().model(emulator)
|
1206
|
+
raise NotImplementedError()
|
1207
|
+
|
1208
|
+
|
1209
|
+
class Vscanf(StdioModel):
|
1210
|
+
name = "vscanf"
|
1211
|
+
|
1212
|
+
# int vscanf(const char *fmt, va_list args);
|
1213
|
+
# TODO: Figure out how to decode a va_list
|
1214
|
+
argument_types = [ArgumentType.POINTER]
|
1215
|
+
return_type = ArgumentType.INT
|
1216
|
+
|
1217
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
1218
|
+
super().model(emulator)
|
1219
|
+
raise NotImplementedError()
|
1220
|
+
|
1221
|
+
|
1222
|
+
class Vsnprintf(StdioModel):
|
1223
|
+
name = "vsnprintf"
|
1224
|
+
|
1225
|
+
# int vsprintf(char *str, size_t len, const char *fmt, va_list args);
|
1226
|
+
# TODO: Figure out how to decode a va_list
|
1227
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.SIZE_T, ArgumentType.POINTER]
|
1228
|
+
return_type = ArgumentType.INT
|
1229
|
+
|
1230
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
1231
|
+
super().model(emulator)
|
1232
|
+
raise NotImplementedError()
|
1233
|
+
|
1234
|
+
|
1235
|
+
class Vsprintf(StdioModel):
|
1236
|
+
name = "vsprintf"
|
1237
|
+
|
1238
|
+
# int vsprintf(char *str, const char *fmt, va_list args);
|
1239
|
+
# TODO: Figure out how to decode a va_list
|
1240
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
|
1241
|
+
return_type = ArgumentType.INT
|
1242
|
+
|
1243
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
1244
|
+
super().model(emulator)
|
1245
|
+
raise NotImplementedError()
|
1246
|
+
|
1247
|
+
|
1248
|
+
class Vsscanf(StdioModel):
|
1249
|
+
name = "vsprintf"
|
1250
|
+
|
1251
|
+
# int vsscanf(char *str, const char *fmt, va_list args);
|
1252
|
+
# TODO: Figure out how to decode a va_list
|
1253
|
+
argument_types = [ArgumentType.POINTER, ArgumentType.POINTER]
|
1254
|
+
return_type = ArgumentType.INT
|
1255
|
+
|
1256
|
+
def model(self, emulator: emulators.Emulator) -> None:
|
1257
|
+
super().model(emulator)
|
1258
|
+
raise NotImplementedError()
|
1259
|
+
|
1260
|
+
|
1261
|
+
__all__ = [
|
1262
|
+
"Clearerr",
|
1263
|
+
"Fclose",
|
1264
|
+
"Feof",
|
1265
|
+
"Ferror",
|
1266
|
+
"Fflush",
|
1267
|
+
"Fgetc",
|
1268
|
+
"Fgetpos",
|
1269
|
+
"Fgets",
|
1270
|
+
"Fopen",
|
1271
|
+
"Fprintf",
|
1272
|
+
"Fputc",
|
1273
|
+
"Fputs",
|
1274
|
+
"Fread",
|
1275
|
+
"Freopen",
|
1276
|
+
"Fscanf",
|
1277
|
+
"Fseek",
|
1278
|
+
"Fsetpos",
|
1279
|
+
"Ftell",
|
1280
|
+
"Fwrite",
|
1281
|
+
"Getc",
|
1282
|
+
"Getchar",
|
1283
|
+
"Gets",
|
1284
|
+
"Printf",
|
1285
|
+
"Putc",
|
1286
|
+
"Putchar",
|
1287
|
+
"Puts",
|
1288
|
+
"Remove",
|
1289
|
+
"Rename",
|
1290
|
+
"Rewind",
|
1291
|
+
"Scanf",
|
1292
|
+
"Snprintf",
|
1293
|
+
"Sprintf",
|
1294
|
+
"Sscanf",
|
1295
|
+
"Tmpfile",
|
1296
|
+
"Tmpnam",
|
1297
|
+
"Ungetc",
|
1298
|
+
"Vfprintf",
|
1299
|
+
"Vfscanf",
|
1300
|
+
"Vprintf",
|
1301
|
+
"Vscanf",
|
1302
|
+
"Vsnprintf",
|
1303
|
+
"Vsprintf",
|
1304
|
+
"Vsscanf",
|
1305
|
+
]
|