Just how position independent is PIC ?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
The Coding Dino

Just how position independent is PIC ?

Post by The Coding Dino »

I was planning to do my kernel as a pure binary - no ELF, PE, COFF stuff.
The only problem is, I have to be able to load modules (for floppy, IDE, SCSI, etc) as apropriate (why waste 3 kB on an FDC driver if the machine ain't got one?). So I figured, just allocate some memory, load some pure binary module into it, let that module start with code that uses my system call interrupt to register it's function calls (just simple pointers). But that leaves me with 2 problems:
- All the module's code must contain *only* relative jumps and relative function calls or things will go horribly wrong. If I tell the compiler to generate position independant code, will it do exactly what I want. My compiler is MinGW32 (yes, I'm using Windows as a development platform for now). I'm using NASM to make small assembly functions - MinGW32's inline assembly syntax sucks. (good old TurboPascal's syntax for inline ASM was *way* better).
- The module's initialisation code must somehow discover what the addresses of it's functions are. I was thinking - do a short jump to push EIP, read that, make a pointer to a function, add the two together - presto! But I'm not entirely sure this will work.

BTW, the main motivation for this setup is that writing a linker/relocater will probably take up to much of my time, plus, the documentation for the ELF format is quite fuzzy on how to actually relocate and ELF file.

Any hints/tips/comments/etc. are appreciated.

TIA, Rogier "Dino" de Groot
Gnome

RE:Just how position independent is PIC ?

Post by Gnome »

PIC uses a register (%ebx, I believe) to store the base address (something you would set upon entry), and everything uses an offset to that.

Gnome
The Coding Dino

RE:Just how position independent is PIC ?

Post by The Coding Dino »

Aha. That makes sense. Thanx :)
Shmooze

RE:Just how position independent is PIC ?

Post by Shmooze »

Does that make it (relatively) quite slow, since it has to do lots of additions, or is there another hardware feature that does it very quickly?
Gnome

RE:Just how position independent is PIC ?

Post by Gnome »

I'm not sure what kind of run-time overhead it has, but I assume it's nearly negligable. IIRC, ELF shared libraries use this technique on Linux, for example, and it doesn't seem to be a problem.

In assembly, there's a simple notation for this:

In AT&T syntax, (%ebx, do_stuff)
In Intel syntax, [ebx + do_stuff]

But, I'm not sure how this translates to machine code.
Shmooze

RE:Just how position independent is PIC ?

Post by Shmooze »

I've been reading more about this, but haven't managed to find out much about how it works (and hence its efficiency), but interestingly, both Intel's and AMD's 64-bit processors have native support for PIC (presumably in the form of a register), whereas on x86 it is more complicated, certainly involving lookup tables.
EyeScream

RE:Just how position independent is PIC ?

Post by EyeScream »

(Hi everyone!)

Perhaps I'm just stupid, but if you have a clean interface between kernel and modules, you could map them to memory in a specific way (so that every module is mapped at the same virtual address, but at a different physical address, of course). You won't have to worry about base address or relocations then.

Where am I wrong? =)
Gnome

RE:Just how position independent is PIC ?

Post by Gnome »

You're right, this is only an issue within a process. Each process's address space is independant.

But, while you *could* give each module its own address space, calling into it would require a context switch, which would be bad. Thus, normally each process has each module (shared libraries, etc.) mapped somewhere into its address space. The problem arises when you have multiple modules.

Normally, binaries are linked for a specific address in memory, which matches the location the OS loads it to. But, in the case of a shared library, this location is determined at load-time. Thus, you need a way to allow the code to run from *any* location in memory.

PIC (Position Indepentant Code) is one way to resolve this. Another way is to patch the binary at load-time.

Gnome.
Anton

RE:Just how position independent is PIC ?

Post by Anton »

//native support for PIC

All it has is the ability to address DATA using eip. On a x86 you would first need to move eip to a general register and then access the data. This is the only help given(as far as i understand). All other things are done the same way as on a x86.

Anton.
Legend

RE:Just how position independent is PIC ?

Post by Legend »

Patching the binary and not sharing the libs across different address spaces, would be easy, but wasteful ;)
Post Reply