objutils 0.10.14__tar.gz → 0.10.15__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 → objutils-0.10.15}/CMakeLists.txt +5 -1
- {objutils-0.10.14 → objutils-0.10.15}/PKG-INFO +1 -1
- {objutils-0.10.14 → objutils-0.10.15}/objutils/__init__.py +1 -1
- {objutils-0.10.14 → objutils-0.10.15}/objutils/elf/__init__.py +120 -60
- objutils-0.10.15/objutils/extensions/elf_parser.cpp +257 -0
- objutils-0.10.15/objutils/extensions/elf_parser.hpp +43 -0
- objutils-0.10.15/objutils/extensions/wrapper.cpp +58 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/version.py +1 -1
- {objutils-0.10.14 → objutils-0.10.15}/pyproject.toml +2 -2
- objutils-0.10.14/objutils/extensions/wrapper.cpp +0 -18
- {objutils-0.10.14 → objutils-0.10.15}/.clang-format +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.codacy.yml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.codeclimate.yml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.coveralls.yml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.github/FUNDING.yml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.github/ISSUE_TEMPLATE/documentation.yml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.github/ISSUE_TEMPLATE.md +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.github/copilot-instructions.md +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.github/workflows/pythonapp.yml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.gitignore +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.idea/.gitignore +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.idea/copilot.data.migration.ask2agent.xml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.idea/deployment.xml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.idea/inspectionProfiles/profiles_settings.xml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.idea/misc.xml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.idea/modules.xml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.idea/pyLspTools.xml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.idea/pyProjectModel.xml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.idea/vcs.xml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.pre-commit-config.yaml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.pylintrc +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.readthedocs.yml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/.travis.yml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/CODE_OF_CONDUCT.md +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/CONTRIBUTORS +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/LICENSE +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/MANIFEST.in +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/PULL_REQUEST_TEMPLATE.md +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/appveyor.yml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/bandit.yml +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/Data_Formats.pdf +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/ELF_Format.pdf +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/KNOWN_GOOD_DWARF_REFERENCE.md +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/README.rst +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/apidoc.sh +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/conf.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/.buildinfo +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/.buildinfo.bak +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/.doctrees/README.doctree +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/.doctrees/environment.pickle +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/.doctrees/howto.doctree +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/.doctrees/index.doctree +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/.doctrees/installation.doctree +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/.doctrees/modules.doctree +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/.doctrees/objutils.doctree +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/.doctrees/objutils.elf.doctree +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/.doctrees/scripts.doctree +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/.doctrees/session.doctree +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/.doctrees/tutorial.doctree +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/README.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_images/objutils_basic.png +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/index.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/ash.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/binfile.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/checksums.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/cosmac.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/elf/defs.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/elf.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/emon52.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/etek.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/exceptions.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/fpc.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/hexdump.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/hexfile.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/ihex.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/image.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/logger.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/mostec.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/pickleif.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/rca.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/readers.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/registry.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/section.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/sig.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/srec.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/tek.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/titxt.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils/utils.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_modules/objutils.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_sources/README.rst.txt +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_sources/howto.rst.txt +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_sources/index.rst.txt +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_sources/installation.rst.txt +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_sources/modules.rst.txt +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_sources/objutils.elf.rst.txt +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_sources/objutils.rst.txt +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_sources/scripts.rst.txt +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_sources/session.rst.txt +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_sources/tutorial.rst.txt +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/alabaster.css +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/basic.css +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/check-solid.svg +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/clipboard.min.js +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/copy-button.svg +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/copybutton.css +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/copybutton.js +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/copybutton_funcs.js +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/custom.css +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/doctools.js +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/documentation_options.js +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/file.png +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/github-banner.svg +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/language_data.js +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/minus.png +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/plus.png +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/pygments.css +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/scripts/bootstrap.js +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/scripts/bootstrap.js.LICENSE.txt +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/scripts/fontawesome.js +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/scripts/fontawesome.js.LICENSE.txt +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/scripts/pydata-sphinx-theme.js +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/searchtools.js +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/sphinx_highlight.js +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/styles/pydata-sphinx-theme.css +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/styles/theme.css +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-brands-400.ttf +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-brands-400.woff2 +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-regular-400.ttf +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-regular-400.woff2 +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-solid-900.ttf +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-solid-900.woff2 +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/_static/webpack-macros.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/genindex.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/howto.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/index.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/installation.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/modules.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/objects.inv +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/objutils.elf.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/objutils.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/py-modindex.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/scripts.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/search.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/searchindex.js +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/session.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/docs/_build/html/tutorial.html +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/elf-64-gen.pdf +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/example0.srec +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/howto.rst +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/index.rst +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/installation.rst +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/make.bat +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/modules.rst +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/objutils.elf.rst +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/objutils.rst +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/objutils_banner.png +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/objutils_basic.png +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/objutils_dark.jpg +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/objutils_social.jpg +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/requirements.txt +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/scripts.rst +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/session.rst +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/tutorial.rst +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/docs/tutorial1.ipynb +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/.coveragerc +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/.vscode/launch.json +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/.vscode/settings.json +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/a2l_test.shf +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/ash.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/binfile.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/checksums.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/cosmac.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/dwarf/__init__.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/dwarf/attrparser.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/dwarf/c_generator.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/dwarf/constants.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/dwarf/encoding.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/dwarf/lineprog.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/dwarf/readers.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/dwarf/sm.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/dwarf/traverser.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/elf/arm/__init__.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/elf/arm/attributes.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/elf/defs.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/elf/model.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/emon52.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/etek.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/exceptions.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/extensions/__init__.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/extensions/ctre.hpp +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/extensions/difflib.h +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/extensions/exceptions.cpp +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/extensions/exceptions.hpp +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/extensions/hexfile.cpp +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/fpc.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/hexdump.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/hexfile.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/ieee695.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/ihex.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/image.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/logger.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/mostec.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/objutils.code-workspace +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/oocdtxt.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/pecoff/__init__.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/pecoff/defs.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/pecoff/model.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/pecoff/pdb/__init__.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/pickleif.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/rca.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/readers.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/registry.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/scripts/arduino_build_artifacts.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/scripts/oj_cgen.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/scripts/oj_coff_extract.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/scripts/oj_coff_import.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/scripts/oj_coff_info.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/scripts/oj_coff_syms.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/scripts/oj_dwarf_import.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/scripts/oj_dwarf_info.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/scripts/oj_elf_arm_attrs.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/scripts/oj_elf_extract.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/scripts/oj_elf_import.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/scripts/oj_elf_info.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/scripts/oj_elf_syms.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/scripts/oj_hex_info.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/scripts/oj_hex_merge.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/scripts/oj_hex_split.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/section.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/shf.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/sig.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/srec.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/symbols.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tek.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/__init__.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_arm_attributes.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_ash.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_c_generator.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_checksums.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_cygpath.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_diff_bin.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_elf.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_emon52.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_etek.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_examples_cgen.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_fpc.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_hexdump.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_hexfile.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_ihex.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_image.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_mostec.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_oocdtxt.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_readers.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_registry.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_repr.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_section.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_section_join.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_shf.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_sm.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_srec.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_tek.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/tests/test_titext.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/titxt.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/utils/__init__.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/utils/arduino.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/objutils/utils/diff.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/poetry.lock +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/requirements.txt +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/setup.cfg +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/setup.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/test_join_sections.py +0 -0
- {objutils-0.10.14 → objutils-0.10.15}/test_requirements.txt +0 -0
|
@@ -82,7 +82,11 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
|
82
82
|
|
|
83
83
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/objutils/extensions ${PROJECT_SOURCE_DIR}/objutils/aml)
|
|
84
84
|
|
|
85
|
-
pybind11_add_module(hexfiles_ext
|
|
85
|
+
pybind11_add_module(hexfiles_ext
|
|
86
|
+
${CMAKE_CURRENT_SOURCE_DIR}/objutils/extensions/wrapper.cpp
|
|
87
|
+
${CMAKE_CURRENT_SOURCE_DIR}/objutils/extensions/exceptions.cpp
|
|
88
|
+
${CMAKE_CURRENT_SOURCE_DIR}/objutils/extensions/elf_parser.cpp
|
|
89
|
+
)
|
|
86
90
|
|
|
87
91
|
target_compile_options(hexfiles_ext PUBLIC "-DEXTENSION_NAME=hexfiles_ext" PUBLIC $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:MSVC>>:/utf-8>)
|
|
88
92
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: objutils
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.15
|
|
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>
|
|
@@ -1428,7 +1428,7 @@ class ElfParser:
|
|
|
1428
1428
|
)
|
|
1429
1429
|
self.session.add(header)
|
|
1430
1430
|
|
|
1431
|
-
def _parse_symbol_section(self, section:
|
|
1431
|
+
def _parse_symbol_section(self, section: typing.Any) -> None:
|
|
1432
1432
|
"""Parse symbol table section and populate database with symbol entries.
|
|
1433
1433
|
|
|
1434
1434
|
Parses all symbol entries from a symbol table section (SHT_SYMTAB or SHT_DYNSYM)
|
|
@@ -1436,43 +1436,119 @@ class ElfParser:
|
|
|
1436
1436
|
section, or other named entity with associated metadata like address, size,
|
|
1437
1437
|
binding, type, and visibility.
|
|
1438
1438
|
|
|
1439
|
-
Symbol table structure for 32-bit ELF:
|
|
1440
|
-
- st_name:
|
|
1441
|
-
- st_value: Symbol value
|
|
1442
|
-
- st_size:
|
|
1443
|
-
- st_info:
|
|
1444
|
-
- st_other: Symbol visibility
|
|
1445
|
-
- st_shndx: Section index symbol is defined in (
|
|
1439
|
+
Symbol table structure for 32-bit ELF (Elf32_Sym, 16 bytes):
|
|
1440
|
+
- st_name: Offset into string table for symbol name (uint32)
|
|
1441
|
+
- st_value: Symbol value / address (uint32)
|
|
1442
|
+
- st_size: Size of symbol in bytes (uint32)
|
|
1443
|
+
- st_info: Binding (upper 4 bits) and type (lower 4 bits) (uint8)
|
|
1444
|
+
- st_other: Symbol visibility (uint8)
|
|
1445
|
+
- st_shndx: Section index symbol is defined in (uint16)
|
|
1446
1446
|
|
|
1447
|
-
Symbol table structure for 64-bit ELF:
|
|
1447
|
+
Symbol table structure for 64-bit ELF (Elf64_Sym, 24 bytes):
|
|
1448
1448
|
- Field order differs: st_name, st_info, st_other, st_shndx, st_value, st_size
|
|
1449
1449
|
|
|
1450
|
+
The method first tries to use the C++ extension ``hexfiles_ext.parse_symbol_table``
|
|
1451
|
+
for maximum performance. If the extension is not available (e.g. not yet built),
|
|
1452
|
+
it falls back to the ``construct``-based pure-Python parser.
|
|
1453
|
+
|
|
1454
|
+
In both cases, section-name resolution (shndx → section_name, sh_flags) is done
|
|
1455
|
+
in Python with a local cache to avoid repeated SQLAlchemy queries for the same
|
|
1456
|
+
section index.
|
|
1457
|
+
|
|
1450
1458
|
Args:
|
|
1451
|
-
section:
|
|
1452
|
-
Must have sh_link
|
|
1459
|
+
section: Parsed construct Container for the symbol-table section.
|
|
1460
|
+
Must have ``sh_link`` (string-table section index) and ``image`` (raw bytes).
|
|
1453
1461
|
|
|
1454
1462
|
Side Effects:
|
|
1455
1463
|
- Bulk inserts model.Elf_Symbol entries into database
|
|
1456
1464
|
- Commits transaction on success, rolls back on error
|
|
1457
|
-
- Prints error messages if symbol parsing or database operations fail
|
|
1458
|
-
|
|
1459
|
-
Note:
|
|
1460
|
-
- Symbol names are resolved via section.sh_link string table index
|
|
1461
|
-
- st_shndx may be special value (SHN_ABS, SHN_COMMON, SHN_UNDEF) or section index
|
|
1462
|
-
- Symbol section_name field resolved from st_shndx section reference
|
|
1463
|
-
- Parse errors for individual symbols are caught and logged but don't stop processing
|
|
1464
|
-
- Uses bulk_save_objects for efficient database insertion
|
|
1465
|
-
|
|
1466
|
-
Example:
|
|
1467
|
-
Symbol types (st_info.st_type):
|
|
1468
|
-
- STT_NOTYPE (0): Type not specified
|
|
1469
|
-
- STT_OBJECT (1): Data object (variable)
|
|
1470
|
-
- STT_FUNC (2): Function or executable code
|
|
1471
|
-
- STT_SECTION (3): Section symbol
|
|
1472
|
-
- STT_FILE (4): Source file name
|
|
1473
1465
|
"""
|
|
1474
1466
|
sh_link = section.sh_link
|
|
1467
|
+
symtab_bytes: bytes = section.image or b""
|
|
1468
|
+
strtab_bytes: bytes = self._images.get(sh_link) or b""
|
|
1469
|
+
|
|
1470
|
+
# ── Fast path: C++ extension ──────────────────────────────────────
|
|
1471
|
+
raw_symbols: list[dict] | None = None
|
|
1472
|
+
try:
|
|
1473
|
+
from objutils.hexfiles_ext import parse_symbol_table as _cpp_parse # type: ignore[import]
|
|
1474
|
+
|
|
1475
|
+
raw_symbols = _cpp_parse(
|
|
1476
|
+
symtab_bytes,
|
|
1477
|
+
strtab_bytes,
|
|
1478
|
+
self.b64,
|
|
1479
|
+
self._endianess == "<",
|
|
1480
|
+
)
|
|
1481
|
+
except Exception:
|
|
1482
|
+
pass # fall through to pure-Python path
|
|
1483
|
+
|
|
1484
|
+
if raw_symbols is None:
|
|
1485
|
+
# ── Fallback: construct-based parser ─────────────────────────
|
|
1486
|
+
raw_symbols = self._parse_symbol_section_py(symtab_bytes, strtab_bytes, sh_link)
|
|
1487
|
+
|
|
1488
|
+
# ── Section-name resolution (Python, with cache) ──────────────────
|
|
1489
|
+
# Cache: shndx -> (section_name: str, sh_flags: int)
|
|
1490
|
+
section_cache: dict[int, tuple[str, int]] = {}
|
|
1475
1491
|
symbols = []
|
|
1492
|
+
|
|
1493
|
+
for sym in raw_symbols:
|
|
1494
|
+
shndx: int = sym["st_shndx"]
|
|
1495
|
+
if shndx in defs.SpecialSections:
|
|
1496
|
+
section_name = defs.special_section_name(shndx)
|
|
1497
|
+
access = 0
|
|
1498
|
+
elif shndx in section_cache:
|
|
1499
|
+
section_name, access = section_cache[shndx]
|
|
1500
|
+
else:
|
|
1501
|
+
section_header = self.session.query(model.Elf_Section).filter(model.Elf_Section.index == shndx).first()
|
|
1502
|
+
if section_header:
|
|
1503
|
+
section_name = section_header.section_name
|
|
1504
|
+
access = section_header.sh_flags
|
|
1505
|
+
else:
|
|
1506
|
+
section_name = str(shndx)
|
|
1507
|
+
access = 0
|
|
1508
|
+
section_cache[shndx] = (section_name, access)
|
|
1509
|
+
|
|
1510
|
+
db_sym = model.Elf_Symbol(
|
|
1511
|
+
st_name=sym["st_name"],
|
|
1512
|
+
st_value=sym["st_value"],
|
|
1513
|
+
st_size=sym["st_size"],
|
|
1514
|
+
st_bind=sym["st_bind"],
|
|
1515
|
+
st_type=sym["st_type"],
|
|
1516
|
+
st_other=sym["st_other"],
|
|
1517
|
+
st_shndx=shndx,
|
|
1518
|
+
symbol_name=sym["symbol_name"],
|
|
1519
|
+
section_name=section_name,
|
|
1520
|
+
access=access,
|
|
1521
|
+
)
|
|
1522
|
+
symbols.append(db_sym)
|
|
1523
|
+
|
|
1524
|
+
try:
|
|
1525
|
+
self.session.bulk_save_objects(symbols)
|
|
1526
|
+
self.session.commit()
|
|
1527
|
+
except SQLAlchemyError as e:
|
|
1528
|
+
self.session.rollback()
|
|
1529
|
+
print(f"{e}")
|
|
1530
|
+
|
|
1531
|
+
def _parse_symbol_section_py(
|
|
1532
|
+
self,
|
|
1533
|
+
symtab_bytes: bytes,
|
|
1534
|
+
strtab_bytes: bytes,
|
|
1535
|
+
sh_link: int,
|
|
1536
|
+
) -> list[dict]:
|
|
1537
|
+
"""Pure-Python fallback for symbol-table parsing (used when the C++ extension
|
|
1538
|
+
is unavailable).
|
|
1539
|
+
|
|
1540
|
+
Uses the ``construct`` library to parse Elf32_Sym / Elf64_Sym entries and
|
|
1541
|
+
resolves symbol names via :meth:`get_string`.
|
|
1542
|
+
|
|
1543
|
+
Args:
|
|
1544
|
+
symtab_bytes: Raw bytes of the symbol-table section.
|
|
1545
|
+
strtab_bytes: Raw bytes of the string-table section (unused here;
|
|
1546
|
+
name resolution goes through :meth:`get_string` instead).
|
|
1547
|
+
sh_link: Index of the string-table section in ``self._images``.
|
|
1548
|
+
|
|
1549
|
+
Returns:
|
|
1550
|
+
List of dicts with keys matching the C++ extension output.
|
|
1551
|
+
"""
|
|
1476
1552
|
if self.b64:
|
|
1477
1553
|
Symbol = Struct(
|
|
1478
1554
|
"st_name" / self.Word,
|
|
@@ -1501,43 +1577,27 @@ class ElfParser:
|
|
|
1501
1577
|
"symbol_name" / Computed(lambda ctx: self.get_string(sh_link, ctx.st_name)),
|
|
1502
1578
|
"st_shndx" / self.Half,
|
|
1503
1579
|
)
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
for offset in range(0, len(
|
|
1580
|
+
entry_size = Symbol.sizeof()
|
|
1581
|
+
result: list[dict] = []
|
|
1582
|
+
for offset in range(0, len(symtab_bytes), entry_size):
|
|
1507
1583
|
try:
|
|
1508
|
-
sym = Symbol.parse(
|
|
1584
|
+
sym = Symbol.parse(symtab_bytes[offset : offset + entry_size])
|
|
1509
1585
|
except StreamError as e:
|
|
1510
|
-
print(f"parse symbol section: {e}")
|
|
1586
|
+
print(f"parse symbol section (fallback): {e}")
|
|
1511
1587
|
continue
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
st_name=sym.st_name,
|
|
1524
|
-
st_value=sym.st_value,
|
|
1525
|
-
st_size=sym.st_size,
|
|
1526
|
-
st_bind=sym.st_info.st_bind,
|
|
1527
|
-
st_type=sym.st_info.st_type,
|
|
1528
|
-
st_other=sym.st_other,
|
|
1529
|
-
st_shndx=sym.st_shndx,
|
|
1530
|
-
symbol_name=sym.symbol_name,
|
|
1531
|
-
section_name=section_name,
|
|
1532
|
-
access=section_header.sh_flags if section_header else 0,
|
|
1588
|
+
result.append(
|
|
1589
|
+
{
|
|
1590
|
+
"st_name": sym.st_name,
|
|
1591
|
+
"st_value": sym.st_value,
|
|
1592
|
+
"st_size": sym.st_size,
|
|
1593
|
+
"st_bind": sym.st_info.st_bind,
|
|
1594
|
+
"st_type": sym.st_info.st_type,
|
|
1595
|
+
"st_other": sym.st_other,
|
|
1596
|
+
"st_shndx": sym.st_shndx,
|
|
1597
|
+
"symbol_name": sym.symbol_name,
|
|
1598
|
+
}
|
|
1533
1599
|
)
|
|
1534
|
-
|
|
1535
|
-
try:
|
|
1536
|
-
self.session.bulk_save_objects(symbols)
|
|
1537
|
-
self.session.commit()
|
|
1538
|
-
except SQLAlchemyError as e:
|
|
1539
|
-
self.session.rollback()
|
|
1540
|
-
print(f"{e}")
|
|
1600
|
+
return result
|
|
1541
1601
|
|
|
1542
1602
|
def _parse_comment(self, data: bytes) -> str:
|
|
1543
1603
|
"""Parse .comment section containing compiler/linker identification strings.
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file elf_parser.cpp
|
|
3
|
+
* @brief Fast C++ ELF symbol-table parser.
|
|
4
|
+
*
|
|
5
|
+
* Design notes
|
|
6
|
+
* ------------
|
|
7
|
+
* The Python/construct-based implementation in ElfParser._parse_symbol_section
|
|
8
|
+
* is slow because it:
|
|
9
|
+
* 1. Invokes the construct DSL parser once per symbol entry.
|
|
10
|
+
* 2. Calls CString.parse() (another construct round-trip) for every name.
|
|
11
|
+
* 3. Had a caching bug so the SQLAlchemy section lookup was never cached.
|
|
12
|
+
*
|
|
13
|
+
* This C++ implementation avoids all of that:
|
|
14
|
+
* - Direct pointer arithmetic over the raw symbol-table bytes.
|
|
15
|
+
* - strnlen / pointer scan for null-terminated strings.
|
|
16
|
+
* - Single allocation: one std::vector<SymbolEntry> for the whole table.
|
|
17
|
+
* - Byte swapping only when target endianness != host endianness.
|
|
18
|
+
*
|
|
19
|
+
* ELF symbol layout (System V ABI)
|
|
20
|
+
* ---------------------------------
|
|
21
|
+
* Elf32_Sym (16 bytes, offsets):
|
|
22
|
+
* 0 st_name uint32
|
|
23
|
+
* 4 st_value uint32
|
|
24
|
+
* 8 st_size uint32
|
|
25
|
+
* 12 st_info uint8 (bind << 4 | type)
|
|
26
|
+
* 13 st_other uint8
|
|
27
|
+
* 14 st_shndx uint16
|
|
28
|
+
*
|
|
29
|
+
* Elf64_Sym (24 bytes, offsets):
|
|
30
|
+
* 0 st_name uint32
|
|
31
|
+
* 4 st_info uint8
|
|
32
|
+
* 5 st_other uint8
|
|
33
|
+
* 6 st_shndx uint16
|
|
34
|
+
* 8 st_value uint64
|
|
35
|
+
* 16 st_size uint64
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
#include "elf_parser.hpp"
|
|
39
|
+
|
|
40
|
+
#include <bit> // std::endian (C++20)
|
|
41
|
+
#include <cstdint>
|
|
42
|
+
#include <cstring> // std::memcpy, strnlen
|
|
43
|
+
#include <string>
|
|
44
|
+
#include <vector>
|
|
45
|
+
|
|
46
|
+
// ── Platform byte-swap helpers ────────────────────────────────────────────────
|
|
47
|
+
|
|
48
|
+
namespace {
|
|
49
|
+
|
|
50
|
+
inline uint16_t bswap16(uint16_t v) noexcept {
|
|
51
|
+
#if defined(_MSC_VER)
|
|
52
|
+
return _byteswap_ushort(v);
|
|
53
|
+
#else
|
|
54
|
+
return __builtin_bswap16(v);
|
|
55
|
+
#endif
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
inline uint32_t bswap32(uint32_t v) noexcept {
|
|
59
|
+
#if defined(_MSC_VER)
|
|
60
|
+
return _byteswap_ulong(v);
|
|
61
|
+
#else
|
|
62
|
+
return __builtin_bswap32(v);
|
|
63
|
+
#endif
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
inline uint64_t bswap64(uint64_t v) noexcept {
|
|
67
|
+
#if defined(_MSC_VER)
|
|
68
|
+
return _byteswap_uint64(v);
|
|
69
|
+
#else
|
|
70
|
+
return __builtin_bswap64(v);
|
|
71
|
+
#endif
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Is the current host little-endian? Evaluated at compile time on C++20.
|
|
75
|
+
constexpr bool HOST_LE = (std::endian::native == std::endian::little);
|
|
76
|
+
|
|
77
|
+
// Read an integer of type T from raw bytes and convert from file endianness
|
|
78
|
+
// to host endianness. Single-byte types are returned unchanged.
|
|
79
|
+
template <typename T>
|
|
80
|
+
[[nodiscard]] T read_val(const uint8_t* p, bool file_le) noexcept {
|
|
81
|
+
T v{};
|
|
82
|
+
std::memcpy(&v, p, sizeof(T));
|
|
83
|
+
if constexpr (sizeof(T) == 1) {
|
|
84
|
+
return v;
|
|
85
|
+
}
|
|
86
|
+
if (file_le != HOST_LE) { // need a swap
|
|
87
|
+
if constexpr (sizeof(T) == 2) v = static_cast<T>(bswap16(static_cast<uint16_t>(v)));
|
|
88
|
+
else if constexpr (sizeof(T) == 4) v = static_cast<T>(bswap32(static_cast<uint32_t>(v)));
|
|
89
|
+
else if constexpr (sizeof(T) == 8) v = static_cast<T>(bswap64(static_cast<uint64_t>(v)));
|
|
90
|
+
}
|
|
91
|
+
return v;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ── String-table helper ───────────────────────────────────────────────────────
|
|
95
|
+
|
|
96
|
+
// Retrieve a null-terminated ASCII string from an ELF string table.
|
|
97
|
+
// Returns an empty string when the offset is out of range.
|
|
98
|
+
[[nodiscard]] std::string strtab_get(
|
|
99
|
+
const uint8_t* strtab,
|
|
100
|
+
std::size_t strtab_size,
|
|
101
|
+
uint32_t offset) noexcept
|
|
102
|
+
{
|
|
103
|
+
if (static_cast<std::size_t>(offset) >= strtab_size) {
|
|
104
|
+
return {};
|
|
105
|
+
}
|
|
106
|
+
const char* s = reinterpret_cast<const char*>(strtab + offset);
|
|
107
|
+
std::size_t max = strtab_size - static_cast<std::size_t>(offset);
|
|
108
|
+
std::size_t len = strnlen(s, max);
|
|
109
|
+
return {s, len};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ── Per-symbol intermediate representation ───────────────────────────────────
|
|
113
|
+
|
|
114
|
+
struct SymEntry {
|
|
115
|
+
uint64_t st_value;
|
|
116
|
+
uint64_t st_size;
|
|
117
|
+
uint32_t st_name;
|
|
118
|
+
uint16_t st_shndx;
|
|
119
|
+
uint8_t st_bind; // st_info >> 4
|
|
120
|
+
uint8_t st_type; // st_info & 0x0F
|
|
121
|
+
uint8_t st_other;
|
|
122
|
+
std::string symbol_name;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
// ── ELF32 parser ─────────────────────────────────────────────────────────────
|
|
126
|
+
|
|
127
|
+
// Elf32_Sym layout (16 bytes):
|
|
128
|
+
// [0] st_name : u32
|
|
129
|
+
// [4] st_value : u32
|
|
130
|
+
// [8] st_size : u32
|
|
131
|
+
// [12] st_info : u8
|
|
132
|
+
// [13] st_other : u8
|
|
133
|
+
// [14] st_shndx : u16
|
|
134
|
+
|
|
135
|
+
static constexpr std::size_t SYM32_SIZE = 16;
|
|
136
|
+
|
|
137
|
+
std::vector<SymEntry> parse_sym32(
|
|
138
|
+
const uint8_t* sym_ptr, std::size_t sym_size,
|
|
139
|
+
const uint8_t* str_ptr, std::size_t str_size,
|
|
140
|
+
bool le)
|
|
141
|
+
{
|
|
142
|
+
const std::size_t count = sym_size / SYM32_SIZE;
|
|
143
|
+
std::vector<SymEntry> result;
|
|
144
|
+
result.reserve(count);
|
|
145
|
+
|
|
146
|
+
for (std::size_t i = 0; i < count; ++i) {
|
|
147
|
+
const uint8_t* p = sym_ptr + i * SYM32_SIZE;
|
|
148
|
+
|
|
149
|
+
SymEntry e{};
|
|
150
|
+
e.st_name = read_val<uint32_t>(p + 0, le);
|
|
151
|
+
e.st_value = read_val<uint32_t>(p + 4, le);
|
|
152
|
+
e.st_size = read_val<uint32_t>(p + 8, le);
|
|
153
|
+
const uint8_t info = p[12];
|
|
154
|
+
e.st_bind = static_cast<uint8_t>(info >> 4u);
|
|
155
|
+
e.st_type = static_cast<uint8_t>(info & 0x0Fu);
|
|
156
|
+
e.st_other = p[13];
|
|
157
|
+
e.st_shndx = read_val<uint16_t>(p + 14, le);
|
|
158
|
+
e.symbol_name = strtab_get(str_ptr, str_size, e.st_name);
|
|
159
|
+
result.push_back(std::move(e));
|
|
160
|
+
}
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// ── ELF64 parser ─────────────────────────────────────────────────────────────
|
|
165
|
+
|
|
166
|
+
// Elf64_Sym layout (24 bytes):
|
|
167
|
+
// [0] st_name : u32
|
|
168
|
+
// [4] st_info : u8
|
|
169
|
+
// [5] st_other : u8
|
|
170
|
+
// [6] st_shndx : u16
|
|
171
|
+
// [8] st_value : u64
|
|
172
|
+
// [16] st_size : u64
|
|
173
|
+
|
|
174
|
+
static constexpr std::size_t SYM64_SIZE = 24;
|
|
175
|
+
|
|
176
|
+
std::vector<SymEntry> parse_sym64(
|
|
177
|
+
const uint8_t* sym_ptr, std::size_t sym_size,
|
|
178
|
+
const uint8_t* str_ptr, std::size_t str_size,
|
|
179
|
+
bool le)
|
|
180
|
+
{
|
|
181
|
+
const std::size_t count = sym_size / SYM64_SIZE;
|
|
182
|
+
std::vector<SymEntry> result;
|
|
183
|
+
result.reserve(count);
|
|
184
|
+
|
|
185
|
+
for (std::size_t i = 0; i < count; ++i) {
|
|
186
|
+
const uint8_t* p = sym_ptr + i * SYM64_SIZE;
|
|
187
|
+
|
|
188
|
+
SymEntry e{};
|
|
189
|
+
e.st_name = read_val<uint32_t>(p + 0, le);
|
|
190
|
+
const uint8_t info = p[4];
|
|
191
|
+
e.st_bind = static_cast<uint8_t>(info >> 4u);
|
|
192
|
+
e.st_type = static_cast<uint8_t>(info & 0x0Fu);
|
|
193
|
+
e.st_other = p[5];
|
|
194
|
+
e.st_shndx = read_val<uint16_t>(p + 6, le);
|
|
195
|
+
e.st_value = read_val<uint64_t>(p + 8, le);
|
|
196
|
+
e.st_size = read_val<uint64_t>(p + 16, le);
|
|
197
|
+
e.symbol_name = strtab_get(str_ptr, str_size, e.st_name);
|
|
198
|
+
result.push_back(std::move(e));
|
|
199
|
+
}
|
|
200
|
+
return result;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
} // anonymous namespace
|
|
204
|
+
|
|
205
|
+
// ── Public API (pybind11) ─────────────────────────────────────────────────────
|
|
206
|
+
|
|
207
|
+
py::list parse_symbol_table(
|
|
208
|
+
py::bytes symtab_data,
|
|
209
|
+
py::bytes strtab_data,
|
|
210
|
+
bool is_64bit,
|
|
211
|
+
bool little_endian)
|
|
212
|
+
{
|
|
213
|
+
// Obtain raw pointers without copying – PyBytes_AsStringAndSize is O(1).
|
|
214
|
+
const char* sym_raw = nullptr;
|
|
215
|
+
Py_ssize_t sym_raw_size = 0;
|
|
216
|
+
if (PyBytes_AsStringAndSize(symtab_data.ptr(),
|
|
217
|
+
const_cast<char**>(&sym_raw), &sym_raw_size) < 0) {
|
|
218
|
+
throw py::error_already_set();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const char* str_raw = nullptr;
|
|
222
|
+
Py_ssize_t str_raw_size = 0;
|
|
223
|
+
if (PyBytes_AsStringAndSize(strtab_data.ptr(),
|
|
224
|
+
const_cast<char**>(&str_raw), &str_raw_size) < 0) {
|
|
225
|
+
throw py::error_already_set();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const auto* sym_ptr = reinterpret_cast<const uint8_t*>(sym_raw);
|
|
229
|
+
const auto* str_ptr = reinterpret_cast<const uint8_t*>(str_raw);
|
|
230
|
+
const std::size_t sym_size = static_cast<std::size_t>(sym_raw_size);
|
|
231
|
+
const std::size_t str_size = static_cast<std::size_t>(str_raw_size);
|
|
232
|
+
|
|
233
|
+
// Parse all symbol entries in C++.
|
|
234
|
+
std::vector<SymEntry> entries = is_64bit
|
|
235
|
+
? parse_sym64(sym_ptr, sym_size, str_ptr, str_size, little_endian)
|
|
236
|
+
: parse_sym32(sym_ptr, sym_size, str_ptr, str_size, little_endian);
|
|
237
|
+
|
|
238
|
+
// Build Python list of dicts. The bulk of the per-symbol overhead is now
|
|
239
|
+
// in Python-object construction, which is unavoidable, but still much
|
|
240
|
+
// cheaper than running the construct DSL for each entry.
|
|
241
|
+
py::list result;
|
|
242
|
+
result.attr("__class__"); // force Python to realise the list (no-op, for clarity)
|
|
243
|
+
|
|
244
|
+
for (const SymEntry& e : entries) {
|
|
245
|
+
py::dict d;
|
|
246
|
+
d["st_name"] = static_cast<uint32_t>(e.st_name);
|
|
247
|
+
d["st_value"] = static_cast<uint64_t>(e.st_value);
|
|
248
|
+
d["st_size"] = static_cast<uint64_t>(e.st_size);
|
|
249
|
+
d["st_bind"] = static_cast<uint8_t>(e.st_bind);
|
|
250
|
+
d["st_type"] = static_cast<uint8_t>(e.st_type);
|
|
251
|
+
d["st_other"] = static_cast<uint8_t>(e.st_other);
|
|
252
|
+
d["st_shndx"] = static_cast<uint16_t>(e.st_shndx);
|
|
253
|
+
d["symbol_name"] = e.symbol_name;
|
|
254
|
+
result.append(std::move(d));
|
|
255
|
+
}
|
|
256
|
+
return result;
|
|
257
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
|
|
2
|
+
#pragma once
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @file elf_parser.hpp
|
|
6
|
+
* @brief Fast C++ ELF symbol-table parser exposed via pybind11.
|
|
7
|
+
*
|
|
8
|
+
* parse_symbol_table() replaces the Python/construct-based loop in
|
|
9
|
+
* ElfParser._parse_symbol_section(). It reads raw ELF32_Sym / ELF64_Sym
|
|
10
|
+
* entries directly with pointer arithmetic – no Python object overhead per
|
|
11
|
+
* entry – and resolves symbol names from the string table in a single pass.
|
|
12
|
+
*
|
|
13
|
+
* Supported:
|
|
14
|
+
* - 32-bit and 64-bit ELF
|
|
15
|
+
* - Little-endian and big-endian ELF files on any host
|
|
16
|
+
*
|
|
17
|
+
* Return value:
|
|
18
|
+
* Python list of dicts, one entry per symbol, with keys:
|
|
19
|
+
* st_name (int), st_value (int), st_size (int),
|
|
20
|
+
* st_bind (int), st_type (int), st_other (int),
|
|
21
|
+
* st_shndx (int), symbol_name (str)
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
#include <pybind11/pybind11.h>
|
|
25
|
+
#include <pybind11/stl.h>
|
|
26
|
+
|
|
27
|
+
namespace py = pybind11;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @brief Parse a raw ELF symbol-table section.
|
|
31
|
+
*
|
|
32
|
+
* @param symtab_data Raw bytes of the symbol-table section (SHT_SYMTAB / SHT_DYNSYM).
|
|
33
|
+
* @param strtab_data Raw bytes of the associated string-table section (.strtab / .dynstr).
|
|
34
|
+
* @param is_64bit True for ELF64, false for ELF32.
|
|
35
|
+
* @param little_endian True when the ELF file uses little-endian encoding (EI_DATA == 1).
|
|
36
|
+
* @return Python list of dicts – one per symbol.
|
|
37
|
+
*/
|
|
38
|
+
py::list parse_symbol_table(
|
|
39
|
+
py::bytes symtab_data,
|
|
40
|
+
py::bytes strtab_data,
|
|
41
|
+
bool is_64bit,
|
|
42
|
+
bool little_endian
|
|
43
|
+
);
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
|
|
2
|
+
#include <pybind11/functional.h>
|
|
3
|
+
#include <pybind11/pybind11.h>
|
|
4
|
+
#include <pybind11/stl.h>
|
|
5
|
+
|
|
6
|
+
#include "difflib.h"
|
|
7
|
+
#include "elf_parser.hpp"
|
|
8
|
+
|
|
9
|
+
namespace py = pybind11;
|
|
10
|
+
using namespace difflib;
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
PYBIND11_MODULE(hexfiles_ext, m) {
|
|
14
|
+
// ── difflib.SequenceMatcher ────────────────────────────────────────────
|
|
15
|
+
py::class_<SequenceMatcher<std::string>>(m, "SequenceMatcher")
|
|
16
|
+
.def(py::init<const std::string &, const std::string &, SequenceMatcher<std::string>::junk_function_type, bool>(),
|
|
17
|
+
py::arg("a"), py::arg("b"),
|
|
18
|
+
py::arg("is_junk") = nullptr, py::arg("auto_junk") = true)
|
|
19
|
+
.def("ratio", &SequenceMatcher<std::string>::ratio)
|
|
20
|
+
.def("get_opcodes",&SequenceMatcher<std::string>::get_opcodes)
|
|
21
|
+
;
|
|
22
|
+
|
|
23
|
+
// ── ELF symbol-table parser ────────────────────────────────────────────
|
|
24
|
+
m.def(
|
|
25
|
+
"parse_symbol_table",
|
|
26
|
+
&parse_symbol_table,
|
|
27
|
+
py::arg("symtab_data"),
|
|
28
|
+
py::arg("strtab_data"),
|
|
29
|
+
py::arg("is_64bit"),
|
|
30
|
+
py::arg("little_endian"),
|
|
31
|
+
R"doc(
|
|
32
|
+
Parse a raw ELF symbol-table section in C++ and return a list of dicts.
|
|
33
|
+
|
|
34
|
+
This is a high-performance replacement for the construct-based loop in
|
|
35
|
+
ElfParser._parse_symbol_section(). It handles both ELF32 and ELF64 as
|
|
36
|
+
well as little-endian and big-endian ELF files.
|
|
37
|
+
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
symtab_data : bytes
|
|
41
|
+
Raw bytes of the SHT_SYMTAB / SHT_DYNSYM section.
|
|
42
|
+
strtab_data : bytes
|
|
43
|
+
Raw bytes of the associated string-table section (.strtab / .dynstr).
|
|
44
|
+
is_64bit : bool
|
|
45
|
+
True for ELF64 (24-byte Elf64_Sym entries), False for ELF32 (16-byte).
|
|
46
|
+
little_endian : bool
|
|
47
|
+
True when EI_DATA == ELFDATA2LSB (little-endian).
|
|
48
|
+
|
|
49
|
+
Returns
|
|
50
|
+
-------
|
|
51
|
+
list[dict]
|
|
52
|
+
One dict per symbol with keys:
|
|
53
|
+
st_name (int), st_value (int), st_size (int),
|
|
54
|
+
st_bind (int), st_type (int), st_other (int),
|
|
55
|
+
st_shndx (int), symbol_name (str).
|
|
56
|
+
)doc"
|
|
57
|
+
);
|
|
58
|
+
}
|
|
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "objutils"
|
|
7
|
-
version = "0.10.
|
|
7
|
+
version = "0.10.15"
|
|
8
8
|
description = "Objectfile library for Python"
|
|
9
9
|
authors = [
|
|
10
10
|
{name = "Christoph Schueler", email = "cpu12.gems@googlemail.com"}
|
|
@@ -126,7 +126,7 @@ skip = ["*_i686", "*-musllinux*"]
|
|
|
126
126
|
build-frontend = "build"
|
|
127
127
|
|
|
128
128
|
[tool.bumpver]
|
|
129
|
-
current_version = "0.10.
|
|
129
|
+
current_version = "0.10.15"
|
|
130
130
|
version_pattern = "MAJOR.MINOR.PATCH"
|
|
131
131
|
commit_message = "bump version {old_version} -> {new_version}"
|
|
132
132
|
commit = true
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
#include <pybind11/functional.h>
|
|
3
|
-
#include <pybind11/pybind11.h>
|
|
4
|
-
#include <pybind11/stl.h>
|
|
5
|
-
|
|
6
|
-
#include "difflib.h"
|
|
7
|
-
|
|
8
|
-
namespace py = pybind11;
|
|
9
|
-
using namespace difflib;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
PYBIND11_MODULE(hexfiles_ext, m) {
|
|
13
|
-
py::class_<SequenceMatcher<std::string>>(m, "SequenceMatcher")
|
|
14
|
-
.def(py::init<const std::string &, const std::string &, SequenceMatcher<std::string>::junk_function_type, bool>(), py::arg("a"), py::arg("b"), py::arg("is_junk")=nullptr, py::arg("auto_junk")=true)
|
|
15
|
-
.def("ratio", &SequenceMatcher<std::string>::ratio)
|
|
16
|
-
.def("get_opcodes", &SequenceMatcher<std::string>::get_opcodes)
|
|
17
|
-
;
|
|
18
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|