重新排列对齐对象的最小空间使用顺序
问题描述:
我有一个数据结构需要4-KiB对齐。我可以使用__attribute__ ((aligned (4096)))
来强制执行此操作。重新排列对齐对象的最小空间使用顺序
问题是,这种对齐要求会导致内存浪费。这是链接器如何放置符号(pg_dir
是对齐的数据结构):
00011000 <cursor_loc>:
00012000 <pg_dir>:
00013000 <idt>:
cursor_loc
的大小只是四个字节。这将是更好的:
00011000 <pg_dir>:
00012000 <cursor_loc>:
00012008 <idt>:
(idt
必须是我们在8字节对齐。)
您可以通过使用多个文件这样的重现:
test1.c
:
char aligned[4096] __attribute__ ((aligned (4096)));
int i;
test2.c
:
0000000000602004 <j>:
...
0000000000603000 <aligned>:
...
0000000000604000 <i>:
我怎样才能移动GNU LD重新排列为最小的空间浪费符号:
int j;
int main(void) { }
然后用
gcc test1.c test2.c
和objdump -D a.out
打印此建呢?我真的很想知道为什么它不能自动完成。
答
有一些成语要求对象按照命令行中指定的顺序排列(这就是为什么你的结果有点奇怪,可能是由于常见的符号),并且对象内定义是不重新排序。要解决这一点,你需要的是这样的:
gcc -fno-common -fdata-sections -Wl,--sort-section=alignment test1.c test2.c
-fno-common
禁用常见的符号,-fdata-sections
允许链接器从同一文件重新排列的符号,并-Wl,--sort-section=alignment
终于能够通过对准排序。
这工作整齐,谢谢。我只是想知道为什么当我objdump时它们仍然出现在'.bss'中,尽管我使用了'-fno-common'和'-fdata-sections'。实际上,我需要它们在'.bss'中,这只是我不明白为什么这些开关不会更改它们所属的部分。 – Downvoter
是的,我对'.bss'感到困惑。如果你指定了一个初始化方法,你只能从'.bss'中得到零初始化的符号,如果它仍然为零,编译'-fno-zero-initialized-in-bss'(来禁止'.bss'优化) 。很高兴你需要'.bss'符号。 –
不会“-Wl, - sort-common”也起作用吗? – Hasturkun