objutils 0.10.12__tar.gz → 0.10.14__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.
- objutils-0.10.14/.idea/pyLspTools.xml +16 -0
- {objutils-0.10.12 → objutils-0.10.14}/.pre-commit-config.yaml +1 -1
- {objutils-0.10.12 → objutils-0.10.14}/PKG-INFO +4 -1
- {objutils-0.10.12 → objutils-0.10.14}/docs/README.rst +3 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/conf.py +1 -1
- {objutils-0.10.12 → objutils-0.10.14}/docs/howto.rst +23 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/__init__.py +10 -10
- {objutils-0.10.12 → objutils-0.10.14}/objutils/ash.py +1 -1
- {objutils-0.10.12 → objutils-0.10.14}/objutils/binfile.py +6 -6
- {objutils-0.10.12 → objutils-0.10.14}/objutils/cosmac.py +2 -2
- {objutils-0.10.12 → objutils-0.10.14}/objutils/dwarf/__init__.py +1 -4
- {objutils-0.10.12 → objutils-0.10.14}/objutils/dwarf/attrparser.py +1 -1
- {objutils-0.10.12 → objutils-0.10.14}/objutils/dwarf/encoding.py +6 -8
- {objutils-0.10.12 → objutils-0.10.14}/objutils/dwarf/readers.py +0 -1
- {objutils-0.10.12 → objutils-0.10.14}/objutils/dwarf/sm.py +0 -2
- {objutils-0.10.12 → objutils-0.10.14}/objutils/dwarf/traverser.py +17 -17
- {objutils-0.10.12 → objutils-0.10.14}/objutils/elf/__init__.py +68 -11
- {objutils-0.10.12 → objutils-0.10.14}/objutils/elf/model.py +1 -3
- {objutils-0.10.12 → objutils-0.10.14}/objutils/emon52.py +1 -1
- {objutils-0.10.12 → objutils-0.10.14}/objutils/etek.py +3 -3
- {objutils-0.10.12 → objutils-0.10.14}/objutils/fpc.py +4 -4
- {objutils-0.10.12 → objutils-0.10.14}/objutils/hexfile.py +31 -40
- {objutils-0.10.12 → objutils-0.10.14}/objutils/ieee695.py +10 -14
- {objutils-0.10.12 → objutils-0.10.14}/objutils/ihex.py +6 -6
- {objutils-0.10.12 → objutils-0.10.14}/objutils/image.py +88 -24
- {objutils-0.10.12 → objutils-0.10.14}/objutils/logger.py +4 -4
- {objutils-0.10.12 → objutils-0.10.14}/objutils/mostec.py +5 -5
- {objutils-0.10.12 → objutils-0.10.14}/objutils/oocdtxt.py +3 -3
- {objutils-0.10.12 → objutils-0.10.14}/objutils/pecoff/__init__.py +1 -1
- {objutils-0.10.12 → objutils-0.10.14}/objutils/pecoff/pdb/__init__.py +2 -2
- {objutils-0.10.12 → objutils-0.10.14}/objutils/rca.py +5 -5
- {objutils-0.10.12 → objutils-0.10.14}/objutils/registry.py +1 -3
- {objutils-0.10.12 → objutils-0.10.14}/objutils/scripts/oj_coff_extract.py +1 -1
- {objutils-0.10.12 → objutils-0.10.14}/objutils/scripts/oj_coff_import.py +1 -1
- {objutils-0.10.12 → objutils-0.10.14}/objutils/scripts/oj_coff_info.py +1 -1
- {objutils-0.10.12 → objutils-0.10.14}/objutils/scripts/oj_coff_syms.py +1 -1
- {objutils-0.10.12 → objutils-0.10.14}/objutils/scripts/oj_elf_arm_attrs.py +1 -1
- {objutils-0.10.12 → objutils-0.10.14}/objutils/scripts/oj_elf_extract.py +1 -1
- {objutils-0.10.12 → objutils-0.10.14}/objutils/scripts/oj_elf_syms.py +3 -10
- {objutils-0.10.12 → objutils-0.10.14}/objutils/scripts/oj_hex_split.py +138 -135
- {objutils-0.10.12 → objutils-0.10.14}/objutils/section.py +39 -19
- {objutils-0.10.12 → objutils-0.10.14}/objutils/shf.py +1 -6
- {objutils-0.10.12 → objutils-0.10.14}/objutils/sig.py +3 -3
- {objutils-0.10.12 → objutils-0.10.14}/objutils/srec.py +8 -16
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tek.py +5 -5
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_elf.py +80 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_image.py +37 -1
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_section.py +18 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/titxt.py +1 -1
- {objutils-0.10.12 → objutils-0.10.14}/objutils/version.py +1 -1
- {objutils-0.10.12 → objutils-0.10.14}/pyproject.toml +2 -2
- objutils-0.10.12/.idea/pyLspTools.xml +0 -6
- {objutils-0.10.12 → objutils-0.10.14}/.clang-format +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.codacy.yml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.codeclimate.yml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.coveralls.yml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.github/FUNDING.yml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.github/ISSUE_TEMPLATE/documentation.yml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.github/ISSUE_TEMPLATE.md +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.github/copilot-instructions.md +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.github/workflows/pythonapp.yml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.gitignore +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.idea/.gitignore +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.idea/copilot.data.migration.ask2agent.xml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.idea/deployment.xml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.idea/inspectionProfiles/profiles_settings.xml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.idea/misc.xml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.idea/modules.xml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.idea/pyProjectModel.xml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.idea/vcs.xml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.pylintrc +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.readthedocs.yml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/.travis.yml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/CMakeLists.txt +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/CODE_OF_CONDUCT.md +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/CONTRIBUTORS +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/LICENSE +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/MANIFEST.in +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/PULL_REQUEST_TEMPLATE.md +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/appveyor.yml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/bandit.yml +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/Data_Formats.pdf +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/ELF_Format.pdf +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/KNOWN_GOOD_DWARF_REFERENCE.md +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/apidoc.sh +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/.buildinfo +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/.buildinfo.bak +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/.doctrees/README.doctree +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/.doctrees/environment.pickle +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/.doctrees/howto.doctree +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/.doctrees/index.doctree +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/.doctrees/installation.doctree +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/.doctrees/modules.doctree +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/.doctrees/objutils.doctree +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/.doctrees/objutils.elf.doctree +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/.doctrees/scripts.doctree +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/.doctrees/session.doctree +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/.doctrees/tutorial.doctree +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/README.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_images/objutils_basic.png +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/index.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/ash.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/binfile.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/checksums.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/cosmac.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/elf/defs.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/elf.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/emon52.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/etek.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/exceptions.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/fpc.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/hexdump.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/hexfile.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/ihex.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/image.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/logger.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/mostec.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/pickleif.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/rca.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/readers.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/registry.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/section.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/sig.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/srec.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/tek.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/titxt.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils/utils.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_modules/objutils.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_sources/README.rst.txt +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_sources/howto.rst.txt +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_sources/index.rst.txt +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_sources/installation.rst.txt +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_sources/modules.rst.txt +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_sources/objutils.elf.rst.txt +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_sources/objutils.rst.txt +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_sources/scripts.rst.txt +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_sources/session.rst.txt +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_sources/tutorial.rst.txt +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/alabaster.css +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/basic.css +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/check-solid.svg +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/clipboard.min.js +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/copy-button.svg +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/copybutton.css +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/copybutton.js +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/copybutton_funcs.js +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/custom.css +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/doctools.js +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/documentation_options.js +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/file.png +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/github-banner.svg +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/language_data.js +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/minus.png +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/plus.png +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/pygments.css +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/scripts/bootstrap.js +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/scripts/bootstrap.js.LICENSE.txt +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/scripts/fontawesome.js +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/scripts/fontawesome.js.LICENSE.txt +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/scripts/pydata-sphinx-theme.js +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/searchtools.js +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/sphinx_highlight.js +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/styles/pydata-sphinx-theme.css +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/styles/theme.css +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-brands-400.ttf +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-brands-400.woff2 +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-regular-400.ttf +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-regular-400.woff2 +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-solid-900.ttf +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-solid-900.woff2 +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/_static/webpack-macros.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/genindex.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/howto.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/index.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/installation.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/modules.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/objects.inv +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/objutils.elf.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/objutils.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/py-modindex.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/scripts.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/search.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/searchindex.js +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/session.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/docs/_build/html/tutorial.html +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/elf-64-gen.pdf +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/example0.srec +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/index.rst +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/installation.rst +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/make.bat +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/modules.rst +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/objutils.elf.rst +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/objutils.rst +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/objutils_banner.png +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/objutils_basic.png +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/objutils_dark.jpg +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/objutils_social.jpg +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/requirements.txt +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/scripts.rst +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/session.rst +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/tutorial.rst +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/docs/tutorial1.ipynb +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/.coveragerc +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/.vscode/launch.json +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/.vscode/settings.json +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/a2l_test.shf +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/checksums.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/dwarf/c_generator.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/dwarf/constants.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/dwarf/lineprog.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/elf/arm/__init__.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/elf/arm/attributes.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/elf/defs.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/exceptions.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/extensions/__init__.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/extensions/ctre.hpp +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/extensions/difflib.h +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/extensions/exceptions.cpp +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/extensions/exceptions.hpp +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/extensions/hexfile.cpp +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/extensions/wrapper.cpp +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/hexdump.py +1 -1
- {objutils-0.10.12 → objutils-0.10.14}/objutils/objutils.code-workspace +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/pecoff/defs.py +15 -15
- {objutils-0.10.12 → objutils-0.10.14}/objutils/pecoff/model.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/pickleif.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/readers.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/scripts/arduino_build_artifacts.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/scripts/oj_cgen.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/scripts/oj_dwarf_import.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/scripts/oj_dwarf_info.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/scripts/oj_elf_import.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/scripts/oj_elf_info.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/scripts/oj_hex_info.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/scripts/oj_hex_merge.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/symbols.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/__init__.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_arm_attributes.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_ash.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_c_generator.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_checksums.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_cygpath.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_diff_bin.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_emon52.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_etek.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_examples_cgen.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_fpc.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_hexdump.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_hexfile.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_ihex.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_mostec.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_oocdtxt.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_readers.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_registry.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_repr.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_section_join.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_shf.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_sm.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_srec.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_tek.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/tests/test_titext.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/utils/__init__.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/utils/arduino.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/objutils/utils/diff.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/poetry.lock +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/requirements.txt +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/setup.cfg +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/setup.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/test_join_sections.py +0 -0
- {objutils-0.10.12 → objutils-0.10.14}/test_requirements.txt +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="PyToolsState">
|
|
4
|
+
<option name="tools">
|
|
5
|
+
<map>
|
|
6
|
+
<entry key="ruff">
|
|
7
|
+
<value>
|
|
8
|
+
<ToolEntry>
|
|
9
|
+
<option name="enabled" value="true" />
|
|
10
|
+
</ToolEntry>
|
|
11
|
+
</value>
|
|
12
|
+
</entry>
|
|
13
|
+
</map>
|
|
14
|
+
</option>
|
|
15
|
+
</component>
|
|
16
|
+
</project>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: objutils
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.14
|
|
4
4
|
Summary: Objectfile library for Python
|
|
5
5
|
Keywords: hex files,intel hex,s19,srec,srecords,object files,map files,embedded,microcontroller,ECU,shf,rfc4194
|
|
6
6
|
Author-Email: Christoph Schueler <cpu12.gems@googlemail.com>
|
|
@@ -87,6 +87,9 @@ Features
|
|
|
87
87
|
Recent improvements
|
|
88
88
|
-------------------
|
|
89
89
|
|
|
90
|
+
- ``ElfParser`` now supports ``in_memory=True``: use a transient ``:memory:`` SQLite
|
|
91
|
+
database instead of persisting a .prgdb file – ideal for read-only analysis, CI
|
|
92
|
+
pipelines and unit tests.
|
|
90
93
|
- New ``oj-hex-merge`` and ``oj-hex-split`` CLI tools for combining and partitioning HEX files.
|
|
91
94
|
- New ``oj-dwarf-import`` CLI replaces ``dwarfer.py``/``cu_info.py`` for DWARF imports, CU listing, summaries, and attribute traversal.
|
|
92
95
|
- Faster DWARF imports: batched ORM writes, quiet flag propagation, and safe DWARF expression evaluation keep large ELF files stable.
|
|
@@ -51,6 +51,9 @@ Features
|
|
|
51
51
|
Recent improvements
|
|
52
52
|
-------------------
|
|
53
53
|
|
|
54
|
+
- ``ElfParser`` now supports ``in_memory=True``: use a transient ``:memory:`` SQLite
|
|
55
|
+
database instead of persisting a .prgdb file – ideal for read-only analysis, CI
|
|
56
|
+
pipelines and unit tests.
|
|
54
57
|
- New ``oj-hex-merge`` and ``oj-hex-split`` CLI tools for combining and partitioning HEX files.
|
|
55
58
|
- New ``oj-dwarf-import`` CLI replaces ``dwarfer.py``/``cu_info.py`` for DWARF imports, CU listing, summaries, and attribute traversal.
|
|
56
59
|
- Faster DWARF imports: batched ORM writes, quiet flag propagation, and safe DWARF expression evaluation keep large ELF files stable.
|
|
@@ -17,7 +17,7 @@ def get_version():
|
|
|
17
17
|
import re
|
|
18
18
|
from pathlib import Path
|
|
19
19
|
|
|
20
|
-
VERSION = re.compile(r'version\s*=\s*"(?P<version>\d+\.\d+(\.\d+)?)\s*"', re.
|
|
20
|
+
VERSION = re.compile(r'version\s*=\s*"(?P<version>\d+\.\d+(\.\d+)?)\s*"', re.MULTILINE)
|
|
21
21
|
|
|
22
22
|
try:
|
|
23
23
|
cfg = Path(r"../pyproject.toml")
|
|
@@ -84,6 +84,29 @@ Use the CLI to generate HEX for flashing:
|
|
|
84
84
|
|
|
85
85
|
oj-elf-extract build/app.elf app.srec -t srec
|
|
86
86
|
|
|
87
|
+
Analyse ELF without writing a .prgdb file (in-memory database)
|
|
88
|
+
---------------------------------------------------------------
|
|
89
|
+
|
|
90
|
+
By default ``ElfParser`` creates a ``<name>.prgdb`` SQLite cache file next to
|
|
91
|
+
the ELF file. Pass ``in_memory=True`` to keep everything in memory – useful
|
|
92
|
+
for read-only scripting, CI pipelines, or unit tests where disk writes are
|
|
93
|
+
undesirable.
|
|
94
|
+
|
|
95
|
+
.. code-block:: python
|
|
96
|
+
|
|
97
|
+
from objutils.elf import ElfParser
|
|
98
|
+
|
|
99
|
+
# No .prgdb file is created – database lives only in RAM
|
|
100
|
+
with ElfParser('build/app.elf', in_memory=True) as parser:
|
|
101
|
+
print(f"Machine: {parser.e_machine}")
|
|
102
|
+
image = parser.create_image()
|
|
103
|
+
|
|
104
|
+
.. note::
|
|
105
|
+
|
|
106
|
+
The in-memory database is rebuilt on every instantiation (no caching
|
|
107
|
+
benefit). Use the default on-disk mode if you parse the same file
|
|
108
|
+
repeatedly and want fast cached access.
|
|
109
|
+
|
|
87
110
|
Extract loadable image from PE/COFF (32-bit and 64-bit)
|
|
88
111
|
-------------------------------------------------------
|
|
89
112
|
|
|
@@ -13,20 +13,20 @@ Registers CODECS and implements an interface to them.
|
|
|
13
13
|
The first parameter is always the codec name.
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
|
-
__version__ = "0.10.
|
|
16
|
+
__version__ = "0.10.14"
|
|
17
17
|
|
|
18
18
|
__all__ = [
|
|
19
19
|
"Image",
|
|
20
|
-
"Section",
|
|
21
|
-
"LazySection",
|
|
22
20
|
"InvalidAddressError",
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"loads",
|
|
21
|
+
"LazySection",
|
|
22
|
+
"Section",
|
|
26
23
|
"dump",
|
|
27
24
|
"dumps",
|
|
25
|
+
"load",
|
|
26
|
+
"loads",
|
|
28
27
|
"probe",
|
|
29
28
|
"probes",
|
|
29
|
+
"registry",
|
|
30
30
|
]
|
|
31
31
|
|
|
32
32
|
__copyright__ = """
|
|
@@ -76,9 +76,9 @@ import objutils.sig
|
|
|
76
76
|
import objutils.srec
|
|
77
77
|
import objutils.tek
|
|
78
78
|
import objutils.titxt
|
|
79
|
-
from objutils.image import Image, InvalidAddressError
|
|
79
|
+
from objutils.image import Image, InvalidAddressError
|
|
80
80
|
from objutils.registry import registry
|
|
81
|
-
from objutils.section import Section, LazySection
|
|
81
|
+
from objutils.section import Section, LazySection
|
|
82
82
|
|
|
83
83
|
# Optional developer-friendly console and tracebacks; disabled by default for library consumers.
|
|
84
84
|
_ENABLE_RICH = os.getenv("OBJUTILS_RICH", "0").lower() in {"1", "true", "yes"}
|
|
@@ -158,7 +158,7 @@ def loads(codec_name: str, data: str | bytes | bytearray, join: bool = True, **k
|
|
|
158
158
|
return registry.get(codec_name).Reader().loads(data, join=join, **kws)
|
|
159
159
|
|
|
160
160
|
|
|
161
|
-
def probe(fp: BinaryIO, **kws: Any) ->
|
|
161
|
+
def probe(fp: BinaryIO, **kws: Any) -> str | None:
|
|
162
162
|
"""Try to guess codec from file.
|
|
163
163
|
|
|
164
164
|
Returns
|
|
@@ -195,7 +195,7 @@ def probe(fp: BinaryIO, **kws: Any) -> Optional[str]:
|
|
|
195
195
|
return None
|
|
196
196
|
|
|
197
197
|
|
|
198
|
-
def probes(data: str | bytes | bytearray, **kws: Any) ->
|
|
198
|
+
def probes(data: str | bytes | bytearray, **kws: Any) -> str | None:
|
|
199
199
|
"""Try to guess codec from bytes.
|
|
200
200
|
|
|
201
201
|
Returns
|
|
@@ -26,9 +26,9 @@ __copyright__ = """
|
|
|
26
26
|
import io
|
|
27
27
|
import zipfile
|
|
28
28
|
from contextlib import closing
|
|
29
|
-
from typing import Any, BinaryIO
|
|
29
|
+
from typing import Any, BinaryIO
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
from objutils import hexfile
|
|
32
32
|
from objutils.image import Image
|
|
33
33
|
from objutils.section import Section
|
|
34
34
|
|
|
@@ -42,7 +42,7 @@ class NoContiniousError(Exception):
|
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
class Reader(hexfile.Reader):
|
|
45
|
-
def load(self, fp:
|
|
45
|
+
def load(self, fp: str | BinaryIO, address: int = 0x0000, **kws: Any) -> Image:
|
|
46
46
|
if isinstance(fp, str):
|
|
47
47
|
fp = open(fp, "rb")
|
|
48
48
|
data = fp.read()
|
|
@@ -52,7 +52,7 @@ class Reader(hexfile.Reader):
|
|
|
52
52
|
fp.close()
|
|
53
53
|
return img
|
|
54
54
|
|
|
55
|
-
def loads(self, image:
|
|
55
|
+
def loads(self, image: str | bytes | bytearray, address: int = 0x0000, **kws: Any) -> Image:
|
|
56
56
|
if isinstance(image, str):
|
|
57
57
|
return self.load(io.BytesIO(bytes(image, "ascii")), address)
|
|
58
58
|
else:
|
|
@@ -112,12 +112,12 @@ class BinZipReader(hexfile.Reader):
|
|
|
112
112
|
except (AttributeError, io.UnsupportedOperation):
|
|
113
113
|
pass
|
|
114
114
|
|
|
115
|
-
def load(self, fp:
|
|
115
|
+
def load(self, fp: str | BinaryIO, **kws: Any) -> Image:
|
|
116
116
|
"""Load from zip file."""
|
|
117
117
|
# TODO: Implementation
|
|
118
118
|
return Image([], valid=True)
|
|
119
119
|
|
|
120
|
-
def loads(self, data:
|
|
120
|
+
def loads(self, data: str | bytes | bytearray, **kws: Any) -> Image:
|
|
121
121
|
"""Load from zip bytes."""
|
|
122
122
|
return self.load(io.BytesIO(data) if isinstance(data, (bytes, bytearray)) else io.BytesIO(data.encode()))
|
|
123
123
|
|
|
@@ -40,7 +40,7 @@ __copyright__ = """
|
|
|
40
40
|
from collections.abc import Sequence
|
|
41
41
|
from typing import Any
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
from objutils import hexfile
|
|
44
44
|
|
|
45
45
|
# Record type identifiers
|
|
46
46
|
DATA0 = 1 # !MAAAA DD
|
|
@@ -80,7 +80,7 @@ class Reader(hexfile.Reader):
|
|
|
80
80
|
Cosmac format has no checksums, validation is minimal.
|
|
81
81
|
"""
|
|
82
82
|
# Cosmac has no checksums - nothing to validate
|
|
83
|
-
return
|
|
83
|
+
return
|
|
84
84
|
|
|
85
85
|
def probe(self, fp: Any, **kws: Any) -> bool:
|
|
86
86
|
"""Check if file matches RCA Cosmac format.
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
|
-
# ruff: noqa: E402
|
|
3
2
|
# Imports come after module docstring
|
|
4
3
|
|
|
5
4
|
"""DWARF 4 debug information parser and processor.
|
|
@@ -266,7 +265,7 @@ class Attribute:
|
|
|
266
265
|
|
|
267
266
|
encoding: constants.AttributeEncoding
|
|
268
267
|
form: constants.AttributeForm
|
|
269
|
-
special_value:
|
|
268
|
+
special_value: Any | None = None
|
|
270
269
|
|
|
271
270
|
def __iter__(self):
|
|
272
271
|
yield self.encoding
|
|
@@ -300,7 +299,6 @@ class Readers:
|
|
|
300
299
|
Used internally by DwarfReaders to organize parsers.
|
|
301
300
|
"""
|
|
302
301
|
|
|
303
|
-
pass
|
|
304
302
|
|
|
305
303
|
|
|
306
304
|
@dataclass
|
|
@@ -531,7 +529,6 @@ class Abbrevations:
|
|
|
531
529
|
)
|
|
532
530
|
continue
|
|
533
531
|
if attr.attrValue != 0 and attr.formValue != 0:
|
|
534
|
-
#
|
|
535
532
|
try:
|
|
536
533
|
self.abbrevations[key].attrs.append(
|
|
537
534
|
Attribute(
|
|
@@ -321,7 +321,7 @@ class AttributeParser:
|
|
|
321
321
|
tag = t.get("tag", "<type>")
|
|
322
322
|
name = ""
|
|
323
323
|
attrs = t.get("attrs", {}) if isinstance(t.get("attrs"), dict) else {}
|
|
324
|
-
if
|
|
324
|
+
if attrs.get("name"):
|
|
325
325
|
try:
|
|
326
326
|
name = str(attrs["name"])
|
|
327
327
|
except (UnicodeDecodeError, ValueError, TypeError):
|
|
@@ -63,13 +63,11 @@ class Endianess(IntEnum):
|
|
|
63
63
|
class ULEBError(ConstructError):
|
|
64
64
|
"""Raised when ULEB128 parsing or building encounters an error."""
|
|
65
65
|
|
|
66
|
-
pass
|
|
67
66
|
|
|
68
67
|
|
|
69
68
|
class SLEBError(ConstructError):
|
|
70
69
|
"""Raised when SLEB128 parsing or building encounters an error."""
|
|
71
70
|
|
|
72
|
-
pass
|
|
73
71
|
|
|
74
72
|
|
|
75
73
|
@singleton
|
|
@@ -96,7 +94,7 @@ class ULEB(Construct):
|
|
|
96
94
|
"""
|
|
97
95
|
|
|
98
96
|
def __init__(self, *args) -> None:
|
|
99
|
-
super(
|
|
97
|
+
super().__init__()
|
|
100
98
|
|
|
101
99
|
def _parse(self, stream, context, path: str | None = None) -> int:
|
|
102
100
|
"""Parse a ULEB128-encoded value from stream.
|
|
@@ -171,7 +169,7 @@ class SLEB(Construct):
|
|
|
171
169
|
"""
|
|
172
170
|
|
|
173
171
|
def __init__(self, *args) -> None:
|
|
174
|
-
super(
|
|
172
|
+
super().__init__()
|
|
175
173
|
|
|
176
174
|
def _parse(self, stream, context, path: str | None = None) -> int:
|
|
177
175
|
"""Parse a SLEB128-encoded value from stream.
|
|
@@ -235,7 +233,7 @@ class One(Construct):
|
|
|
235
233
|
"""
|
|
236
234
|
|
|
237
235
|
def __init__(self, *args) -> None:
|
|
238
|
-
super(
|
|
236
|
+
super().__init__()
|
|
239
237
|
|
|
240
238
|
def _parse(self, stream, context, path: str | None = None) -> int:
|
|
241
239
|
"""Parse returns constant 1."""
|
|
@@ -266,7 +264,7 @@ class Block(Construct):
|
|
|
266
264
|
MASK: str | None = None
|
|
267
265
|
|
|
268
266
|
def __init__(self, *args) -> None:
|
|
269
|
-
super(
|
|
267
|
+
super().__init__()
|
|
270
268
|
|
|
271
269
|
def _parse(self, stream, context, path: str | None = None) -> bytes:
|
|
272
270
|
"""Parse block data with fixed-size length prefix.
|
|
@@ -410,7 +408,7 @@ class Address(Construct):
|
|
|
410
408
|
Raises:
|
|
411
409
|
ValueError: If size not in (1, 2, 4, 8).
|
|
412
410
|
"""
|
|
413
|
-
super(
|
|
411
|
+
super().__init__()
|
|
414
412
|
idx = 0 if endianess == Endianess.Little else 1
|
|
415
413
|
if size not in (1, 2, 4, 8):
|
|
416
414
|
raise ValueError(f"Address size '{size}' not supported.")
|
|
@@ -473,7 +471,7 @@ class StrP(Construct):
|
|
|
473
471
|
self.endianess = endianess
|
|
474
472
|
self.ntype = (Int32ul, Int32ub)[0 if endianess == Endianess.Little else 1]
|
|
475
473
|
self.stype = CString(encoding="utf8")
|
|
476
|
-
super(
|
|
474
|
+
super().__init__()
|
|
477
475
|
|
|
478
476
|
def _parse(self, stream, context, path: str | None = None) -> str:
|
|
479
477
|
"""Parse string pointer and resolve to actual string.
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
|
-
# ruff: noqa: E402
|
|
3
2
|
# Imports come after module docstring (standard Python practice)
|
|
4
3
|
|
|
5
4
|
__copyright__ = """
|
|
@@ -370,7 +369,6 @@ class OperationBase:
|
|
|
370
369
|
Default implementation does nothing (no-op).
|
|
371
370
|
Operations that modify the stack must override this.
|
|
372
371
|
"""
|
|
373
|
-
pass
|
|
374
372
|
|
|
375
373
|
def __str__(self):
|
|
376
374
|
"""Return textual representation of operation with parameters.
|
|
@@ -117,7 +117,7 @@ from collections import defaultdict
|
|
|
117
117
|
from dataclasses import dataclass, field
|
|
118
118
|
from functools import lru_cache
|
|
119
119
|
from itertools import groupby
|
|
120
|
-
from typing import Any
|
|
120
|
+
from typing import Any
|
|
121
121
|
|
|
122
122
|
from objutils import Image, Section, symbols
|
|
123
123
|
from objutils.dwarf.constants import (
|
|
@@ -174,7 +174,7 @@ unions, classes), and special types (typedefs, subroutines, enumerations).
|
|
|
174
174
|
"""
|
|
175
175
|
|
|
176
176
|
|
|
177
|
-
def is_type_encoding(encoding:
|
|
177
|
+
def is_type_encoding(encoding: int | AttributeEncoding) -> bool:
|
|
178
178
|
"""Check if a DWARF tag represents a type definition.
|
|
179
179
|
|
|
180
180
|
Args:
|
|
@@ -359,11 +359,11 @@ class Variable:
|
|
|
359
359
|
"""
|
|
360
360
|
|
|
361
361
|
name: str
|
|
362
|
-
section:
|
|
363
|
-
elf_location:
|
|
364
|
-
dwarf_location:
|
|
362
|
+
section: str | None = field(default=None)
|
|
363
|
+
elf_location: int | None = field(default=None)
|
|
364
|
+
dwarf_location: str | None = field(default=None)
|
|
365
365
|
static: bool = field(default=False)
|
|
366
|
-
type_desc:
|
|
366
|
+
type_desc: DIE | None = field(default=None)
|
|
367
367
|
_allocated: bool = field(default=False, repr=False)
|
|
368
368
|
|
|
369
369
|
|
|
@@ -400,7 +400,7 @@ Keys are attribute names (str), values are type converters (enum classes or int)
|
|
|
400
400
|
# 'data_member_location': b'#\x00',
|
|
401
401
|
|
|
402
402
|
|
|
403
|
-
def get_attribute(attrs: dict[str, DIEAttribute], key: str, default:
|
|
403
|
+
def get_attribute(attrs: dict[str, DIEAttribute], key: str, default: int | str) -> int | str:
|
|
404
404
|
"""Get attribute value from attributes_map with fallback default.
|
|
405
405
|
|
|
406
406
|
Args:
|
|
@@ -417,7 +417,7 @@ def get_attribute(attrs: dict[str, DIEAttribute], key: str, default: Union[int,
|
|
|
417
417
|
size = get_attribute(die.attributes_map, "byte_size", 0)
|
|
418
418
|
```
|
|
419
419
|
"""
|
|
420
|
-
attr:
|
|
420
|
+
attr: DIEAttribute | None = attrs.get(key)
|
|
421
421
|
if attr is None:
|
|
422
422
|
return default
|
|
423
423
|
else:
|
|
@@ -760,7 +760,7 @@ class AttributeParser:
|
|
|
760
760
|
return f"<expr-error:{exc}>"
|
|
761
761
|
|
|
762
762
|
@lru_cache(maxsize=64 * 1024)
|
|
763
|
-
def type_tree(self, obj:
|
|
763
|
+
def type_tree(self, obj: int | model.DebugInformationEntry | DIEAttribute) -> dict[str, Any] | CircularReference:
|
|
764
764
|
"""Resolve and return complete type tree for a DIE, offset, or attribute.
|
|
765
765
|
|
|
766
766
|
This method accepts multiple input types for convenience:
|
|
@@ -810,7 +810,7 @@ class AttributeParser:
|
|
|
810
810
|
# Case 2: attribute object (expected to be DW_AT_type)
|
|
811
811
|
if isinstance(obj, DIEAttribute):
|
|
812
812
|
# Try to resolve relative ref forms to absolute offset using the parent DIE if available
|
|
813
|
-
parent:
|
|
813
|
+
parent: model.DebugInformationEntry | None = getattr(obj, "entry", None)
|
|
814
814
|
off = self._resolve_type_offset(obj, parent)
|
|
815
815
|
if off is None:
|
|
816
816
|
return {"tag": "<invalid>", "attrs": {}}
|
|
@@ -879,7 +879,7 @@ class AttributeParser:
|
|
|
879
879
|
_allocated=section_name in self.allocated_sections,
|
|
880
880
|
)
|
|
881
881
|
|
|
882
|
-
def get_value(self, var: Variable) ->
|
|
882
|
+
def get_value(self, var: Variable) -> Any | None:
|
|
883
883
|
"""Extract variable value from ELF section image.
|
|
884
884
|
|
|
885
885
|
This method resolves the variable's address and extracts its value based
|
|
@@ -926,7 +926,7 @@ class AttributeParser:
|
|
|
926
926
|
# No image for variable, i.e. .bss section and the like.
|
|
927
927
|
return None
|
|
928
928
|
# 1) Resolve address
|
|
929
|
-
addr:
|
|
929
|
+
addr: int | None = None
|
|
930
930
|
if isinstance(var.elf_location, int):
|
|
931
931
|
addr = var.elf_location
|
|
932
932
|
elif var.dwarf_location is not None:
|
|
@@ -948,7 +948,7 @@ class AttributeParser:
|
|
|
948
948
|
return None
|
|
949
949
|
|
|
950
950
|
# 2a) Helpers to work with both dict-based and DIE-based nodes
|
|
951
|
-
def _get_tag(node: Any) ->
|
|
951
|
+
def _get_tag(node: Any) -> str | None:
|
|
952
952
|
if node is None:
|
|
953
953
|
return None
|
|
954
954
|
if isinstance(node, dict):
|
|
@@ -1010,7 +1010,7 @@ class AttributeParser:
|
|
|
1010
1010
|
return cur
|
|
1011
1011
|
|
|
1012
1012
|
# 2d) Unwrap qualifiers all the way down to base_type
|
|
1013
|
-
def unwrap_to_base(d:
|
|
1013
|
+
def unwrap_to_base(d: DIE | dict | CircularReference | None) -> DIE | None:
|
|
1014
1014
|
# Accept DIE or dict-like from older structures
|
|
1015
1015
|
seen = 0
|
|
1016
1016
|
current = d
|
|
@@ -1101,7 +1101,7 @@ class AttributeParser:
|
|
|
1101
1101
|
out.append(_reshape(chunk, dims[1:]))
|
|
1102
1102
|
return out
|
|
1103
1103
|
|
|
1104
|
-
def _element_size(elem: Any) ->
|
|
1104
|
+
def _element_size(elem: Any) -> int | None:
|
|
1105
1105
|
t = _get_tag(elem)
|
|
1106
1106
|
attrs = _get_attrs(elem)
|
|
1107
1107
|
if t in {"base_type", "pointer_type"}:
|
|
@@ -1249,8 +1249,8 @@ class AttributeParser:
|
|
|
1249
1249
|
def _resolve_type_offset(
|
|
1250
1250
|
self,
|
|
1251
1251
|
type_attr: DIEAttribute,
|
|
1252
|
-
context_die:
|
|
1253
|
-
) ->
|
|
1252
|
+
context_die: model.DebugInformationEntry | None,
|
|
1253
|
+
) -> int | None:
|
|
1254
1254
|
"""Resolve DW_AT_type attribute value to absolute DIE offset.
|
|
1255
1255
|
|
|
1256
1256
|
Handles CU-relative reference forms (DW_FORM_ref1/2/4/8/udata) by adding
|
|
@@ -19,6 +19,8 @@ The ELF parser module integrates three key components:
|
|
|
19
19
|
- Automatic database creation and schema management
|
|
20
20
|
- Hash-based change detection to invalidate cached databases when files change
|
|
21
21
|
- Session-based API for efficient database queries
|
|
22
|
+
- Optional **in-memory database** mode (``in_memory=True``) – no .prgdb file is
|
|
23
|
+
written to disk; useful for read-only analysis, CI pipelines, and unit tests
|
|
22
24
|
|
|
23
25
|
3. **Property-Based API**
|
|
24
26
|
- Access ELF header fields directly as properties (e.g., `parser.e_machine`)
|
|
@@ -32,7 +34,7 @@ The ELF parser module integrates three key components:
|
|
|
32
34
|
- **SymbolAPI**: Query interface for accessing ELF symbols with flexible filtering
|
|
33
35
|
- **DBAPI**: Base class providing database session management for API wrappers
|
|
34
36
|
|
|
35
|
-
**Database Integration (.prgdb files):**
|
|
37
|
+
**Database Integration (.prgdb files and in-memory databases):**
|
|
36
38
|
|
|
37
39
|
When an ELF file is parsed, the parser automatically creates a .prgdb file
|
|
38
40
|
(SQLite database) next to it. This database contains:
|
|
@@ -49,6 +51,16 @@ The database is invalidated and rebuilt if:
|
|
|
49
51
|
- The database schema changes (column validation)
|
|
50
52
|
- The database file is manually deleted
|
|
51
53
|
|
|
54
|
+
Pass ``in_memory=True`` to :class:`ElfParser` to skip all on-disk caching.
|
|
55
|
+
All parsed data is then stored in a transient SQLite ``:memory:`` database
|
|
56
|
+
that lives only for the lifetime of the :class:`ElfParser` instance::
|
|
57
|
+
|
|
58
|
+
# Standard (persistent .prgdb)
|
|
59
|
+
parser = ElfParser('firmware.elf')
|
|
60
|
+
|
|
61
|
+
# In-memory only – no file written to disk
|
|
62
|
+
parser = ElfParser('firmware.elf', in_memory=True)
|
|
63
|
+
|
|
52
64
|
**Image Creation Workflow:**
|
|
53
65
|
|
|
54
66
|
The `create_image()` method converts ELF sections into an `objutils.Image`:
|
|
@@ -325,7 +337,7 @@ class Pass2(Construct):
|
|
|
325
337
|
Returns:
|
|
326
338
|
None always.
|
|
327
339
|
"""
|
|
328
|
-
return
|
|
340
|
+
return
|
|
329
341
|
|
|
330
342
|
def _build(self, obj: typing.Any, stream: typing.Any, context: typing.Any, path: str) -> None:
|
|
331
343
|
"""Build nothing to stream.
|
|
@@ -336,7 +348,6 @@ class Pass2(Construct):
|
|
|
336
348
|
context: Context object (not used).
|
|
337
349
|
path: Path in parent construct.
|
|
338
350
|
"""
|
|
339
|
-
pass
|
|
340
351
|
|
|
341
352
|
def _sizeof(self, context: typing.Any, path: str) -> int:
|
|
342
353
|
"""Return size as 0.
|
|
@@ -479,7 +490,6 @@ class ElfFileStruct(Struct):
|
|
|
479
490
|
|
|
480
491
|
This method is reserved for future ELF32-specific address handling.
|
|
481
492
|
"""
|
|
482
|
-
pass
|
|
483
493
|
|
|
484
494
|
def setByteOrder(self) -> None:
|
|
485
495
|
"""Placeholder for byte order configuration.
|
|
@@ -840,18 +850,25 @@ class ElfParser:
|
|
|
840
850
|
- Binary parsing of 32-bit and 64-bit ELF formats
|
|
841
851
|
- Both little-endian and big-endian architectures
|
|
842
852
|
- Persistent database caching via SQLite (.prgdb files)
|
|
853
|
+
- Transient in-memory SQLite databases (``in_memory=True``)
|
|
843
854
|
- Property-based access to ELF header fields
|
|
844
855
|
- Section and symbol queries via SectionAPI and SymbolAPI
|
|
845
856
|
- Image reconstruction for embedded systems workflows
|
|
846
857
|
|
|
847
|
-
|
|
848
|
-
ELF file for efficient caching and querying of parsed data.
|
|
849
|
-
invalidated when the ELF file is modified.
|
|
858
|
+
By default the parser automatically creates and manages a SQLite database
|
|
859
|
+
alongside the ELF file for efficient caching and querying of parsed data.
|
|
860
|
+
This database is invalidated when the ELF file is modified.
|
|
861
|
+
|
|
862
|
+
Pass ``in_memory=True`` to skip all on-disk caching. The ELF file is then
|
|
863
|
+
parsed every time and all data is kept in a transient ``:memory:`` SQLite
|
|
864
|
+
database. Useful for read-only analysis, CI pipelines, or unit tests where
|
|
865
|
+
creating files on disk is undesirable.
|
|
850
866
|
|
|
851
867
|
Attributes:
|
|
852
868
|
fp: Memory-mapped view of the ELF file.
|
|
853
869
|
filename: Path to the ELF file.
|
|
854
|
-
db_name: Path to the associated .prgdb database file
|
|
870
|
+
db_name: Path to the associated .prgdb database file, or ``":memory:"``
|
|
871
|
+
when ``in_memory=True`` was specified.
|
|
855
872
|
session: SQLAlchemy database session for queries.
|
|
856
873
|
db: Model database instance.
|
|
857
874
|
symbols: SymbolAPI for symbol queries.
|
|
@@ -863,6 +880,10 @@ class ElfParser:
|
|
|
863
880
|
>>> text = parser.sections.get('.text')
|
|
864
881
|
>>> main = parser.symbols.get('main')
|
|
865
882
|
>>> image = parser.create_image()
|
|
883
|
+
|
|
884
|
+
>>> # No .prgdb file written to disk
|
|
885
|
+
>>> parser = ElfParser('firmware.elf', in_memory=True)
|
|
886
|
+
>>> image = parser.create_image()
|
|
866
887
|
"""
|
|
867
888
|
|
|
868
889
|
EI_NIDENT: int = 16
|
|
@@ -905,15 +926,24 @@ class ElfParser:
|
|
|
905
926
|
),
|
|
906
927
|
)
|
|
907
928
|
|
|
908
|
-
def __init__(self, filename: str) -> None:
|
|
929
|
+
def __init__(self, filename: str, in_memory: bool = False) -> None:
|
|
909
930
|
"""Initialize ElfParser with an ELF file.
|
|
910
931
|
|
|
911
932
|
Creates or opens the associated .prgdb database file and parses the ELF
|
|
912
933
|
structure. The database is invalidated and rebuilt if the file has been
|
|
913
934
|
modified or the schema has changed.
|
|
914
935
|
|
|
936
|
+
When ``in_memory=True`` is passed, no .prgdb file is written to disk.
|
|
937
|
+
Instead a transient SQLite ``:memory:`` database is used. This is useful
|
|
938
|
+
for read-only analysis, testing, or environments where writing to disk is
|
|
939
|
+
undesirable. In-memory databases are always freshly populated – there is
|
|
940
|
+
no caching benefit.
|
|
941
|
+
|
|
915
942
|
Args:
|
|
916
943
|
filename: Path to the ELF file to parse.
|
|
944
|
+
in_memory: If ``True``, use a transient in-memory SQLite database
|
|
945
|
+
instead of persisting a .prgdb file alongside the ELF file.
|
|
946
|
+
Defaults to ``False``.
|
|
917
947
|
|
|
918
948
|
Raises:
|
|
919
949
|
FileNotFoundError: If the specified file doesn't exist.
|
|
@@ -922,16 +952,24 @@ class ElfParser:
|
|
|
922
952
|
Example:
|
|
923
953
|
>>> parser = ElfParser('firmware.elf')
|
|
924
954
|
>>> print(parser.e_machine)
|
|
955
|
+
|
|
956
|
+
>>> # Use in-memory database – no .prgdb file is created
|
|
957
|
+
>>> parser = ElfParser('firmware.elf', in_memory=True)
|
|
958
|
+
>>> print(parser.e_machine)
|
|
925
959
|
"""
|
|
926
960
|
self.fp = create_memorymapped_fileview(filename)
|
|
927
961
|
self.filename = Path(filename)
|
|
928
|
-
self.
|
|
962
|
+
self._in_memory: bool = in_memory
|
|
963
|
+
self.db_name: Path | str = ":memory:" if in_memory else self.filename.with_suffix(model.DB_EXTENSION)
|
|
929
964
|
|
|
930
965
|
self._images: dict[int, bytes | None] = {}
|
|
931
966
|
self._sections_by_name: OrderedDict[str, typing.Any] = OrderedDict()
|
|
932
967
|
self.asciiCString: CString = CString(encoding="ascii")
|
|
933
968
|
|
|
934
|
-
|
|
969
|
+
if in_memory:
|
|
970
|
+
self._create_in_memory_db()
|
|
971
|
+
else:
|
|
972
|
+
self.create_db_on_demand()
|
|
935
973
|
|
|
936
974
|
self.symbols: SymbolAPI = SymbolAPI(self)
|
|
937
975
|
self.sections: SectionAPI = SectionAPI(self)
|
|
@@ -969,6 +1007,25 @@ class ElfParser:
|
|
|
969
1007
|
for key, value in datatypes:
|
|
970
1008
|
setattr(self, key, value[offset])
|
|
971
1009
|
|
|
1010
|
+
def _create_in_memory_db(self) -> None:
|
|
1011
|
+
"""Create a transient in-memory SQLite database and populate it from the ELF file.
|
|
1012
|
+
|
|
1013
|
+
Unlike :meth:`create_db_on_demand`, this method never reads from or writes to
|
|
1014
|
+
disk. It always performs a full parse of the ELF file and stores the result in
|
|
1015
|
+
a SQLite ``:memory:`` database for the lifetime of this :class:`ElfParser`
|
|
1016
|
+
instance.
|
|
1017
|
+
|
|
1018
|
+
Side Effects:
|
|
1019
|
+
- Creates self.db (in-memory :class:`model.Model`) and self.session
|
|
1020
|
+
- Parses and stores all ELF data via :meth:`load_data`
|
|
1021
|
+
"""
|
|
1022
|
+
hash_value = calculate_crypto_hash(self.fp.tobytes())
|
|
1023
|
+
self.db = model.Model(":memory:")
|
|
1024
|
+
self.session = self.db.session
|
|
1025
|
+
meta = model.Meta(hash_value=hash_value)
|
|
1026
|
+
self.session.add(meta)
|
|
1027
|
+
self.load_data()
|
|
1028
|
+
|
|
972
1029
|
def create_db_on_demand(self) -> None:
|
|
973
1030
|
"""Create or open the ELF database, validating and rebuilding as needed.
|
|
974
1031
|
|