Skip to content

Commit e386237

Browse files
committed
CI test for 16kb and non-16kb page alignment
1 parent df5f1bf commit e386237

File tree

2 files changed

+149
-1
lines changed

2 files changed

+149
-1
lines changed

.github/check_elf_alignment.sh

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/bin/bash
2+
# File copied from https://cs.android.com/android/platform/superproject/main/+/main:system/extras/tools/check_elf_alignment.sh
3+
# See https://developer.android.com/guide/practices/page-sizes for context
4+
5+
progname="${0##*/}"
6+
progname="${progname%.sh}"
7+
8+
# usage: check_elf_alignment.sh [path to *.so files|path to *.apk]
9+
10+
cleanup_trap() {
11+
if [ -n "${tmp}" -a -d "${tmp}" ]; then
12+
rm -rf ${tmp}
13+
fi
14+
exit $1
15+
}
16+
17+
usage() {
18+
echo "Host side script to check the ELF alignment of shared libraries."
19+
echo "Shared libraries are reported ALIGNED when their ELF regions are"
20+
echo "16 KB or 64 KB aligned. Otherwise they are reported as UNALIGNED."
21+
echo
22+
echo "Usage: ${progname} [input-path|input-APK|input-APEX]"
23+
}
24+
25+
if [ ${#} -ne 1 ]; then
26+
usage
27+
exit
28+
fi
29+
30+
case ${1} in
31+
--help | -h | -\?)
32+
usage
33+
exit
34+
;;
35+
36+
*)
37+
dir="${1}"
38+
;;
39+
esac
40+
41+
if ! [ -f "${dir}" -o -d "${dir}" ]; then
42+
echo "Invalid file: ${dir}" >&2
43+
exit 1
44+
fi
45+
46+
if [[ "${dir}" == *.apk ]]; then
47+
trap 'cleanup_trap' EXIT
48+
49+
echo
50+
echo "Recursively analyzing $dir"
51+
echo
52+
53+
if { zipalign --help 2>&1 | grep -q "\-P <pagesize_kb>"; }; then
54+
echo "=== APK zip-alignment ==="
55+
zipalign -v -c -P 16 4 "${dir}" | egrep 'lib/arm64-v8a|lib/x86_64|Verification'
56+
echo "========================="
57+
else
58+
echo "NOTICE: Zip alignment check requires build-tools version 35.0.0-rc3 or higher."
59+
echo " You can install the latest build-tools by running the below command"
60+
echo " and updating your \$PATH:"
61+
echo
62+
echo " sdkmanager \"build-tools;35.0.0-rc3\""
63+
fi
64+
65+
dir_filename=$(basename "${dir}")
66+
tmp=$(mktemp -d -t "${dir_filename%.apk}_out_XXXXX")
67+
unzip "${dir}" lib/* -d "${tmp}" >/dev/null 2>&1
68+
dir="${tmp}"
69+
fi
70+
71+
if [[ "${dir}" == *.apex ]]; then
72+
trap 'cleanup_trap' EXIT
73+
74+
echo
75+
echo "Recursively analyzing $dir"
76+
echo
77+
78+
dir_filename=$(basename "${dir}")
79+
tmp=$(mktemp -d -t "${dir_filename%.apex}_out_XXXXX")
80+
deapexer extract "${dir}" "${tmp}" || { echo "Failed to deapex." && exit 1; }
81+
dir="${tmp}"
82+
fi
83+
84+
RED="\e[31m"
85+
GREEN="\e[32m"
86+
ENDCOLOR="\e[0m"
87+
88+
unaligned_libs=()
89+
90+
echo
91+
echo "=== ELF alignment ==="
92+
93+
matches="$(find "${dir}" -type f)"
94+
IFS=$'\n'
95+
for match in $matches; do
96+
# We could recursively call this script or rewrite it to though.
97+
[[ "${match}" == *".apk" ]] && echo "WARNING: doesn't recursively inspect .apk file: ${match}"
98+
[[ "${match}" == *".apex" ]] && echo "WARNING: doesn't recursively inspect .apex file: ${match}"
99+
100+
[[ $(file "${match}") == *"ELF"* ]] || continue
101+
102+
res="$(objdump -p "${match}" | grep LOAD | awk '{ print $NF }' | head -1)"
103+
if [[ $res =~ 2\*\*(1[4-9]|[2-9][0-9]|[1-9][0-9]{2,}) ]]; then
104+
echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"
105+
else
106+
echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"
107+
unaligned_libs+=("${match}")
108+
fi
109+
done
110+
111+
if [ ${#unaligned_libs[@]} -gt 0 ]; then
112+
echo -e "${RED}Found ${#unaligned_libs[@]} unaligned libs (only arm64-v8a/x86_64 libs need to be aligned).${ENDCOLOR}"
113+
elif [ -n "${dir_filename}" ]; then
114+
echo -e "ELF Verification Successful"
115+
fi
116+
echo "====================="

.github/workflows/tests_emulator.yml

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
# Refactor to make these dynamic with a low/high bracket only on schedule, not push
2828
# For now this is the latest supported API. Previously API 29 was fastest.
2929
# #13695: This was reverted to API 30, 31 was unstable. This should be fixed
30-
api-level: [30]
30+
api-level: [30, 35]
3131
arch: [x86_64]
3232
target: [google_apis]
3333
first-boot-delay: [600]
@@ -158,6 +158,38 @@ jobs:
158158
sleep 5
159159
./gradlew uninstallAll jacocoAndroidTestReport --daemon
160160
161+
- name: Verify Page Size
162+
if: matrix.target == 'google_apis_ps16k'
163+
run: |
164+
PAGE_SIZE=$(adb shell getconf PAGE_SIZE)
165+
echo "Page size: $PAGE_SIZE"
166+
if [ "$PAGE_SIZE" != "16384" ]; then
167+
echo "Error: Expected page size of 16384, got $PAGE_SIZE"
168+
exit 1
169+
fi
170+
171+
- name: Install NDK tools
172+
run: |
173+
echo "Installing NDK tools for alignment checking"
174+
yes | sdkmanager --install "ndk;27.2.12479018"
175+
echo "export PATH=$ANDROID_HOME/ndk/27.2.12479018/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH" >> $GITHUB_ENV
176+
177+
- name: Check APK ELF Alignment
178+
run: |
179+
chmod +x .github/check_elf_alignment.sh
180+
if [ ! -d "AnkiDroid/build/outputs/apk/" ]; then
181+
./gradlew :AnkiDroid:assemblePlayRelease --daemon
182+
fi
183+
APK_PATH="AnkiDroid/build/outputs/apk/play/release/AnkiDroid-play-arm64-v8a-release.apk"
184+
echo "Using APK: $APK_PATH"
185+
.github/check_elf_alignment.sh $APK_PATH
186+
187+
- name: Verify zipalign
188+
run: |
189+
APK_PATH="AnkiDroid/build/outputs/apk/play/release/AnkiDroid-play-arm64-v8a-release.apk"
190+
echo "Verifying zipalign with 16KB alignment for $APK_PATH"
191+
$ANDROID_HOME/build-tools/35.0.0/zipalign -c -P 16 -v 4 $APK_PATH || $ANDROID_HOME/build-tools/34.0.0/zipalign -c -P 16 -v 4 $APK_PATH
192+
161193
- name: Upload Test Report
162194
uses: actions/upload-artifact@v4
163195
if: always()

0 commit comments

Comments
 (0)