From b376658d59d72a62e43d8072e5e829f3ca426427 Mon Sep 17 00:00:00 2001 From: Duncan Ogilvie Date: Sun, 22 Sep 2024 21:37:21 +0200 Subject: [PATCH 1/3] Move type hints to __init__.py --- python/icicle/__init__.py | 138 +++++++++++++++++++++++++++++++++++++- python/icicle/icicle.pyi | 134 ------------------------------------ python/icicle/py.typed | 0 3 files changed, 137 insertions(+), 135 deletions(-) delete mode 100644 python/icicle/icicle.pyi delete mode 100644 python/icicle/py.typed diff --git a/python/icicle/__init__.py b/python/icicle/__init__.py index 5fb47c3..3e931e5 100644 --- a/python/icicle/__init__.py +++ b/python/icicle/__init__.py @@ -1,4 +1,137 @@ -from .icicle import * +from typing import List, Dict, Tuple +from enum import Enum + +class MemoryProtection(Enum): + NoAccess = ... + ReadOnly = ... + ReadWrite = ... + ExecuteOnly = ... + ExecuteRead = ... + ExecuteReadWrite = ... + +class MemoryExceptionCode(Enum): + Unallocated = ... + Unmapped = ... + UnmappedRegisters = ... + Uninitialized = ... + ReadViolation = ... + WriteViolation = ... + ExecViolation = ... + ReadWatch = ... + WriteWatch = ... + Unaligned = ... + OutOfMemory = ... + SelfModifyingCode = ... + AddressOverflow = ... + Unknown = ... + +class RunStatus(Enum): + Running = ... + InstructionLimit = ... + Breakpoint = ... + Interrupted = ... + Halt = ... + Killed = ... + Deadlock = ... + OutOfMemory = ... + Unimplemented = ... + UnhandledException = ... + +class ExceptionCode(Enum): + NoException = ... + InstructionLimit = ... + Halt = ... + Sleep = ... + Syscall = ... + CpuStateChanged = ... + DivisionException = ... + ReadUnmapped = ... + ReadPerm = ... + ReadUnaligned = ... + ReadWatch = ... + ReadUninitialized = ... + WriteUnmapped = ... + WritePerm = ... + WriteWatch = ... + WriteUnaligned = ... + ExecViolation = ... + SelfModifyingCode = ... + OutOfMemory = ... + AddressOverflow = ... + InvalidInstruction = ... + UnknownInterrupt = ... + UnknownCpuID = ... + InvalidOpSize = ... + InvalidFloatSize = ... + CodeNotTranslated = ... + ShadowStackOverflow = ... + ShadowStackInvalid = ... + InvalidTarget = ... + UnimplementedOp = ... + ExternalAddr = ... + Environment = ... + JitError = ... + InternalError = ... + UnmappedRegister = ... + UnknownError = ... + +class Icicle: + def __init__(self, architecture: str, *, + jit = True, + jit_mem = True, + shadow_stack = True, + recompilation = True, + track_uninitialized = False, + optimize_instructions = True, + optimize_block = True, + tracing = False, + ) -> None: ... + + @property + def exception_code(self) -> ExceptionCode: ... + + @property + def exception_value(self) -> int: ... + + icount: int + + icount_limit: int + + # TODO: API to get memory information? + + def mem_map(self, address: int, size: int, protection: MemoryProtection): ... + + def mem_unmap(self, address: int, size: int): ... + + def mem_protect(self, address: int, size: int, protection: MemoryProtection): ... + + def mem_read(self, address: int, size: int) -> bytes: ... + + def mem_write(self, address: int, data: bytes) -> None: ... + + def reg_list(self) -> Dict[str, Tuple[int, int]]: ... + + def reg_offset(self, name: str) -> int: ... + + def reg_size(self, name: str) -> int: ... + + def reg_read(self, name: str) -> int: ... + + def reg_write(self, name: str, value: int) -> None: ... + + def reset(self): ... + + def run(self) -> RunStatus: ... + + def run_until(self, address: int) -> RunStatus: ... + + def step(self, count: int) -> RunStatus: ... + + def add_breakpoint(self, address: int) -> bool: ... + + def remove_breakpoint(self, address: int) -> bool: ... + +def architectures() -> List[str]: ... class MemoryException(Exception): def __init__(self, message: str, code: MemoryExceptionCode): @@ -19,3 +152,6 @@ def __ghidra_init(): raise FileNotFoundError("Ghidra processor definitions not found") __ghidra_init() + +# NOTE: This overrides the stubs at runtime with the actual implementation +from .icicle import * \ No newline at end of file diff --git a/python/icicle/icicle.pyi b/python/icicle/icicle.pyi deleted file mode 100644 index fbb3900..0000000 --- a/python/icicle/icicle.pyi +++ /dev/null @@ -1,134 +0,0 @@ -from typing import List, Dict, Tuple -from enum import Enum - -class MemoryProtection(Enum): - NoAccess = ... - ReadOnly = ... - ReadWrite = ... - ExecuteOnly = ... - ExecuteRead = ... - ExecuteReadWrite = ... - -class MemoryExceptionCode(Enum): - Unallocated = ... - Unmapped = ... - UnmappedRegisters = ... - Uninitialized = ... - ReadViolation = ... - WriteViolation = ... - ExecViolation = ... - ReadWatch = ... - WriteWatch = ... - Unaligned = ... - OutOfMemory = ... - SelfModifyingCode = ... - AddressOverflow = ... - Unknown = ... - -class RunStatus(Enum): - Running = ... - InstructionLimit = ... - Breakpoint = ... - Interrupted = ... - Halt = ... - Killed = ... - Deadlock = ... - OutOfMemory = ... - Unimplemented = ... - UnhandledException = ... - -class ExceptionCode(Enum): - NoException = ... - InstructionLimit = ... - Halt = ... - Sleep = ... - Syscall = ... - CpuStateChanged = ... - DivisionException = ... - ReadUnmapped = ... - ReadPerm = ... - ReadUnaligned = ... - ReadWatch = ... - ReadUninitialized = ... - WriteUnmapped = ... - WritePerm = ... - WriteWatch = ... - WriteUnaligned = ... - ExecViolation = ... - SelfModifyingCode = ... - OutOfMemory = ... - AddressOverflow = ... - InvalidInstruction = ... - UnknownInterrupt = ... - UnknownCpuID = ... - InvalidOpSize = ... - InvalidFloatSize = ... - CodeNotTranslated = ... - ShadowStackOverflow = ... - ShadowStackInvalid = ... - InvalidTarget = ... - UnimplementedOp = ... - ExternalAddr = ... - Environment = ... - JitError = ... - InternalError = ... - UnmappedRegister = ... - UnknownError = ... - -class Icicle: - def __init__(self, architecture: str, *, - jit = True, - jit_mem = True, - shadow_stack = True, - recompilation = True, - track_uninitialized = False, - optimize_instructions = True, - optimize_block = True, - tracing = False, - ) -> None: ... - - @property - def exception_code(self) -> ExceptionCode: ... - - @property - def exception_value(self) -> int: ... - - icount: int - - icount_limit: int - - # TODO: API to get memory information? - - def mem_map(self, address: int, size: int, protection: MemoryProtection): ... - - def mem_unmap(self, address: int, size: int): ... - - def mem_protect(self, address: int, size: int, protection: MemoryProtection): ... - - def mem_read(self, address: int, size: int) -> bytes: ... - - def mem_write(self, address: int, data: bytes) -> None: ... - - def reg_list(self) -> Dict[str, Tuple[int, int]]: ... - - def reg_offset(self, name: str) -> int: ... - - def reg_size(self, name: str) -> int: ... - - def reg_read(self, name: str) -> int: ... - - def reg_write(self, name: str, value: int) -> None: ... - - def reset(self): ... - - def run(self) -> RunStatus: ... - - def run_until(self, address: int) -> RunStatus: ... - - def step(self, count: int) -> RunStatus: ... - - def add_breakpoint(self, address: int) -> bool: ... - - def remove_breakpoint(self, address: int) -> bool: ... - -def architectures() -> List[str]: ... diff --git a/python/icicle/py.typed b/python/icicle/py.typed deleted file mode 100644 index e69de29..0000000 From cc436bd5fdb8cd23feb42256d96ba1c58905ee35 Mon Sep 17 00:00:00 2001 From: Duncan Ogilvie Date: Sun, 22 Sep 2024 21:37:28 +0200 Subject: [PATCH 2/3] Bump to 0.0.4 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ff517b..10ef78e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -406,7 +406,7 @@ dependencies = [ [[package]] name = "icicle-python" -version = "0.0.3" +version = "0.0.4" dependencies = [ "icicle-cpu", "icicle-vm", diff --git a/Cargo.toml b/Cargo.toml index d59bfb2..cdea8d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "icicle-python" -version = "0.0.3" +version = "0.0.4" edition = "2021" [lib] From 6e5d32f35c97a80543368b0866aba44535c3daa3 Mon Sep 17 00:00:00 2001 From: Duncan Ogilvie Date: Sun, 22 Sep 2024 21:37:34 +0200 Subject: [PATCH 3/3] Fix GitHub Actions --- .github/workflows/CI.yml | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index b1787c2..700eb71 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -12,12 +12,12 @@ jobs: PYTHONUNBUFFERED: '1' steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: 'true' - name: Python environment - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.10' @@ -42,9 +42,9 @@ jobs: python tests/invalid.py - name: Upload wheels - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: wheels + name: wheels-windows path: dist macos: @@ -56,12 +56,12 @@ jobs: PYTHONUNBUFFERED: '1' steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: 'true' - name: Python environment - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.10' @@ -90,22 +90,22 @@ jobs: python tests/invalid.py - name: Upload wheels - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: wheels + name: wheels-macos path: dist linux: # Skip building pull requests from the same repository if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) }} - runs-on: ubuntu-latest - container: quay.io/pypa/manylinux2014_x86_64 + runs-on: ubuntu-24.04 + container: quay.io/pypa/manylinux_2_28_x86_64 env: # Disable output buffering in an attempt to get readable errors PYTHONUNBUFFERED: '1' steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: 'true' @@ -116,7 +116,7 @@ jobs: export PATH="$PATH:$HOME/.cargo/bin" export PATH="/opt/python/cp38-cp38/bin:$PATH" pip install -r requirements.txt - python setup.py bdist_wheel --py-limited-api=cp37 --plat-name manylinux2014_x86_64 + python setup.py bdist_wheel --py-limited-api=cp37 --plat-name manylinux_2_28_x86_64 auditwheel show dist/*.whl pip install --force-reinstall dist/*.whl python -c "import icicle" @@ -129,23 +129,24 @@ jobs: python tests/invalid.py - name: Upload wheels - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: wheels + name: wheels-linux path: dist release: if: ${{ startsWith(github.ref, 'refs/tags/') }} - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 needs: [windows, macos, linux] permissions: contents: write discussions: write steps: - name: Download wheels - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: - name: wheels + pattern: wheels-* + merge-multiple: true path: dist - name: Publish to PyPI