Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you cross compile ELF executables for Android?

I have prepared a sample C code below to make it run on Android Operating System by following these procedures,

/*test.c file*/
#include <stdio.h>

int
main(int argc, char **argv)
{
    printf("Android Test Application.\n");
    return 0;
}

$ arm-none-linux-gnueabi-gcc -o test test.c -Wall

I copied the binary file --test-- into target device "/system/bin" directory.

When I attempt to make cross-compiled binary run on the target system, I am getting this error

$ pwd

/system/bin

$ ./test

bash: ./test: No such file or directory

$ ls -al | grep test

-rwxr-xr-x 1 0 0 8384 2011-12-22 15:26 test

although the binary file --test-- is already in "/system/bin" directory.

My cross-compiler is

$ arm-none-linux-gnueabi-gcc --version

arm-none-linux-gnueabi-gcc (Sourcery G++ Lite 2009q1-203) 4.3.3 Copyright (C) 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Why I am getting this error?

bash: ./test: No such file or directory

like image 409
albin Avatar asked Dec 22 '11 21:12

albin


People also ask

What is cross compiling used for?

A cross compiler is useful to compile code for multiple platforms from one development host. Direct compilation on the target platform might be infeasible, for example on embedded systems with limited computing resources. Cross compilers are distinct from source-to-source compilers.

What is cross compiling in Linux?

Cross-compilation is the act of compiling code for one computer system (often known as the target) on a different system, called the host. It's a very useful technique, for instance when the target system is too small to host the compiler and all relevant files.


1 Answers

This problem was related to the dynamic loader. When I checked the output of the binary file with readelf, I notified that the cross-compiler that I use has a different type of default dynamic loader - "/lib/ld-linux.so.3", but Android uses "/system/bin/linker"

$ readelf --program-headers test

Elf file type is EXEC (Executable file)
Entry point 0x8380
There are 8 program headers, starting at offset 52
    Program Headers:
Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
EXIDX          0x0004fc 0x000084fc 0x000084fc 0x00050 0x00050 R   0x4
PHDR           0x000034 0x00008034 0x00008034 0x00100 0x00100 R E 0x4
INTERP         0x000134 0x00008134 0x00008134 0x00013 0x00013 R   0x1
       [Requesting program interpreter: /lib/ld-linux.so.3]
LOAD           0x000000 0x00008000 0x00008000 0x00550 0x00550 R E 0x8000
LOAD           0x000550 0x00010550 0x00010550 0x00124 0x00128 RW  0x8000
DYNAMIC        0x00055c 0x0001055c 0x0001055c 0x000f0 0x000f0 RW  0x4
NOTE           0x000148 0x00008148 0x00008148 0x00020 0x00020 R   0x4
GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x4

In order to change dynamic loader(dynamic linker), "--dynamic-linker=/path/to/loader" should be used for the linker.

$ arm-none-linux-gnueabi-gcc -o test test.c -Wall -Wl,--dynamic-linker=/system/bin/linker

like image 132
albin Avatar answered Oct 20 '22 01:10

albin