Page 1 of 1

[Solved] Newlib exit in crt0 causes page fault

Posted: Tue Jan 17, 2017 2:47 pm
by Agola
Hi osdevers :|

I finally finished debugging and writing my elf loader.
I loaded some elf binaries, and elf loader works good.

Then I wanted to load an elf binary compiled with my OS-Specific toolchain (i686-agola-gcc)
Then... Bam... Got a pagefault with faulting address 0xFF0AF300 :(

Then started to debugging my crt0.c

After some debugging, I found exit(ex) causes the pagefault. Using _exit instead of exit() solves problem, except exit is more correct and elegant, because of also "does two kinds of cleanup before _exit" (from exit.c, newlib)

That is my crt0.c:

Code: Select all

#include <fcntl.h>

extern int main ();
extern void exit(int code);
extern void _init();
extern void _init_signal();
 
void _start() {
    _init();
    _init_signal();
    int ex = main();
    exit(ex); //Page fault, fault happens while executing memory, non-present page, usually in 0xFF0AF300
}
Why exit causes page faults?

Thanks :oops:

Re: Newlib exit in crt0 causes page fault

Posted: Tue Jan 17, 2017 5:50 pm
by dchapiesky
Are you using the reentrant version of newlib?

As you need to initialize the GLOBAL_REENT pointer used by newlib/libc/stdlib/exit.c

as early as possible in _start():

Code: Select all

#include <reent.h>

extern void __sinit(struct _reent *);

_REENT_INIT_PTR(_GLOBAL_REENT);
__sinit(__GLOBAL_REENT);
The _REENT_INIT_PTR() sets some values up that are needed so your exit() doesn't call _GLOBAL_REENT->_cleanup() unless it is defined.

The __sinit() initializes newlib's stdio to be reentrant as well.

Also I presume your elf loader is clearing bss?

Re: Newlib exit in crt0 causes page fault

Posted: Wed Jan 18, 2017 7:48 am
by Agola
dchapiesky wrote:Are you using the reentrant version of newlib?

As you need to initialize the GLOBAL_REENT pointer used by newlib/libc/stdlib/exit.c

as early as possible in _start():

Code: Select all

#include <reent.h>

extern void __sinit(struct _reent *);

_REENT_INIT_PTR(_GLOBAL_REENT);
__sinit(__GLOBAL_REENT);
The _REENT_INIT_PTR() sets some values up that are needed so your exit() doesn't call _GLOBAL_REENT->_cleanup() unless it is defined.

The __sinit() initializes newlib's stdio to be reentrant as well.

Also I presume your elf loader is clearing bss?
I'm not using reentrant version of newlib.
I'm not sure actually. I didn't use any reentrant code in syscalls. And syscalls' form isn't reentrant (ex. open() not open_r()) So I'm not using reentrant version of newlib, right?

And yes, I'm clearing bss.

Re: Newlib exit in crt0 causes page fault

Posted: Wed Jan 18, 2017 9:46 am
by dchapiesky
The simplest way of figuring this out is to dump the assembly of exit().....

if you see reference to a pointer called _impure_ptr or _global_impure_ptr then you are using the reentrant version.... do the init I suggested.

In newlib 2.4.0 at least, the code in newlib/libc/reent is included always in every compile - so if you are using this version you may not have a choice in the matter...

Using 2.4.0 - I had posts on osdev about faults in getenv() which ultimately was this reent stuff.

Re: Newlib exit in crt0 causes page fault

Posted: Wed Jan 18, 2017 10:11 am
by Agola
dchapiesky wrote:The simplest way of figuring this out is to dump the assembly of exit().....

if you see reference to a pointer called _impure_ptr or _global_impure_ptr then you are using the reentrant version.... do the init I suggested.

In newlib 2.4.0 at least, the code in newlib/libc/reent is included always in every compile - so if you are using this version you may not have a choice in the matter...

Using 2.4.0 - I had posts on osdev about faults in getenv() which ultimately was this reent stuff.
Whoa... Crashes back, just copied wrong .elf file :(

Re: Newlib exit in crt0 causes page fault

Posted: Wed Jan 18, 2017 10:52 am
by Agola
I don't know what did I do, page faults started again :(
Maybe I copied another .elf file, and thought it is correct.

Even with initialization, I still get page fault, but I know my Newlib version is reentrant, at least :|

Re: Newlib exit in crt0 causes page fault

Posted: Wed Jan 18, 2017 11:55 am
by Agola
I'm downgrading to Newlib 2.2.0, same crt0 was working in Newlib 2.2.0, that crt0 faults started after upgrading to Newlib 2.5.0, probably because of the wrong reentrancy initialization you said.

Edit:

Fixed, without downgrading...

Wrote :

Code: Select all

    _REENT_INIT_PTR(_REENT);
    _REENT_INIT_PTR(_GLOBAL_REENT);
    __sinit(_GLOBAL_REENT);
Instead of :

Code: Select all

    _REENT_INIT_PTR(_GLOBAL_REENT);
    __sinit(_GLOBAL_REENT);
But maybe still something is incomplete, missing or wrong... @dchapiesky, could you help me, please?

Maybe that was about exit uses _impure_ptr. I decompiled exit, it uses _impure_ptr instead of _global_impure_ptr.

Also which one is correct? __sinit(_GLOBAL_REENT); or __sinit(_REENT);
If _REENT_INIT_PTR(_REENT); worked, does _REENT_INIT_PTR(_GLOBAL_REENT); need to be added also?

Re: Newlib exit in crt0 causes page fault

Posted: Thu Jan 19, 2017 1:57 am
by Agola
There are 2-3 of combinations works also.
How will I know which one correct, and does the full initialization?

Re: Newlib exit in crt0 causes page fault

Posted: Fri Jan 20, 2017 4:06 am
by dchapiesky
To be honest I had to check the source code...

Code: Select all

cd newlib
find . -type f -print0 | xargs -0 grep impure
to search the whole thing....

oooo just remembered -

find getreent.c - whatever var it is referencing is what you want...

getreent() is called from a macro and is called all over the place.

Sorry I am not much more help.

Re: Newlib exit in crt0 causes page fault

Posted: Fri Jan 20, 2017 2:19 pm
by Agola
dchapiesky wrote:To be honest I had to check the source code...

Code: Select all

cd newlib
find . -type f -print0 | xargs -0 grep impure
to search the whole thing....

oooo just remembered -

find getreent.c - whatever var it is referencing is what you want...

getreent() is called from a macro and is called all over the place.

Sorry I am not much more help.
Oh, finally it got work fully.
I started porting easy software now :roll:

Re: [Solved] Newlib exit in crt0 causes page fault

Posted: Fri Jan 20, 2017 2:28 pm
by dchapiesky
glad to hear it... cheers