flat assembler
Message board for the users of flat assembler.
Index
> Linux > Entry point alignment for ELF64 executable |
Author |
|
revolution 14 Dec 2017, 12:10
Code doesn't need to be aligned.
|
|||
14 Dec 2017, 12:10 |
|
fasmnewbie 14 Dec 2017, 12:12
revolution wrote: Code doesn't need to be aligned. |
|||
14 Dec 2017, 12:12 |
|
revolution 14 Dec 2017, 12:41
The instruction lengths are variable. x86 has no requirement for code alignment.
|
|||
14 Dec 2017, 12:41 |
|
fasmnewbie 14 Dec 2017, 16:31
@revolution
ofc code alignment is not a requirement. But it does help in branch prediction, instruction fetch, front-end stalls and similar performance stuff. In fact, FASM PE's executable version does align the entry point to 8 or 16 boundaries (i can't remember which one). If you switched the position of the two segments shown above, the entry point is in fact aligned to 16-byte boundaries. It gives me the impression that FASM aligns only the first segment it finds in the source, and also suggests that the entry point should be in the first (code) segment in the source. This is quite limiting IMHO. idk, perhaps it has something to do with how kernel handles the entry point. |
|||
14 Dec 2017, 16:31 |
|
Furs 14 Dec 2017, 21:09
Usually, the entry point gets executed only once. GCC even marks it as "cold" by default (which means no alignment either, as far as I know). The entry point doesn't have to be at the beginning either.
It makes no sense to align the entry point when a "hot path" function (one called during an inner loop) would benefit from alignment or cache locality instead (stuck hot functions called near each other in close space, and align them of course). Just place the entry point somewhere in darkest pits of anti-performance because it's not important for speed. |
|||
14 Dec 2017, 21:09 |
|
fasmnewbie 15 Dec 2017, 06:02
@Furs
GCC aligns main entry point to 8/16-byte boundaries. Obviously there is branch prediction involved when GCC calls main and therefore it is crucial for performance for __main to be aligned. So does ld and golink. Even FASM PE's/PE64 console format does it all the time, every time. The only one off here is ELF64 executable format. |
|||
15 Dec 2017, 06:02 |
|
fasmnewbie 15 Dec 2017, 06:23
Here is an example (static) with GCC 64 (Windows). Observe the entry point's address in RAX
Code: ;------------------------------------------- ; fasm this.asm ; gcc -m64 this.obj cpu64.dll -s -o this.exe ;------------------------------------------- format MS64 coff public main extrn dumpreg section '.data' writeable msg db 'hello world',0ah,0 section '.text' executable main: sub rsp,40 mov rax,main mov rbx,msg call dumpreg add rsp,40 ret Observe RAX Code: RAX|00000000004015B0 RBX|0000000000403010 RCX|0000000000000001 RDX|00000000001E1360 RSI|0000000000000012 RDI|00000000001E1330 R8 |00000000001E42A0 R9 |00000000001E1360 R10|0000000000000000 R11|0000000000000246 R12|0000000000000001 R13|0000000000000008 R14|0000000000000000 R15|0000000000000000 RBP|00000000001E1360 RSP|000000000060FE30 RIP|00000000004015C8 [UHEX] |
|||
15 Dec 2017, 06:23 |
|
fasmnewbie 15 Dec 2017, 06:29
Another example, this time using GoLink with entry point "start". The entry point is aligned to 16 regardless of the positions of the sections.
Code: ;------------------------------------------- ; fasm this.asm ; golink /console this.obj cpu64.dll ;------------------------------------------- format MS64 coff public start extrn dumpreg extrn exitx section '.data' writeable msg db 'hello world',0ah,0 section '.text' executable start: sub rsp,40 mov rax,start mov rbx,msg call dumpreg add rsp,40 call exitx "start" entry point's address is shown in RAX, well-aligned to page boundaries. Code: RAX|0000000000401000 RBX|0000000000402000 RCX|00000000002CE000 RDX|0000000000401000 RSI|0000000000000000 RDI|0000000000000000 R8 |00000000002CE000 R9 |0000000000401000 R10|0000000000000000 R11|0000000000000000 R12|0000000000000000 R13|0000000000000000 R14|0000000000000000 R15|0000000000000000 RBP|0000000000000000 RSP|000000000014FF30 RIP|0000000000401018 [UHEX] |
|||
15 Dec 2017, 06:29 |
|
fasmnewbie 15 Dec 2017, 06:39
Now the equivalent example in Windows PE64 console format as comparison to the Linux ELF64 executable 3 format.
Code: format PE64 console include 'win64axp.inc' entry start section '.data' data readable writeable msg db 'hello world',0ah,0 section '.text' code readable executable start: sub rsp,40 mov rax,start mov rbx,msg call [dumpreg] call [exitp] section '.idata' import data readable library cpu64f,'cpu64f.dll' import cpu64f,dumpreg,'dumpreg',exitp,'exitp' Observe entry point in RAX Code: RAX|0000000000402000 RBX|0000000000401000 RCX|0000000000243000 RDX|0000000000402000 RSI|0000000000000000 RDI|0000000000000000 R8 |0000000000243000 R9 |0000000000402000 R10|0000000000000000 R11|0000000000000000 R12|0000000000000000 R13|0000000000000000 R14|0000000000000000 R15|0000000000000000 RBP|0000000000000000 RSP|000000000008FF30 RIP|0000000000402013 [UHEX] |
|||
15 Dec 2017, 06:39 |
|
revolution 15 Dec 2017, 07:22
fasmnewbie wrote: GCC aligns main entry point to 8/16-byte boundaries. Obviously there is branch prediction involved when GCC calls main and therefore it is crucial for performance for __main to be aligned. So does ld and golink. fasmnewbie wrote: Even FASM PE's/PE64 console format does it all the time, every time. The only one off here is ELF64 executable format. |
|||
15 Dec 2017, 07:22 |
|
Tomasz Grysztar 15 Dec 2017, 08:13
Neither of the formats does align the entry point, this would be pointless. Usually the sections are aligned (this is needed to set up the section attributes, for example) so if you put your entry point right at the start of an section, like in these PE samples, it is going to be aligned just because it has been given the same address as entire section. But an address given to ENTRY directive can be any address:
Code: format PE entry start section '.text' code readable executable nop start: ; definitely unaligned |
|||
15 Dec 2017, 08:13 |
|
fasmnewbie 15 Dec 2017, 08:44
Tomasz Grysztar wrote: Neither of the formats does align the entry point, this would be pointless. Usually the sections are aligned (this is needed to set up the section attributes, for example) so if you put your entry point right at the start of an section, like in these PE samples, it is going to be aligned just because it has been given the same address as entire section. But an address given to ENTRY directive can be any address: Ok. Fair enough. That means coders wishing to use ELF64 executable format should manually align their entry points, if their code segment is preceded by other segment. Just to confirm my suspicion. One more thing, I am wondering if there's any correlation between the size of data in the data segment and the relative position of the entry point. Because everytime I extend / decrease the string "hello world" in the first post, the entry point position shifted. From what I can see, the two segments are far apart from each other (by pages) and should not interfere with one another? Example, after increasing the string Code: format ELF64 executable 3 entry main segment readable writeable msg db 'hello Worldssss',0ah,0 segment readable executable main: mov rbx,main mov rax,msg call dumpreg call exitx Yields (observe the changes in RBX) Code: RAX|00000000004000B0 RBX|00000000004010C1 RCX|0000000000000000 RDX|0000000000000000 RSI|0000000000000000 RDI|0000000000000000 R8 |0000000000000000 R9 |0000000000000000 R10|0000000000000000 R11|0000000000000000 R12|0000000000000000 R13|0000000000000000 R14|0000000000000000 R15|0000000000000000 RBP|0000000000000000 RSP|00007FFFB3B12350 RIP|00000000004010CF [UHEX] Thanks. |
|||
15 Dec 2017, 08:44 |
|
revolution 15 Dec 2017, 08:49
fasmnewbie wrote: Ok. Fair enough. That means coders wishing to use ELF64 executable format should manually align their entry points ... fasmnewbie wrote: One more thing, I am wondering if there's any correlation between the size of data in the data segment and the relative position of the entry point. Because everytime I extend / decrease the string "hello world" in the first post, the entry point position shifted. From what I can see, the two segments are far apart from each other (by pages) and should not interfere with one another? |
|||
15 Dec 2017, 08:49 |
|
fasmnewbie 15 Dec 2017, 08:58
@revo, I thought the CPU recognizes no sections / format in the final binary and the segment selectors should do their jobs in separating code and data.
|
|||
15 Dec 2017, 08:58 |
|
revolution 15 Dec 2017, 09:01
fasmnewbie wrote: @revo, I thought the CPU recognizes no sections / format in the final binary and the segment selectors should do their jobs in separating code and data. BTW: No modern OS uses the segment registers for rights separation of memory regions. It is all about paging. * Usually. There are other size options on some CPUs but they are rarely used. |
|||
15 Dec 2017, 09:01 |
|
fasmnewbie 15 Dec 2017, 09:29
revolution wrote:
@revo. Ok. But it still doesn't make sense to me how the changes of data size residing in one segment can affect the state of other items in a far away page. Thanks. |
|||
15 Dec 2017, 09:29 |
|
Tomasz Grysztar 15 Dec 2017, 09:36
See the ELF format specification:
ELF specification wrote: Loadable process segments must have congruent values for p_vaddr and p_offset, modulo the page size. |
|||
15 Dec 2017, 09:36 |
|
fasmnewbie 15 Dec 2017, 10:23
Thanks for the explanation and link Tomasz. It answers some of my doubts.
From what I understand, in Linux, the alignment state of a segment is dependant upon how things are laid out in other, probably unrelated, segment or segment(s) which may or may not have similar segment flags as the segment in question. e.g, If my executable segment appears first in my source, then followed by a writeable segment, there's a chance that the data (2nd) segment would start at uneven address/page. Am I seeing this correctly? |
|||
15 Dec 2017, 10:23 |
|
Furs 15 Dec 2017, 12:50
fasmnewbie wrote: @Furs But I mean, you need some hot functions in there (__attribute__((hot))), otherwise there will be no point. If the entry point is the only function then obviously it's going to be aligned since the section itself is. This is just happenstance though. Hot functions get placed before cold functions and thus the entry point is placed last as well in this situation. |
|||
15 Dec 2017, 12:50 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.