ZHCUAV7Z september 1995 – march 2023 66AK2E05 , 66AK2H06 , 66AK2H12 , 66AK2H14 , AM1705 , AM1707 , AM1802 , AM1806 , AM1808 , AM1810 , AM5K2E04 , OMAP-L132 , OMAP-L137 , OMAP-L138 , SM470R1B1M-HT , TMS470R1A288 , TMS470R1A384 , TMS470R1A64 , TMS470R1B1M , TMS470R1B512 , TMS470R1B768
用户可以在已初始化的输出段中创建一个空洞。当用户强制链接器在输出段内的输入段之间留出额外空间时,就会创建空洞。创建此类空洞时,链接器必须为该空洞提供原始数据。
只能在输出段内 创建空洞。输出段之间 可以存在空间,但这种空间不是空洞。若要填充输出段之间的空间,请参阅节 8.5.4.2。
若要在输出段中创建空洞,必须在输出段定义中使用特殊类型的链接器赋值语句。赋值语句会修改 SPC(由 . 表示),修改方法是向其添加、为其分配更大的值或在地址边界上将其对齐。有关赋值语句的运算符、表达式和语法的说明,请参阅节 8.5.10。
以下示例使用了赋值语句在输出段中创建空洞:
SECTIONS
{
outsect:
{
file1.c.obj(.text)
.+= 0x0100 /* 按大小 0x0100 创建一个空洞 */
file2.c.obj(.text)
.= align(16); /* 创建一个空洞以对齐 SPC */
file3.c.obj(.text)
}
}
输出段 outsect 的构建方式如下:
在一个段内分配给 . 符号的所有值指代该段内的相对地址。链接器处理 . 符号的赋值语句时会认为该段从地址 0 开始(即使已指定绑定地址也是如此)。请考虑示例中的赋值语句 .= align(16)。该语句实际上会将 file3.c.obj .text 段与 outsect 内的 16 字节边界上的起点对齐。如果 outsect 最终分配至未对齐的地址起点,则 file3.c.obj .text 段也不会对齐。
. 符号指段的当前运行地址,而不是当前加载地址。
减小 . 符号的表达式是非法的。例如,在 . 符号的赋值语句中使用 -= 运算符是无效的。. 符号的赋值语句中最常用的运算符是 += 和 align。
如果输出段包含某种类型的所有输入段(例如 .text),则可使用以下语句在输出段的开头或结尾创建一个空洞。
.text: { .+= 0x0100; } /* 位于开头的空洞 */
.data: { *(.data)
.+= 0x0100; } /* 位于结尾的空洞 */
在输出段中创建空洞的另一种方法是,将未初始化的段与已初始化的段组合形成单个输出段。在这种情况下,链接器会将未初始化的段视为空洞并为其提供数据。以下示例说明了此方法:
SECTIONS
{
outsect:
{
file1.c.obj(.text)
file1.c.obj(.bss) /* 这成为了一个空洞 */
}
}
由于 .text 段有原始数据,整个 outsect 也必须包含原始数据。因此,未初始化的 .bss 段将成为空洞。
未初始化的段只有在与已初始化的段组合时才会成为空洞。如果将多个未初始化的段链接在一起,则生成的输出段也未经初始化。