放置在静态库中时找不到__isr_vectors变量

时间:2015-03-09 18:21:25

标签: gcc linker arm static-libraries linker-scripts

作为前一个问题(sbrk function not found when placed in a static library)的衍生产品: 我正在为stm32f407微控制器创建一个裸机应用程序,该应用程序具有ARM Cortex M4内核。我正在尝试创建一个包含基本内容的静态库,如cmsis,HAL函数和中断向量表,并将该静态库链接到我的主应用程序。但是,当中断向量表(名为__isr_vectors的变量)放在静态库中时,该变量不会在链接中存在。

我可以把发生的事情拼凑起来:链接器有一个对象main.o和一些库。它采用main.o中找到的所有符号,它采用main.o使用的库中的所有符号或已被认为必要的其他符号使用的符号。此阶段尚不需要__isr_vectors变量,因为没有人明确引用此变量,因此链接器会抛出该变量。然后,链接器搜索名为.isr_vector的所有输入节,以便创建输出节.isr_vector。但是,到目前为止,没有符号存活,因此输出部分保持为空,而我的二进制文件没有中断表。

我知道让__isr_vector生存的一个技巧:在main.c中的虚拟函数中引用它。但是,这有点丑陋且容易出错(在针对同一静态库构建新应用程序时,您可能会忘记这样做)。所以这是我的问题:是否有另一种方法可以使__isr_vector生存下来,这样我就可以链接到我的静态库中并完成它了?

这些是重现问题的文件和步骤:

vectors.c:

  

__ attribute __((section(“。isr_vector”),used used))void * __isr_vectors = 0;

main.c中:

  

void _start(void){}

link.ld:

  

MEMORY      {        FLASH(rx):ORIGIN = 0x08000000,LENGTH = 1024K      }

     

ENTRY(_start)

     

SECTIONS      {          .isr_vector:ALIGN(4)          {              KEEP(*(。isr_vector))          }> FLASH

   .text : ALIGN(4)
   {
       *(.text .text.*)
   } >FLASH
     

}

命令:

  

“C:\ Program Files(x86)\ GNU Tools ARM Embedded \ 4.9 2014q4 \ bin \ arm-none-eabi-gcc.exe”-g -mcpu = cortex-m4 -mfpu = fpv4-sp-d16 - mfloat-abi = softfp -mthumb -ffunction-sections -std = gnu11 -o main.c.obj -c main.c      “C:\ Program Files(x86)\ GNU Tools ARM Embedded \ 4.9 2014q4 \ bin \ arm-none-eabi-gcc.exe”-g -mcpu = cortex-m4 -mfpu = fpv4-sp-d16 -mfloat-abi = softfp -mthumb -ffunction-sections -std = gnu11 -o vectors.c.obj -c vectors.c

     

“C:\ Program Files(x86)\ GNU Tools ARM Embedded \ 4.9 2014q4 \ bin \ arm-none-eabi-gcc.exe”-g -mcpu = cortex-m4 -mfpu = fpv4-sp-d16 - mfloat-abi = softfp -mthumb -ffunction-sections -std = gnu11 -g -mcpu = cortex-m4 -mfpu = fpv4-sp-d16 -mfloat-abi = softfp -mthumb -Wl, - gc-sections -nostartfiles - Wl,-Tlink.ld -Wl,-Map = test_linker.without_library.map main.c.obj vectors.c.obj -o test_linker.without_library.elf

     

“C:\ Program Files(x86)\ GNU Tools ARM Embedded \ 4.9 2014q4 \ bin \ arm-none-eabi-ar.exe cq libtest_linker.lib.a vectors.c.obj

     

“C:\ Program Files(x86)\ GNU Tools ARM Embedded \ 4.9 2014q4 \ bin \ arm-none-eabi-ranlib.exe”libtest_linker.lib.a

     

“C:\ Program Files(x86)\ GNU Tools ARM Embedded \ 4.9 2014q4 \ bin \ arm-none-eabi-gcc.exe”-g -mcpu = cortex-m4 -mfpu = fpv4-sp-d16 - mfloat-abi = softfp -mthumb -ffunction-sections -std = gnu11 -g -mcpu = cortex-m4 -mfpu = fpv4-sp-d16 -mfloat-abi = softfp -mthumb -Wl, - gc-sections -nostartfiles - Wl,-Tlink.ld -Wl,-Map = test_linker.with_library.map main.c.obj -o test_linker.with_library.elf libtest_linker.lib.a

3 个答案:

答案 0 :(得分:3)

我对您的文件进行了两处更改:

在链接描述文件中,我更改了ENTRY

ENTRY(_start)

ENTRY(Reset_Handler)

并在vectors.c中添加了这个函数:

void Reset_Handler(void) {
}

诀窍是Reset_Handler是翻译单元vectors.c中的一个函数,而_start位于其他地方。

现在当Reset_Handler被链接(由ENTRY强制执行)时,__isr_vectors似乎也被考虑了!因此,似乎必须链接该翻译单元中的另一个函数才能“拖拽”该变量。


为了完整起见:

  • 通常Reset_Handler会引用__isr_vectorsReset_Handler main最终会引用_start(在您的情况下是-fdata-sections)。所以这不仅仅是一种解决方法,无论如何你可能还需要它。

  • 我已将{{1}}添加到编译命令

答案 1 :(得分:2)

我在同一种环境中遇到了这个问题(arm-none-eabi-gcc-cs-5.2.0-3.fc23.x86_64,arm-none-eabi-binutils-cs-2.25-2.fc23。 Fedora 23上的x86_64。

链接器似乎不会尝试读取存档的内容,因为它已经拥有了所需的所有符号。它可能是一种优化或错误。

强制读取“已使用”符号的存档的另一种解决方案是强制链接器ld将__isr_vectors视为未定义的-u __isr_vectors

作为gcc选项,-Xlinker -u -Xlinker __isr_vectors-Wl,-u,__isr_vectors

答案 2 :(得分:1)

这更像是已发布答案的后续内容: 我建议您只需要将链接描述文件中的ENTRY更改为: ENTRY(g_pfnVectors) 我认为这不是一件好事,也不需要更改原始源文件。 如果源文件中不存在g_pfnVectors,则它是我们文件中矢量表本身的名称。适当修改。

相关问题