libc init 函数没有返回

问题描述

我正在为 FPGA 上的 Cortex M1 开发裸机应用程序。我在程序启动期间调用 __libc_init_array 函数时看到了 HardFault。

问题似乎是,在 __libc_init_array 期间,它分支到函数“_init”。然而,这个 _init 函数不会返回并运行到杂草中,直到它遇到硬故障。我不确定我做错了什么,函数没有返回。

我使用下面的 github 链接中的完整源代码将我的程序精简到最低限度。我还把我正在使用的 CFLAGS 和 LDFLAGS 以及相关的反汇编函数放在一起。

我正在使用来自 arm.com 的 GCC 版本“gcc-arm-none-eabi-9-2020-q2-update”。我还尝试了较新的“gcc-arm-none-eabi-10-2020-q4-major”版本和 STM32IDE 附带的 GCC,结果相同。

我也将 STM32CUBEIDE 中的编译标志与我的进行了比较,没有任何反应,但是 STM32CUBEIDE 生成的精灵正在从其 _init 中返回...

感谢所有帮助,谢谢!

https://github.com/rockybulwinkle/cortex-m1-example

CFLAGS = \
        -mthumb \
        -march=armv6-m \
        -mcpu=cortex-m0 \
        -Wall \
        -Wextra
        -std=c11 \
        -specs=nano.specs \
        -O0 \
        -fdebug-prefix-map=$(REPO_ROOT)= \
        -g \
        -ffreestanding \
        -ffunction-sections \
        -fdata-sections

LDFLAGS = \
        -mthumb \
        -march=armv6-m \
        -mcpu=cortex-m0 \
        -Wl,--print-memory-usage \
        -Wl,-Map=$(BUILD_DIR)/$(PROJECT).map \
        -T m1.ld \
        -Wl,--gc-sections \
00000084 <Reset_Handler>:
/*
 *  This is the code that gets called on processor reset.
 *  To initialize the device,and call the main() routine.
 */
void Reset_Handler(void)
{
      84:   b580        push    {r7,lr}
      86:   b082        sub sp,#8
      88:   af00        add r7,sp,#0
    /* Initialize the data segment */
    uint32_t *pSrc = &_etext;
      8a:   4b13        ldr r3,[pc,#76]   ; (d8 <Reset_Handler+0x54>)
      8c:   607b        str r3,[r7,#4]
    uint32_t *pDest = &_sdata;
      8e:   4b13        ldr r3,#76]   ; (dc <Reset_Handler+0x58>)
      90:   603b        str r3,#0]

    if (pSrc != pDest) {
      92:   687a        ldr r2,#4]
      94:   683b        ldr r3,#0]
      96:   429a        cmp r2,r3
      98:   d00c        beq.n   b4 <Reset_Handler+0x30>
        for (; pDest < &_edata;) {
      9a:   e007        b.n ac <Reset_Handler+0x28>
            *pDest++ = *pSrc++;
      9c:   687a        ldr r2,#4]
      9e:   1d13        adds    r3,r2,#4
      a0:   607b        str r3,#4]
      a2:   683b        ldr r3,#0]
      a4:   1d19        adds    r1,r3,#4
      a6:   6039        str r1,#0]
      a8:   6812        ldr r2,[r2,#0]
      aa:   601a        str r2,[r3,#0]
        for (; pDest < &_edata;) {
      ac:   683a        ldr r2,#0]
      ae:   4b0c        ldr r3,#48]   ; (e0 <Reset_Handler+0x5c>)
      b0:   429a        cmp r2,r3
      b2:   d3f3        bcc.n   9c <Reset_Handler+0x18>
        }
    }

    /* Clear the zero segment */
    for (pDest = &_sbss; pDest < &_ebss;) {
      b4:   4b0b        ldr r3,#44]   ; (e4 <Reset_Handler+0x60>)
      b6:   603b        str r3,#0]
      b8:   e004        b.n c4 <Reset_Handler+0x40>
        *pDest++ = 0;
      ba:   683b        ldr r3,#0]
      bc:   1d1a        adds    r2,#4
      be:   603a        str r2,#0]
      c0:   2200        movs    r2,#0
      c2:   601a        str r2,#0]
    for (pDest = &_sbss; pDest < &_ebss;) {
      c4:   683a        ldr r2,#0]
      c6:   4b08        ldr r3,#32]   ; (e8 <Reset_Handler+0x64>)
      c8:   429a        cmp r2,r3
      ca:   d3f6        bcc.n   ba <Reset_Handler+0x36>
    }

    /* Run constructors / initializers */
    __libc_init_array();
      cc:   f000 f898   bl  200 <__libc_init_array>

    /* Branch to main function */
    main();
      d0:   f7ff ffb6   bl  40 <main>

    /* Infinite loop */
    while (1);
      d4:   e7fe        b.n d4 <Reset_Handler+0x50>
      d6:   46c0        nop         ; (mov r8,r8)
      d8:   00001370    .word   0x00001370
      dc:   2000001c    .word   0x2000001c
      e0:   20000080    .word   0x20000080
      e4:   20000000    .word   0x20000000
      e8:   2000001c    .word   0x2000001c

00000200 <__libc_init_array>:
     200:   b570        push    {r4,r5,r6,lr}
     202:   2600        movs    r6,#0
     204:   4d0c        ldr r5,#48]   ; (238 <__libc_init_array+0x38>)
     206:   4c0d        ldr r4,#52]   ; (23c <__libc_init_array+0x3c>)
     208:   1b64        subs    r4,r4,r5
     20a:   10a4        asrs    r4,#2
     20c:   42a6        cmp r6,r4
     20e:   d109        bne.n   224 <__libc_init_array+0x24>
     210:   2600        movs    r6,#0
     212:   f001 f8a9   bl  1368 <_init>
     216:   4d0a        ldr r5,#40]   ; (240 <__libc_init_array+0x40>)
     218:   4c0a        ldr r4,#40]   ; (244 <__libc_init_array+0x44>)
     21a:   1b64        subs    r4,r5
     21c:   10a4        asrs    r4,#2
     21e:   42a6        cmp r6,r4
     220:   d105        bne.n   22e <__libc_init_array+0x2e>
     222:   bd70        pop {r4,pc}
     224:   00b3        lsls    r3,#2
     226:   58eb        ldr r3,[r5,r3]
     228:   4798        blx r3
     22a:   3601        adds    r6,#1
     22c:   e7ee        b.n 20c <__libc_init_array+0xc>
     22e:   00b3        lsls    r3,#2
     230:   58eb        ldr r3,r3]
     232:   4798        blx r3
     234:   3601        adds    r6,#1
     236:   e7f2        b.n 21e <__libc_init_array+0x1e>
    ...

disassembly of section .init:

00001368 <_init>:
    1368:   b5f8        push    {r3,r7,lr}
    136a:   46c0        nop         ; (mov r8,r8)

disassembly of section .fini:

0000136c <_fini>:
    136c:   b5f8        push    {r3,lr}
    136e:   46c0        nop         ; (mov r8,r8)

解决方法

我在起草问题时找到了答案。本质上,我需要在我的链接描述文件中为“init”和“fini”添加 KEEP 指令。 之前:

    .text :
    {
        . = ALIGN(4);
        _stext = .;
        KEEP(*(.vectors .vectors.*))
        *(.text .text.*)
        *(.rodata .rodata*)
        . = ALIGN(4);
    } > rom

之后:

    .text :
    {
        . = ALIGN(4);
        _stext = .;
        KEEP(*(.vectors .vectors.*))
        KEEP(*(.init))
        KEEP(*(.fini))
        *(.text .text.*)
        *(.rodata .rodata*)
        . = ALIGN(4);
    } > rom