arm-none-eabi-ld:.ARM.exidx部分与.data部分重叠

3
我正在使用TI Tiva微控制器(TM4C123GH6PM)、TivaWare(前身为StellarisWare)和GCC 4.8.2(-14ubuntu1+6)在Linux上开发一个项目。
在链接过程中,我开始收到以下错误信息:
arm-none-eabi-ld: section .ARM.exidx loaded at [00000000000027d8,00000000000027df] overlaps section .data loaded at [00000000000027d7,00000000000027d8]

我已经搜索了很多,但我没有找到任何有用的信息。
  1. 我找到了一个与此主题相关的问题,但我没有执行任何堆栈跟踪: When is .ARM.exidx is used
  2. 看起来这个部分主要用于调试C++代码。 但我没有使用C++...
  3. 我尝试使用-h转储所有对象文件以显示包含的部分。唯一包含ARM.exidx的文件是libgcc.a。
  4. 错误似乎没有明显的模式(至少我找不到)。
例如,在main.c中:
while( 1 ){
    debug_getc()
    uartA_getc()
}

产生了那个错误。而

while( 1 ){
    debug_getc();
    //uartA_getc();
}

while( 1 ){
    debug_getc();
    //uartA_getc();
}

不行。(两个函数都在它们自己的对象文件中,但做着类似的事情。这个错误不仅限于这两个函数。我也在其他一些地方遇到过。)

我尝试添加了:

.ARM.exidx :                     
{                                
    *(.ARM.exidx*)
    *(.gnu.linkonce.armexidx.*)  
} > SRAM                         

将我的链接器脚本添加进去后,错误信息消失了,但我却遇到了奇怪的崩溃问题。

那么有人能告诉我发生了什么吗? 我感觉出现了一些根本性的问题,但我无法弄清楚是什么。

** ======= 参考 =============== **:

linkerscript.ld:

MEMORY
{
    FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000
    SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000
}

SECTIONS
{
    .text :
    {
        _text = .;
        KEEP(*(.isr_vector))
        *(.text*)
        *(.rodata*)
        _etext = .;
    } > FLASH

    .data : AT(ADDR(.text) + SIZEOF(.text))
    {
        _data = .;
        *(vtable)
        *(.data*)
        _edata = .;
    } > SRAM

    .bss :
    {
        _bss = .;
        *(.bss*)
        *(COMMON)
        _ebss = .;
    } > SRAM

/*
    .ARM.exidx :
    {
        *(.ARM.exidx*)
        *(.gnu.linkonce.armexidx.*)
    } > SRAM
*/
}

用于构建的命令(摘录):

arm-none-eabi-gcc -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -std=gnu99 -Wall -pedantic -DPART_TM4C123GH6PM -c -Os -DTARGET_IS_TM4C129_RA1 -I. -I../tivalib -I../TivaWare -Dgcc -o../tivalib/weather/wind.o ../tivalib/weather/wind.c

arm-none-eabi-ld -T weatherlight.ld \
            --entry ResetISR \
            --gc-sections \
            -o weatherlight.axf weatherlight.o startup_gcc.o pwmA.o pwmB.o ../tivalib/board.o ../tivalib/debug.o ../tivalib/uartA.o ../tivalib/calc.o ../tivalib/rgb.o ../tivalib/color.o ../tivalib/data/data_sin.o ../tivalib/data/data_gamma.o ../tivalib/net/rgb/gen/solid.o ../tivalib/net/rgb/filter/filter_scale_gamma.o ../tivalib/net/rgb/filter/filter_white_balance.o ../tivalib/net/rgb/filter/filter_darken.o ../tivalib/net/rgb/filter/filter_lighten.o ../tivalib/net/val/gen/slider.o ../tivalib/net/val/gen/value_sin.o ../tivalib/net/val/gen/value_noise.o ../tivalib/net/val/gen/value_weightedsin.o ../tivalib/net/val/filter/value_filter_delay.o ../tivalib/net/val/filter/value_filter_scale_down.o ../tivalib/net/val/mixer/value_mixer.o ../tivalib/net/rgb/mixer/mixer.o ../tivalib/weather/sunny.o ../tivalib/weather/rainy.o ../tivalib/weather/cloudy.o ../tivalib/weather/wind.o ../TivaWare/utils/ustdlib.o \
            ../TivaWare/driverlib/gcc/libdriver.a \
            /usr/lib/gcc/arm-none-eabi/4.8.2/../../../arm-none-eabi/lib/armv7e-m/softfp/libm.a \
            /usr/lib/gcc/arm-none-eabi/4.8.2/../../../arm-none-eabi/lib/armv7e-m/softfp/libc.a \
            /usr/lib/gcc/arm-none-eabi/4.8.2/armv7e-m/softfp/libgcc.a

将它们放在.text中;据我所知,它们是常量数据,如果需要读/写,则将它们放在.data中。您必须初始化它们,它们不像.bss那样,并且如果需要,您需要使用NOLOAD。如果您不使用C++异常或任何'C'语言堆栈跟踪内容,则可能不需要idx部分。但是,它们通常不会很大,因此我建议保留它们如上所述。一些'C'库例程可能需要这些部分。 - artless noise
我不确定我是否正确理解了您的意思。但是将“ARM.exidx”直接放在“.text”中会导致错误:arm-none-eabi-ld:.text具有有序[.ARM.exidx'位于 /...../softfp/libgcc.a(_divdi3.o)]和无序[`.rodata.str1.1'位于../TivaWare/utils/ustdlib.o]部分。(但至少我有一个错误告诉我这些东西来自哪里!!! - Scheintod
2个回答

4
你尝试过仅丢弃相关的输出部分吗?
/DISCARD/ :
{
    *(.ARM.exidx*)
    *(.gnu.linkonce.armexidx.*)
}

编辑:

我已经查看了我的一个ARM项目,并将其部分放入了flash中。

请尝试以下操作:

.ARM.exidx :
{
    *(.ARM.exidx*)
    *(.gnu.linkonce.armexidx.*)
} >FLASH

编辑2:

尝试在所有进入Flash的部分之后放置一个标签,并将您的.data部分放在那里:

SECTIONS
{
.text :
{
    _text = .;
    KEEP(*(.isr_vector))
    *(.text*)
    *(.rodata*)
    _etext = .;
} > FLASH

.ARM.exidx :
{
    *(.ARM.exidx*)
    *(.gnu.linkonce.armexidx.*)
} > FLASH

_begin_data = .;

.data : AT ( _begin_data )
{
    _data = .;
    *(vtable)
    *(.data*)
    _edata = .;
} > SRAM

.bss :
{
    _bss = .;
    *(.bss*)
    *(COMMON)
    _ebss = .;
} > SRAM

}

感谢您的回答。删除会移除错误信息,但放入闪存中不会。目前我正在尝试通过这行代码移动.data节:.data:AT(ADDR(.text)+ SIZEOF(.text)+ SIZEOF(.ARM.exidx)+2)。但我不确定我知道自己在做什么。而且我还要在我暂时没有的硬件上尝试。您知道为什么首先会有.ARM.exidx部分吗? - Scheintod
(我感到有点不安,因为我不知道要删除的东西是什么...) - Scheintod
尝试将所有的.text部分放在链接器脚本的开头,添加一个标签,然后将你的.data部分放在那里。请参考我的第二次编辑。 - lkamp
1
据我所知,.ARM.extab和.ARM.exidx用于堆栈展开,因此在常规操作中不使用,但在处理C++异常和调试程序时需要。但我必须承认,我从来没有过多关注它们,因为我从未遇到过您描述的问题。 - lkamp

1

我在Makefile的COMPILE_OPTS中添加了-funwind-tables选项,现在编译时没有错误。


抱歉,应该是“-finwind-tables”,而不是“-funwind-tables”。 - Ning Lian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接