对齐链接描述文件中data / sbss部分中的所有目标文件

时间:2013-05-01 17:24:20

标签: linker embedded ld memory-alignment linker-scripts

编辑:已解决 - 应用于静态数据部分的链接描述文件属性“SUBALIGN(32)”完全符合我的要求,强制链接的每个对象文件对齐到32字节边界,并自动插入填充。

__bss_start = .;  
.bss            :  
SUBALIGN(32)  
{  
  *(.dynbss)  
  *(.bss .bss.* .gnu.linkonce.b.*)  
  *(COMMON)  
      SORT(CONSTRUCTORS)  
  . = ALIGN(32);  
} = 0  
  . = ALIGN(32);  

我正在构建一个缓存无关架构的多程序基准测试,该架构由重命名和链接在一起的EEMBC套件的多个实例组成。

问题是库在可写数据段中没有高速缓存行对齐,而且我在这里遇到数据损坏(在连贯模拟中由高速缓存行抖动证明)。

例如,在Viterb0和Viterb1上运行的内核之间共享0x7500的高速缓存行,映射输出表明这是库0运行到library1启动的高速缓存行的位置:

...  
 .bss           0x000068e8      0xc24 ../EEMBClib/libmark_0.a(renamed_renamed_viterb00_viterb00.o)  
 .bss           0x0000750c        0x4 ../EEMBClib/libmark_1.a(renamed_renamed_viterb00_bmark_lite.o)  
...  

我需要将各个数据段中链接的每个目标文件对齐到32字节边界,我只知道如何对齐整个部分,当前的.bss部分是:

  __bss_start = .;  
  .bss            :  
  {  
    *(.dynbss)  
    *(.bss .bss.* .gnu.linkonce.b.*)  
    *(COMMON)  
        SORT(CONSTRUCTORS)  
    . = ALIGN(32);  
  } = 0  
    . = ALIGN(32);  

在这里可以非常感谢任何帮助,使用填充重建库并不是我想要考虑的选项,因为我希望这个更强大的解决方案可以在此平台上进行未来的链接。

2 个答案:

答案 0 :(得分:3)

解决方案是链接描述文件属性“SUBALIGN(32)”。当应用于静态数据部分时,这完全符合我的要求,强制链接的每个对象文件对齐到32字节边界,并自动插入填充。

__bss_start = .;  
.bss            :  
SUBALIGN(32)  
{  
  *(.bss .bss.* .gnu.linkonce.b.*)
} = 0  
  . = ALIGN(32);  

给出固定的结果

.bss 0x00006940 0xc24 ../EEMBClib/libmark_0.a(renamed_renamed_viterb00_viterb00.o)
fill 0x00007564 0x1c 00000000
.bss 0x00007580 0x4 ../EEMBClib/libmark_1.a(renamed_renamed_viterb00_bmark_lite.o)

而不是

.bss           0x000068e8      0xc24 ../EEMBClib/libmark_0.a(renamed_renamed_viterb00_viterb00.o)  
.bss           0x0000750c        0x4 ../EEMBClib/libmark_1.a(renamed_renamed_viterb00_bmark_lite.o) 

答案 1 :(得分:1)

(抱歉,至少目前这是一个思想集合,而不是具体的答案,但在评论中发布会有点长)

可能首先要做的是提出一些验证例程来解析objdump / readelf输出以验证是否已满足对齐要求,并将其作为检查放入构建过程中。如果你不能在编译时这样做,至少要把它作为运行时检查。

然后可以调查实现对齐的一些路径。

假设一分钟创建了自定义部分,并且所有具有此要求的数据都放在源代码中的pragma中。如果链接器愿意遵守每个目标文件中该部分出现时给出的部分对齐设置,那么需要考虑的事情。例如,您可以对其中一个对象进行hexedit以增加该对齐,并使用转储处理器查看发生的情况。如果这样做很好 - 很好 - 这似乎是处理任务的正确方法,并且希望有一种合理的方法来指定该部分的对齐大小要求,这将最终出现在目标文件中。

另一个想法是尝试某种脚本分配调整。例如,使用objcopy将所有适用的部分连接到一个文件中,同时将它们从其他文件中剥离出来。分析文件并找出您想要的分配,然后使用objcopy或自定义精灵修改程序来设置它。也许您甚至可以对完全链接的结果进行此修改,至少如果您的链接器脚本将特殊部分放在最后,那么当您将其扩展到实现时,您不必移动其他分配内部对齐。

如果你不想修改elf,那么另一种用脚本进行辅助链接的方法可能是在特殊部分计算每个对象数据的大小,然后自动生成一个简单的附加目标文件划分到下一个对齐边界的焊盘。然后,链接阶段将指定列表中的对象:program1.o padding1.o program2.o padding2.o

或者您可以让每个程序将其特殊数据放在其自己唯一命名的链接器部分中。转出所有这些的大小,找出你想要它们的位置,然后让脚本创建一个自定义的链接描述文件,它明确地将命名的部分放在刚确定的位置。