問題鏈接腳本.relocate節的第一個符號,_srelocate,是不正確的(GCC漏洞?)
我的問題是,當我使用它的目的是將代碼放到RAM以下腳本移居部分得到充斥着虛假數據。
我的問題是:
爲什麼比
_etext
符號越大_srelocate
符號4個字節?他們不應該一樣嗎?此外,如果1.的答案是NO,我不應該從
_etext + 4
複製到_srelocate
?
背景和相關代碼
我與愛特梅爾ATSAM3N4X系列處理器(了ARM Cortex M3)合作,並希望與我的鏈接腳本和.relocate
段初始化一點幫助。
原因是_etext
符號比_srelocate
符號少4個字節。
以下鏈接腳本是由Atmel Studio 6中生成的默認腳本(如果你想ram
/rom
符號位置看到Apendix的問題)。
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
/* Section Definitions */
SECTIONS
{
.text :
{
. = ALIGN(4);
_sfixed = .;
KEEP(*(.vectors .vectors.*))
*(.text .text.* .gnu.linkonce.t.*)
*(.glue_7t) *(.glue_7)
*(.rodata .rodata* .gnu.linkonce.r.*)
*(.ARM.extab* .gnu.linkonce.armextab.*)
/* Support C constructors, and C destructors in both user code
and the C library. This also provides support for C++ code. */
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
. = ALIGN(0x4);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
. = ALIGN(4);
KEEP(*(.fini))
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
. = ALIGN(4);
_efixed = .; /* End of text section */
} > ram
. = ALIGN(4);
_etext = .;
.relocate : AT (_etext)
{
. = ALIGN(4);
_srelocate = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram
/* .bss section which is used for uninitialized data */
.bss (NOLOAD) :
{
. = ALIGN(4);
_sbss = . ;
_szero = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = . ;
_ezero = .;
} > ram
/* stack section */
.stack (NOLOAD):
{
. = ALIGN(8);
_sstack = .;
. = . + STACK_SIZE;
. = ALIGN(8);
_estack = .;
} > ram
/* .ARM.exidx is sorted, so has to go in its own output section. */
PROVIDE_HIDDEN (__exidx_start = .);
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > ram
PROVIDE_HIDDEN (__exidx_end = .);
. = ALIGN(4);
_end = . ;
}
我用nm
,看看有什麼符號值分別爲,我已經包括下面這些:
2000115c A _etext
20001160 D _srelocate
200015c8 D _erelocate
現在,愛特梅爾Studio 6中自動生成我的項目,給了我一個Reset_Handler()
該副本.relocate
從_etext
到_srelocate
的部分,並清除.bss
部分。該項目帶有兩個鏈接器腳本,一個用於基於FLASH的執行,另一個用於基於RAM的代碼。默認是基於FLASH的代碼,但我將其更改爲基於RAM的鏈接器腳本(上面提供),並且遇到了問題。
將.relocate
部分從FLASH複製到RAM的初始化代碼也是自動生成的,並且在更改鏈接器腳本時我沒有更改它。它看起來像這樣:
void Reset_Handler(void)
{
uint32_t *pSrc, *pDest, Size;
/* Initialize the relocate segment */
pSrc = &_etext;
pDest = &_srelocate;
if (pSrc != pDest) {
for (; pDest < &_erelocate;) {
*pDest++ = *pSrc++;
}
}
/* Clear the zero segment */
for (pDest = &_szero; pDest < &_ezero;) {
*pDest++ = 0;
}
/* Set the vector table base address */
pSrc = (uint32_t *) & _sfixed;
SCB->VTOR = ((uint32_t) pSrc & SCB_VTOR_TBLOFF_Msk);
if (((uint32_t) pSrc >= IRAM_ADDR) && ((uint32_t) pSrc < IRAM_ADDR + IRAM_SIZE)) {
SCB->VTOR |= (1UL) << SCB_VTOR_TBLBASE_Pos;
}
/* Initialize the C library */
__libc_init_array();
/* Branch to main function */
main();
/* Infinite loop */
while (1);
}
編輯1:
使用objdump -t CodeFile.elf > CodeFile.symbols
,我發現我的.relocate
節的開始,這似乎表明,_srelocate
並不真正指向開始這個符號.relocate
。
2000115c g O .relocate 00000000 .hidden __TMC_END__
是什麼意思?
我查了一下,發現在GCC 4.7中有this bug,但無法弄清楚它在我的版本中是否已修復。
我的編譯器是arm-none-eabi-gcc
和4.7.0
... 鏈接器arm-none-eabi-ld
且版本2.22
指出其版本。
編輯2:
我已經做了一些有關此研究,它被記錄在this related SO question我問。請看看它,因爲它解釋說問題是GCC bug。
Apendix鏈接描述文件
內存佈局
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)
/* Memory Spaces Definitions */
MEMORY
{
rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00040000 /* flash, 256K */
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00006000 /* sram, 24K */
}
/* The stack size used by the application. NOTE: you need to adjust */
STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x800 ;
您確實列出了編輯1中的錯誤。感謝您發佈您的解決方法。 – Patrick
對不起,它實際上沒有列出,所以我重新編輯我的問題列出它。 – nonsensickle
僅供參考,似乎'SRAM_START_ADDRESS'也是atmel所稱的#define。它在'mpu.h'標題中,所以你可能需要添加MPU ASF包。 –