I guess SukantPal will forgive me for reusing his mostly answered thread?
Why making another ELF thread if there is one, quite fresh?
I am writing a utility converting ELF into PE. For using in my FW and OS. And I faced a weird linker behavior. Maybe some of you know is it possible to tell it do things not as dumb. Namely, there is a File Alignment and Section Alignment for executables. First tells how to align sections inside a file as it is stored on disk. The second tells how to put sections in memory. All offsets encoded into instructions of course are valid only when sections are placed with those distances between sections as it was assigned at link time, not as they placed in the file. there, they are compacted for saving space.
When you compile with GCC, for bare metal MIPS at least, without any alignment directives in the linker script, sections get non aligned locations, no page alignment, no sector alignment, just aligned at 4 as for the first symbol lying inside of it. It's weird by itself but OK, linker scripts have ALIGN command, for the output sections (resulting linker generated ones). That's exactly what we need! And everything is good. Except that
in the file sections are placed with huge gaps between them too! They aren't aligned there (relative to file start), but the distance between beginnings of two consecutive sections now is Section Alignment in size! What the hell! Why? That placement is supposed to get real only in memory, not in the file.
Basically the problem is the linker puts sections inside a file with the distance == Section Alignment, whereas it has been assigned for sections when they go in memory for execution, not for storage in the file. Why it is doing so and is there a way to tell it not to do that?
Here is the example of linker script for testing.
Code:
MEMORY{
RegFwSdram : ORIGIN = 80000000h, LENGTH = 10000000h
}
PHDRS{
DxeSegment PT_LOAD;
}
ENTRY( DllMain )
SECTIONS{
. = 80001000h; /* start of code, VA */
__start = .;
.text . :{ /* Code */
halefi.o ( .text )
* ( .text )
} >RegFwSdram :DxeSegment = 0,
.rdata ALIGN(0x1000) :{ /* RO data */
* ( .iat )
halefi.o ( .rdata )
* ( .rdata )
* ( .Strings )
} >RegFwSdram :DxeSegment
.data ALIGN(0x1000) :{ /* Data */
halefi.o ( .data )
* ( .data )
} >RegFwSdram :DxeSegment
}
Note, ".text" section is section aligned (0x1000) without the ALIGN, just by setting the position. And in the file it gets "normal" file offset, something like 0x78. Others are ALIGNed and for example .rdata gets 0x1078 offset. and .data - 0x2078. I suspect should .text be explicitly aligned, it would get that huge file offset too. Despite it is stated ALIGN command just adjusts the current position to the nearest upper aligned location. basically the same as manipulation with the "dot" element.
I don't get it, doesn't ELF likner understand the difference between file position and memory position of sections in memory?
And yet, sections
must be placed page aligned in memory, no matter hat the executable foramt is. For applying different page attributes, corresponding to section attributes, for CoW etc. Why GCC puts sections not aligned at page? Is it only on bare metal MIPS, or it behaves the same for x86? I don't have the latter to check.
If someone is interested in this utility, I might upload its code or the program itself later. Now it only supports MIPS32 targets.
I don't know if GCC for bare metal, freestanding, on x86 lets you generate PE/COFF, but for ARM, ARM64 and MIPS32 it doesn't. That's why I do it by myself.
It lets you use PE format for your images. It's a simple utility so you need to decide on your section arrangement with your linker. the utility won't do section merging or reordering. It just translates resulting Elf executable into PE executable. Also, only ET_EXEC elf type is supported, because PE doesn't use PIC approach, or at least I am not using it. As it is extremely complicated and not giving any advantages.
For executables there is a need to generate import information, and for DLLs export information as well. For my assembly written files now, I do it by hand. How to do it with C, that's the question. Not resolved yet. But when it is, the utility is ready for making a proper PE import and export tables. That's all one needs for comfortable dynamic linking. But an input Elf file can not be position independent code, only Elf executable, linked at the desired address.