gpt4 book ai didi

c - 数据结构对齐 : Linker or Compiler

转载 作者:太空狗 更新时间:2023-10-29 16:05:46 24 4
gpt4 key购买 nike

数据结构对齐对应谁的任务?是编译器、链接器、加载器还是硬件本身,比如 x86?编译器是否进行相对对齐寻址,以便当链接器在编译后的可执行文件中正确“放置”时,数据结构始终与各自的 native 大小边界对齐? loader 之后还有什么任务要做?

最佳答案

答案是编译器和链接器0 需要理解和处理对齐要求。编译器是这对编译器中聪明的一个,因为它只了解实际的结构、堆栈和变量对齐规则 - 但它会将一些有关所需对齐的信息传播给链接器,链接器在生成最终可执行文件。

编译器负责大量运行时对齐处理,相反,也经常依赖于满足某些最小对齐的事实1。此处的现有答案详细介绍了编译器的功能。

缺少的是链接器和加载器框架也处理对齐。一般来说,每个部分都有一个最小对齐属性,链接器写入该属性并且加载器遵守它,确保该部分加载到至少与该属性对齐的边界上。

不同的部分会有不同的要求,代码的更改会直接影响这些。一个简单的例子是全局数据,无论它是在 .bss.rodata.data 还是其他部分。这些部分的对齐至少与存储在其中的任何对象的最大对齐要求一样大。

因此,如果您有一个 64 字节对齐的只读 (const) 全局对象,您的 .rodata 部分将至少有 64 字节对齐,链接器将确保满足此要求。

您可以使用 objdump -h 查看 Algn 列中任何目标文件的实际对齐要求。这是一个随机示例:

Sections:
Idx Name Size VMA LMA File off Algn Flags
0 .interp 0000001c 0000000000400238 0000000000400238 00000238 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .note.ABI-tag 00000020 0000000000400254 0000000000400254 00000254 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .note.gnu.build-id 00000024 0000000000400274 0000000000400274 00000274 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .gnu.hash 00000030 0000000000400298 0000000000400298 00000298 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .dynsym 00000288 00000000004002c8 00000000004002c8 000002c8 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .dynstr 00000128 0000000000400550 0000000000400550 00000550 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .gnu.version 00000036 0000000000400678 0000000000400678 00000678 2**1 CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .gnu.version_r 00000050 00000000004006b0 00000000004006b0 000006b0 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .rela.dyn 00000060 0000000000400700 0000000000400700 00000700 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .rela.plt 00000210 0000000000400760 0000000000400760 00000760 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .init 0000001a 0000000000400970 0000000000400970 00000970 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE
11 .plt 00000170 0000000000400990 0000000000400990 00000990 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .plt.got 00000008 0000000000400b00 0000000000400b00 00000b00 2**3 CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .text 000021e2 0000000000400b10 0000000000400b10 00000b10 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .fini 00000009 0000000000402cf4 0000000000402cf4 00002cf4 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE
15 .rodata 00000700 0000000000402d00 0000000000402d00 00002d00 2**5 CONTENTS, ALLOC, LOAD, READONLY, DATA
16 .eh_frame_hdr 000000b4 0000000000403400 0000000000403400 00003400 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA
17 .eh_frame 000003d4 00000000004034b8 00000000004034b8 000034b8 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA
18 .init_array 00000008 0000000000603e10 0000000000603e10 00003e10 2**3 CONTENTS, ALLOC, LOAD, DATA
19 .fini_array 00000008 0000000000603e18 0000000000603e18 00003e18 2**3 CONTENTS, ALLOC, LOAD, DATA
20 .jcr 00000008 0000000000603e20 0000000000603e20 00003e20 2**3 CONTENTS, ALLOC, LOAD, DATA
21 .dynamic 000001d0 0000000000603e28 0000000000603e28 00003e28 2**3 CONTENTS, ALLOC, LOAD, DATA
22 .got 00000008 0000000000603ff8 0000000000603ff8 00003ff8 2**3 CONTENTS, ALLOC, LOAD, DATA
23 .got.plt 000000c8 0000000000604000 0000000000604000 00004000 2**3 CONTENTS, ALLOC, LOAD, DATA
24 .data 00000020 00000000006040d0 00000000006040d0 000040d0 2**4 CONTENTS, ALLOC, LOAD, DATA
25 .bss 000001c8 0000000000604100 0000000000604100 000040f0 2**5 ALLOC
26 .comment 00000034 0000000000000000 0000000000000000 000040f0 2**0 CONTENTS, READONLY

此处的对齐要求从2**0(不需要对齐)到2**5(对齐32字节边界)不等。

除了您提到的候选项之外,运行时 还需要注意对齐。这个主题有点复杂,但基本上你可以确定 malloc 和相关函数返回适合任何基本类型对齐的内存(这通常意味着 64 位系统上的 8 字节对齐),虽然 things get more complicated当您谈论过度对齐类型或 C++ alignas 时。


0 我最初只是将(编译时)链接器和(运行时)加载器归为一组,因为它们实际上是同一枚硬币的两面(实际上大部分链接实际上是运行时链接).然而,在更仔细地研究加载过程之后,加载程序似乎可能只是在现有文件偏移量处加载段(部分),自动遵守链接器设置的对齐方式。

1 在像 x86 这样通常允许未对齐访问的平台上不太如此,但在对齐限制更严格的平台上,如果遇到不正确的对齐,代码实际上可能会失败。

关于c - 数据结构对齐 : Linker or Compiler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42435434/

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