diff --git a/app/src/main/jniLibs/arm64-v8a/libproot-loader.so b/app/src/main/jniLibs/arm64-v8a/libproot-loader.so index dbb0a0c..a8cfff7 100755 Binary files a/app/src/main/jniLibs/arm64-v8a/libproot-loader.so and b/app/src/main/jniLibs/arm64-v8a/libproot-loader.so differ diff --git a/app/src/main/jniLibs/arm64-v8a/libproot-loader32.so b/app/src/main/jniLibs/arm64-v8a/libproot-loader32.so index ba3114a..0e4534d 100755 Binary files a/app/src/main/jniLibs/arm64-v8a/libproot-loader32.so and b/app/src/main/jniLibs/arm64-v8a/libproot-loader32.so differ diff --git a/app/src/main/jniLibs/arm64-v8a/libproot.so b/app/src/main/jniLibs/arm64-v8a/libproot.so index 079ac6b..0055548 100755 Binary files a/app/src/main/jniLibs/arm64-v8a/libproot.so and b/app/src/main/jniLibs/arm64-v8a/libproot.so differ diff --git a/app/src/main/jniLibs/armeabi-v7a/libproot-loader.so b/app/src/main/jniLibs/armeabi-v7a/libproot-loader.so index 25eb4d4..3ec8209 100755 Binary files a/app/src/main/jniLibs/armeabi-v7a/libproot-loader.so and b/app/src/main/jniLibs/armeabi-v7a/libproot-loader.so differ diff --git a/app/src/main/jniLibs/armeabi-v7a/libproot.so b/app/src/main/jniLibs/armeabi-v7a/libproot.so index 5979f07..3afe452 100755 Binary files a/app/src/main/jniLibs/armeabi-v7a/libproot.so and b/app/src/main/jniLibs/armeabi-v7a/libproot.so differ diff --git a/app/src/main/jniLibs/x86/libproot-loader.so b/app/src/main/jniLibs/x86/libproot-loader.so index ba28af3..149e06a 100755 Binary files a/app/src/main/jniLibs/x86/libproot-loader.so and b/app/src/main/jniLibs/x86/libproot-loader.so differ diff --git a/app/src/main/jniLibs/x86/libproot.so b/app/src/main/jniLibs/x86/libproot.so index a30e2ff..f51e875 100755 Binary files a/app/src/main/jniLibs/x86/libproot.so and b/app/src/main/jniLibs/x86/libproot.so differ diff --git a/app/src/main/jniLibs/x86_64/libproot-loader.so b/app/src/main/jniLibs/x86_64/libproot-loader.so index e6f779a..e72b5d1 100755 Binary files a/app/src/main/jniLibs/x86_64/libproot-loader.so and b/app/src/main/jniLibs/x86_64/libproot-loader.so differ diff --git a/app/src/main/jniLibs/x86_64/libproot-loader32.so b/app/src/main/jniLibs/x86_64/libproot-loader32.so index ba28af3..149e06a 100755 Binary files a/app/src/main/jniLibs/x86_64/libproot-loader32.so and b/app/src/main/jniLibs/x86_64/libproot-loader32.so differ diff --git a/app/src/main/jniLibs/x86_64/libproot.so b/app/src/main/jniLibs/x86_64/libproot.so index d797827..a31e07f 100755 Binary files a/app/src/main/jniLibs/x86_64/libproot.so and b/app/src/main/jniLibs/x86_64/libproot.so differ diff --git a/native/build-proot.sh b/native/build-proot.sh index defc889..2a0786e 100755 --- a/native/build-proot.sh +++ b/native/build-proot.sh @@ -146,6 +146,25 @@ build_proot() { build_talloc echo "==> [$ABI] proot $PROOT_VERSION" + # 32-bit ABIs: bionic's ARM32 static-TLS layout check (StaticTlsLayout in + # bionic/libc/bionic/bionic_elf_tls.cpp) aborts when the executable's + # PT_TLS is underaligned, and it checks p_align AND the skew + # (p_vaddr % p_align) 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". + # Hand-patching the program header cannot fix the vaddr half: p_vaddr + # also feeds init_ptr, the address bionic copies the TLS template from, + # so vaddr must stay where the section really is. Only a re-link with + # a script that START-aligns .tdata at 32 does it. (i686 needs no fix + # — bionic has no TLS gate on i386 — but the same script keeps the + # build uniform.) + TLS_SCRIPT="" + case "$ABI" in + armeabi-v7a) TLS_SCRIPT="$SCRIPT_DIR/proot-tls-align-armv7a.ld" ;; + x86) TLS_SCRIPT="$SCRIPT_DIR/proot-tls-align-i686.ld" ;; + esac + local tls_ldflags="" + [ -n "$TLS_SCRIPT" ] && tls_ldflags=" -Wl,-T$TLS_SCRIPT" if [ ! -d "$work/proot" ]; then git clone "$PROOT_REPO" "$work/proot" fi @@ -162,14 +181,15 @@ import re, sys page = sys.argv[1] p = "GNUmakefile" s = open(p).read() -new = re.sub( - r'(LOADER_LDFLAGS\$1 \+= -static -nostdlib )', - r'\1-Wl,-z,max-page-size=' + page + ' ', - s, -) -if new == s: - sys.exit("ERROR: could not inject loader page size into GNUmakefile") -open(p, "w").write(new) +if "-Wl,-z,max-page-size=" not in s: + new = re.sub( + r'(LOADER_LDFLAGS\$1 \+= -static -nostdlib )', + r'\1-Wl,-z,max-page-size=' + page + ' ', + s, + ) + if new == s: + sys.exit("ERROR: could not inject loader page size into GNUmakefile") + open(p, "w").write(new) PYEOF cat > loader/loader-fix.h << 'EOF' #ifndef PATH_MAX @@ -178,12 +198,76 @@ PYEOF EOF CC="$CC" AR="$AR" STRIP="$STRIP" OBJCOPY="$OBJCOPY" OBJDUMP="$OBJDUMP" \ CFLAGS="-I$TALLOC_INSTALL/include -O2 -fPIC -DARG_MAX=131072 -Wno-implicit-function-declaration -Wno-implicit-int" \ - LDFLAGS="-L$TALLOC_INSTALL/lib -static -Wl,-z,max-page-size=$PAGE_SIZE" \ + LDFLAGS="-L$TALLOC_INSTALL/lib -static -Wl,-z,max-page-size=$PAGE_SIZE$tls_ldflags" \ make -j"$(nproc)" ) echo "==> [$ABI] installing" install -m 0755 "$work/proot/src/proot" "$OUTPUT_DIR/$ABI/libproot.so" + + # TLS alignment fix. bionic's static-TLS layout check exists only on ARM: + # "executable's TLS segment is underaligned ... needs to be at least 32 + # for ARM Bionic / 64 for ARM64 Bionic". 64-bit: the plain link already + # emits a 64-aligned vaddr, so patching p_align 8 -> 64 in the program + # header is safe (init_ptr is vaddr-based and stays correct). i386/x86_64 + # have no gate at all; the patch below is a no-op there. + case "$ABI" in + arm64-v8a|x86_64) + # 64-bit: native layout has TLS vaddr 64-aligned, patch p_align to 64 + python3 - "$OUTPUT_DIR/$ABI/libproot.so" "$ABI" <<'PYEOF' +import struct, sys +path, abi = sys.argv[1], sys.argv[2] +data = bytearray(open(path, "r+b").read()) +assert data[:4] == b"\x7fELF" +cls = data[4] +F = " 64 for {abi}") + patched = True +if patched: + open(path, "wb").write(bytes(data)) +if not patched: + print("No PT_TLS phdr patched (already aligned or not found)") +PYEOF + ;; + armeabi-v7a|x86) + # 32-bit: TLS alignment was baked in at link time (-Wl,-T$TLS_SCRIPT). + # Verify, don't patch: PT_TLS must have p_align 32 and a 32-aligned + # vaddr, or bionic's ARM32 static-TLS check aborts the binary. + python3 - "$OUTPUT_DIR/$ABI/libproot.so" "$ABI" <<'PYEOF' +import struct, sys +path, abi = sys.argv[1], sys.argv[2] +data = open(path, "rb").read() +assert data[:4] == b"\x7fELF" and data[4] == 1 +phoff = struct.unpack_from("