【问题标题】:How to specify ELF section alignment in GNU as?如何在 GNU 中将 ELF 部分对齐指定为?
【发布时间】:2016-04-30 14:21:25
【问题描述】:

我正在尝试将 GNU as 用作与 nasm 类似的通用汇编程序。我制作了这样的模板源:

.section .text
.globl _start
.intel_syntax noprefix
_start:
call 0xb77431c0 # the instruction I want to assemble

然后我像这样运行 assemble 命令:

as --32 -o test.o test.s
ld -m elf_i386 -Ttext 0xb77431d9 --oformat binary -o test.bin test.o

在 binutils 2.24 中一切正常。但似乎 binutils 2.22(Ubuntu Precise 中的那个)中的 as 将 .text 部分与 4 字节边界对齐,因此我得到了错误的结果,而不是预期的反汇编:

 # expected and working in binutils 2.24
$ ndisasm -b 32 -o 0xb77431d9 test.bin
B77431D9  E8E2FFFFFF        call dword 0xb77431c0

 # actual in binutils 2.22
$ ndisasm -b 32 -o 0xb77431d9 test.bin
B77431D9  90                nop
B77431DA  90                nop
B77431DB  90                nop
B77431DC  E8DFFFFFFF        call dword 0xb77431c0

问题出在as 命令中(即不是ld):readelf -S 给了我以下as 2.22 的结果:

$ readelf -S test.o | grep ' \.text'
  [ 1] .text             PROGBITS        00000000 000034 000005 00  AX  0   0  4

对于 2.24,我有

$ readelf -S test.o | grep ' \.text'
  [ 1] .text             PROGBITS        00000000 000034 000005 00  AX  0   0  1

所以问题确实是.text 部分的对齐。我尝试将.align 0 和.align 1 放在源代码的各个位置,但它并没有改变输出。

现在我的问题:如何在 GNU 汇编器中显式指定 ELF 目标的部分对齐方式?

【问题讨论】:

  • 我真的希望这可以直接在程序集中进行,而不需要链接器脚本。很伤心:-(

标签: assembly elf memory-alignment gnu-assembler


【解决方案1】:

可能是默认链接描述文件 LD 导致了某种强制对齐。我会创建一个带有原点的基本链接器脚本,并告诉它您想要哪些部分(指定对齐方式),以及部分将出现的顺序。

linker.ld

SECTIONS
{
    . = 0xb77431d9;
    .text . : SUBALIGN(0)
    {
        *(.text)
    }
}

此脚本利用SUBALIGN 指令覆盖.text 部分的对齐方式,因为它出现在输入对象中。从 GNU Linker 文档来看,它具有以下效果:

3.6.8.4 强制输入对齐

您可以使用 SUBALIGN 强制输入节在输出节内对齐。这 指定的值会覆盖输入节给出的任何对齐方式,无论是更大还是更小。

然后使用:

as --32 -o test.o test.s
ld -T linker.ld -m elf_i386 --oformat binary -o test.bin test.o

我在这里得到的输出是:

ndisasm -b 32 -o 0xb77431d9 test.bin
B77431D9  E8E2FFFFFF        call dword 0xb77431c0

当链接描述文件中的部分未处理目标文件中的部分时,仍会发出输入部分。所有未处理的输入节将按照链接器遇到的顺序在末尾输出。

【讨论】:

  • 这实际上不起作用。调用目标是这样变化的:它应该是0xb77431c0,但看起来却是0xb77431bd。
  • 您的回答确实有帮助,尽管并不能完全解决问题。我做了一些改进,并发布了可行的解决方案。
  • 哦,我忘记了你最初在原始 nasm 中编码的内容。
  • @Ruslan :啊,我正在研究一个新的答案,并没有看到你发布了类似的修复。我也赞成你的回答,因为它似乎很接近这个。对于那个很抱歉。这就是我凌晨 3 点做这件事的结果。
  • 没问题。我想我会接受你的,因为它有更多细节——这样未来的访问者就会立即接触到它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-26
  • 1970-01-01
  • 2013-08-01
相关资源
最近更新 更多