Files
spoopyghosty0--frameport/tests/test_elf.py
T
spoopyghosty0 23a47880e0 Lines within 120 columns everywhere (CI lints without exceptions); community and licence files; docs updated
- reflowed long lines (texts unchanged; generated launcher/PowerShell/README texts byte-identical)
- CONTRIBUTING, SECURITY, CODE_OF_CONDUCT, THIRD_PARTY_NOTICES; pyproject metadata (SPDX licence, authors, urls,
  classifiers, keywords)
- maintainer-only notes moved to a git-ignored CLAUDE.local.md; CLAUDE.md facts updated
- README: what kinds of apps run and how; INSTALL: PC VR and Files wording, new labels
2026-10-02 14:18:41 -04:00

50 lines
2.0 KiB
Python

import struct
import pytest
from frameport.analysis import elf
from frameport.analysis.stubgen import build_stub_library
@pytest.mark.parametrize("abi", ["arm64-v8a", "armeabi-v7a"])
def test_stub_library(abi):
lib = build_stub_library(["ovr_B", "ovr_A", "ovrMessageType_ToString"], abi=abi)
assert elf.is_elf(lib)
assert elf.is_64bit(lib) == (abi == "arm64-v8a")
assert elf.soname(lib) == "libovrstubs.so"
assert elf.dyn_symbols(lib, True) == {"ovr_A", "ovr_B", "ovrMessageType_ToString"}
assert elf.needed(lib) == []
# 16 KiB page-aligned loads, dynamic inside the RW load
loads = elf.load_segments(lib)
assert all(off % 16384 == va % 16384 for va, off, _ in loads)
def _with_note(lib: bytes) -> bytes:
"""Turn the stub's PT_GNU_STACK into a PT_NOTE so add_needed can reuse it (the common case)."""
buf = bytearray(lib)
phoff = struct.unpack_from("<Q", buf, 32)[0]
phentsize, phnum = struct.unpack_from("<H", buf, 54)[0], struct.unpack_from("<H", buf, 56)[0]
for i in range(phnum):
if struct.unpack_from("<I", buf, phoff + i * phentsize)[0] == 0x6474E551:
struct.pack_into("<I", buf, phoff + i * phentsize, 4)
return bytes(buf)
@pytest.mark.parametrize("variant", ["reuse_note", "relocate_phdrs"])
def test_add_needed(variant):
base = build_stub_library(["ovr_X"], soname="libgame.so")
base = elf.add_needed(base, "liblog.so") # give it one NEEDED first
if variant == "reuse_note":
base = _with_note(base)
out = elf.add_needed(base, "libglshim.so")
assert elf.needed(out)[0] == "libglshim.so"
assert elf.needed(out)[1:] == elf.needed(base)
assert elf.dyn_symbols(out, True) == {"ovr_X"}
assert elf.soname(out) == "libgame.so"
assert out[: len(base)][64:] != b"" and out.startswith(base[:16])
loads = elf.load_segments(out)
assert [va for va, _, _ in loads] == sorted(va for va, _, _ in loads)
assert all(off % 16384 == va % 16384 for va, off, _ in loads)
# idempotent
assert elf.add_needed(out, "libglshim.so") == out