Page 1 of 1

Relocations in PE executable

Posted: Sun Oct 14, 2012 5:28 am
by AlfaOmega08
Hi, for the n-th time, I get back to osdev.org. This time I would like to develop using Visual Studio 2012.

So, VS can only emit PE executables. I don't want any creepy hack to inject a multiboot header in it, so I wrote a custom bootloader for PE executables on a FAT16 hard disk.

I've been successful (at least, it seems to work), to build a file interface like fopen, fread, fseek in real mode ASM. Then I loaded the executable sections to the ImageBase address. The problem is that the code contains references to strange memory addresses.

For example main:

Code: Select all

int main()
{
    print("Hello world from the 64-bit kernel.");
    return 0;
}
Is compiled to:

Code: Select all

00000490  4883EC28          sub rsp,byte +0x28
00000494  488D0D650F0000    lea rcx,[rel 0x1400]
0000049B  E8A0FFFFFF        call dword 0x440
000004A0  33C0              xor eax,eax
000004A2  4883C428          add rsp,byte +0x28
000004A6  C3                ret
So, for example, print should be at address 0x440, while actually it is at 0x101440. So that looks like an RVA. The same is for the string which looks to be at 0x1400. Which flags shall I use to ask the linker to remove all those relocations from my code??
My linker command line is:

Code: Select all

/OUT:".\krnl.exe" /NXCOMPAT:NO /PDB:".\krnl.pdb" /DYNAMICBASE /MAPINFO:EXPORTS /FIXED:NO /LARGEADDRESSAWARE /BASE:"0x100000" /MACHINE:X64 /ENTRY:"main" /WINMD:NO /OPT:REF /SAFESEH:NO /INCREMENTAL:NO /PGD:".\krnl.pgd" /SUBSYSTEM:NATIVE /MAP":Kernel.map" /OPT:ICF /ERRORREPORT:QUEUE /NOLOGO /ALIGN:4096 /NODEFAULTLIB /TLBID:1
On the wiki I read that I should use "/DRIVER". Unfortunatey, that switch doesn't work in VS2012 due to a subtle bug, which I'm trying to workaround. More info here: http://connect.microsoft.com/VisualStud ... ith-driver

What does "/DRIVER" do to the ultimate executable?

Thanks in advance.

Update:
Just upgraded from VS2012 RC to the final release. The problem with /DRIVER is now solved. But relocations are still there...

Re: Relocations in PE executable

Posted: Sun Oct 14, 2012 6:39 am
by bluemoon
Just curious, what make you think using VC's toolchain is fun for OS dev?

If you absolutely like the VC IDE, you can still configure it to use Makefile and external cross compiler; and avoid all those hacks and headache when you update to VC2013/2014/etc - it sure breaks something as usual.

Re: Relocations in PE executable

Posted: Sun Oct 14, 2012 6:52 am
by AlfaOmega08
bluemoon wrote:Just curious, what make you think using VC's toolchain is fun for OS dev?

If you absolutely like the VC IDE, you can still configure it to use Makefile and external cross compiler; and avoid all those hacks and headache when you update to VC2013/2014/etc - it sure breaks something as usual.
Just experimenting something new...
One upon a time I did configure VS with cygwin to build the OS, and it worked quite well too (just the errors/warnings from g++ weren't recognized from the VS output window). And yes, I love that IDE.

Re: Relocations in PE executable

Posted: Sun Oct 14, 2012 9:07 am
by Owen
CALL refers to a relative address. No relocation required there.

Re: Relocations in PE executable

Posted: Sun Oct 14, 2012 9:21 am
by AlfaOmega08
Owen wrote:CALL refers to a relative address. No relocation required there.
I guess you're right, since stepping through bochs shows that the function is called correctly. And what about the string?? I get a stupid

Code: Select all

lea rcx, ds:0xf65