From 924a6837609359d09076391fa363fdcf3c8544bd Mon Sep 17 00:00:00 2001 From: Alex Klyubin Date: Wed, 2 Dec 2015 19:02:01 -0800 Subject: [PATCH] Make signapk align .so entries to 4096 bytes. This makes signapk align uncompressed .so entries to memory page boundary (4096 bytes) to enable such libraries to be loaded at runtime through memory-mapping the APK. With this change in place, there should no longer be a need to run zipalign after (or before) signapk. Bug: 25794543 Change-Id: I74775af15a683791f57fcbd3497a79951b3f63a1 --- tools/signapk/SignApk.java | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tools/signapk/SignApk.java b/tools/signapk/SignApk.java index 740a34354..397f8cca5 100644 --- a/tools/signapk/SignApk.java +++ b/tools/signapk/SignApk.java @@ -476,7 +476,7 @@ class SignApk { * more efficient. */ private static void copyFiles(Manifest manifest, JarFile in, JarOutputStream out, - long timestamp, int alignment) throws IOException { + long timestamp, int defaultAlignment) throws IOException { byte[] buffer = new byte[4096]; int num; @@ -515,6 +515,7 @@ class SignApk { offset += 4; firstEntry = false; } + int alignment = getStoredEntryDataAlignment(name, defaultAlignment); if (alignment > 0 && (offset % alignment != 0)) { // Set the "extra data" of the entry to between 1 and // alignment-1 bytes, to make the file data begin at @@ -555,6 +556,24 @@ class SignApk { } } + /** + * Returns the multiple (in bytes) at which the provided {@code STORED} entry's data must start + * relative to start of file or {@code 0} if alignment of this entry's data is not important. + */ + private static int getStoredEntryDataAlignment(String entryName, int defaultAlignment) { + if (defaultAlignment <= 0) { + return 0; + } + + if (entryName.endsWith(".so")) { + // Align .so contents to memory page boundary to enable memory-mapped + // execution. + return 4096; + } else { + return defaultAlignment; + } + } + private static class WholeFileSignerOutputStream extends FilterOutputStream { private boolean closing = false; private ByteArrayOutputStream footer = new ByteArrayOutputStream();