ocgraph 0.3.0__tar.gz → 1.0.0__tar.gz
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.
- ocgraph-1.0.0/.gitlab-ci.yml +156 -0
- ocgraph-1.0.0/.pre-commit-config.yaml +45 -0
- ocgraph-1.0.0/CHANGELOG.md +111 -0
- ocgraph-1.0.0/CONTRIBUTING.md +136 -0
- ocgraph-1.0.0/LICENSE +26 -0
- ocgraph-0.3.0/LICENSES/GTDGmbH.md → ocgraph-1.0.0/LICENSES/Celeres.md +2 -2
- ocgraph-1.0.0/PKG-INFO +124 -0
- ocgraph-1.0.0/README.md +87 -0
- ocgraph-1.0.0/doc/_static/css/custom.css +66 -0
- ocgraph-1.0.0/doc/_static/logo/logo.png +0 -0
- ocgraph-1.0.0/doc/_static/logo/logo.svg +73 -0
- ocgraph-1.0.0/doc/api/index.rst +14 -0
- ocgraph-1.0.0/doc/api/interface.rst +34 -0
- ocgraph-1.0.0/doc/api/internal/architecture.rst +46 -0
- ocgraph-1.0.0/doc/api/internal/data.rst +39 -0
- ocgraph-1.0.0/doc/api/internal/disassembler.rst +30 -0
- ocgraph-1.0.0/doc/api/internal/index.rst +19 -0
- ocgraph-1.0.0/doc/conf.py +72 -0
- ocgraph-1.0.0/doc/coverage.rst +93 -0
- ocgraph-1.0.0/doc/development/analysis.rst +68 -0
- ocgraph-1.0.0/doc/development/architecture.rst +94 -0
- ocgraph-1.0.0/doc/development/disassembler.rst +61 -0
- ocgraph-1.0.0/doc/development/index.rst +106 -0
- ocgraph-1.0.0/doc/execution.rst +232 -0
- ocgraph-1.0.0/doc/index.rst +60 -0
- ocgraph-1.0.0/doc/input.rst +94 -0
- ocgraph-1.0.0/doc/installation.rst +90 -0
- ocgraph-1.0.0/docker/Dockerfile-arch +28 -0
- ocgraph-1.0.0/docker/Dockerfile-debian-bookworm +33 -0
- ocgraph-1.0.0/docker/Dockerfile-debian-trixie +33 -0
- ocgraph-1.0.0/docker/Dockerfile-ubuntu-24-04 +33 -0
- ocgraph-1.0.0/ocgraph/__init__.py +20 -0
- ocgraph-1.0.0/ocgraph/__main__.py +238 -0
- ocgraph-1.0.0/ocgraph/_version.py +11 -0
- ocgraph-1.0.0/ocgraph/interface/__init__.py +1 -0
- ocgraph-1.0.0/ocgraph/interface/analyzer.py +581 -0
- ocgraph-1.0.0/ocgraph/interface/coverage_reader.py +332 -0
- ocgraph-1.0.0/ocgraph/interface/drawer.py +248 -0
- ocgraph-1.0.0/ocgraph/internal/__init__.py +12 -0
- ocgraph-1.0.0/ocgraph/internal/architecture/__init__.py +20 -0
- ocgraph-1.0.0/ocgraph/internal/architecture/arm.py +93 -0
- ocgraph-1.0.0/ocgraph/internal/architecture/factory.py +44 -0
- ocgraph-1.0.0/ocgraph/internal/architecture/generic.py +38 -0
- ocgraph-0.3.0/ocgraph/configuration/architecture/architecture.py → ocgraph-1.0.0/ocgraph/internal/architecture/interface.py +16 -26
- {ocgraph-0.3.0/ocgraph/configuration → ocgraph-1.0.0/ocgraph/internal}/architecture/msp430.py +9 -4
- {ocgraph-0.3.0/ocgraph/configuration → ocgraph-1.0.0/ocgraph/internal}/architecture/ppc.py +14 -6
- ocgraph-1.0.0/ocgraph/internal/architecture/riscv.py +70 -0
- ocgraph-1.0.0/ocgraph/internal/architecture/sparc.py +171 -0
- {ocgraph-0.3.0/ocgraph/configuration → ocgraph-1.0.0/ocgraph/internal}/architecture/x86.py +8 -4
- ocgraph-1.0.0/ocgraph/internal/data/__init__.py +23 -0
- {ocgraph-0.3.0/ocgraph → ocgraph-1.0.0/ocgraph/internal}/data/address.py +1 -0
- {ocgraph-0.3.0/ocgraph → ocgraph-1.0.0/ocgraph/internal}/data/basic_block.py +6 -3
- ocgraph-1.0.0/ocgraph/internal/data/delay_slot.py +21 -0
- {ocgraph-0.3.0/ocgraph → ocgraph-1.0.0/ocgraph/internal}/data/encoding.py +1 -0
- {ocgraph-0.3.0/ocgraph → ocgraph-1.0.0/ocgraph/internal}/data/function_header.py +1 -0
- ocgraph-1.0.0/ocgraph/internal/data/instruction.py +173 -0
- {ocgraph-0.3.0/ocgraph → ocgraph-1.0.0/ocgraph/internal}/data/jump_table.py +22 -18
- ocgraph-1.0.0/ocgraph/internal/disassembler/__init__.py +11 -0
- ocgraph-1.0.0/ocgraph/internal/disassembler/factory.py +38 -0
- ocgraph-1.0.0/ocgraph/internal/disassembler/interface.py +39 -0
- ocgraph-0.3.0/ocgraph/configuration/disassembler/disassembler.py → ocgraph-1.0.0/ocgraph/internal/disassembler/objdump.py +45 -65
- {ocgraph-0.3.0/ocgraph/configuration → ocgraph-1.0.0/ocgraph/internal}/disassembler/objdump_msp430.py +4 -2
- ocgraph-1.0.0/ocgraph/internal/disassembler/objdump_riscv.py +23 -0
- {ocgraph-0.3.0/ocgraph/configuration → ocgraph-1.0.0/ocgraph/internal}/logger.py +12 -7
- ocgraph-1.0.0/poetry.lock +1353 -0
- ocgraph-1.0.0/pyproject.toml +138 -0
- ocgraph-1.0.0/test/__init__.py +1 -0
- ocgraph-1.0.0/test/ocgraph/__init__.py +1 -0
- ocgraph-1.0.0/test/ocgraph/unit/.gitkeep +0 -0
- ocgraph-1.0.0/test/ocgraph/unit/test_analyzer.py +726 -0
- ocgraph-1.0.0/test/ocgraph/unit/test_architecture.py +358 -0
- ocgraph-1.0.0/test/ocgraph/unit/test_basic_block.py +41 -0
- ocgraph-1.0.0/test/ocgraph/unit/test_coverage_reader.py +436 -0
- ocgraph-1.0.0/test/ocgraph/unit/test_disassembler.py +75 -0
- ocgraph-1.0.0/test/ocgraph/unit/test_drawer.py +336 -0
- ocgraph-1.0.0/test/ocgraph/unit/test_instruction.py +169 -0
- ocgraph-1.0.0/test/ocgraph/unit/test_jump_table.py +37 -0
- ocgraph-1.0.0/test/ocgraph/unit/test_main.py +298 -0
- ocgraph-1.0.0/test/ocgraph/validation/__init__.py +1 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/ARM/big.gv +830 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/ARM/objdump.gv +157 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/ARM/small.gv +172 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/MSP430/big.gv +1500 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/MSP430/small.gv +183 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/PowerPC/big.gv +507 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/PowerPC/indirect.gv +40 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/PowerPC/indirect2.gv +44 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/PowerPC/small.gv +133 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/RISC-V/big.gv +647 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/RISC-V/small.gv +107 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/SPARCv8/big.gv +478 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/SPARCv8/coverage.gv +116 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/SPARCv8/small.gv +176 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/x86/big.gv +443 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/x86/objdump.gv +103 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/x86/small.gv +161 -0
- ocgraph-1.0.0/test/ocgraph/validation/expected/x86/stripped_objdump.gv +54 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/ARM/big.asm +236 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/ARM/objdump.asm +50 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/ARM/small.asm +59 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/MSP430/big.asm +491 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/MSP430/small.asm +54 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/PowerPC/big.asm +240 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/PowerPC/indirect.asm +15 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/PowerPC/indirect2.asm +12 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/PowerPC/small.asm +72 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/RISC-V/big.asm +177 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/RISC-V/small.asm +31 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/SPARCv8/big.asm +229 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/SPARCv8/coverage.asm +35 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/SPARCv8/small.asm +63 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/x86/big.asm +223 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/x86/objdump.asm +22 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/x86/small.asm +71 -0
- ocgraph-1.0.0/test/ocgraph/validation/input/x86/stripped_objdump.asm +14 -0
- ocgraph-1.0.0/test/ocgraph/validation/input_coverage/SPARCv8/coverage.csv +35 -0
- ocgraph-1.0.0/test/ocgraph/validation/test_integration.py +101 -0
- ocgraph-1.0.0/test_templates/call.c +8 -0
- ocgraph-1.0.0/test_templates/common.py +80 -0
- ocgraph-1.0.0/test_templates/funtable.c +5 -0
- ocgraph-1.0.0/test_templates/gen_calls.py +55 -0
- ocgraph-1.0.0/test_templates/gen_funtable.py +49 -0
- ocgraph-1.0.0/test_templates/gen_jumps.py +46 -0
- ocgraph-1.0.0/test_templates/gen_jumptable.py +49 -0
- ocgraph-1.0.0/test_templates/jump.c +6 -0
- ocgraph-1.0.0/test_templates/jumptable.c +27 -0
- ocgraph-0.3.0/PKG-INFO +0 -55
- ocgraph-0.3.0/README.md +0 -28
- ocgraph-0.3.0/ocgraph/__main__.py +0 -95
- ocgraph-0.3.0/ocgraph/configuration/__init__.py +0 -4
- ocgraph-0.3.0/ocgraph/configuration/architecture/__init__.py +0 -8
- ocgraph-0.3.0/ocgraph/configuration/architecture/arm.py +0 -52
- ocgraph-0.3.0/ocgraph/configuration/architecture/sparc.py +0 -100
- ocgraph-0.3.0/ocgraph/configuration/configuration.py +0 -122
- ocgraph-0.3.0/ocgraph/configuration/disassembler/__init__.py +0 -10
- ocgraph-0.3.0/ocgraph/configuration/disassembler/gdb_default.py +0 -11
- ocgraph-0.3.0/ocgraph/configuration/disassembler/objdump_arm.py +0 -11
- ocgraph-0.3.0/ocgraph/configuration/disassembler/objdump_ppc.py +0 -11
- ocgraph-0.3.0/ocgraph/configuration/disassembler/objdump_sparc.py +0 -11
- ocgraph-0.3.0/ocgraph/configuration/disassembler/objdump_x86.py +0 -11
- ocgraph-0.3.0/ocgraph/data/__init__.py +0 -9
- ocgraph-0.3.0/ocgraph/data/instruction.py +0 -102
- ocgraph-0.3.0/ocgraph/interface/__init__.py +0 -5
- ocgraph-0.3.0/ocgraph/interface/analyzer.py +0 -220
- ocgraph-0.3.0/ocgraph/interface/coverage_reader.py +0 -70
- ocgraph-0.3.0/ocgraph/interface/drawer.py +0 -181
- ocgraph-0.3.0/pyproject.toml +0 -104
- {ocgraph-0.3.0 → ocgraph-1.0.0}/LICENSES/MauriMustonen.md +0 -0
- /ocgraph-0.3.0/ocgraph/__init__.py → /ocgraph-1.0.0/ocgraph/py.typed +0 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
stages:
|
|
2
|
+
- setup
|
|
3
|
+
- test
|
|
4
|
+
- code-quality
|
|
5
|
+
- build
|
|
6
|
+
- doc
|
|
7
|
+
- publish
|
|
8
|
+
|
|
9
|
+
# Default image of the jobs that do not select one: the Debian stable build of
|
|
10
|
+
# this project. The matrix jobs pick the image of their distribution.
|
|
11
|
+
image: $CI_REGISTRY_IMAGE/debian-bookworm
|
|
12
|
+
|
|
13
|
+
# Build and push one project image per supported distribution. Each image pins
|
|
14
|
+
# the Python of that distribution, so the matrix below tests the package on the
|
|
15
|
+
# interpreter versions the classifiers claim: 3.11 on Debian bookworm, 3.12 on
|
|
16
|
+
# Ubuntu 24.04, 3.13 on Debian trixie and on Arch. The images also carry the
|
|
17
|
+
# Graphviz binaries, which render the graphs of the suite.
|
|
18
|
+
setup:
|
|
19
|
+
stage: setup
|
|
20
|
+
image: docker
|
|
21
|
+
before_script:
|
|
22
|
+
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
|
|
23
|
+
script:
|
|
24
|
+
- docker pull $(grep FROM docker/Dockerfile-$OS | cut -d' ' -f2)
|
|
25
|
+
- docker build -t $CI_REGISTRY_IMAGE/$OS -f docker/Dockerfile-$OS .
|
|
26
|
+
- docker push $CI_REGISTRY_IMAGE/$OS
|
|
27
|
+
parallel:
|
|
28
|
+
matrix:
|
|
29
|
+
- OS: [debian-bookworm, debian-trixie, ubuntu-24-04, arch]
|
|
30
|
+
|
|
31
|
+
test:
|
|
32
|
+
stage: test
|
|
33
|
+
# The image of the matrix entry pins the interpreter: 3.11 on bookworm, 3.12 on
|
|
34
|
+
# Ubuntu 24.04, 3.13 on trixie and on Arch.
|
|
35
|
+
image: $CI_REGISTRY_IMAGE/$OS
|
|
36
|
+
before_script:
|
|
37
|
+
- poetry install
|
|
38
|
+
script:
|
|
39
|
+
- poetry run pytest
|
|
40
|
+
# The coverage reports come from the addopts of the pytest section of
|
|
41
|
+
# pyproject.toml, which is also what a local run produces. The job variable is
|
|
42
|
+
# the one report that only the pipeline wants: the JUnit results of the merge
|
|
43
|
+
# request.
|
|
44
|
+
variables:
|
|
45
|
+
PYTEST_ADDOPTS: --junitxml=report.xml
|
|
46
|
+
coverage: '/^TOTAL.*\s+(\d+\%)$/'
|
|
47
|
+
needs: [setup]
|
|
48
|
+
artifacts:
|
|
49
|
+
reports:
|
|
50
|
+
coverage_report:
|
|
51
|
+
coverage_format: cobertura
|
|
52
|
+
path: coverage.xml
|
|
53
|
+
junit: report.xml
|
|
54
|
+
paths:
|
|
55
|
+
- htmlcov
|
|
56
|
+
- output
|
|
57
|
+
- coverage.xml
|
|
58
|
+
- report.xml
|
|
59
|
+
parallel:
|
|
60
|
+
matrix:
|
|
61
|
+
- OS: [debian-bookworm, debian-trixie, ubuntu-24-04, arch]
|
|
62
|
+
|
|
63
|
+
# The type check is a gate: the package ships `ocgraph/py.typed` and the strict
|
|
64
|
+
# settings of pyproject.toml apply, so a type error blocks a change. It runs on
|
|
65
|
+
# the interpreter of the default image, 3.11, like the release build does.
|
|
66
|
+
mypy:
|
|
67
|
+
stage: code-quality
|
|
68
|
+
before_script:
|
|
69
|
+
- poetry install
|
|
70
|
+
script:
|
|
71
|
+
- poetry run mypy -p ocgraph
|
|
72
|
+
needs: [setup]
|
|
73
|
+
|
|
74
|
+
# The two linters publish review reports on the merge request. Their findings do
|
|
75
|
+
# not block a change, in contrast to the type check above.
|
|
76
|
+
pylint:
|
|
77
|
+
stage: code-quality
|
|
78
|
+
before_script:
|
|
79
|
+
- poetry install
|
|
80
|
+
script:
|
|
81
|
+
- poetry run pylint -j0 --allow-reexport-from-package y --output-format=codeclimate ocgraph > pylint-report.json
|
|
82
|
+
needs: [setup]
|
|
83
|
+
allow_failure: true
|
|
84
|
+
artifacts:
|
|
85
|
+
reports:
|
|
86
|
+
codequality: pylint-report.json
|
|
87
|
+
paths:
|
|
88
|
+
- pylint-report.json
|
|
89
|
+
expire_in: 30 days
|
|
90
|
+
|
|
91
|
+
ruff:
|
|
92
|
+
stage: code-quality
|
|
93
|
+
before_script:
|
|
94
|
+
- poetry install
|
|
95
|
+
script:
|
|
96
|
+
- poetry run ruff check ocgraph test --output-format=gitlab --output-file=ruff-report.json
|
|
97
|
+
- poetry run ruff check ocgraph test --output-format=concise
|
|
98
|
+
needs: [setup]
|
|
99
|
+
allow_failure: true
|
|
100
|
+
artifacts:
|
|
101
|
+
reports:
|
|
102
|
+
codequality: ruff-report.json
|
|
103
|
+
paths:
|
|
104
|
+
- ruff-report.json
|
|
105
|
+
expire_in: 30 days
|
|
106
|
+
|
|
107
|
+
build:
|
|
108
|
+
stage: build
|
|
109
|
+
before_script:
|
|
110
|
+
- poetry install
|
|
111
|
+
script:
|
|
112
|
+
- poetry build
|
|
113
|
+
needs: [test, mypy]
|
|
114
|
+
artifacts:
|
|
115
|
+
paths:
|
|
116
|
+
- dist
|
|
117
|
+
expire_in: 30 days
|
|
118
|
+
|
|
119
|
+
documentation:
|
|
120
|
+
stage: doc
|
|
121
|
+
before_script:
|
|
122
|
+
- poetry install
|
|
123
|
+
script:
|
|
124
|
+
- poetry run sphinx-build -W -b html doc doc_html
|
|
125
|
+
needs: [build]
|
|
126
|
+
artifacts:
|
|
127
|
+
paths:
|
|
128
|
+
- doc_html/
|
|
129
|
+
expire_in: 30 days
|
|
130
|
+
|
|
131
|
+
pages:
|
|
132
|
+
stage: publish
|
|
133
|
+
script:
|
|
134
|
+
- cp -R doc_html/ public/
|
|
135
|
+
artifacts:
|
|
136
|
+
paths:
|
|
137
|
+
- public/
|
|
138
|
+
expire_in: 30 days
|
|
139
|
+
needs: [documentation]
|
|
140
|
+
|
|
141
|
+
# Publish the release to PyPI. Requires the CI variable POETRY_PYPI_TOKEN_PYPI
|
|
142
|
+
# (a PyPI API token scoped to this project) and runs on tagged commits only.
|
|
143
|
+
publish-to-pypi:
|
|
144
|
+
stage: publish
|
|
145
|
+
before_script:
|
|
146
|
+
- poetry install
|
|
147
|
+
script:
|
|
148
|
+
- poetry build
|
|
149
|
+
- poetry run pip install --quiet twine
|
|
150
|
+
- poetry run twine check dist/*
|
|
151
|
+
- poetry publish --skip-existing
|
|
152
|
+
needs: [build, documentation, pages]
|
|
153
|
+
rules:
|
|
154
|
+
- if: '$CI_COMMIT_TAG'
|
|
155
|
+
environment:
|
|
156
|
+
name: pypi
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
exclude: |
|
|
2
|
+
(?x)^(
|
|
3
|
+
test/ocgraph/validation/(input|expected)/.*
|
|
4
|
+
)$
|
|
5
|
+
repos:
|
|
6
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
7
|
+
rev: v6.0.0
|
|
8
|
+
hooks:
|
|
9
|
+
- id: check-added-large-files
|
|
10
|
+
- id: check-ast
|
|
11
|
+
- id: check-builtin-literals
|
|
12
|
+
- id: check-case-conflict
|
|
13
|
+
- id: check-docstring-first
|
|
14
|
+
- id: check-executables-have-shebangs
|
|
15
|
+
- id: check-json
|
|
16
|
+
- id: check-merge-conflict
|
|
17
|
+
- id: check-shebang-scripts-are-executable
|
|
18
|
+
- id: check-symlinks
|
|
19
|
+
- id: check-toml
|
|
20
|
+
- id: check-vcs-permalinks
|
|
21
|
+
- id: check-xml
|
|
22
|
+
- id: check-yaml
|
|
23
|
+
args: [--allow-multiple-documents]
|
|
24
|
+
- id: debug-statements
|
|
25
|
+
- id: destroyed-symlinks
|
|
26
|
+
- id: detect-private-key
|
|
27
|
+
- id: end-of-file-fixer
|
|
28
|
+
- id: fix-byte-order-marker
|
|
29
|
+
- id: mixed-line-ending
|
|
30
|
+
- id: pretty-format-json
|
|
31
|
+
- id: trailing-whitespace
|
|
32
|
+
args: [--markdown-linebreak-ext=md]
|
|
33
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
34
|
+
rev: v0.17.4 # Ruff version.
|
|
35
|
+
hooks:
|
|
36
|
+
- id: ruff # Run the linter.
|
|
37
|
+
args: [ --fix, --config=pyproject.toml ]
|
|
38
|
+
- id: ruff-format # Run the formatter.
|
|
39
|
+
- repo: https://github.com/doublify/pre-commit-clang-format
|
|
40
|
+
rev: 62302476d0da01515660132d76902359bed0f782
|
|
41
|
+
hooks:
|
|
42
|
+
- id: clang-format
|
|
43
|
+
types: [file]
|
|
44
|
+
files: \.(cpp|cc|cxx|c|h|hxx)$
|
|
45
|
+
args: [--style=file]
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file. The format
|
|
4
|
+
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project
|
|
5
|
+
uses [semantic versioning](https://semver.org/spec/v2.0.0.html). The version is
|
|
6
|
+
the `version` entry of `pyproject.toml`, and every release is tagged
|
|
7
|
+
`v<version>` in the repository.
|
|
8
|
+
|
|
9
|
+
## [Unreleased]
|
|
10
|
+
|
|
11
|
+
## [1.0.0] - 2026-11-06
|
|
12
|
+
|
|
13
|
+
The first release published to PyPI, and the first whose packaging, licensing,
|
|
14
|
+
typing, and documentation are covered by the pipeline. The tool itself grew from
|
|
15
|
+
the single-architecture renderer of 0.3.0 into an analyzer of five object-code
|
|
16
|
+
architectures with runtime coverage, and the release engineering of this section
|
|
17
|
+
is what makes that behavior verifiable by someone who did not write it.
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
* RISC-V support, and instruction lists of ARM, PowerPC, and SPARC V8 extended to
|
|
22
|
+
cover the instructions that carry a delay slot, including the `bgeu` and `blu`
|
|
23
|
+
aliases.
|
|
24
|
+
* TSIM `.cov` files as coverage input next to the OCCTRE reports, with an
|
|
25
|
+
address-space offset for images linked away from zero, a manual coverage type
|
|
26
|
+
selection, and `--assert-coverage` for the coverage of a graph.
|
|
27
|
+
* `get_export_structure()` gives a caller the graph as data, with the taken jump,
|
|
28
|
+
the jump destination in the middle of a basic block, the edge coverage, and the
|
|
29
|
+
sinks distinguished from unresolved targets.
|
|
30
|
+
* Branch delay slots are tracked per architecture, an unresolved call ends a
|
|
31
|
+
block, and several observed targets of one conditional branch are rendered as
|
|
32
|
+
several edges.
|
|
33
|
+
* `--version`, `python -m ocgraph`, and `--view` to open the generated PDF.
|
|
34
|
+
* Sphinx documentation, published on GitLab Pages, covering the command line, the
|
|
35
|
+
accepted disassembly, the coverage formats, the graph reading guide, and the
|
|
36
|
+
extension of an architecture.
|
|
37
|
+
* A container image per supported distribution, so the suite runs on the
|
|
38
|
+
interpreter of each distribution that the classifiers claim: 3.11, 3.12, 3.13,
|
|
39
|
+
and 3.14.
|
|
40
|
+
* The strict type check is a gate of the pipeline, and `ocgraph/py.typed`
|
|
41
|
+
advertises the annotations to downstream type checks.
|
|
42
|
+
* A test ties the version of the package to the `version` entry of
|
|
43
|
+
`pyproject.toml`, the file the build backend reads.
|
|
44
|
+
* `CHANGELOG.md` and `CONTRIBUTING.md`.
|
|
45
|
+
|
|
46
|
+
### Changed
|
|
47
|
+
|
|
48
|
+
* The modules are reorganised into `ocgraph.interface` and `ocgraph.internal`,
|
|
49
|
+
with factory patterns for the architecture and the disassembler.
|
|
50
|
+
* Python 3.11 is the minimum supported version, and `requires-python` caps the
|
|
51
|
+
interpreter below 4.0.
|
|
52
|
+
* The distributions are described with a PEP 621 `[project]` table and carry PEP
|
|
53
|
+
639 license metadata, and the source distribution carries the test suite, the
|
|
54
|
+
documentation sources, the container images, the pipeline definition, the
|
|
55
|
+
pre-commit configuration, the contributor guide, and the lock file.
|
|
56
|
+
* The license is named by the SPDX identifier `MIT` in every source file. The
|
|
57
|
+
text of the two notices of `LICENSES/` is the MIT License verbatim, and
|
|
58
|
+
`LICENSE` collects both copyright statements, the upstream asm2cfg one and the
|
|
59
|
+
Celeres one.
|
|
60
|
+
* Generated PDFs are reproducible: the metadata of the document is normalised, and
|
|
61
|
+
the snapshot tests ignore the Graphviz layout coordinates.
|
|
62
|
+
* The `--type` argument is required only when coverage is given, and the coverage
|
|
63
|
+
colors distinguish executed, uncovered, and sink instructions.
|
|
64
|
+
|
|
65
|
+
### Fixed
|
|
66
|
+
|
|
67
|
+
* SPARC trap opcodes are decoded, and the SPARC instruction lists no longer
|
|
68
|
+
contain duplicates.
|
|
69
|
+
* A disassembly line whose jump target is followed by more text is parsed, and
|
|
70
|
+
malformed disassembly is reported as an input error instead of a traceback.
|
|
71
|
+
* Delay slot handling, the handling of an unconditional branch that coverage
|
|
72
|
+
reports with more than one target, and the drawer initialization.
|
|
73
|
+
* Coverage state is restored when an update is rolled back, and non-branch
|
|
74
|
+
instructions observed with more than one successor are invalidated.
|
|
75
|
+
* Empty blocks are guarded against in the rendering, blocks that are not directly
|
|
76
|
+
reached are no longer dropped, and edges to address zero are rendered.
|
|
77
|
+
* The reproducibility test no longer compares the creation timestamp that Graphviz
|
|
78
|
+
embeds in the PDF, which made the suite fail at random.
|
|
79
|
+
* `--version` works from a source tree without installed distribution metadata.
|
|
80
|
+
|
|
81
|
+
### Removed
|
|
82
|
+
|
|
83
|
+
* `ocrecord`, the GDB helper of 0.3.0. It imports the `Configuration` module that
|
|
84
|
+
this release removes, so it could not run, and nothing in the package, the
|
|
85
|
+
documentation, the tests, or the distribution referenced it.
|
|
86
|
+
* The GitHub workflow files and the helper scripts of the pre-Packaging era, and
|
|
87
|
+
the obsolete `Configuration` module.
|
|
88
|
+
|
|
89
|
+
## [0.3.0] - 2025-01-10
|
|
90
|
+
|
|
91
|
+
The release in which the tool became a Python package. The releases before it were
|
|
92
|
+
not tagged, so this is the first point that a packager can name.
|
|
93
|
+
|
|
94
|
+
### Added
|
|
95
|
+
|
|
96
|
+
* Packaging with Poetry, the `ocgraph` console command, and the container image
|
|
97
|
+
that the pipeline builds.
|
|
98
|
+
* Unit tests and validation tests built from the earlier examples, and the test
|
|
99
|
+
template generators that produce the inputs of a test.
|
|
100
|
+
* Abstract base classes for the architecture and the disassembler, with parsing of
|
|
101
|
+
the instructions in a single step and non-coverable code excluded.
|
|
102
|
+
* `ocrecord`, a GDB helper that produces the disassembly that ocgraph reads.
|
|
103
|
+
|
|
104
|
+
### Changed
|
|
105
|
+
|
|
106
|
+
* The configuration moved from `setup.cfg` to `pyproject.toml`, and the
|
|
107
|
+
re-exports of the package `__init__` files simplify the imports.
|
|
108
|
+
|
|
109
|
+
[Unreleased]: https://gitlab.com/gtd-gmbh/ocgraph/-/compare/v1.0.0...main
|
|
110
|
+
[1.0.0]: https://gitlab.com/gtd-gmbh/ocgraph/-/compare/v0.3.0...v1.0.0
|
|
111
|
+
[0.3.0]: https://gitlab.com/gtd-gmbh/ocgraph/-/tags/v0.3.0
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Contributing to ocgraph
|
|
2
|
+
|
|
3
|
+
This file describes the development environment of ocgraph. The tool itself, its
|
|
4
|
+
options, and its graphs are documented in
|
|
5
|
+
[README.md](README.md) and in the
|
|
6
|
+
[Sphinx documentation](https://gtd-gmbh.gitlab.io/ocgraph/), whose
|
|
7
|
+
development chapter explains the analysis flow and the extension points.
|
|
8
|
+
|
|
9
|
+
## System Dependencies
|
|
10
|
+
|
|
11
|
+
ocgraph needs the Graphviz binaries to render a graph, and the suite renders real
|
|
12
|
+
PDFs, so a development machine needs the same package:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
sudo apt-get update
|
|
16
|
+
sudo apt-get install python3 python3-pip python3-venv graphviz
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
On Arch Linux, use pacman:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
sudo pacman -Sy python python-pip graphviz
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Install Poetry 2.5 with [pipx](https://pipx.pypa.io/), `pipx install poetry`. The
|
|
26
|
+
Poetry of a Debian stable release predates PEP 621 support, and only poetry-core
|
|
27
|
+
2.5 writes the PEP 639 metadata of a release, which the
|
|
28
|
+
`poetry-core>=2.5.0` floor of `pyproject.toml` asks for.
|
|
29
|
+
|
|
30
|
+
## Setting up a virtual environment
|
|
31
|
+
|
|
32
|
+
After cloning the repository, create and populate the Python virtualenv:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
poetry install
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Installing and updating Python dependencies
|
|
39
|
+
|
|
40
|
+
All explicit dependencies are listed in `pyproject.toml`. Exact versions and the
|
|
41
|
+
dependencies of your dependencies are in `poetry.lock`.
|
|
42
|
+
|
|
43
|
+
Adding or removing packages is done through the `poetry add` command or by
|
|
44
|
+
editing `pyproject.toml`, followed by `poetry lock`. Updating all existing
|
|
45
|
+
dependencies is done with `poetry update`. Commit the lock file with the change
|
|
46
|
+
that requires it, because the pipeline installs from it.
|
|
47
|
+
|
|
48
|
+
## Release notes
|
|
49
|
+
|
|
50
|
+
`CHANGELOG.md` documents every release in the format of
|
|
51
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Add an entry to the
|
|
52
|
+
`Unreleased` section together with the commit that changes the behaviour of the
|
|
53
|
+
tool, so that the section of the next release is complete when the version is
|
|
54
|
+
bumped.
|
|
55
|
+
|
|
56
|
+
## Commit hooks
|
|
57
|
+
|
|
58
|
+
The repository uses git pre-commit hooks so that no obvious error is committed.
|
|
59
|
+
Install them after activating the virtualenv:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
poetry run pre-commit install
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The hooks run Ruff as linter and formatter, and check the plain things: syntax,
|
|
66
|
+
trailing whitespace, merge conflict markers, large files, private keys.
|
|
67
|
+
|
|
68
|
+
## Running the test suite
|
|
69
|
+
|
|
70
|
+
The suite is run with pytest:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
poetry run pytest
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
It needs no target, debugger, or emulator, but it does render real graphs, so the
|
|
77
|
+
Graphviz binaries of the section above are required. The unit tests cover the
|
|
78
|
+
disassemblers, the architectures, the analyzer, the coverage readers, and the
|
|
79
|
+
drawer; the validation tests render a graph per architecture and compare the
|
|
80
|
+
generated `.gv` file with the expected file in `test/ocgraph/validation`.
|
|
81
|
+
|
|
82
|
+
The pipeline runs the suite once per supported distribution, on the interpreter of
|
|
83
|
+
that distribution: 3.11 on Debian bookworm, 3.12 on Ubuntu 24.04, 3.13 on Debian
|
|
84
|
+
trixie, and the rolling 3.14 of Arch Linux.
|
|
85
|
+
|
|
86
|
+
Add a unit test when changing parsing, instruction classification, coverage, or
|
|
87
|
+
block formation, and a validation fixture when a change alters a rendered graph.
|
|
88
|
+
|
|
89
|
+
The pipeline also runs `mypy -p ocgraph` with the strict settings of
|
|
90
|
+
`pyproject.toml`. Because the package ships `ocgraph/py.typed`, a type error
|
|
91
|
+
fails the pipeline, so run the same command before pushing:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
poetry run mypy -p ocgraph
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`pylint` and `ruff check` publish review reports on the merge request, and a
|
|
98
|
+
finding in the internal modules does not block a change:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
poetry run pylint -j0 --allow-reexport-from-package y ocgraph
|
|
102
|
+
poetry run ruff check ocgraph test
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Building the documentation
|
|
106
|
+
|
|
107
|
+
The Sphinx HTML documentation is built with:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
poetry run sphinx-build -W -b html doc doc_html
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The generated entry page is `doc_html/index.html`. The `-W` option turns
|
|
114
|
+
documentation warnings into errors, as the pipeline does.
|
|
115
|
+
|
|
116
|
+
## Building a release
|
|
117
|
+
|
|
118
|
+
Releases are built with Poetry 2.5, the version the container images install and
|
|
119
|
+
the `poetry-core>=2.5.0` floor of `pyproject.toml` asks for: only poetry-core 2.5
|
|
120
|
+
writes the PEP 639 metadata of the release, with `License-Expression: MIT` and
|
|
121
|
+
the three license files listed in the wheel. Build the archives and check them
|
|
122
|
+
before publishing:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
poetry build
|
|
126
|
+
poetry run pip install twine && poetry run twine check dist/*
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
The sdist carries the test suite, the test templates, the documentation sources,
|
|
130
|
+
the container images, the pipeline definition, and the lock file, so a release
|
|
131
|
+
built from the sdist can be verified with the commands above. The wheel contains
|
|
132
|
+
only the `ocgraph` package and its `py.typed` marker.
|
|
133
|
+
|
|
134
|
+
Releases are published to PyPI by the pipeline on tagged commits. The pipeline
|
|
135
|
+
needs the `POETRY_PYPI_TOKEN_PYPI` CI variable, a PyPI API token scoped to this
|
|
136
|
+
project.
|
ocgraph-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Mauri Mustonen
|
|
4
|
+
Copyright (c) 2023-2026 Celeres
|
|
5
|
+
|
|
6
|
+
ocgraph originates in asm2cfg by Mauri Mustonen and was extended by Celeres. The
|
|
7
|
+
two notices are kept apart in `LICENSES/MauriMustonen.md` and
|
|
8
|
+
`LICENSES/Celeres.md`, which carry the same text as below.
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
11
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
12
|
+
the Software without restriction, including without limitation the rights to
|
|
13
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
14
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
15
|
+
subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
ocgraph-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ocgraph
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Tool to visualize object code as control flow graph
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
License-File: LICENSES/Celeres.md
|
|
8
|
+
License-File: LICENSES/MauriMustonen.md
|
|
9
|
+
Keywords: Object Code,Control Flow Graph,ECSS Category A,asm2cfg,Coverage
|
|
10
|
+
Author: Mauri Mustonen
|
|
11
|
+
Author-email: kazooiebombchu@gmail.com
|
|
12
|
+
Maintainer: Christoph Weiss
|
|
13
|
+
Maintainer-email: christoph.weiss@celeres.com
|
|
14
|
+
Requires-Python: >=3.11,<4.0
|
|
15
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
16
|
+
Classifier: Environment :: Console
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
24
|
+
Classifier: Topic :: Software Development :: Debuggers
|
|
25
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
26
|
+
Classifier: Topic :: Software Development :: Testing
|
|
27
|
+
Classifier: Topic :: Utilities
|
|
28
|
+
Requires-Dist: graphviz (>=0.21,<0.22)
|
|
29
|
+
Project-URL: Changelog, https://gitlab.com/gtd-gmbh/ocgraph/-/blob/main/CHANGELOG.md
|
|
30
|
+
Project-URL: Documentation, https://gtd-gmbh.gitlab.io/ocgraph/
|
|
31
|
+
Project-URL: Forked from asm2cfg, https://github.com/Kazhuu/asm2cfg
|
|
32
|
+
Project-URL: Homepage, https://gitlab.com/gtd-gmbh/ocgraph
|
|
33
|
+
Project-URL: Issues, https://gitlab.com/gtd-gmbh/ocgraph/-/issues
|
|
34
|
+
Project-URL: Repository, https://gitlab.com/gtd-gmbh/ocgraph
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
|
|
37
|
+
# Object Code Graph (ocgraph)
|
|
38
|
+
|
|
39
|
+
ocgraph converts the disassembly of one function into a control-flow graph
|
|
40
|
+
(CFG). It can enrich the graph with instruction and branch coverage from
|
|
41
|
+
[OCCTRE](https://pypi.org/project/occtre/) or TSIM.
|
|
42
|
+
|
|
43
|
+
The analyzer supports ARM, MSP430, PowerPC, RISC-V, SPARC V8, and x86 GNU
|
|
44
|
+
objdump output. Every run writes both a PDF for review and the corresponding
|
|
45
|
+
Graphviz source (`.gv`).
|
|
46
|
+
|
|
47
|
+
A graph is a view of the disassembly you supply: it depends on that disassembly,
|
|
48
|
+
on the architecture selection, and on the optional runtime coverage, so validate
|
|
49
|
+
a generated graph for the intended toolchain and assurance process.
|
|
50
|
+
|
|
51
|
+
## Quick start
|
|
52
|
+
|
|
53
|
+
Python 3.11 or newer and the Graphviz system package are required, because the
|
|
54
|
+
`dot` binary renders the PDF. Install the tool with
|
|
55
|
+
[pipx](https://pipx.pypa.io/), which keeps it in its own virtual environment:
|
|
56
|
+
|
|
57
|
+
```console
|
|
58
|
+
pipx install ocgraph
|
|
59
|
+
objdump -d --disassemble=my_function ./application > my_function.asm
|
|
60
|
+
ocgraph --file my_function.asm --arch x86 --diss objdump
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`python -m pip install ocgraph` installs it into the active environment instead,
|
|
64
|
+
which is what a packager wants. `python -m ocgraph` runs the same command from a
|
|
65
|
+
checkout of the source tree, and `ocgraph --version` reports the version.
|
|
66
|
+
|
|
67
|
+
This creates `my_function.pdf` and `my_function.gv`. Use `--output` to choose a
|
|
68
|
+
different output basename and `--view` to open the generated PDF after both
|
|
69
|
+
files have been written.
|
|
70
|
+
|
|
71
|
+
## Documentation
|
|
72
|
+
|
|
73
|
+
The full documentation covers installation, accepted disassembly input,
|
|
74
|
+
coverage formats, command-line and Python usage, graph interpretation, and
|
|
75
|
+
extension development:
|
|
76
|
+
|
|
77
|
+
- [Published documentation](https://gtd-gmbh.gitlab.io/ocgraph/)
|
|
78
|
+
- [Documentation sources](https://gitlab.com/gtd-gmbh/ocgraph/-/tree/main/doc)
|
|
79
|
+
|
|
80
|
+
Build it locally with:
|
|
81
|
+
|
|
82
|
+
```console
|
|
83
|
+
poetry install
|
|
84
|
+
poetry run sphinx-build -W -b html doc doc_html
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The generated entry page is `doc_html/index.html`.
|
|
88
|
+
|
|
89
|
+
## Development
|
|
90
|
+
|
|
91
|
+
[CONTRIBUTING.md](https://gitlab.com/gtd-gmbh/ocgraph/-/blob/main/CONTRIBUTING.md)
|
|
92
|
+
describes the development environment, and the
|
|
93
|
+
[development chapter](https://gitlab.com/gtd-gmbh/ocgraph/-/tree/main/doc/development)
|
|
94
|
+
explains the analysis flow and the extension points. The short version:
|
|
95
|
+
|
|
96
|
+
```console
|
|
97
|
+
poetry install
|
|
98
|
+
poetry run pytest
|
|
99
|
+
poetry run mypy -p ocgraph
|
|
100
|
+
poetry run pre-commit run --all-files
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The pipeline runs the suite on Debian bookworm, Debian trixie, Ubuntu 24.04, and
|
|
104
|
+
Arch Linux, which pins the interpreters 3.11, 3.13, 3.12, and the rolling 3.14.
|
|
105
|
+
|
|
106
|
+
## License
|
|
107
|
+
|
|
108
|
+
Released under the MIT License, see
|
|
109
|
+
[LICENSE](https://gitlab.com/gtd-gmbh/ocgraph/-/blob/main/LICENSE).
|
|
110
|
+
The project was forked from [asm2cfg](https://github.com/Kazhuu/asm2cfg) by
|
|
111
|
+
Mauri Mustonen, who holds the copyright of 2021 for the work it builds on, and
|
|
112
|
+
Celeres holds the copyright of 2023 to 2026 for the extensions. The two notices
|
|
113
|
+
are kept apart in
|
|
114
|
+
[LICENSES](https://gitlab.com/gtd-gmbh/ocgraph/-/tree/main/LICENSES).
|
|
115
|
+
|
|
116
|
+
## Links
|
|
117
|
+
|
|
118
|
+
- [Documentation](https://gtd-gmbh.gitlab.io/ocgraph/)
|
|
119
|
+
- [PyPI](https://pypi.org/project/ocgraph/)
|
|
120
|
+
- [Source repository](https://gitlab.com/gtd-gmbh/ocgraph)
|
|
121
|
+
- [Issues](https://gitlab.com/gtd-gmbh/ocgraph/-/issues)
|
|
122
|
+
- [Changelog](https://gitlab.com/gtd-gmbh/ocgraph/-/blob/main/CHANGELOG.md)
|
|
123
|
+
- [asm2cfg, the upstream project](https://github.com/Kazhuu/asm2cfg)
|
|
124
|
+
|