如何为Android交叉编译ELF可执行文件?

11

我准备了下面一份C语言示例代码,按照以下步骤可以在Android操作系统上运行:

/*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

我将二进制文件--test--复制到了目标设备的"/system/bin"目录中。

但是当我尝试在目标系统上运行交叉编译的二进制文件时,出现了以下错误:

$ pwd

/system/bin

$ ./test

bash: ./test: 没有那个文件或目录

$ ls -al | grep test

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

尽管二进制文件--test--已经在"/system/bin"目录中。

我的交叉编译器是

$ 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. 这是自由软件;请参见拷贝条件的源代码。 没有任何形式的保证,包括针对特定用途的适销性或适用性的保证。

为什么会出现以下错误:

bash: ./test: 没有那个文件或目录


1
可能是缺失/链接错误的动态加载器或类似的问题。使用readelf查找加载器。在设备上尝试ldd ./test。还可以尝试静态链接可执行文件,看看是否能够正常工作。 - Mat
在我的手机上运行ls -al | grep date得到的权限是lrwxrwxrwx。也许这是一个权限问题? - Wesley Wiser
1
我如何检测当前的动态加载器?我可以使用readelf实用程序来学习吗? - albin
1个回答

21

这个问题与动态加载器有关。当我使用readelf检查二进制文件的输出时,我发现我使用的交叉编译器有一个不同类型的默认动态加载器 - “/lib/ld-linux.so.3”,但是Android使用“/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

为了改变动态加载器(dynamic linker),应该使用“--dynamic-linker=/path/to/loader”来链接器。

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


3
非常有用,可用于编译Android恢复文件系统的二进制文件,在该系统中没有/system/bin/linker可用,路径必须重新定义。谢谢。 - Santiago Villafuerte

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接