Page 1 of 1

Problem compiling application for OS

Posted: Mon Mar 25, 2013 4:31 pm
by kfreezen
I have been trying to run a helloworld program with my OS. My "libc" has two object files: syscalls.o and stdio.o

This code works, and prints "Hello, world0" to the screen.

Code: Select all

void _start() {
	syscall3(SYSCALL_CONSOLE, CONSOLE_PUTS, "Hello, world0\n");
	//internal_puts("Hello, world 234");
	syscall2(SYSCALL_EXIT, 0);
}
This code doesn't work, and prints nothing.

Code: Select all

void _start() {
	syscall3(SYSCALL_CONSOLE, CONSOLE_PUTS, "Hello, world0\n");
	internal_puts("Hello, world 234");
	syscall2(SYSCALL_EXIT, 0);
}
I compile it with

"./kos-gcc -o helloworld helloworld.c -Llibc -lc"

kos-gcc is a script file:

Code: Select all

#!/bin/sh

CFLAGS="-m32 -I libc/include -nostdlib -fno-builtin -fno-stack-protector -nostartfiles -nodefaultlibs"

gcc $CFLAGS $@ -Llibc -lc
I've tried multiple variations of this and none have fixed the problem.

Re: Problem compiling application for OS

Posted: Mon Mar 25, 2013 5:24 pm
by FallenAvatar
Build output? Code of internal_puts? Where are you linking your userspace?

You have given us nothing beyond what an application developer would give us. Why should we help you when this is an OS dev community????

- Monk

Re: Problem compiling application for OS

Posted: Tue Mar 26, 2013 11:41 am
by kfreezen
The application is in kernel space and syscall is just a vanilla interrupt. syscall2 and syscall3 are assembly functions and work properly, but internal_puts is C code. It's this

Code: Select all

void internal_puts(const char* str) {
	syscall3(SYSCALL_CONSOLE, CONSOLE_PUTS, (unsigned)str);
}
The "libc" source is https://github.com/kfreezen/kos/tree/master/libc

I think the problem is either in kos-gcc or, most likely, my libc Makefile.

Code: Select all

C_SRC:=$(shell find src -mindepth 1 -maxdepth 3 -name "*.c")
S_SRC:=$(shell find src -mindepth 1 -maxdepth 3 -name "*.s")
C_SOURCES:=$(patsubst %.c, %.o, $(C_SRC))
S_SOURCES:=$(patsubst %.s, %.o, $(S_SRC))

SOURCES:=$(S_SOURCES) $(C_SOURCES)

CC:=@gcc
CFLAGS:=-I include -m32 -nostdlib -fno-builtin -fno-stack-protector -nostartfiles -nodefaultlibs
AS:=@nasm
ASFLAGS:=-felf32
AR:=@ar
ARFLAGS:=rcs

all: $(SOURCES) link

link:
	$(AR) $(ARFLAGS) libc.a $(SOURCES)
It appears in my debugging that the application calls where the function is supposed to be and executes zeroes.

I shall take a look at the stdio.o object file when I get to the store and see if I can make sense of it.

P.S. Sorry about not posting more details; I was being lazy.

Re: Problem compiling application for OS

Posted: Tue Mar 26, 2013 11:58 am
by bluemoon
If your application is in kernel space now, try writing a character (not string, it require .rodata to be in right place) on screen to verify that your code actually get executed.
Chances are that you messed up for relocation (or did you do that?)

Re: Problem compiling application for OS

Posted: Tue Mar 26, 2013 12:49 pm
by kfreezen
No sir, I load it as if it were a user space application. No relocation involved, just parse it, load the various sections into the virtual memory, and execute. I wanted to get the loading working and then add stuff like userspace and relocation for kernel modules.

If you want to, you can take a look at the ELF parsing code.
It works for simple application that do not make use of any library.
It also works with applications containing references to code in assembled object files.

I did a "syscall!" indicator in my kernel code before, but I can't remember whether it gets put to the screen on that call. I think it did, but I'll have to try it again.

I did have a call to a puts() function which added an extra newline seperately. I think that added the newline to the output but didn't print anything else.

Will post with results as soon as I can.

Re: Problem compiling application for OS

Posted: Tue Mar 26, 2013 1:39 pm
by FallenAvatar
I see 2 problems, I think. First, your internal_puts call in the test code does not end with \0 (I can't recall if gcc requires you do that?) And why are you casting the str to (unsigned) in the internal_puts function?

- Monk

Re: Problem compiling application for OS

Posted: Tue Mar 26, 2013 1:57 pm
by jnc100
I haven't looked into it in detail but immediately see two problems with your elf loader - it assumes hdr->e_phentsize == sizeof(Elf32_Phdr) which may not be true, and that the structures are correctly packed.

Regards,
John.

Re: Problem compiling application for OS

Posted: Tue Mar 26, 2013 3:02 pm
by kfreezen
jnc100:

I added an error check that aborts the function if hdr->e_phentsize != sizeof(Elf32_Phdr).

tjmonk15:

From my experimentation, I don't think gcc requires you to do it by default.
Casting str to unsigned is to prevent nasty little warnings in my code.

I enabled the output in the system call handler and with this code, the handler is called as many times as it should be (four, two times for the puts call), but no string from the program is there.

Code: Select all

void _start() {
	syscall3(SYSCALL_CONSOLE, CONSOLE_PUTS, "Hello, world0\n");
	puts("Hello, world 234");
	syscall2(SYSCALL_EXIT, 0);
}
Which proves that my initial suspiscion about it being the compiler was wrong.

Code: Select all

[section .text]
[global _start]

[extern syscall3]
[extern syscall2]
[extern puts]

%define SYSCALL_EXIT 0x0
%define SYSCALL_CONSOLE 0x1
	%define CONSOLE_PUTS 0x0
	%define CONSOLE_PUTCH 0x1
	%define CONSOLE_PUTHEX 0x2
	%define CONSOLE_PUTDEC 0x3
%define SYSCALL_TASK 0x3
	%define TASK_GETPID 0x0
	
_start:
	push ebp
	mov ebp, esp
	
	push hello_world_text
	push CONSOLE_PUTS
	push SYSCALL_CONSOLE
	call syscall3
	add esp, 12
	
	push hello_world2_text
	call puts
	add esp, 4
	
	push  0
	push SYSCALL_EXIT
	call syscall2
	
[section .data]

hello_world_text: db "Hello, world0", 0xa, 0
hello_world2_text: db "Hello, world 234", 0xa, 0

Edit: Fixed the bug causing the pagefault, this code has the same behaviour as the C code when I link with my libc.a

Re: Problem compiling application for OS

Posted: Tue Mar 26, 2013 4:24 pm
by bluemoon
kfreezen wrote:From my experimentation, I don't think gcc requires you to do it by default.
Casting str to unsigned is to prevent nasty little warnings in my code.
Note that it only silence the problem, the size of unsigned is subject to compiler implementation.
The proper ways are cast to uint32_t, uintptr_t, make a union type, keep using void*, or reinterpret_cast, etc
kfreezen wrote:I enabled the output in the system call handler and with this code, the handler is called as many times as it should be (four, two times for the puts call), but no string from the program is there.
Having correct number of syscall mean you've done it at least half right =D>
kfreezen wrote:proves that my initial suspiscion about it being the compiler was wrong.
No, You don't. Most likely there is problems with loader, linker script, or program bugs.
Have you checked the content of the string pointer? As I mentioned earlier, linker may put literal string on .rodata section that require relocation (specifically, entry with R_386_32(absolute) or R_386_PC32(pic) or R_X86_64_GLOB_DAT(64-bit)).

Re: Problem compiling application for OS

Posted: Tue Mar 26, 2013 5:46 pm
by kfreezen
There is another pagefault now, in the program itself.

eip is 0x8049f8c, address is 0x804a000, and error code is 0.

What kind of problem would cause nonexistant code to be called?

Also I created two variables pointing to the strings.
The .data section is

Code: Select all

8049ff4 f3830408 03840408
I have a feeling that this could be part of the problem.

... A while later ...
I just discovered that my OS has many bugs so this will have to wait until I've fixed them.

Thank you for your help