Linaro g++ aarch64 编译导致未对齐错误 [英] Linaro g++ aarch64 compilation cause unalignment fault

查看:52
本文介绍了Linaro g++ aarch64 编译导致未对齐错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 linaro g++ for ARM arch64 来编译一个简单的 cpp 文件:

I'm using linaro g++ for ARM arch64 to compile a simple cpp file:

int main()
{
    char  *helloMain      = "main module (crm.c)";
    long  faculty, num    = 12;
    int   stop,mainLoop   = 1; 
    char  word[80]        = "";
}

经过objdump生成的elf文件,我得到了它的asm代码:

After objdump the generated elf file, I got its asm code:

0000000000001270 <main>:
int main()
{
    1270:   d101c3ff    sub sp, sp, #0x70
    char  *helloMain      = "main module (crm.c)";
    1274:   90000020    adrp    x0, 5000 <_malloc_trim_r+0x160>
    1278:   9111c000    add x0, x0, #0x470
    127c:   f90003e0    str x0, [sp]
    long  faculty, num    = 12;
    1280:   d2800180    movz    x0, #0xc
    1284:   f90007e0    str x0, [sp,#8]
    int   stop,mainLoop   = 1; 
    1288:   52800020    movz    w0, #0x1
    128c:   b90013e0    str w0, [sp,#16]
    char  word[80]        = "";
    1290:   910063e0    add x0, sp, #0x18
    1294:   90000021    adrp    x1, 5000 <_malloc_trim_r+0x160>
    1298:   91122021    add x1, x1, #0x488
    129c:   39400021    ldrb    w1, [x1]
    12a0:   39000001    strb    w1, [x0]
    12a4:   91000400    add x0, x0, #0x1
    12a8:   a9007c1f    stp xzr, xzr, [x0]
    12ac:   a9017c1f    stp xzr, xzr, [x0,#16]
    12b0:   a9027c1f    stp xzr, xzr, [x0,#32]
    12b4:   a9037c1f    stp xzr, xzr, [x0,#48]
    12b8:   f900201f    str xzr, [x0,#64]
    12bc:   b900481f    str wzr, [x0,#72]
    12c0:   7900981f    strh    wzr, [x0,#76]
    12c4:   3901381f    strb    wzr, [x0,#78]
}
    12c8:   52800000    movz    w0, #0x0
    12cc:   9101c3ff    add sp, sp, #0x70
    12d0:   d65f03c0    ret

在 ARMV8 板上执行此代码之前,sp 被初始化为与 0x1000 对齐的地址.

Before executing this code on an ARMV8 board, sp is initialized to an address aligned to 0x1000.

此类代码的执行引发了对齐错误异常12a8: a9007c1f stp xzr, xzr, [x0]

The execution of such code raised an alignment fault exception on 12a8: a9007c1f stp xzr, xzr, [x0]

我注意到 x0 是由 0x1 添加的,因此在执行 stp 指令时它与 0x1 对齐.

I noticed x0 was added by 0x1 so it was aligned to 0x1 when stp instruction was executed.

为什么 g++ 没有让它与 0x10 对齐以避免这种对齐错误异常?

Why g++ didn't make it align to 0x10 to avoid such alignment fault exception?

g++ 版本是:

gcc  4.8.1 20130506 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2013.05 - Linaro GCC 2013.05)

推荐答案

来自 手册:

-munaligned-access
-mno-unaligned-access

启用(或禁用)从非 16 位或 32 位对齐的地址读取和写入 16 位和 32 位值.默认情况下,所有 ARMv6 之前的和所有ARMv6-M 架构,并为所有其他架构启用.如果未启用未对齐访问然后打包数据结构中的字将一次访问一个字节.

Enables (or disables) reading and writing of 16- and 32- bit values from addresses that are not 16- or 32- bit aligned. By default unaligned access is disabled for all pre-ARMv6 and all ARMv6-M architectures, and enabled for all other architectures. If unaligned access is not enabled then words in packed data structures will be accessed a byte at a time.

ARM 属性 Tag_CPU_unaligned_access 将在生成的目标文件为真或假,取决于此选项的设置.如果启用了未对齐访问,则预处理器符号 __ARM_FEATURE_UNALIGNED 也将被定义.

The ARM attribute Tag_CPU_unaligned_access will be set in the generated object file to either true or false, depending upon the setting of this option. If unaligned access is enabled then the preprocessor symbol __ARM_FEATURE_UNALIGNED will also be defined.

AArch64/ARMv8 支持开箱即用的未对齐访问,因此 GCC 假定它可用.如果不是这种情况,您可能必须使用上述开关明确禁用它.预发行版"也有可能您使用的版本尚未完成,并且存在各种错误/问题.

AArch64/ARMv8 supports unaligned access out of box, so GCC assumes it's available. If this is not the case, you may have to disable it explicitly with the above switch. It's also possible that the "prerelease" version you're using is not quite finished yet and various bugs/issues are present.

编辑

如评论中所述,相应的AArch64 选项是:

As mentioned in the comments, the corresponding AArch64 options are:

-mstrict-align
-mno-strict-align

避免或允许生成可能未在架构规范中描述的自然对象边界上对齐的内存访问.

Avoid or allow generating memory accesses that may not be aligned on a natural object boundary as described in the architecture specification.

顺便说一下,代码的行为是这样的,因为 GCC 从字面上解释了赋值:

By the way, the code behaves like this because GCC interpreted the assignment literally:

  1. 复制字符串";(所以只有一个零字节)到缓冲区的开头.
  2. 用零填充缓冲区的其余部分.

我怀疑如果您启用优化,未对齐的访问将消失.或者,如果您使用 char word[80] = {0},它应该一次性完成归零.

I suspect that if you enable optimizations, the unaligned access will be gone. Or, if you use char word[80] = {0}, it should do the zeroing in one go.

这篇关于Linaro g++ aarch64 编译导致未对齐错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆