语法规则:
section [address] [(type)] :
[AT(lma)]
[ALIGN(section_align) | ALIGN_WITH_INPUT]
[SUBALIGN(subsection_align)]
[constraint]
{
output-section-command
output-section-command
...
} [>region] [AT>lma_region] [:phdr :phdr ...] [=fillexp] [,]
1. output section 中的 “.”为location counter, 不可以move backward
SECTIONS{
}
2. output section的assignment语法,要注意link会插入lds中未定义的section,插入的位置默认赋值语句是跟随前一个output sections
例如:
SECTIONS
{
start_of_text = . ;
.text: { *(.text) }
end_of_text = . ;
start_of_data = . ;
.data: { *(.data) }
end_of_data = . ;
}
默认插入.rodata如下:
SECTIONS
{
start_of_text = . ;
.text: { *(.text) }
end_of_text = . ;
start_of_data = . ;
.rodata: { *(.rodata) }
.data: { *(.data) }
end_of_data = . ;
}
导致start_of_data 的值并不是.data sectios的起始值,为解决这个问题,必须插入.赋值语句,link会认为是给后面的output sections设置一个新的起始地址。
如下:
SECTIONS
{
start_of_text = . ;
.text: { *(.text) }
end_of_text = . ;
. = . ;
start_of_data = . ;
.data: { *(.data) }
end_of_data = . ;
}
3. 为防止出以为,output sections尽量写成这样:
.text . : { *(.text) }
而不要写成
.text : { *(.text) }
第一种text放到当前的location counter
第二种text放到alignment最严格的地方region。所以不一定是放在当前位置。
4. AT潜规则, 如果AT和AT>都没有使用,则按照下面顺序的规则
1. 如果有指定具体的VMA地址,如 .text 0x1000 : { *(.text) _etext = . ; }, 则LMA=VMA;
2. 如果section是not allocatable的,则LMA=VMA; 比如type为OVERLAY的时候是not allocatable
3. 如果能找到能兼容当前section的memory region,且已经至少有一个section,那么LMA设置为与已经定位到该region最后一个section相同的差值(LMA和VMA)
4. 如果没有定义memory region,那么默认为region是包含所有完整的地址空间,且同样应用上面第3点
5. 如果有定义memory region,但是找不到合适属性的region,或者能找到合适的region,但是没有之前没有section定位到该region,则LMA=VMA;
5. output section address潜规则:
1. 有指定输出地址的放在指定输出地址,按照output section内部最严alignment对齐。
2. 没有指定地址的,如果有指定region,就放在该region下的free位置。
3. 如果都没有指定,从MEMROY列表中找第一个满足属性要求的memory region,放在该region的free位置
4. 如果也没有memory列表,则放在当前的location counter位置,也就是“.”的位置。