在鏈接腳本中很重要的一部分就是對於section的描述,本文將結合上例對於鏈接腳本中的section部分的描述進行簡單的整理。
SECTIONS
{
.vector :
{
*(.vector)
} > flash
. = ALIGN(4);
/* .text */
.text :
{
CREATE_OBJECT_SYMBOLS
__cs3_reset = .;
*(.text .text.* .gnu.linkonce.t.*)
*(.plt)
*(.gnu.warning)
*(.glue_7t) *(.glue_7) *(.vfp11_veneer)
*(.ARM.extab* .gnu.linkonce.armextab.*)
*(.gcc_except_table)
} > flash
.eh_frame_hdr : ALIGN (4)
{
KEEP (*(.eh_frame_hdr))
} > flash
.eh_frame : ALIGN (4)
{
KEEP (*(.eh_frame))
} > flash
/* .ARM.exidx is sorted, so has to go in its own output section. */
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > flash
__exidx_end = .;
.rodata : ALIGN(4)
{
*(.rodata .rodata.* .gnu.linkonce.r.*)
. = 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(4);
KEEP(*(.fini))
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
. = ALIGN(0x4);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
. = ALIGN(0x4);
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
. = ALIGN(4);
__cs3_regions = .;
LONG (0)
LONG (__cs3_region_init_ram)
LONG (__cs3_region_start_ram)
LONG (__cs3_region_init_size_ram)
LONG (__cs3_region_zero_size_ram)
__cs3_regions_end = .;
. = ALIGN (8);
_etext = .;
} > flash
.data : ALIGN(8)
{
__cs3_region_start_ram = .;
KEEP(*(.jcr))
*(.got.plt) *(.got)
*(.shdata)
*(.data .data.* .gnu.linkonce.d.*)
. = ALIGN (8);
*(.sram)
_edata = .;
} > sram AT > flash
.bss :
{
*(.shbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN (8);
*(.sram.b .bss.sram)
_end = .;
__end = .;
} > sram
/* __cs3_region_end_ram is deprecated */
__onchip_ram_end = 0x1FFF8000 + LENGTH(sram);
__cs3_region_end_ram = 0x1FFF8000 + LENGTH(sram);
__cs3_region_size_ram = __cs3_region_end_ram - __cs3_region_start_ram;
__cs3_region_init_ram = LOADADDR (.data);
__cs3_region_init_size_ram = _edata - ADDR (.data);
__cs3_region_zero_size_ram = _end - _edata;
.stab 0 (NOLOAD) : { *(.stab) }
.stabstr 0 (NOLOAD) : { *(.stabstr) }
/* 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) }
.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) }
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) }
}
(1)section部分的基本的描述格式如下:
SECTIONS命令告訴鏈接器如何將輸出section組織到輸出的sections當中。基本的格式如下:
SECTIONS
{
sections-command
sections-command
...
}
對應的sections-command可能爲:
a)ENTRY命令
b)一個符號的分配(賦值語句)
c)輸出section的描述
d)an overlay description
輸出section描述的基本格式如下:
section [address ] [(type )] :
[AT(lma )]
[ALIGN(section_align )]
[SUBALIGN(subsection_align )]
[constraint ]
{
output-section-command
output-section-command
...
} [>region ] [AT>lma_region ] [:phdr :phdr ...] [=fillexp ]
[ ]內的內容爲可選選項, 一般不需要.
SECTION:section名字
SECTION左右的空白、圓括號、冒號是必須的,換行符和其他空格是可選的。
例:
.vector :
{
*(.vector)
} > flash
描述輸出的目標文件中存在一個節爲.vector,他將所有輸入的文件的.vector節放在一起組成了輸出的.vector節,並且輸出的.vector節放置在存儲區域flash當中
對於輸入的section有很多方式,描述方式和正則表達式相似。
(2)KEEP
在 連接命令行內使用了選項--gc-sections後,連接器可能將某些它認爲沒用的section過濾掉,此時就有必要強制連接器保留一些特定的 section,可用KEEP()關鍵字達此目的。如KEEP(*(.text)).
(3)在輸出section內存放數據命令:
能夠顯示地在輸出section內填入你想要填入的信息(這樣是不是可以自己通過連接腳本寫程序?當然是簡單的程序)。
BYTE(EXPRESSION) 1 字節
SHORT(EXPRESSION) 2 字節
LOGN(EXPRESSION) 4 字節
QUAD(EXPRESSION) 8 字節SQUAD(EXPRESSION) 64位處理器的代碼時,8 字節
這些命令只能放在輸出section描述內,其他地方不行
(4)輸出section內命令的關鍵字
CREATE_OBJECT_SYMBOLS :爲每個輸入文件建立一個符號,符號名爲輸入文件的名字。每個符號所在的section是出現該關鍵字的section。
(5)SORT
此處的SORT是SORT_BY_NAME的別名,具體的描述如下:
When the SORT_BY_NAME keyword is used, the linker will sort the files or sections into ascending order by name before placing them in the output file.可以用SORT()關鍵字對滿足字符串模式的所有名字進行遞增排序,如SORT(.text*)。
關於鏈接腳本的要點信息基本上就如同上面所描述的這樣,對於具體的鏈接腳本的分析,建議在結合上面的兩篇博客的要點描述的基礎上查閱如下資料進行:
鏈接腳本相關的資料(Mahao_ALex整理)(提取密碼:ghh1)