Page 1 of 1

Simple executable format

Posted: Sun Mar 12, 2006 1:26 am
by Zioo
Hello.
I want to implement simple executable files, which can be loaded anywere in the memory, instead of flat binarys. But which formats are mostly used, and simple to implement? I've been looking at the ELF format, but I think it's overkill to implement ELF in a tiny OS..
Or is it possible to reallocate a flat binary to the address where it's loaded?

Re:Simple executable format

Posted: Sun Mar 12, 2006 7:59 am
by Pype.Clicker
The intel processors lack the proper addressing mode to support binaries that can be loaded at any position, that means the program (or the environment) needs to be adjusted to the position where the program is loaded.

- by linking programs so that the first bit is e.g. at 4K and setting appropriate base in code segments and data segments so that the program feels "at home" anywhere.
- by linking programs the way you want and giving them a new address space where they appear at their preferred address.
- by linking programs incrementally, keeping relocation lists and patching the binary for its actual address. For things like kernel modules, that's what i recommend.
- by going deep into the ELF specifications and implementing global offset table, procedure linkage table and whatever else is required for run-time support of "position independent code" ...

... or you might want to decide that x86 altogether is a flawed architecture and osdev' for powerpc, strongarms, amd-64 which all have support for position-relative addressing, giving back the problem to the toolchain (where -fPIC should then produce a binary that will feel "at home" everywhere :)

Re:Simple executable format

Posted: Sun Mar 12, 2006 8:17 am
by GLneo
would code like this work?:

jmp ($ + (code - $)) ; <--- turn to asm
mov stuff, stuff
code:
mov stuff, stuff

Re:Simple executable format

Posted: Sun Mar 12, 2006 9:13 am
by hendric
Reallocating a binary is not sensible.I prefer to implementing a reduced executable file format from ELF or PE.

Re:Simple executable format

Posted: Sun Mar 12, 2006 11:34 am
by Zioo
Thanks Pype, I'll take a look at it, and try it.. When I've some sparetime..

@Hendric, reduced ELF file? Can you give an explanation?

Re:Simple executable format

Posted: Sun Mar 12, 2006 12:26 pm
by Dex4u
Here is a very simple, relocatable bin file format.

Code: Select all

org 0
use32
jmp  start
;maybe a simple header here
start:
mov eax,[MyVar1 + ebx] ; you need to do this
mov [MyVar2 + ebx],edx; same with this
mov esi,MyString
add esi,ebx ;  you need to do this
call print ; this is ok like this
jmp LetsGo ;this is ok like this
; some more code here, maybe
LetsGo:
         ret
print:
;print code here
ret

;Data
MyString: db 'hello world!',13,0
MyVar1 rd 1
MyVar2 rd 1
This can be loaded any where in memory, you just need to load ebx with the load address at load time and keep ebx untouched.

I call it the "KISS" file format.

PS: Please do not comment on that it does nothing, as the vars have random data in them etc, its just a demo, to show what needs fixing and what does not.

Re:Simple executable format

Posted: Sun Mar 12, 2006 3:54 pm
by blip
If you don't mind me modifying your code a little:

Code: Select all

org 0
use32
begin:   ; This way you can have code before the CALL but after "begin"
call  start   ; Near CALL instructions encode a displacement to the destination
AfterCall:

;maybe a simple header here

start:
pop ebx
sub ebx,AfterCall - begin
mov eax,[MyVar1 + ebx] ; you need to do this
mov [MyVar2 + ebx],edx; same with this
mov esi,MyString
add esi,ebx ;  you need to do this
call print ; this is ok like this
jmp LetsGo ;this is ok like this
; some more code here, maybe
LetsGo:
        ret
print:
;print code here
ret

;Data
MyString: db 'hello world!',13,0
MyVar1 rd 1
MyVar2 rd 1
This way the code could handle the relocation itself if you so desired.

I did something like this to have one program able to run on several related but dissimilar enough Z80-based graphing calculator systems except the Z80 CALL instruction encodes an absolute address so it was a bit harder. I figured the stack was always writable so I solved it by PUSHing some code bytes onto the stack and then CALLing it. The code was PUSH HL / POP HL / RET and that would put the address of the instruction after the CALL instruction into HL. From the origin address I could determine which calculator it was and use the correct system call addresses. The origin had to be known since both CALLs and JMPs encoded absolute addresses, though IIRC some conditional short ones were relative. Hacky I know but it's what I love about it. ;D

Re:Simple executable format

Posted: Sun Mar 12, 2006 11:35 pm
by Zioo
That "KISS" format looks nice, but my assembly is pretty poor. Can something similar be done in C?

Re:Simple executable format

Posted: Mon Mar 13, 2006 3:54 am
by Solar
Zioo wrote: Can something similar be done in C?
No, IMHO. Even if you make your compiler create "flat binary" code, it still does its own thing regarding relocations, stack allocations etc.

Re:Simple executable format

Posted: Mon Mar 13, 2006 4:00 am
by Pype.Clicker
Zioo wrote: That "KISS" format looks nice, but my assembly is pretty poor. Can something similar be done in C?
not easily afaik. Here, dex4u has used one of the register to be the "base of the executable", and explicitly uses it everytime a direct reference is made. The C compiler, instead will issue "mov eax,[var1]", and you have little control on what it generated here...

If that kind of trick (i mean, losing one of the scarce general registers of x86) doesn't cause you trouble, you may decide to go -fPIC anyway, but honnestly, for executables, performing relocations is just as easy.

You may find coff2sfs and elf2sfs tools handy to get yourself used to read ELF and COFF binaries (that's basically a "stripper" that keeps the entry point and the section payload). Then Clicker's program maker may provide help to read and process the full symbol tables and relocation lists.

Additionnal info about those tools can be found in the wiclicker aswell:
* KmodFormat
* kernel module maker
*
userlevel program maker