Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions .github/check_elf_alignment.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#!/bin/bash
Comment thread
Haz3-jolt marked this conversation as resolved.
# File copied from https://cs.android.com/android/platform/superproject/main/+/main:system/extras/tools/check_elf_alignment.sh
# See https://developer.android.com/guide/practices/page-sizes for context

progname="${0##*/}"
progname="${progname%.sh}"

# usage: check_elf_alignment.sh [path to *.so files|path to *.apk]

cleanup_trap() {
if [ -n "${tmp}" -a -d "${tmp}" ]; then
rm -rf ${tmp}
fi
exit $1
}

usage() {
echo "Host side script to check the ELF alignment of shared libraries."
echo "Shared libraries are reported ALIGNED when their ELF regions are"
echo "16 KB or 64 KB aligned. Otherwise they are reported as UNALIGNED."
echo
echo "Usage: ${progname} [input-path|input-APK|input-APEX]"
}

if [ ${#} -ne 1 ]; then
usage
exit
fi

case ${1} in
--help | -h | -\?)
usage
exit
;;

*)
dir="${1}"
;;
esac

if ! [ -f "${dir}" -o -d "${dir}" ]; then
echo "Invalid file: ${dir}" >&2
exit 1
fi

if [[ "${dir}" == *.apk ]]; then
trap 'cleanup_trap' EXIT

echo
echo "Recursively analyzing $dir"
echo

if { zipalign --help 2>&1 | grep -q "\-P <pagesize_kb>"; }; then
echo "=== APK zip-alignment ==="
zipalign -v -c -P 16 4 "${dir}" | egrep 'lib/arm64-v8a|lib/x86_64|Verification'
echo "========================="
else
echo "NOTICE: Zip alignment check requires build-tools version 35.0.0-rc3 or higher."
echo " You can install the latest build-tools by running the below command"
echo " and updating your \$PATH:"
echo
echo " sdkmanager \"build-tools;35.0.0-rc3\""
fi

dir_filename=$(basename "${dir}")
tmp=$(mktemp -d -t "${dir_filename%.apk}_out_XXXXX")
unzip "${dir}" lib/* -d "${tmp}" >/dev/null 2>&1
dir="${tmp}"
fi

if [[ "${dir}" == *.apex ]]; then
trap 'cleanup_trap' EXIT

echo
echo "Recursively analyzing $dir"
echo

dir_filename=$(basename "${dir}")
tmp=$(mktemp -d -t "${dir_filename%.apex}_out_XXXXX")
deapexer extract "${dir}" "${tmp}" || { echo "Failed to deapex." && exit 1; }
dir="${tmp}"
fi

RED="\e[31m"
GREEN="\e[32m"
ENDCOLOR="\e[0m"

unaligned_libs=()

echo
echo "=== ELF alignment ==="

matches="$(find "${dir}" -type f)"
IFS=$'\n'
for match in $matches; do
# We could recursively call this script or rewrite it to though.
[[ "${match}" == *".apk" ]] && echo "WARNING: doesn't recursively inspect .apk file: ${match}"
[[ "${match}" == *".apex" ]] && echo "WARNING: doesn't recursively inspect .apex file: ${match}"

[[ $(file "${match}") == *"ELF"* ]] || continue

res="$(objdump -p "${match}" | grep LOAD | awk '{ print $NF }' | head -1)"
if [[ $res =~ 2\*\*(1[4-9]|[2-9][0-9]|[1-9][0-9]{2,}) ]]; then
echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"
else
echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"
unaligned_libs+=("${match}")
fi
done

if [ ${#unaligned_libs[@]} -gt 0 ]; then
echo -e "${RED}Found ${#unaligned_libs[@]} unaligned libs (only arm64-v8a/x86_64 libs need to be aligned).${ENDCOLOR}"
elif [ -n "${dir_filename}" ]; then
echo -e "ELF Verification Successful"
fi
echo "====================="
50 changes: 49 additions & 1 deletion .github/workflows/tests_emulator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
// These are used for performance tuning what emulator to use.
// try different architectures, targets, delays etc
let arch = ['x86_64'];
let target = ['google_apis'];
let target = ['google_apis', 'google_apis_ps16k'];
let firstBootDelay = [600];

return {
Expand Down Expand Up @@ -223,6 +223,54 @@ jobs:
sleep 5
./gradlew uninstallAll jacocoAndroidTestReport --daemon

- name: Configure NDK tools PATH for alignment checking
run: |
echo "Using pre-installed NDK tools for alignment checking"
if [ ! -d "$ANDROID_NDK_LATEST_HOME" ]; then
echo "Error: NDK tools not found at $ANDROID_NDK_LATEST_HOME"
echo "The NDK should be pre-installed in the runner image. Failing fast."
exit 1
fi

NDK_VERSION=$(basename $ANDROID_NDK_LATEST_HOME)
echo "Using NDK version: $NDK_VERSION"
echo "export PATH=$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH" >> $GITHUB_ENV

- name: Check APK ELF Alignment
run: |
chmod +x .github/check_elf_alignment.sh
APK_PATH="AnkiDroid/build/outputs/apk/play/release/AnkiDroid-play-arm64-v8a-release.apk"

if [ ! -f "$APK_PATH" ]; then
echo "Error: APK file not found at $APK_PATH"
echo "The APK should have been built in previous steps. Failing fast."
exit 1
fi

echo "Using APK: $APK_PATH"
.github/check_elf_alignment.sh $APK_PATH

- name: Verify zipalign
run: |
APK_PATH="AnkiDroid/build/outputs/apk/play/release/AnkiDroid-play-arm64-v8a-release.apk"
echo "Verifying zipalign with 16KB alignment for $APK_PATH"

# Find the latest build-tools version dynamically
LATEST_BUILD_TOOLS=$(ls -d $ANDROID_HOME/build-tools/* | sort -V | tail -n 1)
ZIPALIGN_PATH="$LATEST_BUILD_TOOLS/zipalign"
echo "Using zipalign at: $ZIPALIGN_PATH"

# Verify zipalign exists
if [ ! -f "$ZIPALIGN_PATH" ]; then
echo "Error: zipalign not found at $ZIPALIGN_PATH"
echo "Available build-tools versions:"
ls -la $ANDROID_HOME/build-tools/
exit 1
fi

# Use the zipalign tool
$ZIPALIGN_PATH -c -P 16 -v 4 $APK_PATH

- name: Upload Test Report
uses: actions/upload-artifact@v7
if: always()
Expand Down
Loading