gpt4 book ai didi

c++ - 未记录的链接器问题 : "ld returned 253 exit status"

转载 作者:可可西里 更新时间:2023-11-01 17:57:22 25 4
gpt4 key购买 nike

我收到一条错误消息,我找不到任何相关信息。在哪里可以找到有关 ld 的 253 退出状态的信息?

我到处都找不到任何东西。 Google 上只有一个提及,而且它似乎与任何解决方案都无关。

错误信息:

collect2.exe: error: ld returned 253 exit status

对于链接器和编译器的详细输出,没有其他警告或错误甚至与上述内容模糊相关。

尝试找出问题

这个错误在某种程度上与程序大小有关,但程序还没有达到系统闪存大小,所以我有点困惑。

如果我运行 size,结果如下(设备限制为 64 KB):

text    data     bss     dec
45608 396 6200 52204

当我将设备内存大小增加到 128K 时,没有任何变化,相同的消息...

但是,如果我将代码大小减少到大约 54 KB 以下,程序可以编译,并且删除哪些代码并不重要。

如果我只添加一点点代码,二进制文件的大小应该只会增加几百个字节。但是,当我这样做时,链接器因上述错误而失败。

检查objcopy创建的二进制文件时,内存中有一个巨大的空闲区域;内存肯定没有满。链接器文件已附加,但我看不出它们是如何导致我的问题的:

链接已删除,以便在问题中包含链接器文件。

更新

问题仍然存在,但我注意到在生成的 map 文件中它似乎停在模板对象的中间。就好像链接器只是抛出了一些异常并中止了一样。它停止的那一行是非常繁重的模板代码,但它确实实例化了它崩溃的确切事物的实例(或者至少是相似的对象,唯一的区别是捕获的 lambda 类型。它们始终是按照标准的唯一类型) .

映射文件中的最后一项位于 0x080008CE,并且因为闪存从地址 0x08000000 开始,这实际上是 0x08CE,它远不是闪存的末尾。

文件 sections.ld

/*
* Default linker script for Cortex-M (it includes specifics for STM32F[34]xx).
*
* To make use of the multi-region initialisations, define
* OS_INCLUDE_STARTUP_INIT_MULTIPLE_RAM_SECTIONS for the _startup.c file.
*/

/*
* The '__stack' definition is required by crt0, do not remove it.
*/
__stack = ORIGIN(RAM) + LENGTH(RAM);

_estack = __stack; /* STM specific definition */

/*
* Default stack sizes.
* These are used by the startup in order to allocate stacks
* for the different modes.
*/

__Main_Stack_Size = 1024 ;

PROVIDE ( _Main_Stack_Size = __Main_Stack_Size ) ;

__Main_Stack_Limit = __stack - __Main_Stack_Size ;

/* "PROVIDE" allows to easily override these values from an
* object file or the command line. */
PROVIDE ( _Main_Stack_Limit = __Main_Stack_Limit ) ;

/*
* There will be a link error if there is not this amount of
* RAM free at the end.
*/
_Minimum_Stack_Size = 256 ;

/*
* Default heap definitions.
* The heap start immediately after the last statically allocated
* .sbss/.noinit section, and extends up to the main stack limit.
*/
PROVIDE ( _Heap_Begin = _end_noinit ) ;
PROVIDE ( _Heap_Limit = __stack - __Main_Stack_Size ) ;

/*
* The entry point is informative, for debuggers and simulators,
* since the Cortex-M vector points to it anyway.
*/
ENTRY(_start)


/* Sections Definitions */

SECTIONS
{
/*
* For Cortex-M devices, the beginning of the startup code is stored in
* the .isr_vector section, which goes to FLASH.
*/
.isr_vector : ALIGN(4)
{
FILL(0xFF)

__vectors_start = ABSOLUTE(.) ;
__vectors_start__ = ABSOLUTE(.) ; /* STM specific definition */
KEEP(*(.isr_vector)) /* Interrupt vectors */

KEEP(*(.cfmconfig)) /* Freescale configuration words */

/*
* This section is here for convenience, to store
* the startup code at the beginning of the flash
* area, hoping that this will increase
* the readability of the listing.
*/
*(.after_vectors .after_vectors.*) /* Startup code and ISR */

} >FLASH

.inits : ALIGN(4)
{
/*
* Memory regions initialisation arrays.
*
* Thee are two kinds of arrays for each RAM region, one for
* data and one for bss. Each is iterated at startup and the
* region initialisation is performed.
*
* The data array includes:
* - from (LOADADDR())
* - region_begin (ADDR())
* - region_end (ADDR()+SIZEOF())
*
* The bss array includes:
* - region_begin (ADDR())
* - region_end (ADDR()+SIZEOF())
*
* WARNING: It is mandatory that the regions are word aligned,
* since the initialisation code works only on words.
*/

__data_regions_array_start = .;

LONG(LOADADDR(.data));
LONG(ADDR(.data));
LONG(ADDR(.data)+SIZEOF(.data));

__data_regions_array_end = .;

__bss_regions_array_start = .;

LONG(ADDR(.bss));
LONG(ADDR(.bss)+SIZEOF(.bss));

__bss_regions_array_end = .;

/* End of memory regions initialisation arrays. */

/*
* These are the old initialisation sections, intended to contain
* naked code, with the prologue/epilogue added by crti.o/crtn.o
* when linking with startup files. The standalone startup code
* currently does not run these, better use the init arrays below.
*/
KEEP(*(.init))
KEEP(*(.fini))

. = ALIGN(4);

/*
* The preinit code, i.e. an array of pointers to initialisation
* functions to be performed before constructors.
*/
PROVIDE_HIDDEN (__preinit_array_start = .);

/*
* Used to run the SystemInit() before anything else.
*/
KEEP(*(.preinit_array_sysinit .preinit_array_sysinit.*))

/*
* Used for other platform inits.
*/
KEEP(*(.preinit_array_platform .preinit_array_platform.*))

/*
* The application inits. If you need to enforce some order in
* execution, create new sections, as before.
*/
KEEP(*(.preinit_array .preinit_array.*))

PROVIDE_HIDDEN (__preinit_array_end = .);

. = ALIGN(4);

/*
* The init code, i.e. an array of pointers
* to static constructors.
*/
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);

. = ALIGN(4);

/*
* The fini code, i.e. an array of pointers to static destructors.
*/
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);

} >FLASH


/*
* For some STRx devices, the beginning of the startup code
* is stored in the .flashtext section, which goes to FLASH.
*/
.flashtext : ALIGN(4)
{
*(.flashtext .flashtext.*) /* Startup code */
} >FLASH


/*
* The program code is stored in the .text section,
* which goes to FLASH.
*/
.text : ALIGN(4)
{
*(.text .text.*) /* All remaining code */

/* Read-only data (constants) */
*(.rodata .rodata.* .constdata .constdata.*)

*(vtable) /* C++ virtual tables */

KEEP(*(.eh_frame*))

/*
* Stub sections generated by the linker, to glue together
* ARM and Thumb code. .glue_7 is used for ARM code calling
* Thumb code, and .glue_7t is used for Thumb code calling
* ARM code. Apparently always generated by the linker,
* for some architectures, so better leave them here.
*/
*(.glue_7)
*(.glue_7t)

} >FLASH

/* ARM magic sections */
.ARM.extab : ALIGN(4)
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH

. = ALIGN(4);
__exidx_start = .;
.ARM.exidx : ALIGN(4)
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH

__exidx_end = .;

. = ALIGN(4);
_etext = .;
__etext = .;


/*
* This address is used by the startup code to
* initialise the .data section.
*/
_sidata = LOADADDR(.data);

.ConfigData : ALIGN(4)
{
KEEP(*(.ConfigData));
PROVIDE (ConfigAddress = ABSOLUTE(.));
} > CONFIG

/*
* The initialised data section.
*
* The program executes knowing that the data is in the RAM
* but the loader puts the initial values in the FLASH (inidata).
* It is one task of the startup to copy the initial values from
* FLASH to RAM.
*/
.data : ALIGN(4)
{
FILL(0xFF)
/* This is used by the startup code
to initialise the .data section */
_sdata = . ; /* STM specific definition */
__data_start__ = . ;
*(.data_begin .data_begin.*)

*(.data .data.*)
*(.data_end .data_end.*)
. = ALIGN(4);

/* This is used by the startup code
to initialise the .data section */
_edata = . ; /* STM specific definition */
__data_end__ = . ;

} >RAM AT>FLASH



/* The primary uninitialised data section. */
.bss (NOLOAD) : ALIGN(4)
{
__bss_start__ = .; /* standard newlib definition */
_sbss = .; /* STM specific definition */
*(.bss_begin .bss_begin.*)

*(.bss .bss.*)
*(COMMON)

*(.bss_end .bss_end.*)
. = ALIGN(4);
__bss_end__ = .; /* Standard newlib definition */
_ebss = . ; /* STM specific definition */
} >RAM

.noinit (NOLOAD) : ALIGN(4)
{
_noinit = .;

*(.noinit .noinit.*)

. = ALIGN(4) ;
_end_noinit = .;
} > RAM


/* Mandatory to be word aligned, _sbrk assumes this */
PROVIDE ( end = _end_noinit ); /* was _ebss */
PROVIDE ( _end = _end_noinit );
PROVIDE ( __end = _end_noinit );
PROVIDE ( __end__ = _end_noinit );

/*
* Used for validation only, do not allocate anything here!
*
* This is just to check that there is enough RAM left for the Main
* stack. It should generate an error if it's full.
*/
._check_stack : ALIGN(4)
{
. = . + _Minimum_Stack_Size ;
} >RAM

/* After that there are only debugging sections. */
/* This can remove the debugging information from the standard libraries */

DISCARD :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}

/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/*
* DWARF debug sections.
* Symbols in the DWARF debugging sections are relative to the beginning
* of the section so we begin them at 0.
*/
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

文件mem.ld

MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x4000
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x1F800
CONFIG (rx) : ORIGIN = ORIGIN(FLASH) + LENGTH(FLASH), LENGTH = 0x800
FLASHB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
EXTMEMB0 (rx) : ORIGIN = 0x00000000, LENGTH = 0
EXTMEMB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
EXTMEMB2 (rx) : ORIGIN = 0x00000000, LENGTH = 0
EXTMEMB3 (rx) : ORIGIN = 0x00000000, LENGTH = 0
MEMORY_ARRAY (xrw) : ORIGIN = 0x00000000, LENGTH = 0
}

更新 2

发生错误时正在链接的相关代码确实在 Visual Studio 中链接。

更新 3

使用新的链接器文件和以下标志,错误仍然存​​在:

arm-none-eabi-g++ -mcpu=cortex-m0 -march=armv6-m -mthumb -Os -fmessage-length=0 -ffreestanding -flto -Wunused -Wuninitialized -Wall -Wextra  -g -T "../ldscripts/mem.ld" -T "../ldscripts/sections.ld" -T "../ldscripts/libs.ld" -nostartfiles -Xlinker --gc-sections -L"../ldscripts" -Wl,-Map,"uSupply Firmware V1_0.map" --specs=nano.specs -o "uSupply Firmware V1_0.elf"  ./system/src/stm32f0-stdperiph/stm32f0xx_adc.o ./system/src/stm32f0-stdperiph/stm32f0xx_can.o ./system/src/stm32f0-stdperiph/stm32f0xx_cec.o ./system/src/stm32f0-stdperiph/stm32f0xx_comp.o ./system/src/stm32f0-stdperiph/stm32f0xx_crc.o ./system/src/stm32f0-stdperiph/stm32f0xx_crs.o ./system/src/stm32f0-stdperiph/stm32f0xx_dac.o ./system/src/stm32f0-stdperiph/stm32f0xx_dbgmcu.o ./system/src/stm32f0-stdperiph/stm32f0xx_dma.o ./system/src/stm32f0-stdperiph/stm32f0xx_exti.o ./system/src/stm32f0-stdperiph/stm32f0xx_flash.o ./system/src/stm32f0-stdperiph/stm32f0xx_gpio.o ./system/src/stm32f0-stdperiph/stm32f0xx_i2c.o ./system/src/stm32f0-stdperiph/stm32f0xx_iwdg.o ./system/src/stm32f0-stdperiph/stm32f0xx_misc.o ./system/src/stm32f0-stdperiph/stm32f0xx_pwr.o ./system/src/stm32f0-stdperiph/stm32f0xx_rcc.o ./system/src/stm32f0-stdperiph/stm32f0xx_rtc.o ./system/src/stm32f0-stdperiph/stm32f0xx_spi.o ./system/src/stm32f0-stdperiph/stm32f0xx_syscfg.o ./system/src/stm32f0-stdperiph/stm32f0xx_tim.o ./system/src/stm32f0-stdperiph/stm32f0xx_usart.o ./system/src/stm32f0-stdperiph/stm32f0xx_wwdg.o  ./system/src/newlib/_cxx.o ./system/src/newlib/_exit.o ./system/src/newlib/_sbrk.o ./system/src/newlib/_startup.o ./system/src/newlib/_syscalls.o ./system/src/newlib/assert.o  ./system/src/diag/Trace.o ./system/src/diag/trace_impl.o  ./system/src/cortexm/_initialize_hardware.o ./system/src/cortexm/_reset_hardware.o ./system/src/cortexm/exception_handlers.o  ./system/src/cmsis/system_stm32f0xx.o ./system/src/cmsis/vectors_stm32f0xx.o  ./src/peripherals/Interrupt.o  ./src/_write.o ./src/main.o

最佳答案

错误的原因是在 Libiberty 的实现中使用了 VLA。 VLA 是放置在堆栈上的数据结构,当程序具有大量符号时,它会突破应用程序的堆栈限制。在 Libiberty 中有一个允许避免 VLA 的标志,其结果是使用 alloca。此分配发生在堆栈上,并出现相同的问题。

GCC 7.2 生成的符号信息比 GCC 8.2 多得多。

解决方案有三个:

  1. 在 Linux 上,使用 ulimit -s unlimited 并从同一终端窗口启动 GCC 7.2。 ulimit 只影响子进程。
  2. 在 Windows 上,重新编译 GCC ld.exe,为 Windows 使用不同的堆栈大小。 editbin 无法在 ld.exe 上正常工作。
  3. Windows/Linux:升级到 GCC 8.2。此版本的编译器对符号的处理要好得多,在这种情况下问题会自行解决。

Tamar Christina 在 Libiberty 中提出了这个问题,我怀疑,就像 Linux 内核一样,VLA 将从实现中删除。

关于c++ - 未记录的链接器问题 : "ld returned 253 exit status",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53257425/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com