zaval wrote:
you can instruct the linker to keep info of relocations, but still it's not quite the same. by "resolved" relocations I meant those, that don't need load time fixing at all, say you place a variable X, compiler doesn't know where it ends up, so makes a relocation on it, but linker does know its final placement - it resolves it
So far I have the same understanding.
zaval wrote:
it resolves it PC-related (IP-related) and referencing X doesn't use absolute address at all.
That might be true for x86_64, but it certainly is not true for ia32 since that architecture doesn't have IP-relative addressing. It only has absolute addressing. For lot of details, see
https://nullprogram.com/blog/2016/12/23/.
zaval wrote:
such things are the only real PIC. now, I ask, maybe I am wrong - what exactly relocations the ELF linker preserves - all or only those, that are subject to base relocations? because in PE, only the latter are bookkept
The exact same thing is happening with the (non-PIC) ELF files I am generating. They only contain "R_386_RELATIVE" or "R_X86_64_RELATIVE" relocations, which are basically relative offsets that need to be corrected to take the image base into account. Although they are called "relative" relocations, the instructions are actually using absolute addresses and this is why the offsets need to be corrected to account for the image base.
ia32 version:
https://github.com/kiznit/rainbow-os/bl ... oc.cpp#L76x86_64 version:
https://github.com/kiznit/rainbow-os/bl ... oc.cpp#L76Note that in both cases my linker script will link the ELF file with an image base of 0x00000000. This is not a requirement, it just makes it easier to debug things (relative addresses become offset into the memory image). The other reason to link at 0x00000000 is that it ensures my relocation code works properly since UEFI will not load my bootloader at that address (I verified this).
zaval wrote:
, because it's a native method for the format, it knows what they are for. whereas for ELF, keeping relocations is something clueless
I have no idea why you say that or what you mean by it. You seem to suggest that relocations in ELF files are a hack. They are not. They do work differently than for PE files, but they are not less hacky / clueless / useful. They are very well documented an easy to use. They are also used for the exact same reason relocations are used in PE files.
https://intezer.com/blog/elf/executable ... locations/zaval wrote:
that is for "analyzing tools" and I fear it dumps everything that was relocations at the link time. this means, that you would need to through a lot of garbage, extracting only relocations of interest, but maybe I am wrong, since I ditched my attempts to try to convert ELF in PE a long time ago and forgot many things.
There isn't much to it. I have a ".reloc" section in my linker script:
Code:
.reloc ALIGN(4K) :
{
*(.reloc)
}
and the only relocation types I get in my executable (they certainly are not discarded!) are R_386_NONE and R_386_RELATIVE. The former you can ignore and the later is trivial to handle.
zaval wrote:
btw about this. I know this is one of the main points of those, who advocates for using gcc - like, hey, one day, your OS would be capable of running a compiler, self hosting, b1tches, so take gcc, it teaches you to have a million variants from the beginning!
I won't be arguing if this is a really good advice to listen to, but I don't see how using another compiler while you don't have yet such an established environment in your OS is preventing from having that future compiler. just don't second linux mistake and don't make code of your OS compiler bound.
I agree that it doesn't prevent changing the compiler in the future. But I really don't want to spend time dealing with #ifdef GCC/MSVC/... and having to typedef every basic type I want to use because they might not be the same on all platforms. I also don't want to deal with compiler incompatibilities, compiler bugs, compiler supporting different version of C++, and so on. Basically, having the exact same compiler for all binaries just saves development time, a resource that is scarce on a one-man osdev project (I get the irony).
I did start this project using mingw for the UEFI bootloader as I used to think that using a non-PE compiler to generate PE files made no sense. In the end it was causing me more grief than it was helping me. This is when I switched to this method. I suppose YMMV.