pelfy dependency vendored

This commit is contained in:
Nicolas Kruse 2025-12-14 22:04:37 +01:00
parent d436dd9116
commit 8877b4d893
4 changed files with 62 additions and 12 deletions

View File

@ -44,6 +44,12 @@ jobs:
with: with:
python-version: "3.11" python-version: "3.11"
- name: Vendor pelfy
run: |
git clone --depth 1 https://github.com/Nonannet/pelfy.git /tmp/pelfy
mkdir -p src/${{ github.event.repository.name }}/_vendor
cp -r /tmp/pelfy/pelfy src/${{ github.event.repository.name }}/_vendor/
# Only needed for Linux ARM builds # Only needed for Linux ARM builds
- name: Set up QEMU - name: Set up QEMU
if: runner.os == 'Linux' if: runner.os == 'Linux'

View File

@ -30,6 +30,42 @@ jobs:
name: musl-object-files name: musl-object-files
path: /object_files/musl_objects_*.*o path: /object_files/musl_objects_*.*o
build-package-test:
needs: [build_stencils]
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.12"]
steps:
- name: Check out code
uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: stencil-object-files
path: src/copapy/obj
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Python dependencies
run: |
python -m pip install -e .
python -m pip install pytest
- name: Vendor pelfy
run: |
git clone --depth 1 https://github.com/Nonannet/pelfy.git /tmp/pelfy
mkdir -p src/${{ github.event.repository.name }}/_vendor
cp -r /tmp/pelfy/pelfy src/${{ github.event.repository.name }}/_vendor/
- name: Run tests with pytest
run: pytest -m "not runner"
build-ubuntu: build-ubuntu:
needs: [build_stencils] needs: [build_stencils]
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@ -13,7 +13,6 @@ classifiers = [
"Operating System :: OS Independent", "Operating System :: OS Independent",
] ]
dependencies = [ dependencies = [
"pelfy>=1.0.7"
] ]
[project.urls] [project.urls]
@ -34,13 +33,15 @@ copapy = ["obj/*.o", "py.typed"]
dev = [ dev = [
"ruff", "ruff",
"mypy", "mypy",
"pytest" "pytest",
"pelfy>=1.0.7"
] ]
doc_build = [ doc_build = [
"sphinx", "sphinx",
"pydata_sphinx_theme", "pydata_sphinx_theme",
"sphinx-autodoc-typehints", "sphinx-autodoc-typehints",
"myst-parser" "myst-parser",
"pelfy>=1.0.7"
] ]
[tool.mypy] [tool.mypy]

View File

@ -1,10 +1,17 @@
from dataclasses import dataclass from dataclasses import dataclass
from pelfy import open_elf_file, elf_file, elf_symbol from typing import Generator, Literal, Iterable, TYPE_CHECKING
from typing import Generator, Literal, Iterable
import pelfy
import struct import struct
import platform import platform
if TYPE_CHECKING:
import pelfy
else:
try:
from ._vendor import pelfy
except ImportError:
import pelfy
ByteOrder = Literal['little', 'big'] ByteOrder = Literal['little', 'big']
@ -62,7 +69,7 @@ def detect_process_arch() -> str:
return arch_family return arch_family
def get_return_function_type(symbol: elf_symbol) -> str: def get_return_function_type(symbol: pelfy.elf_symbol) -> str:
if symbol.relocations: if symbol.relocations:
for reloc in reversed(symbol.relocations): for reloc in reversed(symbol.relocations):
func_name = reloc.symbol.name func_name = reloc.symbol.name
@ -71,7 +78,7 @@ def get_return_function_type(symbol: elf_symbol) -> str:
return 'void' return 'void'
def get_stencil_position(func: elf_symbol) -> tuple[int, int]: def get_stencil_position(func: pelfy.elf_symbol) -> tuple[int, int]:
start_index = 0 # There must be no prolog start_index = 0 # There must be no prolog
# Find last relocation in function # Find last relocation in function
last_instr = get_last_call_in_function(func) last_instr = get_last_call_in_function(func)
@ -84,7 +91,7 @@ def get_stencil_position(func: elf_symbol) -> tuple[int, int]:
return start_index, end_index return start_index, end_index
def get_last_call_in_function(func: elf_symbol) -> int: def get_last_call_in_function(func: pelfy.elf_symbol) -> int:
# Find last relocation in function # Find last relocation in function
assert func.relocations, f'No call function in stencil function {func.name}.' assert func.relocations, f'No call function in stencil function {func.name}.'
reloc = func.relocations[-1] reloc = func.relocations[-1]
@ -95,7 +102,7 @@ def get_last_call_in_function(func: elf_symbol) -> int:
return reloc.fields['r_offset'] - func.fields['st_value'] + address_field_length - instruction_lengths return reloc.fields['r_offset'] - func.fields['st_value'] + address_field_length - instruction_lengths
def get_op_after_last_call_in_function(func: elf_symbol) -> int: def get_op_after_last_call_in_function(func: pelfy.elf_symbol) -> int:
# Find last relocation in function # Find last relocation in function
assert func.relocations, f'No call function in stencil function {func.name}.' assert func.relocations, f'No call function in stencil function {func.name}.'
reloc = func.relocations[-1] reloc = func.relocations[-1]
@ -120,9 +127,9 @@ class stencil_database():
obj_file: path to the ELF object file or bytes of the ELF object file obj_file: path to the ELF object file or bytes of the ELF object file
""" """
if isinstance(obj_file, str): if isinstance(obj_file, str):
self.elf = open_elf_file(obj_file) self.elf = pelfy.open_elf_file(obj_file)
else: else:
self.elf = elf_file(obj_file) self.elf = pelfy.elf_file(obj_file)
self.stencil_definitions = {s.name: get_return_function_type(s) self.stencil_definitions = {s.name: get_return_function_type(s)
for s in self.elf.symbols for s in self.elf.symbols