How to Create Android’s libc.so

In the course of troubleshooting some problems found in Android’s emulator environment, I’ve came across on one of the tasks, which is to create Android’s libc.so.

Since it will involved many issues if I tried it to compile libc.so in linux box, I decided to use windows environment and the NDK. This is to test some limits that will be found in this environment and whether it is possible to resolve the issues found in manual method.

libc.so or libc.a is the results of compiling Android bionic’s framework. It is build using Android build system. By combining the build system with my existing NDK, I almost reached the final phase, but I encounter the libc_common.a issue.

Maybe this works in linux environment, but it breaks on windows environment. Here, it causes libc_common.a to be incomplete and invalid format.

After performing some investigation in the build system, I’ve found that libc_common.a is the result of unpacking and re-packing of object files inside several *.a files that already compiled previously.

For those who are curious, those *.a files are:

libbionic_ssp.a
libc_bionic.a
libc_freebsd.a
libc_netbsd.a
libc_tzcode.a

So, basically, the libc_common.a is a combined of all the object files inside the above library archives.

The above libraries is defined using PRIVATE_ALL_WHOLE_STATIC_LIBRARIES build system variable. In some mysterious ways, the archiver (i.e. arm-linux-androideabi-ar.exe) can’t create libc_common.a and the linking phase causes error and libc.so is not created.

libc_common.a failed to manifest itself due to malformed *.o files that is generated during packaging and re-packaging process. This is proved by using (arm-linux-androideabi-readelf.exe) to view one of the *.o files.

By acknowledging the above problem, so the idea is to create a batch shell file to manually creates the library archive of libc_common.a using original source of *.o instead of the one inside the *.a files.

The shell files is basically to include all of *.o using series of commands like:

c:/NDK/toolchains/arm-linux-androideabi-4.7/prebuilt/windows/bin/arm-linux-androideabi-ar crsPD out/target/product/generic/obj/STATIC_LIBRARIES/libc_common_intermediates/libc_common.a out/target/product/generic/obj/STATIC_LIBRARIES/libbionic_ssp_intermediates/bionic/__stack_chk_fail.o

The result intermediate library is then placed in appropriate location so it can be picked up by make application. The linking process can be done, but I’ve found more confusing issues.

The linker complains that __aeabi_unwind_cpp_pr0, etc can not be found. After perform more investigation, it is found that the functions resides in libgcc.a. So I can instruct the make file to include this file by modifying the related Android.mk file as follows:

by changing:

LOCAL_WHOLE_STATIC_LIBRARIES := libc_common

to:

LOCAL_WHOLE_STATIC_LIBRARIES := libc_common libgcc

It is after this addition, then the linker successfully created the libc.so. To prove whether it works, I have to inject it into /system/lib in my emulator, but first, I have to execute this command to enable the writing of /system directory:

mount -o rw,remount /system

After performing adb push command to place the compiled libc.so, I try to run some command (such as ls) inside the shell. It works without a glitch šŸ™‚

The size is rather large, about 3 MB since it contains symbolic information.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: