Repository navigation
fix(android): make the NDK build compile and target the API floor - #20
Merged
Merged
Conversation
Two defects kept tools/build-android.sh from producing a library, both only visible on the on-device build (the host build never set the flag and never compiled for Android): - COMMON_FLAGS passed -fno-exceptions, but include/berry/hook_chain.h wraps each chain handler in try/catch to isolate a faulting handler. The translation unit failed with "cannot use 'try' with exceptions disabled". Exceptions are now enabled to match the host build, so the fault-isolation path compiles. - core/lifecycle/crash.cpp guarded backtrace(3) on __linux__, but on Android it is only declared from API 33 while the build targets API 24, so the symbol was undeclared. The guard now requires glibc, or a non-Android Linux, or Android API >= 33; below that the crash report still carries the signal, the fault address and the last log line. Verified: tools/build-android.sh now emits libBerryAPI.so (AArch64) exporting the full ABI-8 C surface (BERRY_SetWorldSeam / BERRY_GetReplayApi / BERRY_GetGovernorApi and the struct-size/abi-version queries).
) * feat(cosmetic): add a C ABI for cosmetics and the player-model hook The cosmetics system was C++ only, so a host that dlopen's libBerryAPI.so - a launcher's native preloader - could not drive it without linking the whole C++ surface. berry/cosmetic_c.h closes that gap the same way berry/replay_c.h did for the replay: a plain C struct of function pointers obtained from BERRY_GetCosmeticApi(), with a size/abi_version guard the host checks before calling a pointer, and a named status on every call that can fail. The surface covers reload_packs, the catalog (list/registry_count), the local loadout (equip/unequip/equipped/clear/canonical), presets and stats. It also carries the player-model plumbing: set_player_model_hook installs the detour on the host's per-build player-render target and binds a host-supplied bone reader, which is what makes a cosmetic resolve to a real rig. Without it the render path fails closed and draws nothing. BerryConfigC grew cosmetic_pack_directory and cosmetic_asset_directory, so a host can point the client at its packs through the C ABI; the global BERRY_ABI_VERSION moves 8 -> 9 (the world-seam layout is unchanged, sizeof stays 112). BerryClient gains the public ReloadCosmeticPacks / InstallPlayerModelHook / ClearPlayerModelHook that both the attach path and the C ABI use, so the two cannot drift. Verified: make test green (incl. the new tests/test_cosmetic_c.cpp and the extended tests/dlopen_test.c); the five BERRY_* symbols export in the shared library. * fix(seam): give the world seam its own ABI version The world seam reported the global BERRY_ABI_VERSION, so any config-struct growth moved the seam's ABI number too and the preloader (which pins kHostSeamAbiVersion) would refuse a seam whose layout had not changed. The seam struct now carries BERRY_SEAM_ABI_VERSION, an independent number bumped only when BerrySeamC itself changes. Its value stays 8, so the preloader's pinned 8 keeps matching; the global version is free to grow for config-only reasons. * fix(cosmetic): hook a real function in the C ABI test, not a stack int The player-model hook test passed `int hookTarget = 0` as the detour target. The shim decodes the target's prologue as x86-64 code, and reading past the four-byte stack variable is a stack-buffer-overflow that ASan aborts on. It also depended on an anonymous mapping being within a rel32 of the detour and trampoline, which the shim's jmp needs. Hook a real function in this module instead. The prologue is a normal function, the distance is guaranteed to fit, and the test now actually installs and clears the hook rather than skipping on a refused target. * fix(mbedtls): drop MBEDTLS_AESCE_C; the unit it needs is not vendored The vendored config enabled MBEDTLS_AESCE_C, but only the trimmed client stack is vendored and library/aesce.c is not one of its units. aes.c guards its Armv8-A fast path on that option, so an arm64 build referenced the mbedtls_aesce_* symbols with nothing to satisfy them: the arm64 test job failed to link, and the shipping .so would carry the same unresolved symbols (a jump to address 0 the first time AES ran on an arm64 device with the crypto extension). The portable AES in aes.c is used instead. tools/check-mbedtls.py now keeps the option off, and PROVENANCE.md records why. Also stop the check-sigcheck self-test from tripping over the compiler's own bytes: the pattern is the 16-byte ELF identification header, not the bare 4-byte magic, which clang embeds as an immediate in its generated loader checks and so appears twice in a clang-built binary. * fix(ci): green the clang and sanitize host jobs Three independent defects, each of which the g++ job either masked or never reached: - check-sigcheck pinned the ELF OSABI byte (e_ident[7]) to 00, but the g++ toolchain writes 03 (GNU/Linux). Wildcard that byte so the 16-byte identification pattern matches either toolchain. - LanCosmeticTransport::Magic() returned cosmeticfrag::kMagic, a 4-byte array with no terminator; the test builds a std::string from it, which clang read past the end. Return a NUL-terminated static, as the sibling transports do. - test_packet_capture called its fake receive function directly, so clang inlined the body and the call never reached the patched prologue. Mark it noinline and reach it through a volatile pointer. - async.http_get cast the raw double timeout to long before the call, so a NaN argument was UB at the call site even though HttpGetBlocking clamps. Guard the cast. --------- Co-authored-by: Lynxifyy <297587416+Lynxifyy@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Two defects kept
tools/build-android.shfrom producing a library. Both are invisible to the host build (it never set the flag and never compiled for Android), so they only showed up on the first real on-device build.Why
COMMON_FLAGSpassed-fno-exceptions, butinclude/berry/hook_chain.hwraps each chain handler intry/catchto isolate a faulting handler. The translation unit failed withcannot use 'try' with exceptions disabled. Exceptions are now enabled, matching the host build, so the fault-isolation path compiles.backtrace(3).core/lifecycle/crash.cppguarded the unwinder on__linux__, but on Android it is only declared from API 33 while the build targets API 24, so the symbol was undeclared. The guard now requires glibc, or a non-Android Linux, or Android API >= 33; below that the crash report still carries the signal, the fault address and the last log line.Evidence
tools/build-android.shnow emitslibBerryAPI.so(AArch64) exporting the full ABI-8 C surface (BERRY_SetWorldSeam/BERRY_GetReplayApi/BERRY_GetGovernorApiand the struct-size/abi-version queries).Verified locally with NDK 28.2.13676358; Dobby is built from the vendored source.