Page 1 of 1

Newlib C Library Page Fault

Posted: Wed Jul 27, 2016 2:29 pm
by Cl9
Hi,

I've been following the porting Newlib and OS specific toolchain guides. I've got everything needed kernel side, and I wanted to have a go at writing usermode applications although I've hit a bit of a wall.

I've ported newlib and built the OS specific toolchain, both seem to work fine, although whenever I try to call a function from usermode, it page faults. It would page fault as soon as the application starts, but adding 'e main' to the linker options causes it not to crash until I call a C function, although calling things like 'getpid' work fine, and trigger a syscall. It looks a bit like a linking issue of some kind, could anyone point me in the right direction with what's causing this?

The test C program:

Code: Select all

#include <stdlib.h>
#include <unistd.h>
int main()
{
    volatile int c = getpid(); // Works fine (with '-e main' as a linker option), triggers a syscall
    volatile int *b = malloc(20); //Page faults, without even triggering a syscall
    return 0;
}


I'm using the crti and crtn provided by the wiki:

Crti.s:

Code: Select all

/* x86 crti.s */
.section .init
.global _init
.type _init, @function
_init:
	push %ebp
	movl %esp, %ebp

.section .fini
.global _fini
.type _fini, @function
_fini:
	push %ebp
	movl %esp, %ebp
Crtn.s:

Code: Select all

/* x86 crtn.s */
.section .init
	popl %ebp
	ret

.section .fini
	popl %ebp
	ret
I've built these separately, using the custom toolchain (which Newlib was also built with), using the command:

Code: Select all

i686-fros-gcc -c crtn.s -o crtn.o
and letting GCC link them in for me.

Crt0.c:

Code: Select all

#include <fcntl.h>
extern void exit(int code);
extern int main ();
void _start() {
    _init_signal();
    int ex = main();
    exit(ex);
}
The other files are pretty much just stock tutorial ones with 'myos' being replaced with 'fros'. Before the page fault, there's also no syscalls being called by the program. If there's any other files that you'd like to see then please do let me know thanks.

Re: Newlib C Library Page Fault

Posted: Wed Jul 27, 2016 2:36 pm
by max
Hey,

so you say that whatever function of the libc you are calling it crashes, but when calling a function within your program it works? It seems like you have made some kind of mistake when setting up your executables memory space (what do you do there?), probably missing a segment or something?

As you seem to be quite a bit advanced, you should try to use gdb to see where exactly the program crashes - it even prints out the registers and current source location for you ;)

Greets

Re: Newlib C Library Page Fault

Posted: Wed Jul 27, 2016 2:49 pm
by Cl9
I can call functions defined by Newlib too. For example, this works:

Code: Select all

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
volatile char *add(volatile char *s)
{
    return s;
}
int main()
{
    char str[80]; //Works fine
    sprintf(str, "hey"); //Works fine
    add(str); //Works fine
    volatile int c = getpid(); // Still works fine
    volatile int *b = malloc(20); // Page faults
    return 0;
}
Up until the malloc at least.

Though it's weird, because I cannot call some other functions. For example, if I were to call 'puts' on 'str', it'd page fault:

Code: Select all

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
volatile char *add(volatile char *s)
{
    return s;
}
int main()
{
    char str[80]; //Works fine
    sprintf(str, "hey"); //Works fine
    add(str); //Works fine
    puts(str); //Page faults
    return 0;
}
And I don't think that I'm at the point where I'd be able to use gbd yet though I'm looking through it now.

Re: Newlib C Library Page Fault

Posted: Wed Jul 27, 2016 3:03 pm
by max
Cl9 wrote:Though it's weird, because I cannot call some other functions. For example, if I were to call 'puts' on 'str', it'd page fault:
Well. seems like it's related to your malloc.
Cl9 wrote:And I don't think that I'm at the point where I'd be able to use gbd yet though I'm looking through it now.
Don't worry, you can do it: you have to make it load your executable (using "file /path/to/your/binary"), start your program in QEMU with GDB stub turned on, and then use GDB to connect to "target remote :1234". See this page for details, it's really easier than it sounds.

Re: Newlib C Library Page Fault

Posted: Wed Jul 27, 2016 4:14 pm
by Cl9
I've built gdb and added it into the ISO, but it's a bit late now so I'll look at it tomorrow thanks :)

Re: Newlib C Library Page Fault

Posted: Wed Jul 27, 2016 6:56 pm
by gerryg400
Try looking at the address of the instruction that causes the fault. Then do an objdump -d on your executable to see whereabouts in the program the fault is happening. By examining register contents and the disassembled object code you ought to be able to find the bug.

Re: Newlib C Library Page Fault

Posted: Wed Jul 27, 2016 8:43 pm
by bluemoon
Cl9 wrote:I can call functions defined by Newlib too. ......Up until the malloc at least.
Though it's weird, because I cannot call some other functions.
Just my wild guess, it looks like those functions rely on some internal states were not properly initialized.
Have you zero out the necessary region of memory when loading the program?

Re: Newlib C Library Page Fault

Posted: Thu Jul 28, 2016 1:21 pm
by Cl9
Tyvm bluemoon for pushing me into looking back into my Elf loading code.. It wasn't that I wasn't zeroing stuff out, I was mishandling some of the memory whilst loading it, so I've made some changes and it seems to all be working properly now.

Thanks everyone for your help :)