Skip to content

Fix proot TLS underalignment for all ABIs and rebuild the four proot binaries - #27

Closed
GlobalTechInfo wants to merge 4 commits into
mainfrom
proot/fix
Closed

GlobalTechInfo wants to merge 4 commits into
mainfrom
proot/fix

Conversation

@GlobalTechInfo

@GlobalTechInfo GlobalTechInfo commented Oct 25, 2026 •

Copy link
Copy Markdown
Owner

Summary

Fixes the on-device abort when starting a distro session on 32-bit (armv7)
hardware: executable's TLS segment is underaligned ... needs to be at least 32 for ARM Bionic. Bionic's ARM32/ARM64 static-TLS layout check
gates on p_align and the vaddr skew together, and a plain NDK link
emits p_align 8 with a 16-aligned vaddr. This re-links the 32-bit ABIs
with a script that start-aligns .tdata at 32 (skew 0), and keeps the
p_align 64 program-header patch for the 64-bit ABIs (their vaddr is
already 64-aligned, so the patch is safe). All four libproot.so
binaries were rebuilt from the d4d2a19 proot baseline (the one already
confirmed working on aarch64).

Changes

  • native/proot-tls-align-armv7a.ld, native/proot-tls-align-i686.ld:
    full layout scripts; .tdata/.tbss start-aligned at 32, 16 KB data
    segment alignment, lld-compatible
  • native/build-proot.sh: the -Wl,-T script is baked into the main
    link; the 32-bit branch verifies p_align/vaddr instead of a dead
    ld.bfd re-link (the NDK ships no ld.bfd); ABI case fixed (i686's
    ABI is x86, so the old i686) pattern never matched); the 64-bit
    patch now actually writes the file back; loader page-size injection is
    idempotent
  • app/src/main/jniLibs/*/: all four ABIs rebuilt and verified
    • arm64-v8a: PT_TLS p_align 64, vaddr 0x2a8ec0 (64-aligned)
    • armeabi-v7a: PT_TLS p_align 32, vaddr 0x84000 (skew 0)
    • x86: PT_TLS p_align 32, vaddr 0x4b8000 (skew 0; i386 has no bionic
      TLS gate, kept uniform with armv7)
    • x86_64: PT_TLS p_align 64, vaddr 0x2af400 (64-aligned)
      All ET_EXEC, every LOAD 16 KB-page aligned, entry at bionic's static
      _start; .tdata template bytes identical before/after the re-link

How it was tested

  • Check cross-referenced against bionic platform source
    (StaticTlsLayout::reserve_exe_segment_and_tcb in
    bionic/libc/bionic/bionic_elf_tls.cpp): p_align 8 fails on
    ARM32/ARM64; 32 (i386/x86_64 have no gate); 32/64 with skew 0 pass
  • Clean build: ./gradlew clean assembleDebug (39/39 tasks, zero
    compiler warnings); the APK's four libproot.so are md5-identical to
    jniLibs
  • Pending: on-device verification on all four ABIs (arm64 confirmed with
    the pre-change binary; armv7/x86/x86_64 to be verified on real devices
    before merge)

Checklist

  • Builds and passes ./gradlew assembleDebug lintDebug
    (clean assembleDebug done; lintDebug not run in this pass)
  • CHANGELOG.md updated under ## [Unreleased] if user-visible
    (deliberately untouched until the on-device verification lands,
    per project convention)
  • No unrelated changes included

Summary by CodeRabbit

  • Bug Fixes
    • Improved compatibility of the bundled runtime on ARMv7 and x86 devices by correcting memory alignment in its native components.
    • Added alignment checks during builds to catch incompatible binaries earlier.

…1.107.101

- Update proot to v5.1.107.101 (commit 968ae1be) with link2symlink fix
- Patch PT_TLS p_align 8->64 for arm64-v8a to satisfy bionic's TLS alignment requirement
- Build with NDK r27c for arm64-v8a
- This fixes the 'TLS segment underaligned' abort on Android 14+ devices
…for arm64

- Update proot to v5.1.107.101 (commit 968ae1be) with link2symlink fix
- Fix TLS alignment for arm64-v8a: patch PT_TLS p_align 8->64
- armv7 binary built with linker script for TLS alignment (known issue: TLS alignment not fully fixed)
- All 4 architectures built with proot v5.1.107.101
- Proot binaries updated in jniLibs for all 4 architectures
…ries

bionic's ARM32 static-TLS check (StaticTlsLayout in bionic_elf_tls.cpp)
gates on p_align AND the vaddr skew together: a plain NDK link emits
p_align 8 with a 16-aligned vaddr, which aborts on-device with
"executable's TLS segment is underaligned ... needs to be at least 32
for ARM Bionic". Patching the program header alone cannot fix the vaddr
half, because p_vaddr also feeds init_ptr, the address bionic copies the
TLS template from. Re-link armv7 and i686 with a linker script that
START-aligns .tdata at 32 (PT_TLS p_align 32, skew 0); the previous
scripts only end-aligned .tdata and their ld.bfd re-link was a no-op
(the NDK ships no ld.bfd). 64-bit keeps the p_align 64 program-header
patch, which now actually writes the file back. build-proot.sh: the
-T script is baked into the main link, the 32-bit branch verifies
instead of the dead re-link, the ABI case is fixed (i686's ABI is
"x86"), and the loader page-size injection is idempotent. All four
ABIs rebuilt from d4d2a19: arm64 p_align 64 / armv7 32 / i686 32 /
x86_64 64, every LOAD 16 KB aligned, entry at bionic's static _start.
@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 97e458a4-5a4f-4c8c-99f1-9880ce448521
Commits

Reviewing files that changed from the base of the PR and between 4b70375 and f1e5c0b.

Files ignored due to path filters: 10
  • app/src/main/jniLibs/arm64-v8a/libproot-loader.so is excluded by !**/*.so
  • app/src/main/jniLibs/arm64-v8a/libproot-loader32.so is excluded by !**/*.so
  • app/src/main/jniLibs/arm64-v8a/libproot.so is excluded by !**/*.so
  • app/src/main/jniLibs/armeabi-v7a/libproot-loader.so is excluded by !**/*.so
  • app/src/main/jniLibs/armeabi-v7a/libproot.so is excluded by !**/*.so
  • app/src/main/jniLibs/x86/libproot-loader.so is excluded by !**/*.so
  • app/src/main/jniLibs/x86/libproot.so is excluded by !**/*.so
  • app/src/main/jniLibs/x86_64/libproot-loader.so is excluded by !**/*.so
  • app/src/main/jniLibs/x86_64/libproot-loader32.so is excluded by !**/*.so
  • app/src/main/jniLibs/x86_64/libproot.so is excluded by !**/*.so
Files selected for processing: 3
  • native/build-proot.sh
  • native/proot-tls-align-armv7a.ld
  • native/proot-tls-align-i686.ld

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

The build now selects linker layouts for 32-bit ARM and x86, and injects loader page-size flags only when absent. After installing libproot.so, it patches 64-bit PT_TLS alignment when the virtual address is 64-byte aligned and checks for 32-byte alignment on 32-bit binaries.

Changes: Proot TLS alignment

Layer / File(s) Summary
32-bit TLS linker layouts
native/proot-tls-align-armv7a.ld, native/proot-tls-align-i686.ld
The ARMv7-A and i386 linker layouts align the data segment to 16 KB. Both place .tdata and the end of BSS at 32-byte boundaries.
ABI-specific build and TLS handling
native/build-proot.sh
build_proot selects the 32-bit linker scripts and adds them to the link flags. It injects loader page-size flags only when absent. After installation, it patches eligible 64-bit PT_TLS entries and verifies 32-bit alignment.

Priority: Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Merge Risk: Minimal · up to f1e5c

The identified issue is an inaccurate build-script comment, not a demonstrated failure of the rebuilt binaries. Normal validation, including the pending on-device checks, remains appropriate.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title names the main change: fixing proot TLS underalignment across all ABIs. It also names the rebuild of the four proot binaries. The changeset matches this. The linker scripts and build-proot.s…
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (2 skipped: 2 …
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title names the main change: fixing proot TLS underalignment across all ABIs. It also names the rebuild of the four proot binaries. The changeset matches this. The linker scripts and build-proot.sh change the TLS alignment for each ABI. The jniLibs binaries are excluded from the diff by the path filter, but the title still describes the intent of the PR. The title is specific and uses no vague terms. Its length (77 characters, 13 words) is slightly long, but it is still one clear sentence.

Full details: Docstring Coverage

Explanation

Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (2 skipped: 2 unsupported.)

Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant