gpt4 book ai didi

ld - 如何获取输入节的大小(将其放在内存末尾)

转载 作者:行者123 更新时间:2023-12-04 04:26:03 25 4
gpt4 key购买 nike

我有以下链接器脚本:.data & .bss被放入 ram,然后是 .heap部分填充剩余的内存。

现在我想添加一个 .noinit总是放在内存末尾的部分。所以它会被引导加载程序等忽略。

我还想要我的.heap部分占用 .bss 之间的所有可用空间和 .noinit ,但为此我需要知道 .noinit 的大小部分。

一种幼稚的方法失败了:

/* .bss section which is used for uninitialized data */
.bss (NOLOAD) :
{
. = ALIGN(4);
_sbss = . ;
_szero = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = . ;
_ezero = .;
} > ram

/* heap section */
.heap (NOLOAD) :
{
. = ALIGN(4);
_sheap = . ;
. = ORIGIN(ram) + LENGTH(ram) - SIZEOF(.noinit);
_eheap = . ;
} > ram

/*
* collect all uninitialized sections that go into RAM
*/
.noinit (NOLOAD) :
{
. = ALIGN(4);
__noinit_start = .;
*(.noinit)
__noinit_end = .;
} > ram

这里 SIZEOF(.noinit)始终为 0,因为该部分是在该语句之后定义的。

但其实我想要的是 SIZEOF(*(.noinit)) - 然而这是一个语法错误。

那么如何在不先将输入部分放入输出部分的情况下获得输入部分的大小呢?

最佳答案

不完全是犹太洁食,但在挖掘 source code 之后对于 GNU ld,看起来您可以在定义后指定节的地址。
以下链接器脚本应该为您提供所需的行为:

MEMORY {
ram (rwx) : ORIGIN = 0x10000, LENGTH = 0x0002000
}

SECTIONS {

.bss (NOLOAD) : {
. = ALIGN(4);
_sbss = . ;
_szero = .;
*(.bss .bss.*)
*(COMMON)

/* Note: Just for example - padding .bss by 0x100 bytes so its not empty */
. = 0x100;

. = ALIGN(4);
_ebss = . ;
_ezero = .;
} > ram

/* create .noinit section */
.noinit (NOLOAD): {
. = ALIGN(4);
__noinit_start = .;

/* Note: Just for example - padding .noinit by 0x100 bytes so its not empty */
. = 0x100;

*(.noinit)
__noinit_end = .;
} > ram

/* place .heap after .bss */
.heap _ebss (NOLOAD) : {
. = ALIGN(4);
_sheap = . ;
. = ABSOLUTE(ORIGIN(ram) + LENGTH(ram) - SIZEOF(.noinit));
_eheap = . ;
} > ram

/* update .noinit to be placed at end of heap */
.noinit _eheap (NOLOAD) : { } > ram
}

与上述脚本链接的空二进制文件的输出显示了节和符号的正确位置:
echo | gcc -x c++ - -nostartfiles -T linkerScript.ld -Xlinker --orphan-handling=discard -fuse-ld=bfd  && objdump -th a.out

a.out: file format elf64-x86-64

Sections:
Idx Name Size VMA LMA File off Algn
0 .bss 00000100 0000000000010000 0000000000010000 00001000 2**0
ALLOC
1 .noinit 00000100 0000000000011f00 0000000000011f00 00001000 2**0
ALLOC
2 .heap 00001e00 0000000000010100 0000000000010100 00001000 2**0
ALLOC
SYMBOL TABLE:
0000000000010000 l d .bss 0000000000000000 .bss
0000000000011f00 l d .noinit 0000000000000000 .noinit
0000000000010100 l d .heap 0000000000000000 .heap
0000000000010100 g .heap 0000000000000000 _sheap
0000000000010000 g .bss 0000000000000000 _sbss
0000000000010000 g .bss 0000000000000000 _szero
0000000000010100 g .bss 0000000000000000 _ebss
0000000000010100 g .bss 0000000000000000 _ezero
0000000000011f00 g .noinit 0000000000000000 __noinit_start
0000000000012000 g .noinit 0000000000000000 __noinit_end
0000000000011f00 g .heap 0000000000000000 _eheap

Note: I couldn't find any documentation regarding this behavior so I can't guarantee this trick will work in future revisions of ld.


Note: This trick doesn't work for the gold linker.

关于ld - 如何获取输入节的大小(将其放在内存末尾),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56212181/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com