How to specify ELF section alignment in GNU as?

空扰寡人 提交于 2019-12-11 13:09:16

问题


I'm trying to use GNU as as a generic assembler similar in use as nasm. I make a template source like this:

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

And then I run the assemble command like this:

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

All works well with binutils 2.24. But it appears that as from binutils 2.22 (the one in Ubuntu Precise) aligns .text section to the 4-byte boundary, thus instead of the expected disassembly I get wrong results:

 # 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

The problem is in the as command (i.e. not ld): readelf -S gives me the following for results of as 2.22:

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

And for 2.24 I have

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

So the problem is indeed alignment of .text section. I've tried placing .align 0 and .align 1 in various places in the source, but it didn't change the output.

So my question now: how to explicitly specify section alignment for ELF target in GNU assembler?


回答1:


Likely the default linker script LD is causing some kind of forced alignment. I'd create a basic linker script with the origin point, and tell it which sections you want (specifying the alignment), and in what order sections will appear.

linker.ld

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

This script utilizes the SUBALIGN directive to override the alignment of the .text section as it appears in the input object. From the GNU Linker documentation it has this effect:

3.6.8.4 Forced Input Alignment

You can force input section alignment within an output section by using SUBALIGN. The value specified overrides any alignment given by input sections, whether larger or smaller.

Then use:

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

The output I get here is:

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

When a section in an object file(s) doesn't get processed by the sections in the linker script, the input sections will still be emitted. All unprocessed input sections will be output at the end in the order they were encountered by the linker.




回答2:


Inspired by answer by Michael Petch (v3), I've found a way to make the working linker script to subalign the output section:

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

Now I have the following result:

$ as --32 -o test.o test.s
$ ld -m elf_i386 -T linker.ld --oformat binary -o test.bin test.o
$ ndisasm -b 32 -o 0xb77431d9 test.bin
B77431D9  E8E2FFFFFF        call dword 0xb77431c0

This is exactly the desired output, with the correct call target and no extraneous alignment.



来源:https://stackoverflow.com/questions/36956010/how-to-specify-elf-section-alignment-in-gnu-as

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!