I am playing with arm-none-eabi-as
trying to understand how it aligns sections. I have the following source:
; source.s
.text
.byte 0xff
.byte 0xff
.byte 0xff
I am inspecting the resulting object file:
$ arm-none-eabi-as -mthumb -o source.o source.s
$ arm-none-eabi-readelf -S source.o
There are 8 section headers, starting at offset 0xec:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000003 00 AX 0 0 1
[ 2] .data PROGBITS 00000000 000037 000000 00 WA 0 0 1
[ 3] .bss NOBITS 00000000 000037 000000 00 WA 0 0 1
[ 4] .ARM.attributes ARM_ATTRIBUTES 00000000 000037 000014 00 0 0 1
[ 5] .symtab SYMTAB 00000000 00004c 000060 10 6 6 4
[ 6] .strtab STRTAB 00000000 0000ac 000004 00 0 0 1
[ 7] .shstrtab STRTAB 00000000 0000b0 00003c 00 0 0 1
The .text
section is byte-aligned and contains the 3 bytes.
Now, I add an instruction to source.s
:
; source.s
.text
.byte 0xff
nop
.byte 0xff
.byte 0xff
Looking into the object file, now all of a sudden the .text
section is halfword-aligned:
There are 8 section headers, starting at offset 0x114:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000006 00 AX 0 0 2
[ 2] .data PROGBITS 00000000 00003a 000000 00 WA 0 0 1
[ 3] .bss NOBITS 00000000 00003a 000000 00 WA 0 0 1
[ 4] .ARM.attributes ARM_ATTRIBUTES 00000000 00003a 000014 00 0 0 1
[ 5] .symtab SYMTAB 00000000 000050 000080 10 6 8 4
[ 6] .strtab STRTAB 00000000 0000d0 000007 00 0 0 1
[ 7] .shstrtab STRTAB 00000000 0000d7 00003c 00 0 0 1
What is causing the assembler to decide to pad the section in the second case? I am confused because:
.data
then the assembler will not pad it anyway, which makes sense, but.text
, the assembler won't pad it unless it sees an instruction (I can have as many data directives, the section won't be padded without having also an instruction), and finallynop
instruction is definitely not aligned and the assembler has no problem with it, but it still decides to care about section alignment.How is the assembler deciding here to pad?
Can I force the assembler to not pad the .text
section even if I had an instruction?
Here is what I learned after discussing it with the binutils folks:
The assembler does not care if one encodes misaligned instructions in any particular section. However, it cares about two aspects:
The assembler enforces (2) because later those sections might need to be merged and after the merge all the elements within must keep their alignment (thus it pads the sections to ensure this property).
The difference between the two cases shown in the original post is that:
.byte
with an alignment of 1
, thus giving the entire section an alignment of 1
, whilenop
thumb instruction becomes the most aligned element and the section is now 2
-aligned.Since the section in the example is a .text
section and has the X
flag set, the assembler will pad the section in the second case to match its alignment. Nevertheless, the nop
instruction is still misaligned inside the section.