kzinti wrote:
This is correct. The UEFI executable needs to be position independent. UEFI can relocate your code anywhere.
relocating means fixing absolute addresses used inside instructions and data (pointers). It is NOT PIC. PE is not PIC by the nature.
nullplan wrote:
I was under the impression the image had to be position independent, or else the UEFI would refuse to load it. Besides, I don't know ahead of time what addresses will be free, and having a PIC PE image will allow the UEFI to relocate the image properly wherever is space.
You don't have to know free addresses, your PE image uses some as a base, it may be even 0; then the FW, when loading the image, looks if it can place it at this address, if it can, then that's all, if not, it relocates the image, fixing (changing) all the references to the absolute addresses, both in code and data. That's why it's not PIC, because PIC means no references to absolute addresses at all, all references are relative, for example, to the program counter. Then putting an image somewhere else wouldn't require fixing anything, since for example a reference "load word into reg R from the memory, that is N bytes above program counter" remains the same. Position dependent then would be "load word into reg R from the memory at the address A0". That's exactly what PE uses. if the image has been put not at the preferred base, then A0 needs to be changed to A1, before the image starts execution. It applies both to exes and dlls. loaders are exes. dlls would be something that imports/exports from/to other images. unfortunately, UEFI doesn't make use this feature (for example exporting Boot Services/Runtime Services is an obvious case, but they decided to invent almost the same instead, resulting in an uglier code).
Quote:
EFI binaries are supposed to be relocatable, which is almost the same as position-independent. I don't think the UEFI spec says anything about what will happen if your binary isn't relocatable. (OVMF will load it anyway, which makes it difficult to tell if your linker options are correct.)
The only way to make a PE image non-relocatable is to strip relocation information. If you do this and the image really has a non empty .reloc section and the preferred base, the image has been linked to isn't available, the FW has zero chances to start it. Unless it includes instruction decoder and some euristic to guess if these data (in the data sections) are pointers or something else.