Position independent code
Position independent code
Hello!
I wonder how I can make memory position independent code, like "jump 10 bytes" instead of "jump to this location"?
That's how shared libraries work huh?
I wonder how I can make memory position independent code, like "jump 10 bytes" instead of "jump to this location"?
That's how shared libraries work huh?
Re:Position independent code
You can generate position independant code with "-fPIC" on the GCC command line IIRC.
As for the relative jumps, I'm not sure how to declare them in GAS but in NASM:To jump to an absolute address is "jmp far jmppoint" IIRC.
As for the relative jumps, I'm not sure how to declare them in GAS but in NASM:
Code: Select all
jmp near jmppoint ;Allows for very short jumps (Default NASM)
jmp short jmppoint ;Allows for longer jumps
jmppoint:
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Position independent code
jumps will usually be relative unless you tell the assembler otherwise. The only notable exception is for jump/call'ing something that's not in the current object file (e.g. in a library or whatever you made ".extern") ...
Re:Position independent code
Oh, I forgot to tell: I want to do position independent C-code with GCC, not assembly.
But all that is needed is -fPIC?
But all that is needed is -fPIC?
Re:Position independent code
To create it, yes, but to actually load and run it, you'll probably have to do some additional steps. Have a look at GCC's ABI as well as ELF (AFAIK, the implementation of PIC also depends on the binary format that is used).ohboy wrote: Oh, I forgot to tell: I want to do position independent C-code with GCC, not assembly.
But all that is needed is -fPIC?
cheers Joe
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Position independent code
very honestly, i don't recommend -fPIC for kernel level i386 stuff: the amount of things that gets added in the ELF format (global object tables, etc) and the restrictions on registers use will (imho) quickly get a nuisance. Rather keep a relocation table and perform code relocation on load-time.
PIC only gets useful when you need to load the _same_ code at several place (like in a _shared_ library), but when it's just about loading a thing at an address you can't tell at link time, relocations are clearly a better choice.
PIC only gets useful when you need to load the _same_ code at several place (like in a _shared_ library), but when it's just about loading a thing at an address you can't tell at link time, relocations are clearly a better choice.
Re:Position independent code
i will agree with Pype.Clicker, doing -fPic for OS code will make
it very heavy (with GOT and PLT table), another way might be to generate a relocatable object file with gcc and while loading it parse the relocation table to load it where every u want to.
A small loader might be required.
it very heavy (with GOT and PLT table), another way might be to generate a relocatable object file with gcc and while loading it parse the relocation table to load it where every u want to.
A small loader might be required.
Re:Position independent code
Really how does a relocation table work?
Is every symbol in the code pointing to a value in the table, which is an address?
And then when I load the binary I step through the table and add the address of where I loaded the code to the table entry?
You don't happen to have docs about these relocatable object files, do you?
Is every symbol in the code pointing to a value in the table, which is an address?
And then when I load the binary I step through the table and add the address of where I loaded the code to the table entry?
You don't happen to have docs about these relocatable object files, do you?
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Position independent code
i do happen to have docs ... and you can easily find them on "wotsit.org" (or googling for ELF/COFF specification)
The master reference for understanding this is the online book "linkers and loaders" which should be referenced by the FAQ.
Let's say your code contains
here:
call _some_external_symbol
the compiler/assembler has produced
<call-opcode> <long int 0000 0000>
then, in the so-called symbol tables, it adds
SYM[X] "_some_external_symbol": unresolved symbol
and in the relocation table,
location <here+1> should be adjusted with the value of symbol X.
The reason why you have both relocation table AND symbol table is of course to allow one to quickly patch a large collection of references to the same symbol.
The master reference for understanding this is the online book "linkers and loaders" which should be referenced by the FAQ.
Let's say your code contains
here:
call _some_external_symbol
the compiler/assembler has produced
<call-opcode> <long int 0000 0000>
then, in the so-called symbol tables, it adds
SYM[X] "_some_external_symbol": unresolved symbol
and in the relocation table,
location <here+1> should be adjusted with the value of symbol X.
The reason why you have both relocation table AND symbol table is of course to allow one to quickly patch a large collection of references to the same symbol.
Re:Position independent code
I found an article on "Linux Journal" with the name "Linkers and Loaders", and I'm currently reading it.
I have one more question though, which switch is needed for ld to create relocatable code? -shared?
Thanks for the great help!
I have one more question though, which switch is needed for ld to create relocatable code? -shared?
Thanks for the great help!
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Position independent code
i think it's -r. "-shared" makes it a shared object, which is usually PIC, not relocatable.
Re:Position independent code
-fPIC is used to compile to position independent code.
-shared is used to link to shared library.
To create shared libraries compile with -fPIC, and then link with -fPIC -shared. To create anything other than shared libraries, forget about -fPIC as it's just overhead.
As for actual position independent code on x86: since there isn't EIP-relative data-addressing, some tricks are needed. To get current EIP, one can near-call to next instruction, so as to push the "return address". Pop that, and you know where you are.
Ofcourse, once you have one address, you can calculate all the rest as offsets to that. So you put some base address into (say) EBX, and then use EBX relative addressing for all data. The only complication is restoring the base if called from non-PIC code.
There are some other possibilities, but generally PIC on x86 is a pain.
-shared is used to link to shared library.
To create shared libraries compile with -fPIC, and then link with -fPIC -shared. To create anything other than shared libraries, forget about -fPIC as it's just overhead.
As for actual position independent code on x86: since there isn't EIP-relative data-addressing, some tricks are needed. To get current EIP, one can near-call to next instruction, so as to push the "return address". Pop that, and you know where you are.
Ofcourse, once you have one address, you can calculate all the rest as offsets to that. So you put some base address into (say) EBX, and then use EBX relative addressing for all data. The only complication is restoring the base if called from non-PIC code.
There are some other possibilities, but generally PIC on x86 is a pain.
Re:Position independent code
Which is where relocatable files come in, no need to determine where you are as the loader "relocates" (or in MS speak: "rebases") it.