zipalign: Allow specifiying the target page size

Allow apps to specify the target page size for aligning their
uncompressed shared libraries.

This allows apps that want to support larger page sizes to do
so by specifiying the -P <pagesize_kb> flag.

However, apps built for 4k-only devices are unaffected as they
can continue to use -p flag for 4kB page alignment of uncompressed
shared libraries.

Bug: 276963821
Test: atest -c zipalign_tests
Change-Id: I890db067b8f898045f73e86788662f94a48af772
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
This commit is contained in:
Kalesh Singh
2023-08-17 09:44:45 -07:00
parent 7e0aa04637
commit 55405b61be
6 changed files with 139 additions and 36 deletions

View File

@@ -34,15 +34,18 @@ void usage(void)
fprintf(stderr, "Zip alignment utility\n");
fprintf(stderr, "Copyright (C) 2009 The Android Open Source Project\n\n");
fprintf(stderr,
"Usage: zipalign [-f] [-p] [-v] [-z] <align> infile.zip outfile.zip\n"
" zipalign -c [-p] [-v] <align> infile.zip\n\n" );
"Usage: zipalign [-f] [-p] [-P <pagesize_kb>] [-v] [-z] <align> infile.zip outfile.zip\n"
" zipalign -c [-p] [-P <pagesize_kb>] [-v] <align> infile.zip\n\n" );
fprintf(stderr,
" <align>: alignment in bytes, e.g. '4' provides 32-bit alignment\n");
fprintf(stderr, " -c: check alignment only (does not modify file)\n");
fprintf(stderr, " -f: overwrite existing outfile.zip\n");
fprintf(stderr, " -p: page-align uncompressed .so files\n");
fprintf(stderr, " -p: 4kb page-align uncompressed .so files\n");
fprintf(stderr, " -v: verbose output\n");
fprintf(stderr, " -z: recompress using Zopfli\n");
fprintf(stderr, " -P <pagesize_kb>: Align uncompressed .so files to the specified\n");
fprintf(stderr, " page size. Valid values for <pagesize_kb> are 4, 16\n");
fprintf(stderr, " and 64. '-P' cannot be used in combination with '-p'.\n");
}
@@ -57,12 +60,16 @@ int main(int argc, char* const argv[])
bool verbose = false;
bool zopfli = false;
bool pageAlignSharedLibs = false;
int pageSize = 4096;
bool legacyPageAlignmentFlag = false; // -p
bool pageAlignmentFlag = false; // -P <pagesize_kb>
int result = 1;
int alignment;
char* endp;
int opt;
while ((opt = getopt(argc, argv, "fcpvz")) != -1) {
while ((opt = getopt(argc, argv, "fcpvzP:")) != -1) {
switch (opt) {
case 'c':
check = true;
@@ -77,7 +84,29 @@ int main(int argc, char* const argv[])
zopfli = true;
break;
case 'p':
legacyPageAlignmentFlag = true;
pageAlignSharedLibs = true;
pageSize = 4096;
break;
case 'P':
pageAlignmentFlag = true;
pageAlignSharedLibs = true;
if (!optarg) {
fprintf(stderr, "ERROR: -P requires an argument\n");
wantUsage = true;
goto bail;
}
pageSize = atoi(optarg);
if (pageSize != 4 && pageSize != 16 && pageSize != 64) {
fprintf(stderr, "ERROR: Invalid argument for -P: %s\n", optarg);
wantUsage = true;
goto bail;
}
pageSize *= 1024; // Convert from kB to bytes.
break;
default:
fprintf(stderr, "ERROR: unknown flag -%c\n", opt);
@@ -86,6 +115,13 @@ int main(int argc, char* const argv[])
}
}
if (legacyPageAlignmentFlag && pageAlignmentFlag) {
fprintf(stderr, "ERROR: Invalid options: '-P <pagesize_kb>' and '-p'"
"cannot be used in combination.\n");
wantUsage = true;
goto bail;
}
if (!((check && (argc - optind) == 2) || (!check && (argc - optind) == 3))) {
wantUsage = true;
goto bail;
@@ -100,14 +136,15 @@ int main(int argc, char* const argv[])
if (check) {
/* check existing archive for correct alignment */
result = verify(argv[optind + 1], alignment, verbose, pageAlignSharedLibs);
result = verify(argv[optind + 1], alignment, verbose, pageAlignSharedLibs, pageSize);
} else {
/* create the new archive */
result = process(argv[optind + 1], argv[optind + 2], alignment, force, zopfli, pageAlignSharedLibs);
result = process(argv[optind + 1], argv[optind + 2], alignment, force, zopfli,
pageAlignSharedLibs, pageSize);
/* trust, but verify */
if (result == 0) {
result = verify(argv[optind + 2], alignment, verbose, pageAlignSharedLibs);
result = verify(argv[optind + 2], alignment, verbose, pageAlignSharedLibs, pageSize);
}
}