2016-08-02 26 views
0

在x86架构的小型32位内核上工作时,我发现ld处理nobits节时有些奇怪。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

好吧我想通了。

显然你不应该在该部分的名称后面有一个逗号。 objdump包含部分名称中的逗号,以便清楚地表明这是错误。

所以

section .bootstrap_stack, nobits 

应该

section .bootstrap_stack nobits