在链接脚本中很重要的一部分就是对于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)