Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cm_backtrace.c:236: undefined reference to `_sstack' #35

Open
katcoo opened this issue Jun 30, 2020 · 5 comments
Open

cm_backtrace.c:236: undefined reference to `_sstack' #35

katcoo opened this issue Jun 30, 2020 · 5 comments

Comments

@katcoo
Copy link

katcoo commented Jun 30, 2020

使用NXP的S32K144芯片,裸机,gcc version 4.9.3 20150529 (release) [ARM/embedded-4_9-branch revision 227977] (GNU Tools for ARM Embedded Processors)编译器编译发生以下报错:
cm_backtrace.c:236: undefined reference to _sstack' cm_backtrace.c:236: undefined reference to _stext'
cm_backtrace.c:236: undefined reference to _estack' cm_backtrace.c:236: undefined reference to _etext'
请问大佬是什么原因,感谢大佬解答

@armink
Copy link
Owner

armink commented Jun 30, 2020

GCC 的链接脚本里要稍微改一下,增加 _stext_etext,即 text 段的起止

@katcoo
Copy link
Author

katcoo commented Jul 1, 2020

如下所示,我已经在ld文件中添加了:
.text : { _stext = .; . = ALIGN(4); *(.text) /* .text sections (code) */ *(.text*) /* .text* sections (code) */ *(.rodata) /* .rodata sections (constants, strings, etc.) */ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ *(.init) /* section used in crti.o files */ *(.fini) /* section used in crti.o files */ *(.eh_frame) /* section used in crtbegin.o files */ . = ALIGN(4); _etext = .; } > m_text
.stack __StackLimit : { . = ALIGN(8); __stack_start__ = .; . += STACK_SIZE; __stack_end__ = .; _sstack = __stack_start__; _estack = __stack_end__; } > m_data

但是编译时候仍报错:
/cm_backtrace.c:236:undefined reference to _sstack' /cm_backtrace.c:236: undefined reference to _stext'
/cm_backtrace.c:236: undefined reference to _estack' /cm_backtrace.c:236: undefined reference to _etext'
请问还要修改其他地方吗?

@armink
Copy link
Owner

armink commented Jul 1, 2020

我随便找了一个 RT-Thread Stduio 生成 链接脚本 ,你可以参考一下

/*
 * linker script for STM32F205RG with GNU ld
 */

/* Program Entry, set to mark it as "used" and avoid gc */
MEMORY
{
    ROM (rx) : ORIGIN = 0x08000000, LENGTH =  1024k /* 1024K flash */
    RAM (rw) : ORIGIN = 0x20000000, LENGTH =  128k /* 128K sram */
}
ENTRY(Reset_Handler)
_system_stack_size = 0x200;

SECTIONS
{
    .text :
    {
        . = ALIGN(4);
        _stext = .;
        KEEP(*(.isr_vector))            /* Startup code */

        . = ALIGN(4);
        *(.text)                        /* remaining code */
        *(.text.*)                      /* remaining code */
        *(.rodata)                      /* read-only data (constants) */
        *(.rodata*)
        *(.glue_7)
        *(.glue_7t)
        *(.gnu.linkonce.t*)

        /* section information for finsh shell */
        . = ALIGN(4);
        __fsymtab_start = .;
        KEEP(*(FSymTab))
        __fsymtab_end = .;

        . = ALIGN(4);
        __vsymtab_start = .;
        KEEP(*(VSymTab))
        __vsymtab_end = .;

        /* section information for utest */
        . = ALIGN(4);
        __rt_utest_tc_tab_start = .;
        KEEP(*(UtestTcTab))
        __rt_utest_tc_tab_end = .;

        /* section information for at server */
        . = ALIGN(4);
        __rtatcmdtab_start = .;
        KEEP(*(RtAtCmdTab))
        __rtatcmdtab_end = .;
        . = ALIGN(4);

        /* section information for initial. */
        . = ALIGN(4);
        __rt_init_start = .;
        KEEP(*(SORT(.rti_fn*)))
        __rt_init_end = .;

        . = ALIGN(4);

        PROVIDE(__ctors_start__ = .);
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array))
        PROVIDE(__ctors_end__ = .);

        . = ALIGN(4);

        _etext = .;
    } > ROM = 0

    /* .ARM.exidx is sorted, so has to go in its own output section.  */
    __exidx_start = .;
    .ARM.exidx :
    {
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)

        /* This is used by the startup in order to initialize the .data secion */
        _sidata = .;
    } > ROM
    __exidx_end = .;

    /* .data section which is used for initialized data */

    .data : AT (_sidata)
    {
        . = ALIGN(4);
        /* This is used by the startup in order to initialize the .data secion */
        _sdata = . ;

        *(.data)
        *(.data.*)
        *(.gnu.linkonce.d*)


        PROVIDE(__dtors_start__ = .);
        KEEP(*(SORT(.dtors.*)))
        KEEP(*(.dtors))
        PROVIDE(__dtors_end__ = .);

        . = ALIGN(4);
        /* This is used by the startup in order to initialize the .data secion */
        _edata = . ;
    } >RAM

    .stack : 
    {
        . = ALIGN(4);
        _sstack = .;
        . = . + _system_stack_size;
        . = ALIGN(4);
        _estack = .;
    } >RAM

    __bss_start = .;
    .bss :
    {
        . = ALIGN(4);
        /* This is used by the startup in order to initialize the .bss secion */
        _sbss = .;

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

        . = ALIGN(4);
        /* This is used by the startup in order to initialize the .bss secion */
        _ebss = . ;
        
        *(.bss.init)
    } > RAM
    __bss_end = .;

    _end = .;

    /* 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) }
}

@zhang00956
Copy link

zhang00956 commented May 6, 2021

gcc脚本写的千差万别,我这边也是这个问题。cmback的宏定义
CMB_CSTACK_BLOCK_START;
CMB_CSTACK_BLOCK_END;
CMB_CODE_SECTION_START;
CMB_CODE_SECTION_END;
主要是为了知道堆栈起止地址和code段起止地址。
首先说code段。code段需要修改链接脚本如下
.text :
{
_stext = .;
//中间各种内容不用管,没有的话只需在首尾添加上 _stext = .; 和 _etext = .;
_etext = .;
}>FLASH

然后说堆栈,堆栈各种厂商写的不统一。有的厂商的连接脚本连
.stack :
{
. = ALIGN(4);
_sstack = .;
. = . + _system_stack_size;
. = ALIGN(4);
_estack = .;
} >RAM
这部分都不写,但是我们可以根据gcc 编译的map文件找到.stack段。

例如我的map文件搜索 .stack可以查找到如下内容:

.stack 0x00008e80 0x1000 ./build/Debug/startup.o
[!provide] PROVIDE (stack_data_start = (ORIGIN (RAM) + LENGTH (RAM)))
[!provide] PROVIDE (mesh_stack_data_start = stack_data_start)
0x0000b8c8 __StackTop = mesh_stack_data_start
0x0000a8c8 __StackLimit = (__StackTop - SIZEOF (.stack_dummy))
0x0000b8c8 PROVIDE (__stack = __StackTop)
0x00000001 ASSERT ((__StackLimit >= __HeapLimit), region RAM overflowed with stack)

然后我的连接脚本又是这种的:
MEMORY
{
RAM (rwx) : ORIGIN = 0x0000, LENGTH = 0xc000
FLASH (rx) : ORIGIN = 0x18005000, LENGTH = 0x40000
}

SECTIONS
{
vector_lma = ORIGIN(FLASH);

.vector :
{
    . = ALIGN(4);
    __vector__start__ = .;
    KEEP(*(.isr_vector))
    __vector__end__ = .;
}>RAM AT>FLASH


.text :
{
    _stext = .;
    KEEP(*(.init))
    KEEP(*(.fini))
    _etext = .;
}>FLASH

.bss (NOLOAD):
{
    __bss_start__ = .;
    *(.bss*)
    *(COMMON)
    *(SECTION_RTT)
    __bss_end__ = ALIGN(4);
}>RAM

.heap (NOLOAD):
{
    __end__ = .;
    PROVIDE(end = .);
    *(.heap*)
} > RAM

ASSERT(reset_retain_end <= 0xb800, "Error end address for reset retain")
.dmaram 0xa000 (NOLOAD):
{
    *(DMAC1)
    *(DMARAM)
}
/* .stack_dummy section doesn't contains any symbols. It is only
 * used for linker to calculate size of stack sections, and assign
 * values to stack symbols later */
.stack_dummy (NOLOAD):
{
    *(.stack*)
} > RAM

/* Set stack top to end of RAM, and stack limit move down by
 * size of stack_dummy section */
PROVIDE(__stack_data_start__ = ORIGIN(RAM) + LENGTH(RAM));
PROVIDE(__mesh_stack_data_start__ = __stack_data_start__);
__StackTop = __mesh_stack_data_start__;
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);

/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")

}
根据摸索map文件和连接脚本反复测试,最后发现堆栈开始地址
CMB_CSTACK_BLOCK_START = __StackTop
CMB_CSTACK_BLOCK_END = __StackLimit

@Mexico-zyy-lost
Copy link

请教一下各位,这个问题现在解决了吗?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants