我们在Android开发中需要ARM EABI v7a系统映像吗?该特定图像的目的是什么?
当你构建一个gcc工具链时,有可能将它构建为arm-elf或arm-none-eabi,但有什么区别?
我今天使用的是eabi,但这只是因为其他人似乎都这样做了......但是因为这是一个非常糟糕的论点,所以理解它们的区别真的很好.
注意:此工具链将交叉编译基于Cortex-M3的mcu代码:如stm32.
谢谢
一些链接:
EABI:
ELF:
我正在开发一个Android项目,我正在使用NDK来调用本机方法.我有两个库(.so文件),一个位于libs/armeabi文件夹中,另一个位于libs/armeabi-v7alib文件夹中.
如果我尝试运行该应用程序,那么它将不会加载该/libs/armeabi文件夹中的库.如果我将库文件移动到该libs/armeabi-v7a文件夹,则它会加载库,但在5到10分钟后它会崩溃并出现分段错误错误.
我想知道库(不同文件夹)的位置是否可能导致此问题.
我有一个产品,使用编译器(gnuarm GCC 4.1.1)编译bootloader和应用程序,生成"arm-elf".
引导加载程序和应用程序在链接描述文件的不同FLASH存储区中分隔.
该应用程序具有一个功能,使其能够调用引导加载程序(作为一个带有2个参数的简单c函数).
我需要能够升级世界各地的现有产品,并且我可以使用始终相同的编译器安全地完成此操作.
现在,我希望能够使用输出arm-eabi的新GCC版本来编译此产品应用程序.
一切都适用于新产品,其中应用程序和引导程序都使用相同的工具链进行编译,但现有产品会发生什么?如果我使用GCC 4.6.x和arm-none-eabi编译一个新的应用程序,我的应用程序是否仍然可以从旧的arm-elf引导程序中调用引导加载程序功能?
此外,与上述问题没有直接关系,我可以将用arm-elf编译的目标文件混合到用arm-eabi编译的二进制文件中吗?
编辑:
我认为很清楚我正在为裸机ARM7构建,如果它有任何区别......
我有一些使用此函数的gcc交叉编译器翻译的PowerPC汇编代码:
uint32_t fill_cache(void)
{
__asm__ ("addi 3, 0, 0\n"); /* R3 = 0 */
/* More asm here modifying R3 and filling the cache lines. */
}
Run Code Online (Sandbox Code Playgroud)
在PowerPC EABI下,返回R3中计算的值.编译时,我得到
foo.c:105: warning: control reaches end of non-void function
Run Code Online (Sandbox Code Playgroud)
有没有办法教gcc实际返回一个值?或者有没有办法抑制警告(不删除-Wall或添加-Wno-*)?我想非常有选择地仅针对此功能禁止此警告,以便尽可能高地保留一般警告级别.
由于调用者需要计算的值,因此不能使此函数返回void.
我见过arm-linux-gnueabi-和arm-linux-eabi- triplets.从小的我可以发现,似乎gnueabi是eabi的"sub-abi".我想知道究竟是什么区别.
我正在努力为QNX目标编译,所以我想知道使用哪个abi,我尝试了gnueabi,它对一个小程序工作得很好.
在检查了clang的源之后,我发现两者之间没有太大区别,除了"eabi"std :: size_t在Darwin上是无符号长,而"gnueabi"总是使用unsigned int,独立于OS.
我用 c 编写了一个非常简单的 memset,它在 -O2 范围内工作正常,但在 -O3 范围内则不行...
内存集:
void * memset(void * blk, int c, size_t n)
{
unsigned char * dst = blk;
while (n-- > 0)
*dst++ = (unsigned char)c;
return blk;
}
Run Code Online (Sandbox Code Playgroud)
...使用 -O2 时编译为该程序集:
20000430 <memset>:
20000430: e3520000 cmp r2, #0 @ compare param 'n' with zero
20000434: 012fff1e bxeq lr @ if equal return to caller
20000438: e6ef1071 uxtb r1, r1 @ else zero extend (extract byte from) param 'c'
2000043c: e0802002 add r2, …Run Code Online (Sandbox Code Playgroud) 我刚刚阅读了https://www.keil.com/support/man/docs/armlink/armlink_pge1406301797482.htm。但无法理解arm链接器在函数调用之间插入的胶合板是什么。
在“ARM 架构的过程调用标准”文档中,它说:
5.3.1.1 链接器对 IP 的使用 ARM 和 Thumb 状态 BL 指令都无法寻址完整的 32 位地址空间,因此链接器可能需要在调用例程和被调用例程之间插入一个胶合板。子程序。还可能需要胶合板来支持 ARM-Thumb 互操作或动态链接。插入的任何单板必须保留除 IP (r12) 和条件代码标志之外的所有寄存器的内容;符合要求的程序必须假设可以在任何支持互操作或长分支的重定位的分支指令处插入更改 IP 的胶合代码。注意 R_ARM_CALL、R_ARM_JUMP24、R_ARM_PC24、R_ARM_THM_CALL、R_ARM_THM_JUMP24 和 R_ARM_THM_JUMP19 是具有此属性的 ELF 重定位类型的示例。请参阅 [AAELF] 了解完整详细信息
这是我的猜测,是这样的吗?:当函数 A 调用函数 B 时,并且当这两个函数相距太远而命令bl无法表达时,链接器会在函数 A 和 B 之间插入函数 C,使得函数 C 靠近函数 B。现在函数 A 使用b指令转到函数C(在函数调用之间复制所有寄存器),并且函数C使用bl指令(也复制所有寄存器)。当然r12寄存器是用来保存剩余的长跳转地址位的。这就是贴面的意思吗?(我不知道为什么arm不解释veneer是什么,而只解释veneer提供了什么..)
GCC默认使用4字节的wchar_t.我可以设置选项wchar_t,在每个wchar_t中获取2个字节-fshort-wchar.但是当我将编译器选项设置为我的源文件时,我得到了着名的警告消息
foo.o使用2字节的wchar_t但输出是使用4字节的wchar_t; 跨对象使用wchar_t值可能会失败
因为我真的想要2字节的wchar_t,我也希望输出使用这个变种.是否有任何链接器选项告诉它我想要什么?
编辑
此警告不会禁止链接器生成有效输出.但是,数十个虚假警告涵盖了其他信息.