What is the path of OAT file in Android 7? - android

There is a similar question:
What is the path of OAT file in Android 5.0
But Android 7, in the same path:
/data/dalvik-cache/<ARCH>/
I can't find the user-installed app, but only the system ones.
Where can I find the oat file generated by the normal installation of an app?

I found the oat file generated by the normal installation of an app in:
/data/app/<PACKAGE_NAME>/oat/<ARCH>/base.odex
And I verified that is an oat file running (on my machine, not in Android) the command:
$ readelf -e base.odex
ELF Header:
Magic: 7f 45 4c 46 01 01 01 03 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - GNU
ABI Version: 0
Type: DYN (Shared object file)
Machine: ARM
Version: 0x1
Entry point address: 0x0
Start of program headers: 52 (bytes into file)
Start of section headers: 3928128 (bytes into file)
Flags: 0x5000000, Version5 EABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 7
Size of section headers: 40 (bytes)
Number of section headers: 9
Section header string table index: 8
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .rodata PROGBITS 00001000 001000 34f000 00 A 0 0 4096
[ 2] .text PROGBITS 00350000 350000 06c3f4 00 AX 0 0 4096
[ 3] .bss NOBITS 003bd000 000000 034604 00 A 0 0 4096
[ 4] .dynstr STRTAB 003f2000 3bd000 00003d 00 A 0 0 4096
[ 5] .dynsym DYNSYM 003f2040 3bd040 000060 10 A 4 0 4
[ 6] .hash HASH 003f20a0 3bd0a0 000024 04 A 5 0 4
[ 7] .dynamic DYNAMIC 003f3000 3be000 000038 08 A 4 0 4096
[ 8] .shstrtab STRTAB 00000000 3bf000 00003d 00 0 0 4096
...
because it contains the .rodata and .text headers as described in: http://newandroidbook.com/files/Andevcon-ART.pdf

Related

Android BLE Glucometer data parsing - Datetime

I am working on android app which is used to read sugar level from BLE device (Any Glocometer) whenever new data available. I am able to read data from device. Below is the HEX formatted data i received.
0B 04 00 E4 07 05 0E 0C 31 1D 4E 01 68 B0 F8 00 00
Field3: Date Time (54 bits): E4 07 05 0E 0C 31 1D
I am not able to get year from this data, value of E4 is 228 and what about 07
Other data is month, date, hour, minute, second
How to get year from the above datetime data. Any help
For me, it looks like it's 2020 May(or June) 14, 12:49:29. In a case like this wherein the document protocol is not available, we can do some guessing.
07E4 => 2020 - E4 is low byte and 07 is high byte - this is a common practice
05 => May - It's my guess that this is the month. The other numbers are more than 12. It can also be June if 00 represents January
0E => 14 - Since it follows after the month byte, I guess this is the day.
0C => 12 - It's my guess that this is the hour, 49 and 29 can never be the hour value
31 => 49 - minute
1D => 29 - second
This can be verified by getting the actual values in the glucometer and see if it matches to the parsed data.
This has a very detailed explanation on how to decode the data.
The data format is given at: https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.glucose_measurement.xml
Using this format, what I understood was if we convert your hex (
0B 04 00 E4 07 05 0E 0C 31 1D 4E 01 68 B0 F8 00 00
) to binary and then look at it byte by byte, we'll be able to decode the data. For eg. :
(Here I have prepended the binary 1011 with 0000)
Bytes
76543210 : Bit index (Remember Little Endian)
00001011 11 | 1 byte (Flag byte) | C1,C2,C5 are present
00000100 4 | 2 byte Sequence Number
00000000 0 | 4 + (0<<8) = 4 [Because Little Endian]
11100100 228 | 228 + (7<<8) = 228 + (1792) = 2020
00000111 7
00000101 5 | 1 byte | 5 = May
00001110 14 | 1 byte | 14 = Date
00001100 12 | 1 byte | 12 = Hour
00110001 49 | 1 byte | 49 = Minute
00011101 29 | 1 byte | 29 = seconds
01001110 78 | 2 byte | 78 + (1<<8) = 334 Time Offset
00000001 1
01101000 0.104 | Glucose reading in kg/l
10110000 | SFLOAT datatype of 2 bytes where first 12 bytes are mantissa and next 4 bits give exponent. Therefore 000001101000 = 104 | 1011 = -3. Thereby total value = 104 * 10^-3 = 0.104 kg/mol
11111000 | 2 Nibbles (values are 8 and 15)
00000000 0 | 7 6 5 4 3 2 1 0 Bit indexes
00000000 0 | 15 14 13 12 11 10 9 8 Bit indexes

Can not execute hexagon_graph_execution on hexagon-sim

I have followed the build_and_run_inception_hexagon.sh and generated the hexagon_graph_execution executable. Now instead of using a real device I would like to test inception model with hexagon-sim available at SDK 3.0. So there is no need to use adb push commands as the SDK can simulate HVX device with hexagon-sim.
I have put the run-time libraries and the inception model plus the image at the same folder. After execution It gives me this error:
~/Qualcomm/HEXAGON_Tools/7.2.12/Tools/bin/hexagon-sim ./hexagon_graph_execution "/home/aashouri/Qualcomm/Hexagon_SDK/3.0/test/common/inception"
Error: Unsupported machine type 0x0 in ELF image "./hexagon_graph_execution" - exiting.
Can anyone comment on this?
Hexagon-readelf:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: ARM
Version: 0x1
Entry point address: 0xc8c9c
Start of program headers: 52 (bytes into file)
Start of section headers: 39944896 (bytes into file)
Flags: 0x5000000, Version5 EABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 8
Size of section headers: 40 (bytes)
Number of section headers: 36
Section header string table index: 35
XXD info:
0000000: 7f45 4c46 0101 0100 0000 0000 0000 0000 .ELF............
0000010: 0300 2800 0100 0000 9c8c 0c00 3400 0000 ..(.........4...
0000020: c082 6102 0000 0005 3400 2000 0800 2800 ..a.....4. ...(.
0000030: 2400 2300 0600 0000 3400 0000 3400 0000 $.#.....4...4...
0000040: 3400 0000 0001 0000 0001 0000 0400 0000 4...............
0000050: 0400 0000 0300 0000 3401 0000 3401 0000 ........4...4...
0000060: 3401 0000 1300 0000 1300 0000 0400 0000 4...............
0000070: 0100 0000 0100 0000 0000 0000 0000 0000 ................
0000080: 0000 0000 ece6 2a01 ece6 2a01 0500 0000 ......*...*.....
0000090: 0010 0000 0100 0000 20eb 2a01 20fb 2a01 ........ .*. .*.
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: ARM
Version: 0x1
This binary was not built by hexagon-clang. You must have accidentally built it with the ARM toolchain -- the "Machine" field would say "Qualcomm Hexagon" if it had been built for the hexagon DSP.

android error dynamically loading libc++.so native library

I am trying to build a proof-of-concept android application which uses OpenSSH code to establish a SSH session with a server.
For that I am using android sources to build the required libraries and then pull them up to an AndroidStudio native project where everything should be packed and installed on the device.
However, one of the libraries (libc++.so) is failing to load dynamically on the device with the message "java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__register_atfork" referenced by "libc++.so"..."
This error is being thrown when loading libc++.so library from MainActivity java code (I am now loading one library at a time to be sure where it fails):
public class MainActivity extends AppCompatListActivity implements OnHostStatusChangedListener {
...................
static {
System.loadLibrary("dl");
System.loadLibrary("c");
System.loadLibrary("m");
System.loadLibrary("c++"); // <--- Error dlopen failed: cannot locate symbol "__register_atfork" referenced by "libc++.so
System.loadLibrary("ssh");
System.loadLibrary("vrx-native");
}
.............
}
My interpretation of the error message is that symbol __register_atfork required by libc++.so is not defined by any of the other libraries. But examining the libraries symbol tables I dont see why dlopen fails to recognize the symbol being defined on libc.so:
$readelf -s libc++.so
Symbol table '.dynsym' contains 2367 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
.....................
3: 00000000 0 FUNC GLOBAL DEFAULT UND __register_atfork#LIBC (2) <-- Undefined symbol reference
.....................
$readelf -s libc.so
Symbol table '.dynsym' contains 1505 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
.............
62: 00043509 120 FUNC GLOBAL DEFAULT 13 __register_atfork##LIBC
..............
7518: 00043509 120 FUNC GLOBAL DEFAULT 13 __register_atfork <-- symbol defined and exported by libc.so!!!
Examining the header and dynamic section of the libraries also does not provide any clue as to why this might be failing:
$ readelf -hd libc++.so
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: ARM
Version: 0x1
Entry point address: 0x0
Start of program headers: 52 (bytes into file)
Start of section headers: 573972 (bytes into file)
Flags: 0x5000200, Version5 EABI, soft-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 9
Size of section headers: 40 (bytes)
Number of section headers: 29
Section header string table index: 28
Dynamic section at offset 0x8abf8 contains 29 entries:
Tag Type Name/Value
0x00000003 (PLTGOT) 0x8dfe8
0x00000002 (PLTRELSZ) 8216 (bytes)
0x00000017 (JMPREL) 0x2d738
0x00000014 (PLTREL) REL
0x6000000f (Operating System specific: 6000000f) 0x2b280
0x60000010 (Operating System specific: 60000010) 0x24b8
0x00000013 (RELENT) 8 (bytes)
0x6ffffffa (RELCOUNT) 397
0x00000006 (SYMTAB) 0x21a0
0x0000000b (SYMENT) 16 (bytes)
0x00000005 (STRTAB) 0xb590
0x0000000a (STRSZ) 107756 (bytes)
0x00000004 (HASH) 0x25a7c
0x00000001 (NEEDED) Shared library: [libdl.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x0000000e (SONAME) Library soname: [libc++.so]
0x0000001a (FINI_ARRAY) 0x8b3c0
0x0000001c (FINI_ARRAYSZ) 4 (bytes)
0x00000019 (INIT_ARRAY) 0x8dbf4
0x0000001b (INIT_ARRAYSZ) 4 (bytes)
0x0000001e (FLAGS) BIND_NOW
0x6ffffffb (FLAGS_1) Flags: NOW
0x6ffffff0 (VERSYM) 0x29f94
0x6ffffffc (VERDEF) 0x2b214
0x6ffffffd (VERDEFNUM) 1
0x6ffffffe (VERNEED) 0x2b230
0x6fffffff (VERNEEDNUM) 2
0x00000000 (NULL) 0x0
$ readelf -hd libc.so
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: ARM
Version: 0x1
Entry point address: 0x0
Start of program headers: 52 (bytes into file)
Start of section headers: 757116 (bytes into file)
Flags: 0x5000200, Version5 EABI, soft-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 10
Size of section headers: 40 (bytes)
Number of section headers: 33
Section header string table index: 30
Dynamic section at offset 0x8232c contains 27 entries:
Tag Type Name/Value
0x00000003 (PLTGOT) 0x835bc
0x00000002 (PLTRELSZ) 5232 (bytes)
0x00000017 (JMPREL) 0x105c4
0x00000014 (PLTREL) REL
0x00000011 (REL) 0xd85c
0x00000012 (RELSZ) 11624 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffa (RELCOUNT) 1304
0x00000006 (SYMTAB) 0x1c0
0x0000000b (SYMENT) 16 (bytes)
0x00000005 (STRTAB) 0x5fd0
0x0000000a (STRSZ) 17483 (bytes)
0x00000004 (HASH) 0xa41c
0x00000001 (NEEDED) Shared library: [libdl.so]
0x0000000e (SONAME) Library soname: [libc.so]
0x00000019 (INIT_ARRAY) 0x83304
0x0000001b (INIT_ARRAYSZ) 36 (bytes)
0x0000001a (FINI_ARRAY) 0x83328
0x0000001c (FINI_ARRAYSZ) 4 (bytes)
0x0000001e (FLAGS) BIND_NOW
0x6ffffffb (FLAGS_1) Flags: NOW
0x6ffffff0 (VERSYM) 0xcbc4
0x6ffffffc (VERDEF) 0xd788
0x6ffffffd (VERDEFNUM) 5
0x6ffffffe (VERNEED) 0xd82c
0x6fffffff (VERNEEDNUM) 1
0x00000000 (NULL) 0x0
Any help appreciated
Update: Investigating the meaning of (2) on __register_atfork#LIBC (2)
Checking readelf sources we can see the (2) token is being printed from:
if (version_string)
{
if (sym_info == symbol_undefined)
printf ("#%s (%d)", version_string, vna_other);
else
printf (sym_info == symbol_hidden ? "#%s" : "##%s",
version_string);
}
vna_other is being loaded from struct Elf32_External_Sym, member st_other...
typedef struct {
unsigned char st_name[4]; /* Symbol name, index in string tbl */
unsigned char st_value[4]; /* Value of the symbol */
unsigned char st_size[4]; /* Associated symbol size */
unsigned char st_info[1]; /* Type and binding attributes */
unsigned char st_other[1]; /* No defined meaning, 0 */
unsigned char st_shndx[2]; /* Associated section index */
} Elf32_External_Sym;
ELF specification states (on page 32):
st_other This member currently holds 0 and has no defined meaning.
Maybe this has some special meaning on ARM? No, this document does not define anything arm-specific for st_other...
Update: Investigating the meaning of st_other in the ELF file definition
Found this post titled Request to extend symbol visibilities (st_other)
Symbol visibility is currently represented by the least significant 2 bits of a symbol's st_other field.
The post mentions the visibility attributes that currently goes into st_other...
#define STV_DEFAULT 0
#define STV_INTERNAL 1
#define STV_HIDDEN 2
#define STV_PROTECTED 3
...and proposes two new visibility attributes...
#define STV_SINGLETON 4
#define STV_ELIMINATE 5
It seems (2) on readelf symbol table output corresponds to STV_HIDDEN attribute on the symbol st_other member...

Android editing ubi/ubfs system image

I have a ubifs system image (https://www.dropbox.com/s/txgye8mu5r3og5y/system.img?dl=0) for a mediatek tablet device and am trying to add and remove some files.
I'm stuck trying to mount/extract files from the image.
Here are the steps I have tried so far on Debian Jessie with kernel 4.1.0-0.bpo.2-amd64:
I tried:
https://github.com/jrspruitt/ubi_reader
$ ubireader_display_info ./system.img
UBI File
---------------------
Min I/O: 16384
LEB Size: 4161536
PEB Size: 4194304
Total Block Count: 122
Data Block Count: 120
Layout Block Count: 2
Internal Volume Block Count: 0
Unknown Block Count: 0
First UBI PEB Number: 0
Image: 1101756791
---------------------
Image Sequence Num: 1101756791
Volume Name:system
PEB Range: 0 - 121
Volume: system
---------------------
Vol ID: 0
Name: system
Block Count: 120
Volume Record
---------------------
alignment: 1
crc: 3336263623
data_pad: 0
errors:
flags: autoresize
name: system
name_len: 6
padding:
rec_index: 0
reserved_pebs: 248
upd_marker: 0
vol_type: dynamic
But when I try and extract files using ubireader_extract_files I get the correct number of files but the resulting files are garbage.
Next I dismantled the tablet to work out what nand flash it was using to try and use nandsim following this post:
https://web.archive.org/web/20150109021228/http://www.linux-mtd.infradead.org/faq/ubifs.html#L_ubifs_extract
to emulate the nand and found out it was using SanDisk SDTNRGAMA 64G 3.3V 8-bit which has id bytes of 0x45,0xde,0x94,0x93,0x76,0x50 - from the following post:
http://lists.infradead.org/pipermail/linux-mtd/2014-January/051330.html
Running the following causes a segfault - on earlier kernels the id_bytes option is not recognized:
`modprobe nandsim id_bytes=0x45,0xde,0x94,0x93,0x76,0x50 cache_file=./test.img`
which gives the following segfault:
[ 142.734637] [nandsim] warning: read_byte: unexpected data output cycle, state is STATE_READY return 0x0
[ 142.734637] [nandsim] warning: read_byte: unexpected data output cycle, state is STATE_READY return 0x0
[ 142.734640] nand: device found, Manufacturer ID: 0x45, Chip ID: 0xde
[ 142.734641] nand: SanDisk SDTNRGAMA 64G 3.3V 8-bit
[ 142.734644] nand: 8192 MiB, MLC, erase size: 4096 KiB, page size: 16384, OOB size: 1280
[ 142.734650] nand: No oob scheme defined for oobsize 1280
[ 142.734672] ------------[ cut here ]------------
[ 142.734674] kernel BUG at /build/linux-PoJsUp/linux-4.1.6/drivers/mtd/nand/nand_base.c:3952!
[ 142.734677] invalid opcode: 0000 [#1] SMP
[ 142.734680] Modules linked in: nandsim(+) nand nand_ecc nand_bch bch nand_ids mtd cfg80211 rfkill joydev nfsd auth_rpcgss oid_registry nfs_acl nfs lockd grace fscache sunrpc iosf_mbi coretemp crct10dif_pclmul crc32_pclmul ghash_clmulni_intel aesni_intel hid_generic aes_x86_64 lrw irda gf128mul glue_helper psmouse vmw_balloon crc_ccitt ablk_helper serio_raw vmw_vmci cryptd battery pcspkr 8250_fintek acpi_cpufreq processor thermal_sys ac shpchp evdev i2c_piix4 fuse parport_pc ppdev lp parport autofs4 usbhid hid ext4 crc16 mbcache jbd2 sr_mod cdrom ata_generic sg sd_mod crc32c_intel ata_piix uhci_hcd ehci_pci ehci_hcd usbcore e1000 usb_common button libata vmwgfx ttm mptspi scsi_transport_spi mptscsih drm_kms_helper mptbase scsi_mod drm
[ 142.734731] CPU: 0 PID: 1235 Comm: modprobe Not tainted 4.1.0-0.bpo.2-amd64 #1 Debian 4.1.6-1~bpo8+1
[ 142.734733] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 09/20/2012
[ 142.734735] task: ffff88007aaf54f0 ti: ffff880079134000 task.ti: ffff880079134000
[ 142.734737] RIP: 0010:[<ffffffffa05d5ff0>] [<ffffffffa05d5ff0>] nand_scan_tail+0xa40/0xac0 [nand]
[ 142.734743] RSP: 0018:ffff880079137c58 EFLAGS: 00010296
[ 142.734745] RAX: 000000000000002c RBX: ffff880077093450 RCX: 0000000000000006
[ 142.734746] RDX: 000000000000002c RSI: 0000000000000246 RDI: ffff88007f60ea10
[ 142.734748] RBP: ffff880077093000 R08: 00000000000094d8 R09: 00000000000044aa
[ 142.734750] R10: 0000000000000086 R11: 20726f662064656e R12: ffff880077093860
[ 142.734751] R13: 0000000000000000 R14: ffffffffa05ec200 R15: ffff88007b67ad40
[ 142.734754] FS: 00007fe945772700(0000) GS:ffff88007f600000(0000) knlGS:0000000000000000
[ 142.734756] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 142.734757] CR2: 00007f57a6920040 CR3: 00000000790fa000 CR4: 00000000000406f0
[ 142.734870] Stack:
[ 142.734873] 0000000000000000 0000000000000000 ffff880077093000 ffffffffa05ef54a
[ 142.734877] 0000000000000000 0000000000000018 ffff880079137cd8 ffff880079137c98
[ 142.734879] 0000000000000000 ffffffff81814080 ffff880077211760 ffffffffa05ef000
[ 142.734882] Call Trace:
[ 142.734889] [<ffffffffa05ef54a>] ? ns_init_module+0x54a/0x1000 [nandsim]
[ 142.734896] [<ffffffffa05ef000>] ? 0xffffffffa05ef000
[ 142.734902] [<ffffffff81002148>] ? do_one_initcall+0xd8/0x210
[ 142.734907] [<ffffffff815723c1>] ? do_init_module+0x5a/0x1c2
[ 142.734912] [<ffffffff810f2316>] ? load_module+0x2026/0x24e0
[ 142.734915] [<ffffffff810ede60>] ? store_uevent+0x40/0x40
[ 142.734919] [<ffffffff810ee9d5>] ? copy_module_from_fd.isra.45+0xb5/0x140
[ 142.734923] [<ffffffff810f299d>] ? SyS_finit_module+0x7d/0xa0
[ 142.734928] [<ffffffff815792b2>] ? system_call_fast_compare_end+0xc/0x6b
[ 142.734930] Code: 00 00 30 10 5d a0 e9 f8 f6 ff ff 48 c7 83 88 03 00 00 30 19 5d a0 e9 3c f7 ff ff 89 c6 48 c7 c7 b8 9c 5d a0 31 c0 e8 33 c2 f9 e0 <0f> 0b 48 c7 83 40 03 00 00 40 bb 5d a0 e9 14 f6 ff ff 48 c7 83
[ 142.734959] RIP [<ffffffffa05d5ff0>] nand_scan_tail+0xa40/0xac0 [nand]
[ 142.734964] RSP <ffff880079137c58>
[ 142.734975] ---[ end trace 0270ba33a10a2b05 ]---
So, in short - I need help. I'm not massively familiar with ubi/ubifs method and cannot find any sane well written guides which show you have to mount/extract files from an existing image.
Update: su is installed on the tablet, and I set selinux to permissive mode:
adb shell su -c setenforce 0
from: https://source.android.com/devices/tech/security/selinux/validate.html
Update 03Oct15:
Ran the mdtinfo -a on the tablet and got the following result:
mtd16
Name: system
Type: nand
Eraseblock size: 4194304 bytes, 4.0 MiB
Amount of eraseblocks: 256 (1073741824 bytes, 1024.0 MiB)
Minimum input/output unit size: 16384 bytes
Sub-page size: 16384 bytes
OOB size: 1280 bytes
Character device major/minor: 90:32
Bad blocks are allowed: true
Device is writable: true
Using the information above I tried to create a blank ubifs image on my pc, I get the error that the LEB is too large! Looks like I have a limit of 2MiB on the LEB size!
$ mkfs.ubifs -m 16384 -e 4MiB -c 256 -o ./image.img
Error: too large LEB size 4194304
It looks like that ubi image is using a different compression type for the data. If you run ubireader_extract_files -v system.img the -v is for very verbose, the UBIFS data nodes have a compression type of 3 (compr_type: 3) as far as I know 1 and 2 are the only valid options, LZO and ZLIB respectively. Perhaps they used a custom compression, or somehow it got the wrong number associated with it. But it explains why the files and directories extract okay, but the data is scrambled.
Just in case someone else finds this post. I managed to find a workaround which involved editing the boot.img using mtk-tools to mount the root partition in rw mode rather than ro. (Look in init.rc in the root of boot.img and change any mount options for /system to rw).
I them managed to edit the root image, power down the tablet and then used MTK Droid Tools to image the partition.

Android NDK produce unreasonable big binaries, how to optimize .so size?

I have notice that Android NDK (r6b in my case) produce unreasonable big resulting .so files. For example, in my case I have ~150-200 lines of C++ code (6 native methods and 3 C++ simplest classes) and this native code produce 60kb (!) .so with enabled exceptions and RTTI or 12kb .so with disabled exceptions and RTTI. Just to check I have compile hello-jni example included in NDK package and get 10kb .so for single-line native method from this example.
In my opinion it is somehow unreasonable overhead for mobile platform (on my desktop the comparable by size code produce ~10-15 times less .so).
Are there tricks I should know to reduce the binaries size ?
Why there is such overhead for C-only code ?
And why there is even bigger overhead for C++ code with enabled exceptions and RTTI ?
Update #1: readelf output for hello-jni example from NDK
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: ARM
Version: 0x1
Entry point address: 0xc18
Start of program headers: 52 (bytes into file)
Start of section headers: 9344 (bytes into file)
Flags: 0x5000002, has entry point, Version5 EABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 5
Size of section headers: 40 (bytes)
Number of section headers: 19
Section header string table index: 18
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .hash HASH 000000d4 0000d4 0001a4 04 A 2 0 4
[ 2] .dynsym DYNSYM 00000278 000278 000420 10 A 3 3 4
[ 3] .dynstr STRTAB 00000698 000698 0004aa 00 A 0 0 1
[ 4] .rel.dyn REL 00000b44 000b44 000048 08 A 2 0 4
[ 5] .rel.plt REL 00000b8c 000b8c 000030 08 A 2 6 4
[ 6] .plt PROGBITS 00000bbc 000bbc 00005c 04 AX 0 0 4
[ 7] .text PROGBITS 00000c18 000c18 001518 00 AX 0 0 4
[ 8] .rodata PROGBITS 00002130 002130 000014 01 AMS 0 0 4
[ 9] .ARM.extab PROGBITS 00002144 002144 000024 00 A 0 0 4
[10] .ARM.exidx ARM_EXIDX 00002168 002168 0000e0 00 AL 7 0 4
[11] .init_array INIT_ARRAY 00003248 002248 000008 00 WA 0 0 1
[12] .fini_array FINI_ARRAY 00003250 002250 00000c 00 WA 0 0 1
[13] .dynamic DYNAMIC 0000325c 00225c 0000e8 08 WA 3 0 4
[14] .got PROGBITS 00003344 002344 000040 04 WA 0 0 4
[15] .bss NOBITS 00003390 002384 000010 00 WA 0 0 16
[16] .comment PROGBITS 00000000 002384 000036 00 0 0 1
[17] .ARM.attributes ARM_ATTRIBUTES 00000000 0023ba 000029 00 0 0 1
[18] .shstrtab STRTAB 00000000 0023e3 00009b 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
EXIDX 0x002168 0x00002168 0x00002168 0x000e0 0x000e0 R 0x4
LOAD 0x000000 0x00000000 0x00000000 0x02248 0x02248 R E 0x1000
LOAD 0x002248 0x00003248 0x00003248 0x0013c 0x00158 RW 0x1000
DYNAMIC 0x00225c 0x0000325c 0x0000325c 0x000e8 0x000e8 RW 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
Section to Segment mapping:
Segment Sections...
00 .ARM.exidx
01 .hash .dynsym .dynstr .rel.dyn .rel.plt .plt .text .rodata .ARM.extab .ARM.exidx
02 .init_array .fini_array .dynamic .got .bss
03 .dynamic
04
Dynamic section at offset 0x225c contains 25 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libstdc++.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x0000000e (SONAME) Library soname: [libhello-jni.so]
0x00000010 (SYMBOLIC) 0x0
0x00000019 (INIT_ARRAY) 0x3248
0x0000001b (INIT_ARRAYSZ) 8 (bytes)
0x0000001a (FINI_ARRAY) 0x3250
0x0000001c (FINI_ARRAYSZ) 12 (bytes)
0x00000004 (HASH) 0xd4
0x00000005 (STRTAB) 0x698
0x00000006 (SYMTAB) 0x278
0x0000000a (STRSZ) 1194 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000003 (PLTGOT) 0x3344
0x00000002 (PLTRELSZ) 48 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0xb8c
0x00000011 (REL) 0xb44
0x00000012 (RELSZ) 72 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x00000016 (TEXTREL) 0x0
0x6ffffffa (RELCOUNT) 7
0x00000000 (NULL) 0x0
Relocation section '.rel.dyn' at offset 0xb44 contains 9 entries:
Offset Info Type Sym.Value Sym. Name
00000c24 00000017 R_ARM_RELATIVE
00003254 00000017 R_ARM_RELATIVE
00003368 00000017 R_ARM_RELATIVE
0000336c 00000017 R_ARM_RELATIVE
00003374 00000017 R_ARM_RELATIVE
00003378 00000017 R_ARM_RELATIVE
00003380 00000017 R_ARM_RELATIVE
00003370 00001015 R_ARM_GLOB_DAT 00000000 __cxa_call_unexpected
0000337c 00003215 R_ARM_GLOB_DAT 00000000 __gnu_Unwind_Find_exid
Relocation section '.rel.plt' at offset 0xb8c contains 6 entries:
Offset Info Type Sym.Value Sym. Name
00003350 00000d16 R_ARM_JUMP_SLOT 00000000 __cxa_begin_cleanup
00003354 00001216 R_ARM_JUMP_SLOT 00000000 memcpy
00003358 00001416 R_ARM_JUMP_SLOT 00000000 __cxa_finalize
0000335c 00001f16 R_ARM_JUMP_SLOT 00000000 abort
00003360 00002a16 R_ARM_JUMP_SLOT 00000000 __cxa_type_match
00003364 00003216 R_ARM_JUMP_SLOT 00000000 __gnu_Unwind_Find_exid
There are no unwind sections in this file.
Symbol table '.dynsym' contains 66 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000c18 0 SECTION LOCAL DEFAULT 7
2: 00003390 0 SECTION LOCAL DEFAULT 15
3: 00001c64 36 FUNC GLOBAL DEFAULT 7 ___Unwind_ForcedUnwind
4: 00001668 164 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_RaiseExcepti
5: 00001b20 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Save_VFP
6: 00001c40 36 FUNC GLOBAL DEFAULT 7 _Unwind_Resume_or_Rethrow
7: 00002248 0 NOTYPE GLOBAL DEFAULT ABS __exidx_end
8: 000011c0 8 FUNC GLOBAL DEFAULT 7 __aeabi_unwind_cpp_pr0
9: 00001d4c 44 FUNC GLOBAL DEFAULT 7 _Unwind_GetRegionStart
10: 00001c40 36 FUNC GLOBAL DEFAULT 7 ___Unwind_Resume_or_Rethr
11: 000033a0 0 NOTYPE GLOBAL DEFAULT ABS _bss_end__
12: 00001c88 36 FUNC GLOBAL DEFAULT 7 _Unwind_Backtrace
13: 00000000 0 NOTYPE WEAK DEFAULT UND __cxa_begin_cleanup
14: 00001b04 20 FUNC GLOBAL DEFAULT 7 __restore_core_regs
15: 00001b40 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Save_VFP_D_1
16: 00000000 0 NOTYPE WEAK DEFAULT UND __cxa_call_unexpected
17: 00000cf0 8 FUNC GLOBAL DEFAULT 7 _Unwind_GetCFA
18: 00000000 0 FUNC GLOBAL DEFAULT UND memcpy
19: 00000c8c 76 FUNC GLOBAL DEFAULT 7 _Unwind_VRS_Set
20: 00000000 0 FUNC GLOBAL DEFAULT UND __cxa_finalize
21: 00003250 0 NOTYPE GLOBAL DEFAULT 12 __FINI_ARRAY__
22: 00003384 0 NOTYPE GLOBAL DEFAULT ABS __bss_start__
23: 00001404 212 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Backtrace
24: 00003390 4 OBJECT GLOBAL DEFAULT 15 __dso_handle
25: 00001b30 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Save_VFP_D
26: 00001798 876 FUNC GLOBAL DEFAULT 7 _Unwind_VRS_Pop
27: 000011b0 8 FUNC WEAK DEFAULT 7 __aeabi_unwind_cpp_pr2
28: 00001c88 36 FUNC GLOBAL DEFAULT 7 ___Unwind_Backtrace
29: 00002168 0 NOTYPE GLOBAL DEFAULT ABS __exidx_start
30: 00001bf8 36 FUNC GLOBAL DEFAULT 7 ___Unwind_RaiseException
31: 00000000 0 FUNC GLOBAL DEFAULT UND abort
32: 00001c1c 36 FUNC GLOBAL DEFAULT 7 ___Unwind_Resume
33: 00001b48 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Restore_WMMX
34: 00001b18 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Restore_VFP
35: 00001c1c 36 FUNC GLOBAL DEFAULT 7 _Unwind_Resume
36: 00000cfc 32 FUNC GLOBAL DEFAULT 7 _Unwind_DeleteException
37: 00000cf8 4 FUNC GLOBAL DEFAULT 7 _Unwind_Complete
38: 000033a0 0 NOTYPE GLOBAL DEFAULT ABS __bss_end__
39: 00003248 0 NOTYPE GLOBAL DEFAULT 11 __INIT_ARRAY__
40: 00001d78 888 FUNC GLOBAL DEFAULT 7 __gnu_unwind_execute
41: 00001b28 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Restore_VFP_
42: 00000000 0 NOTYPE WEAK DEFAULT UND __cxa_type_match
43: 0000172c 108 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Resume
44: 00001b38 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Restore_VFP_
45: 00001bf8 36 FUNC GLOBAL DEFAULT 7 _Unwind_RaiseException
46: 00003384 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
47: 000033a0 0 NOTYPE GLOBAL DEFAULT ABS __end__
48: 000015f4 28 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_ForcedUnwind
49: 0000170c 32 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Resume_or_Re
50: 00000000 0 FUNC WEAK DEFAULT UND __gnu_Unwind_Find_exidx
51: 00001b04 20 FUNC GLOBAL DEFAULT 7 restore_core_regs
52: 00001be4 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Save_WMMXC
53: 00001d04 8 FUNC GLOBAL DEFAULT 7 _Unwind_GetTextRelBase
54: 00000c29 24 FUNC GLOBAL DEFAULT 7 Java_com_example_hellojni
55: 00001d14 56 FUNC GLOBAL DEFAULT 7 _Unwind_GetLanguageSpecif
56: 00000c40 76 FUNC GLOBAL DEFAULT 7 _Unwind_VRS_Get
57: 00001bd0 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Restore_WMMX
58: 000020f0 64 FUNC GLOBAL DEFAULT 7 __gnu_unwind_frame
59: 00001c64 36 FUNC GLOBAL DEFAULT 7 _Unwind_ForcedUnwind
60: 00003384 0 NOTYPE GLOBAL DEFAULT ABS _edata
61: 000033a0 0 NOTYPE GLOBAL DEFAULT ABS _end
62: 00001b8c 0 FUNC GLOBAL DEFAULT 7 __gnu_Unwind_Save_WMMXD
63: 000011b8 8 FUNC WEAK DEFAULT 7 __aeabi_unwind_cpp_pr1
64: 00001d0c 8 FUNC GLOBAL DEFAULT 7 _Unwind_GetDataRelBase
65: 00003384 0 NOTYPE GLOBAL DEFAULT 14 __data_start
Histogram for bucket list length (total of 37 buckets):
Length Number % of total Coverage
0 5 ( 13.5%)
1 14 ( 37.8%) 22.2%
2 9 ( 24.3%) 50.8%
3 6 ( 16.2%) 79.4%
4 2 ( 5.4%) 92.1%
5 1 ( 2.7%) 100.0%
No version information found in this file.
Attribute Section: aeabi
File Attributes
Tag_CPU_name: "5TE"
Tag_CPU_arch: v5TE
Tag_ARM_ISA_use: Yes
Tag_THUMB_ISA_use: Thumb-1
Tag_ABI_PCS_wchar_t: 4
Tag_ABI_FP_denormal: Needed
Tag_ABI_FP_exceptions: Needed
Tag_ABI_FP_number_model: IEEE 754
Tag_ABI_align8_needed: Yes
Tag_ABI_align8_preserved: Yes, except leaf SP
Tag_ABI_enum_size: int
You may see the difference from one provided by #Joel F, and especially stuff about stack unwinding (for C++ exceptions ?)
Update #2
The problem is in toolchain included in NDK r6b and in particular it is about of linker. Thanks to #Joel F for glues about previous NDK release. I have installed the NDK r5c alongside of NDK r6b and compare results. Compilers produce the same object files by both toolchains but after linking results are different.
EDIT 3
I was able to reproduce the 10KB hello-jni binary with NDK r6b. I found an awful hack here. Basically put this line in one of your files:
char __aeabi_unwind_cpp_pr0[0];
But your code will be lacking exception handling (which I thought was the point of -fno-exceptions....)
Anyways, this brings libhello-jni.so down to 2228 bytes for me. Still larger than r5c, but a lot less than 10KB.
EDIT 2
Yes it seems like you have a lot of C++ related overhead in your readelf output. Perhaps they changed something between r5c and r6b? There is no C++ code in r5c's hello-jni.c.
I have 160 lines of C code that NDK r5c reduces to a 3.8KB .so. Try the following to see what is responsible for the size:
/path/to/ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/<platform>/bin/arm-linux-androideabi-readelf -a libmylib.so
EDIT
I built the hello-jni example with NDK r5c and the resulting libhello-jni.so file is 1588 bytes.
Build command:
ndk-build V=1
Build output: http://pastebin.com/AdRDVbnF (apparently SO has limits on line length or something).
Output from readelf -a libhello-jni.so:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: ARM
Version: 0x1
Entry point address: 0x2dc
Start of program headers: 52 (bytes into file)
Start of section headers: 1108 (bytes into file)
Flags: 0x5000002, has entry point, Version5 EABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 5
Size of section headers: 40 (bytes)
Number of section headers: 12
Section header string table index: 11
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .hash HASH 000000d4 0000d4 00004c 04 A 2 0 4
[ 2] .dynsym DYNSYM 00000120 000120 0000e0 10 A 3 2 4
[ 3] .dynstr STRTAB 00000200 000200 0000db 00 A 0 0 1
[ 4] .text PROGBITS 000002dc 0002dc 00002c 00 AX 0 0 4
[ 5] .rodata PROGBITS 00000308 000308 000014 00 A 0 0 4
[ 6] .ARM.exidx ARM_EXIDX 0000031c 00031c 000008 00 AL 4 0 4
[ 7] .dynamic DYNAMIC 00001324 000324 000088 08 WA 3 0 4
[ 8] .got PROGBITS 000013ac 0003ac 00000c 04 WA 0 0 4
[ 9] .comment PROGBITS 00000000 0003b8 000012 00 0 0 1
[10] .ARM.attributes ARM_ATTRIBUTES 00000000 0003ca 000029 00 0 0 1
[11] .shstrtab STRTAB 00000000 0003f3 000061 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
EXIDX 0x00031c 0x0000031c 0x0000031c 0x00008 0x00008 R 0x4
LOAD 0x000000 0x00000000 0x00000000 0x00324 0x00324 R E 0x1000
LOAD 0x000324 0x00001324 0x00001324 0x00094 0x00094 RW 0x1000
DYNAMIC 0x000324 0x00001324 0x00001324 0x00088 0x00088 RW 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
Section to Segment mapping:
Segment Sections...
00 .ARM.exidx
01 .hash .dynsym .dynstr .text .rodata .ARM.exidx
02 .dynamic .got
03 .dynamic
04
Dynamic section at offset 0x324 contains 12 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libstdc++.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x0000000e (SONAME) Library soname: [libhello-jni.so]
0x00000010 (SYMBOLIC) 0x0
0x00000004 (HASH) 0xd4
0x00000005 (STRTAB) 0x200
0x00000006 (SYMTAB) 0x120
0x0000000a (STRSZ) 219 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000000 (NULL) 0x0
There are no relocations in this file.
There are no unwind sections in this file.
Symbol table '.dynsym' contains 14 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 000002dc 0 SECTION LOCAL DEFAULT 4
2: 00000324 0 NOTYPE GLOBAL DEFAULT ABS __exidx_end
3: 00000000 0 FUNC GLOBAL DEFAULT UND __aeabi_unwind_cpp_pr0
4: 000013b8 0 NOTYPE GLOBAL DEFAULT ABS _bss_end__
5: 000013b8 0 NOTYPE GLOBAL DEFAULT ABS __bss_start__
6: 0000031c 0 NOTYPE GLOBAL DEFAULT ABS __exidx_start
7: 000013b8 0 NOTYPE GLOBAL DEFAULT ABS __bss_end__
8: 000013b8 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
9: 000013b8 0 NOTYPE GLOBAL DEFAULT ABS __end__
10: 000002dd 44 FUNC GLOBAL DEFAULT 4 Java_com_example_hellojni
11: 000013b8 0 NOTYPE GLOBAL DEFAULT ABS _edata
12: 000013b8 0 NOTYPE GLOBAL DEFAULT ABS _end
13: 000013b8 0 NOTYPE GLOBAL DEFAULT 8 __data_start
Histogram for bucket list length (total of 3 buckets):
Length Number % of total Coverage
0 0 ( 0.0%)
1 0 ( 0.0%) 0.0%
2 1 ( 33.3%) 16.7%
3 0 ( 0.0%) 16.7%
4 1 ( 33.3%) 50.0%
5 0 ( 0.0%) 50.0%
6 1 ( 33.3%) 100.0%
No version information found in this file.
Attribute Section: aeabi
File Attributes
Tag_CPU_name: "5TE"
Tag_CPU_arch: v5TE
Tag_THUMB_ISA_use: Thumb-1
Tag_ABI_PCS_wchar_t: 4
Tag_ABI_FP_denormal: Needed
Tag_ABI_FP_exceptions: Needed
Tag_ABI_FP_number_model: IEEE 754
Tag_ABI_align8_needed: Yes
Tag_ABI_align8_preserved: Yes, except leaf SP
Tag_ABI_enum_size: int
Tag_ABI_optimization_goals: Aggressive Debug
The NDK toolchain supports C++ exceptions, since NDK r5, however all C++ sources are compiled with -fno-exceptions support by default, for compatibility reasons with previous releases.
To enable it, use the '-fexceptions' C++ compiler flag. This can be done by adding the following to every module definition in your Android.mk:
LOCAL_CPPFLAGS += -fexceptions
More simply, add a single line to your Application.mk, the setting will automatically apply to all your project's NDK modules:
APP_CPPFLAGS += -fexceptions
follow this page
But in NDK r6b, this FLAG is open by default, and can not close.
Don't use c++ exceptions if you want to have a lightweight mobile program. There's a reason c++ features were limited in early versions of the ndk. Android itself uses the subset of c++ that was thought cost effective on a mobile platform, and thats more or less what was originally supported.
Also be sure you are not doing a debug build with symbols included - that could be your hello-jni bloat.

Categories

Resources