Punch holes in 64 bit native libs
Extra padding at the end of LOAD segments is being introduced when libraries are being
aligned to 64KB. This increases space used by shared libraries.
This change deallocates space used by zero padding at the end of LOAD segments in given
uncompressed ELF file. Zero padding can be detected by reading ELF headers. Executable header
gives out the position of program headers. LOAD segments can be identified from program headers.
FileSiz specifies the size of the data in corresponding LOAD segment.
Ex. ELF header format for libpunchtest.so
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000000040 0x0000000000000040 0x0001f8 0x0001f8 R 0x8
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0003e8 0x0003e8 R 0x10000
LOAD 0x010000 0x0000000000010000 0x0000000000010000 0x000050 0x000050 R E 0x10000
LOAD 0x020000 0x0000000000020000 0x0000000000020000 0x0001b8 0x0001b8 RW 0x10000
DYNAMIC 0x020018 0x0000000000020018 0x0000000000020018 0x000180 0x000180 RW 0x8
GNU_RELRO 0x020000 0x0000000000020000 0x0000000000020000 0x0001b8 0x001000 R 0x1
GNU_EH_FRAME 0x000368 0x0000000000000368 0x0000000000000368 0x000024 0x000024 R 0x4
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0
NOTE 0x000238 0x0000000000000238 0x0000000000000238 0x000050 0x000050 R 0x4
Zero padding can be found as :
Padding Length = Offset of LOAD SEGMENT 2 - (Offset of LOAD SEGMENT 1 + FileSiz of LOAD SEGMENT 1)
This padding is present at position = (Offset of LOAD SEGMENT 1 + FileSiz of LOAD SEGMENT 1)
[fallocate(2)](http://man7.org/linux/man-pages/man2/fallocate.2.html) is used to deallocate the
zero ranges at the end of LOAD segments. It is called with above padding length and position.
If ELF file is present inside of ApK/Zip file, offset to the start of the ELF file should be added
to the position.
From test logs, stats for installation embedded_native_libs_test_app.apk. Note: ELF was 64bit aligned during tests.
Size before punching holes st_blocks: 2072, st_blksize: 4096, st_size: 1058429
Size after punching holes st_blocks: 1832, st_blksize: 4096, st_size: 1058429
Punching will be skipped for content which is less than 4096 bytes in
size.
Test: acloud delete --all && m && acloud create --local-instance --local-image && adb logcat -c && m FileSystemUtilsTests && atest -c FileSystemUtilsTests
Bug: 301631861
Change-Id: I86060f877f90e98c103e884cf6d303f0bdfa4d12
3 files changed