Rustc / LLVM为aarch64生成错误代码,opt-level = 0

时间:2015-06-10 13:46:25

标签: rust qemu arm64 osdev

我有两个文件被汇编/编译/链接到简约内核。

的start.s:

    .set CPACR_EL1_FPEN, 0b11 << 20

    .set BOOT_STACK_SIZE, 8 * 1024

    .global __boot_stack
    .global __start
    .global __halt

    .bss
    .align 16
__boot_stack:
    .fill BOOT_STACK_SIZE

    .text
__start:
    /* disable FP and SIMD traps */
    mov x0, #CPACR_EL1_FPEN
    msr cpacr_el1, x0

    /* set stack */
    adr x0, __boot_stack
    add sp, x0, #BOOT_STACK_SIZE

    /* call the Rust entry point */
    bl __boot

__halt:
    /* halt CPU */
    wfi
    b __halt

boot.rs:

#[no_mangle]
pub extern fn __boot() {
    unsafe {
        let ptr = 0x9000000 as *mut u8;
        *ptr = '!' as u8;
   }
}

对于opt-level = 3,结果代码输出单个'!'到串口(按预期)。对于opt-level = 0,我有一个奇怪的无限循环(例如'!!!!!!!!! ....')。以下是有问题的代码的反汇编转储:

0000000000000000 <__kernel_begin>:
   0:   d2a00600    mov x0, #0x300000               // #3145728
   4:   d5181040    msr cpacr_el1, x0
   8:   100007c0    adr x0, 100 <__boot_stack>
   c:   9140081f    add sp, x0, #0x2, lsl #12
  10:   94000003    bl  1c <__boot>

0000000000000014 <__halt>:
  14:   d503207f    wfi
  18:   17ffffff    b   14 <__halt>

000000000000001c <__boot>:
  1c:   a9bf7bfd    stp x29, x30, [sp,#-16]!
  20:   910003fd    mov x29, sp
  24:   94000003    bl  30 <aarch64::boot::__boot::__rust_abi>
  28:   a8c17bfd    ldp x29, x30, [sp],#16
  2c:   d65f03c0    ret

0000000000000030 <aarch64::boot::__boot::__rust_abi>:
  30:   d10043ff    sub sp, sp, #0x10
  34:   52a12008    mov w8, #0x9000000              // #150994944
  38:   2a0803e9    mov w9, w8
  3c:   f90007e9    str x9, [sp,#8]
  40:   52800428    mov w8, #0x21                   // #33
  44:   39000128    strb    w8, [x9]
  48:   910043ff    add sp, sp, #0x10
  4c:   d65f03c0    ret

使用qemu-system-aarch64测试代码。我没有看到它的严重问题(冗余除外)。你能否提出这种异常行为的可能原因?

P.S。这是正常运行的优化版本:

0000000000000000 <__kernel_begin>:
   0:   d2a00600    mov x0, #0x300000               // #3145728
   4:   d5181040    msr cpacr_el1, x0
   8:   1007ffc0    adr x0, 10000 <__boot_stack>
   c:   9140081f    add sp, x0, #0x2, lsl #12
  10:   94000003    bl  1c <__boot>

0000000000000014 <__halt>:
  14:   d503207f    wfi
  18:   17ffffff    b   14 <__halt>

000000000000001c <__boot>:
  1c:   52a12008    mov w8, #0x9000000              // #150994944
  20:   52800429    mov w9, #0x21                   // #33
  24:   39000109    strb    w9, [x8]
  28:   d65f03c0    ret

1 个答案:

答案 0 :(得分:1)

我成功运行了非优化代码而没有异常。感谢Notlikethat的想法。我的堆栈刚刚映射到只读内存。

所以我刚刚将偏移语句添加到我的链接器脚本中(&#34;。= 1024M;&#34;),以使所有符号从1GiB(RAM开始)开始。在此修改之后,代码开始正常工作。