Loading Static ELF Binary

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
omin0us

Loading Static ELF Binary

Post by omin0us »

So, i'm at the point in my kernel of loading binaries from disk. basically, I read in the whole file. and then copy all sections of type PT_LOAD into memory. that should basically be enough for statically linked elf binaries shouldn't it? Well for some reason, they only execute properly in bochs. i ported some of the basic parts of newlib and link against that. and printf() works in bochs, but not in vmware or qemu... am i missing something?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Freenode IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re:Loading Static ELF Binary

Post by Combuster »

the ELF specification states that you should zero the BSS area. In bochs, everything's zeroed by default, but on real computers and virtual machines it isnt.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
omin0us

Re:Loading Static ELF Binary

Post by omin0us »

So i sort of narrowed down the problem...

When running it in VMWare or qemu,
its not actually copying the .rodata section into memory.

to explain in more detail.
when i encounter a section who's type is PT_LOAD, i map memory at the sections reported Virtual Address and map enough for the sections memsize. then i do memcpy and copy the data from the elf binary into the mapped memory. the copy succeeds on the .text section. but fails on the .rodata section. but not in bochs. memcpy is standard. takes 3 arguments. Dest, Src, and Len.
while stepping through the memcpy, i see
*dst is 0, and *src is '/'
then it does *dst = *src
and after that, *dst is still 0, not '/'
but it only does this with the .rodata section. but not in bochs. i'm so confused.
Habbit

Re:Loading Static ELF Binary

Post by Habbit »

maybe you've set some kind of memory permissions (like the paging R/W) flags before starting the copy, so you are trying to write on a read-only region of memory... but that should raise a GPF exception, shouldn't it? ???
User avatar
Kevin McGuire
Member
Member
Posts: 843
Joined: Tue Nov 09, 2004 12:00 am
Location: United States
Contact:

Re:Loading Static ELF Binary

Post by Kevin McGuire »

a GPF exception, shouldn't it?


It will raise a interrupt 14?page-fault exception and details can be found in the, "INTEL ARCHITECTURE SOFTWARE DEVELOPER?S MANUAL, VOLUME 3: SYSTEM PROGRAMMING GUIDE" under section 5.11 on page 5-44 which I had looked up a few days ago and _just_ relooked up to make sure.

@omin0us:
You will have to narrow the problem down even more. ::)
omin0us

Re:Loading Static ELF Binary

Post by omin0us »

i'm really unsure where to go from here. I dont have anything Flagged as read only. and if i did, that would cause an exception wouldn't it? i'm getting no exceptions or faults. i verified that the virtual address of the .rodata section is getting mapped to the physical address that i am mapping it to. but then when i write data to that address, and read it back. its just 0x0.

I dont know what to do to narrow this down any farther.

if you would like to inspect my code,
here is the elf loading code:
http://ominos.cvs.sourceforge.net/ominos/ominos/kernel/elf.c?revision=1.1&view=markup

and here is the page mapping code:
http://ominos.cvs.sourceforge.net/ominos/ominos/mm/page.c?revision=1.3&view=markup
Habbit

Re:Loading Static ELF Binary

Post by Habbit »

Kevin McGuire wrote:
a GPF exception, shouldn't it?


It will raise a interrupt 14?page-fault exception and details can be found in the, "INTEL ARCHITECTURE SOFTWARE DEVELOPER?S MANUAL, VOLUME 3: SYSTEM PROGRAMMING GUIDE" under section 5.11 on page 5-44 which I had looked up a few days ago and _just_ relooked up to make sure.


Excuse my urges of checking the infinitely precise information you gave, but if I'm not wrong, the page 5-44 of my copy of "INTEL ARCHITECTURE SOFTWARE DEVELOPER?S MANUAL, VOLUME 3: SYSTEM PROGRAMMING GUIDE", order number #253668-016, June 2005, is not in section 5.11 ("IDT Descriptors"), but in section 5.15 ("Exception and interrupt reference"), and it speaks about neither #GP or #PF, but #NP (segment not present). :o
So I can conclude that either you just made up all that information (why, I don't know), or one of our copies of the Intel manual is outdated. For the sake of Wikipedia-style good faith assumption, I'll choose the second option. :P

Morale: don't give soooooo precise data about your sources, especially if they are subject to regular changes. If you totally and absolutely need to give it, be totaly and absolutely precise (edition, order #, date...).

PS: with all this fuss, I didn't really check your claims (that is, I didn't re-read the whole chapter 5). Could you please tell me where is that explanation? Maybe some context would help ;)
omin0us

Re:Loading Static ELF Binary

Post by omin0us »

Ok, while trying to figure this out, i noticed that if i add a few kprintf() lines that print some stuff....it suddenly works in all emulators....

i dont know what conclusions one could draw from that.

my guess is there is something to do with how long it takes to do stuff. i notice bochs is the slowest emulater and it is the one that can run it. After i printed 1 line, vmware started working. and then i added in another kprintf to print some more info, and qemu started working (which appears to be the fasted emulator).

Any specific ideas about this timing?
omin0us

Re:Loading Static ELF Binary

Post by omin0us »

AHA!!! I figured it out.
i wasn't invalidating the page after i mapped it. because the virtual address had been mapped earlier.
omin0us

Re:Loading Static ELF Binary

Post by omin0us »

omin0us wrote:AHA!!! I figured it out.
i wasn't invalidating the page after i mapped it. because the virtual address had been mapped earlier.


I question if this is really fixing it or not now that i have thought about it some... Because before it was made apparent that it was some kind fo timing issue (as the bug would "fix" itself and everything would work when i threw in some debugging kprintf lines.). Why would it suddenly work with a delay before writing to the memory if the page needed to be invalidated?
Habbit

Re:Loading Static ELF Binary

Post by Habbit »

omin0us wrote:
omin0us wrote:AHA!!! I figured it out.
i wasn't invalidating the page after i mapped it. because the virtual address had been mapped earlier.


I question if this is really fixing it or not now that i have thought about it some... Because before it was made apparent that it was some kind fo timing issue (as the bug would "fix" itself and everything would work when i threw in some debugging kprintf lines.). Why would it suddenly work with a delay before writing to the memory if the page needed to be invalidated?


Maybe because calling kprintf required several other pages, removing the one you didn't invalidate from the TLBs. Maybe even your kprintf function, or the way you're calling it, flushes the TLBs! just look around your asm code and you should find it
omin0us

Re:Loading Static ELF Binary

Post by omin0us »

But if that was the case, wouldn't just 1 kprintf call have made the other emulators work? vmware worked after i put 1 debug line in. and qemu didn't start working till i had 3 kprintf calls
Habbit

Re:Loading Static ELF Binary

Post by Habbit »

omin0us wrote:But if that was the case, wouldn't just 1 kprintf call have made the other emulators work? vmware worked after i put 1 debug line in. and qemu didn't start working till i had 3 kprintf calls


And since when have computers been logical, deterministic and non-arcane? Maybe you filled some buffer in your kprintf that required the allocation of a new page. Maybe QEMU is emulating a processor with more TLB entries than yours has...
Maybe ???
Post Reply