当处理x86架构的小型32位内核时,我发现ld
处理nobits部分的方式很奇怪。
在我的内核中,我定义了一个.bootstrap_stack
部分,它包含系统初始化部分的临时堆栈。我还为堆栈的开头和结尾保存符号。此输入部分重定向到.bss
输出部分。我内核的每个输出部分都有一个符号,用于该部分的开头和结尾。
问题是在最终的可执行文件中,堆栈末尾的符号是在.bss
部分结束之后。在下面的示例中,符号stack_top
和_kernel_ebss
(和_kernel_end
)具有相同的值,这不是我想要的。
我希望_kernel_ebss
等于stack_bottom
。
但是,一旦我将.bootstrap_stack
重命名为.bss
,就不会发生这种情况。删除nobits
也有效,但生成的二进制文件要大得多。
以下是重现我的问题的剥离文件:
boot.s
section .bootstrap_stack, nobits ; this does not work
;section .bootstrap_stack ; this works
;section .bss ; this also works
stack_top:
resb 8096
stack_bottom:
section .text
global _start
_start:
hlt
jmp _start
linker.ld
ENTRY(_start)
SECTIONS
{
. = 0xC0100000;
_kernel_start = .;
.text ALIGN(4K) : AT(ADDR(.text) - 0xC0000000)
{
_kernel_text = .;
*(.multiboot)
*(.text)
_kernel_etext = .;
}
.bss ALIGN(4K) : AT(ADDR(.bss) - 0xC0000000)
{
_kernel_bss = .;
*(COMMON)
*(.bss)
*(.bootstrap_stack)
_kernel_ebss = .;
}
_kernel_end = .;
}
以下是符号:
$ objdump -t kernel | sort
00000000 l df *ABS* 00000000 boot.s
c0100000 g .text 00000000 _kernel_start
c0100000 g .text 00000000 _kernel_text
c0100000 g .text 00000000 _start
c0100000 l d .text 00000000 .text
c0100003 g .text 00000000 _kernel_etext
c0101000 g .text 00000000 _kernel_bss
c0101000 g .text 00000000 _kernel_ebss
c0101000 g .text 00000000 _kernel_end
c0101000 l .bootstrap_stack, 00000000 stack_top
c0101000 l d .bootstrap_stack, 00000000 .bootstrap_stack,
c0102fa0 l .bootstrap_stack, 00000000 stack_bottom
通过将.bootstrap_stack
重命名为.bss
,我得到了我的预期。
00000000 l df *ABS* 00000000 boot.s
c0100000 g .text 00000000 _kernel_start
c0100000 g .text 00000000 _kernel_text
c0100000 g .text 00000000 _start
c0100000 l d .text 00000000 .text
c0100003 g .text 00000000 _kernel_etext
c0101000 g .bss 00000000 _kernel_bss
c0101000 l .bss 00000000 stack_top
c0101000 l d .bss 00000000 .bss
c0102fa0 g .bss 00000000 _kernel_ebss
c0102fa0 g .bss 00000000 _kernel_end
c0102fa0 l .bss 00000000 stack_bottom
我的问题是这是否是ld的预期行为。如果是的话,我的例子有什么问题,因为据我所知.bss
也是一个nobits部分,但它会产生预期的结果?
答案 0 :(得分:1)
好的,我明白了。
显然你不应该在该部分名称后面有一个逗号。 objdump
包含该部分名称中的逗号,以便清楚地表明这是错误。
所以
section .bootstrap_stack, nobits
应该是
section .bootstrap_stack nobits