【问题标题】:How do you cross compile ELF executables for Android?您如何交叉编译适用于 Android 的 ELF 可执行文件?
【发布时间】:2012-01-26 11:05:33
【问题描述】:

我在下面准备了一个示例 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”目录中。

当我尝试在目标系统上运行交叉编译的二进制文件时,我收到了这个错误

$密码

/系统/bin

$ ./test

bash: ./test: 没有这样的文件或目录

$ ls -al | grep 测试

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

虽然二进制文件 --test-- 已经在“/system/bin”目录下。

我的交叉编译器是

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

arm-none-linux-gnueabi-gcc (Sourcery G++ Lite 2009q1-203) 4.3.3 版权所有 (C) 2008 Free Software Foundation, Inc. 这是免费的 软件;查看复制条件的来源。没有 保修单;甚至不适合适销性或适合特定的 目的。

为什么会出现这个错误?

bash: ./test: 没有这样的文件或目录

【问题讨论】:

  • 可能是缺少/错误链接的动态加载器或类似的东西。通过readelf 了解加载程序是什么。在设备上尝试ldd ./test。还可以尝试静态链接 exe,看看是否至少有效。
  • 在我的手机上运行ls -al | grep date 会产生lrwxrwxrwx 作为权限。也许是权限问题?
  • 如何检测我当前的动态加载器?我可以使用 readelf 实用程序来学习吗?

标签: android cross-compiling elf


【解决方案1】:

这个问题与动态加载器有关。当我用 readelf 检查二进制文件的输出时,我通知我使用的交叉编译器具有不同类型的默认动态加载器 - “/lib/ld-linux.so.3”,但 Android 使用“/system /bin/链接器"

$ 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=/path/to/loader”。

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

【讨论】:

  • 这对于在没有 /system/bin/linker 并且必须重新定义路径的 Android 中为恢复文件系统编译二进制文件非常有用。谢谢。
猜你喜欢
  • 1970-01-01
  • 2012-09-02
  • 1970-01-01
  • 2011-01-24
  • 1970-01-01
  • 1970-01-01
  • 2019-07-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多