Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/Makefile	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -38,4 +38,5 @@
 	lib/softfloat \
 	srv/ns \
+	srv/loader \
 	srv/fb \
 	srv/kbd \
@@ -48,4 +49,5 @@
 	app/tetris \
 	app/tester \
+	app/cli \
 	app/klog \
 	app/init
Index: uspace/app/cli/Makefile
===================================================================
--- uspace/app/cli/Makefile	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/app/cli/Makefile	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,86 @@
+#
+# Copyright (c) 2005 Martin Decky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+include ../../../version
+include ../../Makefile.config
+
+## Setup toolchain
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+CFLAGS += -I../../srv/kbd/include
+
+LIBS = $(LIBC_PREFIX)/libc.a
+DEFS += -DRELEASE=\"$(RELEASE)\"
+
+ifdef REVISION
+	DEFS += "-DREVISION=\"$(REVISION)\""
+endif
+
+ifdef TIMESTAMP
+	DEFS += "-DTIMESTAMP=\"$(TIMESTAMP)\""
+endif
+
+## Sources
+#
+
+OUTPUT = cli
+SOURCES = \
+	cli.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all clean depend disasm
+
+all: $(OUTPUT) disasm
+
+-include Makefile.depend
+
+clean:
+	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
+
+depend:
+	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+disasm:
+	$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm
+
+%.o: %.S
+	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o: %.c
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
Index: uspace/app/cli/cli.c
===================================================================
--- uspace/app/cli/cli.c	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/app/cli/cli.c	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2008 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup cli cli
+ * @brief	Trivial command-line interface for running programs.
+ * @{
+ */ 
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <task.h>
+
+#define LINE_BUFFER_SIZE 128
+static char line_buffer[LINE_BUFFER_SIZE];
+
+#define MAX_ARGS 16
+static char *argv_buf[MAX_ARGS + 1];
+
+static void read_line(char *buffer, int n)
+{
+	char c;
+	int chars;
+
+	printf("> ");
+
+	chars = 0;
+	while (chars < n - 1) {
+		c = getchar();
+		if (c < 0) exit(0);
+		if (c == '\n') break;
+		if (c == '\b') {
+			if (chars > 0) {
+				putchar('\b');
+				--chars;
+			}
+			continue;
+		}
+		
+		putchar(c);
+		buffer[chars++] = c;
+	}
+
+	putchar('\n');
+	buffer[chars] = '\0';
+}
+
+static void program_run(void)
+{
+	char *p;
+	int n;
+
+	p = line_buffer;
+	n = 0;
+
+	while (n < MAX_ARGS) {
+		argv_buf[n++] = p;
+		p = strchr(p, ' ');
+		if (p == NULL) break;
+
+		*p++ = '\0';
+	}
+	argv_buf[n] = NULL;
+
+	printf("spawn task '%s' with %d args\n", argv_buf[0], n);
+	printf("args:");
+	int i;
+	for (i = 0; i < n; ++i) {
+		printf(" '%s'", argv_buf[i]);
+	}
+	printf("\n");
+
+	task_spawn(argv_buf[0], argv_buf);
+}
+
+
+int main(int argc, char *argv[])
+{
+	printf("This is CLI\n");
+
+	while (1) {
+		read_line(line_buffer, LINE_BUFFER_SIZE);
+		printf("'%s'\n", line_buffer);
+		if (strcmp(line_buffer, "exit") == 0)
+			break;
+		
+		if (line_buffer[0] != '\0')
+		program_run();
+	}
+
+	printf("Bye\n");
+	
+	return 0;
+}
+
+/** @}
+ */
+
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/app/init/init.c	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -46,8 +46,4 @@
 #include "version.h"
 
-#define BUF_SIZE 150000
-
-static char *buf;
-
 static void console_wait(void)
 {
@@ -83,26 +79,14 @@
 static void spawn(char *fname)
 {
+	char *argv[2];
+
 	printf(NAME ": Spawning %s\n", fname);
-	
-	int fd = open(fname, O_RDONLY);
-	if (fd >= 0) {
-	
-		ssize_t rd;
-		size_t len = 0;
-		
-		// FIXME: cannot do long reads yet
-		do {
-			rd = read(fd, buf + len, 1024);
-			if (rd > 0)
-				len += rd;
-			
-		} while (rd > 0);
-		
-		if (len > 0) {
-			task_spawn(buf, len);
-			sleep(1);	// FIXME
-		}
-		
-		close(fd);
+
+	argv[0] = fname;
+	argv[1] = NULL;
+
+	if (task_spawn(fname, argv) != 0) {
+		/* Success */
+		sleep(1);
 	}
 }
@@ -118,6 +102,4 @@
 	}
 	
-	buf = malloc(BUF_SIZE);
-	
 	// FIXME: spawn("/sbin/pci");
 	spawn("/sbin/fb");
@@ -130,8 +112,8 @@
 	spawn("/sbin/fat");
 	spawn("/sbin/tetris");
+	spawn("/sbin/cli");
 	// FIXME: spawn("/sbin/tester");
 	spawn("/sbin/klog");
 	
-	free(buf);
 	return 0;
 }
Index: uspace/app/tester/tester.c
===================================================================
--- uspace/app/tester/tester.c	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/app/tester/tester.c	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -108,6 +108,15 @@
 }
 
-int main(void)
+int main(int argc, char **argv)
 {
+	printf("Number of arguments: %d\n", argc);
+	if (argv) {
+		printf("Arguments:");
+		while (*argv) {
+			printf(" '%s'", *argv++);
+		}
+		printf("\n");
+	}
+
 	while (1) {
 		char c;
Index: uspace/lib/libc/Makefile
===================================================================
--- uspace/lib/libc/Makefile	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/lib/libc/Makefile	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -52,4 +52,6 @@
 	generic/string.c \
 	generic/fibril.c \
+	generic/pcb.c \
+	generic/smc.c \
 	generic/thread.c \
 	generic/tls.c \
Index: uspace/lib/libc/arch/amd64/src/entry.s
===================================================================
--- uspace/lib/libc/arch/amd64/src/entry.s	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/lib/libc/arch/amd64/src/entry.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -35,7 +35,10 @@
 ## User-space task entry point
 #
+# %rdi contains the PCB pointer
 #
 __entry:
+	# %rdi was deliberately chosen as the first argument is also in %rdi
+	# Pass PCB pointer to __main (no operation)
 	call __main
-	call main
+
 	call __exit
Index: uspace/lib/libc/arch/arm32/src/entry.s
===================================================================
--- uspace/lib/libc/arch/arm32/src/entry.s	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/lib/libc/arch/arm32/src/entry.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -35,7 +35,10 @@
 ## User-space task entry point
 #
+# r1 contains the PCB pointer
 #
 __entry:
+	# Pass pcb_ptr to __main as the first argument (in r0)
+	mov r0, r1
 	bl __main
-	bl main
+
 	bl __exit
Index: uspace/lib/libc/arch/ia32/src/entry.s
===================================================================
--- uspace/lib/libc/arch/ia32/src/entry.s	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/lib/libc/arch/ia32/src/entry.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -35,4 +35,5 @@
 ## User-space task entry point
 #
+# %ebx contains the PCB pointer
 #
 __entry:
@@ -42,6 +43,8 @@
 	mov %ax, %fs
 	# Do not set %gs, it contains descriptor that can see TLS
-	
+
+	# Pass the PCB pointer to __main as the first argument
+	pushl %ebx
 	call __main
-	call main
+
 	call __exit
Index: uspace/lib/libc/arch/ia64/src/entry.s
===================================================================
--- uspace/lib/libc/arch/ia64/src/entry.s	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/lib/libc/arch/ia64/src/entry.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -35,11 +35,13 @@
 ## User-space task entry point
 #
+# r2 contains the PCB pointer
 #
 __entry:
 	alloc loc0 = ar.pfs, 0, 1, 2, 0
-	mov r1 = _gp 
+	mov r1 = _gp
+
+	# Pass PCB pointer as the first argument to __main
+	mov out0 = r2
 	br.call.sptk.many b0 = __main
 0:
-	br.call.sptk.many b0 = main
-1:
 	br.call.sptk.many b0 = __exit
Index: uspace/lib/libc/arch/mips32/src/entry.s
===================================================================
--- uspace/lib/libc/arch/mips32/src/entry.s	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/lib/libc/arch/mips32/src/entry.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -36,4 +36,5 @@
 ## User-space task entry point
 #
+# $a0 ($4) contains the PCB pointer
 #
 .ent __entry
@@ -41,6 +42,5 @@
 	.frame $sp, 32, $31
 	.cpload $25
-	
-	
+
 	# Mips o32 may store its arguments on stack, make space (16 bytes),
 	# so that it could work with -O0
@@ -49,9 +49,10 @@
 	addiu $sp, -32
 	.cprestore 16   # Allow PIC code
-	
+
+	# Pass pcb_ptr to __main() as the first argument. pcb_ptr is already
+	# in $a0. As the first argument is passed in $a0, no operation
+	# is needed.
+
 	jal __main
-	nop
-	
-	jal main
 	nop
 	
Index: uspace/lib/libc/arch/ppc32/src/entry.s
===================================================================
--- uspace/lib/libc/arch/ppc32/src/entry.s	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/lib/libc/arch/ppc32/src/entry.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -35,7 +35,10 @@
 ## User-space task entry point
 #
+# r3 contains the PCB pointer
 #
 __entry:
+	# Pass the PCB pointer to __main() as the first argument.
+	# Since the first argument is passed in r3, no operation is needed.
 	bl __main
-	bl main
+
 	bl __exit
Index: uspace/lib/libc/arch/ppc64/src/entry.s
===================================================================
--- uspace/lib/libc/arch/ppc64/src/entry.s	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/lib/libc/arch/ppc64/src/entry.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -32,5 +32,4 @@
 
 .globl __entry
-.globl __entry_driver
 
 ## User-space task entry point
@@ -39,10 +38,3 @@
 __entry:
 	bl __main
-	bl __io_init
-	bl main
 	bl __exit
-
-__entry_driver:
-	bl __main
-	bl main
-	bl __exit
Index: uspace/lib/libc/arch/sparc64/src/entry.s
===================================================================
--- uspace/lib/libc/arch/sparc64/src/entry.s	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/lib/libc/arch/sparc64/src/entry.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -35,11 +35,14 @@
 ## User-space task entry point
 #
+# %o0 contains uarg
+# %o1 contains pcb_ptr
 #
 __entry:
+	# Pass pcb_ptr as the first argument to __main()
+	mov %o1, %o0
 	sethi %hi(_gp), %l7
 	call __main
 	or %l7, %lo(_gp), %l7
-	call main
-	nop
+
 	call __exit
 	nop
Index: uspace/lib/libc/generic/as.c
===================================================================
--- uspace/lib/libc/generic/as.c	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/lib/libc/generic/as.c	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -84,4 +84,18 @@
 {
 	return __SYSCALL1(SYS_AS_AREA_DESTROY, (sysarg_t ) address);
+}
+
+/** Change address-space area flags.
+ *
+ * @param address Virtual address pointing into the address space area being
+ * 	modified.
+ * @param flags New flags describing type of the area.
+ *
+ * @return Zero on success or a code from @ref errno.h on failure.
+ */
+int as_area_change_flags(void *address, int flags)
+{
+	return __SYSCALL2(SYS_AS_AREA_CHANGE_FLAGS, (sysarg_t) address,
+	    (sysarg_t) flags);
 }
 
Index: uspace/lib/libc/generic/io/stream.c
===================================================================
--- uspace/lib/libc/generic/io/stream.c	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/lib/libc/generic/io/stream.c	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -97,4 +97,13 @@
 }
 
+void close_console(void)
+{
+	if (console_phone >= 0) {
+		if (ipc_hangup(console_phone) == 0) {
+			console_phone = -1;
+		}
+	}
+}
+
 void klog_update(void)
 {
Index: uspace/lib/libc/generic/libc.c
===================================================================
--- uspace/lib/libc/generic/libc.c	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/lib/libc/generic/libc.c	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -49,6 +49,8 @@
 #include <async.h>
 #include <as.h>
+#include <loader/pcb.h>
 
 extern char _heap;
+extern int main(int argc, char *argv[]);
 
 void _exit(int status)
@@ -57,7 +59,9 @@
 }
 
-void __main(void)
+void __main(void *pcb_ptr)
 {
 	fibril_t *f;
+	int argc;
+	char **argv;
 
 	(void) as_area_create(&_heap, 1, AS_AREA_WRITE | AS_AREA_READ);
@@ -67,4 +71,17 @@
 	
 	open_console();
+
+	/* Save the PCB pointer */
+	__pcb = (pcb_t *)pcb_ptr;
+
+	if (__pcb == NULL) {
+		argc = 0;
+		argv = NULL;
+	} else {
+		argc = __pcb->argc;
+		argv = __pcb->argv;
+	}
+
+	main(argc, argv);
 }
 
Index: uspace/lib/libc/generic/pcb.c
===================================================================
--- uspace/lib/libc/generic/pcb.c	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/lib/libc/generic/pcb.c	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2008 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#include <loader/pcb.h>
+
+pcb_t *__pcb;
+
+/** @}
+ */
Index: uspace/lib/libc/generic/smc.c
===================================================================
--- uspace/lib/libc/generic/smc.c	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/lib/libc/generic/smc.c	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#include <libc.h>
+#include <sys/types.h>
+
+int smc_coherence(void *address, size_t size)
+{
+	return __SYSCALL2(SYS_SMC_COHERENCE, (sysarg_t) address,
+	    (sysarg_t) size);
+}
+
+/** @}
+ */
Index: uspace/lib/libc/generic/task.c
===================================================================
--- uspace/lib/libc/generic/task.c	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/lib/libc/generic/task.c	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2006 Jakub Jermar
+ * Copyright (c) 2008 Jiri Svoboda
  * All rights reserved.
  *
@@ -34,5 +35,11 @@
 
 #include <task.h>
+#include <ipc/ipc.h>
+#include <ipc/loader.h>
 #include <libc.h>
+#include <string.h>
+#include <stdlib.h>
+#include <async.h>
+#include <errno.h>
 
 task_id_t task_get_id(void)
@@ -45,7 +52,121 @@
 }
 
-int task_spawn(void *image, size_t size)
+static int task_spawn_loader(void)
 {
-	return __SYSCALL2(SYS_TASK_SPAWN, (sysarg_t) image, (sysarg_t) size);
+	int phone_id, rc;
+
+	rc = __SYSCALL1(SYS_PROGRAM_SPAWN_LOADER, (sysarg_t) &phone_id);
+	if (rc != 0)
+		return rc;
+
+	return phone_id;
+}
+
+static int loader_set_args(int phone_id, const char *argv[])
+{
+	aid_t req;
+	ipc_call_t answer;
+	ipcarg_t rc;
+
+	const char **ap;
+	char *dp;
+	char *arg_buf;
+	size_t buffer_size;
+	size_t len;
+
+	/* 
+	 * Serialize the arguments into a single array. First
+	 * compute size of the buffer needed.
+	 */
+	ap = argv;
+	buffer_size = 0;
+	while (*ap != NULL) {
+		buffer_size += strlen(*ap) + 1;
+		++ap;
+	}
+
+	arg_buf = malloc(buffer_size);
+	if (arg_buf == NULL) return ENOMEM;
+
+	/* Now fill the buffer with null-terminated argument strings */
+	ap = argv;
+	dp = arg_buf;
+	while (*ap != NULL) {
+		strcpy(dp, *ap);
+		dp += strlen(*ap) + 1;
+
+		++ap;
+	}
+
+	/* Send serialized arguments to the loader */
+
+	req = async_send_0(phone_id, LOADER_SET_ARGS, &answer);
+	rc = ipc_data_write_start(phone_id, (void *)arg_buf, buffer_size);
+	if (rc != EOK) {
+		async_wait_for(req, NULL);
+		return rc;
+	}
+
+	async_wait_for(req, &rc);
+	if (rc != EOK) return rc;
+
+	/* Free temporary buffer */
+	free(arg_buf);
+
+	return EOK;
+}
+
+/** Create a new task by running an executable from VFS.
+ *
+ * @param path	pathname of the binary to execute
+ * @param argv	command-line arguments
+ * @return	ID of the newly created task or zero on error.
+ */
+task_id_t task_spawn(const char *path, const char *argv[])
+{
+	int phone_id;
+	ipc_call_t answer;
+	aid_t req;
+	int rc;
+	ipcarg_t retval;
+
+	/* Spawn a program loader */	
+	phone_id = task_spawn_loader();
+	if (phone_id < 0) return 0;
+
+	/*
+	 * Say hello so that the loader knows the incoming connection's
+	 * phone hash.
+	 */
+	rc = async_req_0_0(phone_id, LOADER_HELLO);
+	if (rc != EOK) return 0;
+
+	/* Send program pathname */
+	req = async_send_0(phone_id, LOADER_SET_PATHNAME, &answer);
+	rc = ipc_data_write_start(phone_id, (void *)path, strlen(path));
+	if (rc != EOK) {
+		async_wait_for(req, NULL);
+		return 1;
+	}
+
+	async_wait_for(req, &retval);
+	if (retval != EOK) goto error;
+
+	/* Send arguments */
+	rc = loader_set_args(phone_id, argv);
+	if (rc != EOK) goto error;
+
+	/* Request loader to start the program */	
+	rc = async_req_0_0(phone_id, LOADER_RUN);
+	if (rc != EOK) goto error;
+
+	/* Success */
+	ipc_hangup(phone_id);
+	return 1;
+
+	/* Error exit */
+error:
+	ipc_hangup(phone_id);
+	return 0;
 }
 
Index: uspace/lib/libc/include/as.h
===================================================================
--- uspace/lib/libc/include/as.h	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/lib/libc/include/as.h	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -43,4 +43,5 @@
 extern void *as_area_create(void *address, size_t size, int flags);
 extern int as_area_resize(void *address, size_t size, int flags);
+extern int as_area_change_flags(void *address, int flags);
 extern int as_area_destroy(void *address);
 extern void *set_maxheapsize(size_t mhs);
Index: uspace/lib/libc/include/io/stream.h
===================================================================
--- uspace/lib/libc/include/io/stream.h	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/lib/libc/include/io/stream.h	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -41,4 +41,5 @@
 
 extern void open_console(void);
+extern void close_console(void);
 extern void klog_update(void);
 
Index: uspace/lib/libc/include/ipc/loader.h
===================================================================
--- uspace/lib/libc/include/ipc/loader.h	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/lib/libc/include/ipc/loader.h	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcipc
+ * @{
+ */
+/** @file
+ */ 
+
+#ifndef LIBC_LOADER_H_
+#define LIBC_LOADER_H_
+
+#include <ipc/ipc.h>
+
+typedef enum {
+	LOADER_HELLO = IPC_FIRST_USER_METHOD,
+	LOADER_SET_PATHNAME,
+	LOADER_SET_ARGS,
+	LOADER_RUN
+} fb_request_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/include/libc.h
===================================================================
--- uspace/lib/libc/include/libc.h	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/lib/libc/include/libc.h	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -49,5 +49,5 @@
     __syscall(p1, p2, p3, p4, p5, p6,id)
 
-extern void __main(void);
+extern void __main(void *pcb_ptr);
 extern void __exit(void);
 
Index: uspace/lib/libc/include/loader/pcb.h
===================================================================
--- uspace/lib/libc/include/loader/pcb.h	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/lib/libc/include/loader/pcb.h	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2008 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup fs
+ * @{
+ */
+/** @file
+ * @brief Program Control Block interface.
+ */
+
+#ifndef LIBC_PCB_H_
+#define LIBC_PCB_H_
+
+#include <sys/types.h>
+
+typedef void (*entry_point_t)(void);
+
+/**
+ * Holds pointers to data passed from the program loader to the program
+ * and/or to the dynamic linker. This includes the program entry point,
+ * arguments, environment variables etc.
+ */
+typedef struct {
+	/** Program entry point */
+	entry_point_t entry;
+
+	/** Number of command-line arguments */
+	int argc;
+	/** Command-line arguments */
+	char **argv;
+
+	/*
+	 * ELF-specific data
+	 */
+	/** Pointer to ELF dynamic section of the program */
+	void *dynamic;
+	/** Pointer to dynamic section of the runtime linker */
+	void *rtld_dynamic;
+	/** Runtime-linker load bias */
+	uintptr_t rtld_bias;
+} pcb_t;
+
+extern pcb_t *__pcb;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/libc/include/smc.h
===================================================================
--- uspace/lib/libc/include/smc.h	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/lib/libc/include/smc.h	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_SMC_H_
+#define LIBC_SMC_H_
+
+#include <sys/types.h>
+
+extern int smc_coherence(void *address, size_t size);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/include/task.h
===================================================================
--- uspace/lib/libc/include/task.h	(revision b7f908712f345dc3c714eaee170629c2df743a90)
+++ uspace/lib/libc/include/task.h	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -41,5 +41,5 @@
 
 extern task_id_t task_get_id(void);
-extern int task_spawn(void *image, size_t size);
+extern task_id_t task_spawn(const char *path, const char *argv[]);
 
 #endif
Index: uspace/srv/loader/Makefile
===================================================================
--- uspace/srv/loader/Makefile	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/Makefile	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,94 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2008 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+include ../../../version
+include ../../Makefile.config
+
+## Setup toolchain
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+include $(LIBC_PREFIX)/Makefile.toolchain
+include arch/$(ARCH)/Makefile.inc
+
+CFLAGS += -Iinclude
+
+LIBS = $(LIBC_PREFIX)/libc.a $(SOFTINT_PREFIX)/libsoftint.a
+DEFS += -DRELEASE=\"$(RELEASE)\"
+
+ifdef REVISION
+	DEFS += "-DREVISION=\"$(REVISION)\""
+endif
+
+ifdef TIMESTAMP
+	DEFS += "-DTIMESTAMP=\"$(TIMESTAMP)\""
+endif
+
+## Sources
+#
+
+OUTPUT = loader
+GENERIC_SOURCES = \
+	main.c \
+	elf_load.c \
+	interp.s
+
+SOURCES := $(GENERIC_SOURCES) $(ARCH_SOURCES)
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all clean depend disasm
+
+all: $(OUTPUT) disasm
+
+-include Makefile.depend
+
+clean:
+	-rm -f $(OUTPUT) $(OBJECTS) $(OUTPUT).map $(OUTPUT).disasm arch/$(ARCH)/_link.ld Makefile.depend
+
+depend:
+	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
+
+$(OUTPUT): $(OBJECTS) $(LIBS) arch/$(ARCH)/_link.ld
+	$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(OBJECTS) $(LIBS) -o $@ -Map $(OUTPUT).map
+
+disasm:
+	$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm
+
+arch/$(ARCH)/_link.ld: arch/$(ARCH)/_link.ld.in
+	$(CC) $(DEFS) $(CFLAGS) -DLIBC_PREFIX=$(LIBC_PREFIX) -E -x c $< | grep -v "^\#" > $@
+
+%.o: %.S
+	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o: %.c
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
Index: uspace/srv/loader/arch/amd64/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/amd64/Makefile.inc	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/amd64/Makefile.inc	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2008 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+CFLAGS += -D__64_BITS__
+ARCH_SOURCES := arch/$(ARCH)/amd64.s
Index: uspace/srv/loader/arch/amd64/_link.ld.in
===================================================================
--- uspace/srv/loader/arch/amd64/_link.ld.in	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/amd64/_link.ld.in	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,52 @@
+STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
+ENTRY(__entry)
+
+PHDRS {
+	interp PT_INTERP;
+	text PT_LOAD FLAGS(5);
+	data PT_LOAD FLAGS(6);
+}
+
+SECTIONS {
+	.interp : {
+		*(.interp);
+	} : interp
+
+	/* . = 0x0000700000001000;*/
+	. = 0x70001000;
+	
+	.init ALIGN(0x1000) : SUBALIGN(0x1000) {
+		*(.init);
+	} :text
+	.text : {
+		*(.text);
+		*(.rodata*);
+	} :text
+	
+	.data ALIGN(0x1000) : SUBALIGN(0x1000) {
+		*(.data);
+	} :data
+	.tdata : {
+		_tdata_start = .;
+		*(.tdata);
+		_tdata_end = .;
+	} :data
+	.tbss : {
+		_tbss_start = .;
+		*(.tbss);
+		_tbss_end = .;
+	} :data
+	_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
+	.bss : {
+		*(COMMON);
+		*(.bss);
+	} :data
+
+	. = ALIGN(0x1000);
+	_heap = .;
+	
+	/DISCARD/ : {
+		*(*);
+	}
+
+}
Index: uspace/srv/loader/arch/amd64/amd64.s
===================================================================
--- uspace/srv/loader/arch/amd64/amd64.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/amd64/amd64.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2008 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+.globl program_run
+
+## void program_run(void *entry_point, void *pcb);
+#
+# %rdi	contains entry_point
+# %rsi	contains pcb
+#
+# Jump to a program entry point
+program_run:
+	# pcb must be passed in %rdi, use %rdx as a scratch register
+	mov %rdi, %rdx
+	mov %rsi, %rdi
+
+	# jump to entry point
+	jmp %rdx
Index: uspace/srv/loader/arch/arm32/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/arm32/Makefile.inc	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/arm32/Makefile.inc	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2008 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+CFLAGS += -D__32_BITS__
+ARCH_SOURCES := arch/$(ARCH)/arm32.s
Index: uspace/srv/loader/arch/arm32/_link.ld.in
===================================================================
--- uspace/srv/loader/arch/arm32/_link.ld.in	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/arm32/_link.ld.in	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,59 @@
+/* 
+ * The only difference from _link.ld.in for regular statically-linked apps
+ * is the base address.
+ */
+STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
+ENTRY(__entry)
+
+PHDRS {
+	interp PT_INTERP;
+	text PT_LOAD FLAGS(5);
+	data PT_LOAD FLAGS(6);
+}
+
+SECTIONS {
+	.interp : {
+		*(.interp);
+	} : interp
+
+	. = 0x70001000;
+
+	.init ALIGN(0x1000): SUBALIGN(0x1000) {
+		*(.init);
+	} : text
+	.text : {
+		*(.text);
+        *(.rodata*);
+	} :text
+	
+	.data ALIGN(0x1000) : SUBALIGN(0x1000) {
+		*(.opd);
+		*(.data .data.*);
+		*(.sdata);
+	} :data
+	.tdata : {
+		_tdata_start = .;
+		*(.tdata);
+		_tdata_end = .;
+	} :data
+	.tbss : {
+		_tbss_start = .;
+		*(.tbss);
+		_tbss_end = .;
+	} :data
+	_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
+	.bss : {
+		*(.sbss);
+		*(.scommon);
+        *(COMMON);
+        *(.bss);
+	} :data
+	
+	. = ALIGN(0x1000);
+	_heap = .;
+	
+	/DISCARD/ : {
+		*(*);
+	}
+
+}
Index: uspace/srv/loader/arch/arm32/arm32.s
===================================================================
--- uspace/srv/loader/arch/arm32/arm32.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/arm32/arm32.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2008 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+.globl program_run
+
+## void program_run(void *entry_point, void *pcb);
+#
+# r0	contains entry_point
+# r1	contains pcb
+#
+# Jump to a program entry point
+program_run:
+	# pcb is passed to the entry point in r1 (where it already is)
+	mov r15, r0
Index: uspace/srv/loader/arch/ia32/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/ia32/Makefile.inc	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/ia32/Makefile.inc	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2008 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+CFLAGS += -D__32_BITS__
+ARCH_SOURCES := arch/$(ARCH)/ia32.s
Index: uspace/srv/loader/arch/ia32/_link.ld.in
===================================================================
--- uspace/srv/loader/arch/ia32/_link.ld.in	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/ia32/_link.ld.in	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,55 @@
+/* 
+ * The difference from _link.ld.in for regular statically-linked apps
+ * is the base address and the special interp section.
+ */
+STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
+ENTRY(__entry)
+
+PHDRS {
+	interp PT_INTERP;
+        text PT_LOAD FILEHDR PHDRS FLAGS(5);
+	data PT_LOAD FLAGS(6);
+}
+
+SECTIONS {
+	.interp : {
+		*(.interp);
+	} :interp
+
+	. = 0x70001000;
+
+	.init ALIGN(0x1000) : SUBALIGN(0x1000) {
+		*(.init);
+	} :text
+	.text : {
+		*(.text);
+                *(.rodata*);
+	} :text
+	
+	.data ALIGN(0x1000) : SUBALIGN(0x1000) {
+		*(.data);
+	} :data
+	.tdata : {
+		_tdata_start = .;
+		*(.tdata);
+		_tdata_end = .;
+	} :data
+	.tbss : {
+		_tbss_start = .;
+		*(.tbss);
+		_tbss_end = .;
+	} :data
+	_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
+	.bss : {
+                *(COMMON);
+                *(.bss);
+	} :data
+	
+	. = ALIGN(0x1000);
+	_heap = .;
+	
+	/DISCARD/ : {
+		*(*);
+	}
+
+}
Index: uspace/srv/loader/arch/ia32/ia32.s
===================================================================
--- uspace/srv/loader/arch/ia32/ia32.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/ia32/ia32.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2008 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+.globl program_run
+
+## void program_run(void *entry_point, void *pcb);
+#
+# Jump to a program entry point
+program_run:
+	# Use standard ia32 prologue not to confuse anybody
+	push %ebp
+	movl %esp, %ebp
+
+	# %eax := entry_point
+	movl 0x8(%ebp), %eax
+
+	# %ebx := pcb
+	# pcb is passed to the entry point int %ebx
+	mov 0xc(%ebp), %ebx
+
+	# Save a tiny bit of stack space
+	pop %ebp
+
+	jmp %eax
Index: uspace/srv/loader/arch/ia64/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/ia64/Makefile.inc	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/ia64/Makefile.inc	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2008 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+CFLAGS += -D__64_BITS__
+ARCH_SOURCES := arch/$(ARCH)/ia64.s
+AFLAGS += -xexplicit
Index: uspace/srv/loader/arch/ia64/_link.ld.in
===================================================================
--- uspace/srv/loader/arch/ia64/_link.ld.in	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/ia64/_link.ld.in	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,66 @@
+STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
+ENTRY(__entry)
+
+PHDRS {
+	interp PT_INTERP;
+	text PT_LOAD FLAGS(5);
+	data PT_LOAD FLAGS(6);
+}
+
+SECTIONS {
+	.interp : {
+		*(.interp);
+	} :interp
+
+	. = 0x00084000 + SIZEOF_HEADERS;
+
+	.init : {
+		LONG(0);
+		LONG(0);
+		LONG(0);
+		LONG(0);
+		LONG(0);
+		LONG(0);
+		*(.init);
+	} : text
+	.text : {
+		*(.text);
+		*(.rodata*);
+	} :text
+
+	. = . + 0x4000;
+
+	.got : {
+		_gp = .;
+		*(.got*);
+	} :data	
+	.data : {
+		*(.opd);
+		*(.data .data.*);
+		*(.sdata);
+	} :data
+	.tdata : {
+		_tdata_start = .;
+		*(.tdata);
+		_tdata_end = .;
+	} :data
+	.tbss : {
+		_tbss_start = .;
+		*(.tbss);
+		_tbss_end = .;
+	} :data
+	_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
+	.bss : {
+		*(.sbss);
+		*(.scommon);
+		*(COMMON);
+		*(.bss);
+	} :data
+
+	. = ALIGN(0x4000);
+	_heap = .;
+ 
+	/DISCARD/ : {
+		*(*);
+        }
+}
Index: uspace/srv/loader/arch/ia64/ia64.s
===================================================================
--- uspace/srv/loader/arch/ia64/ia64.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/ia64/ia64.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2008 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+.text
+.globl program_run
+
+## void program_run(void *entry_point, void *pcb);
+#
+# in0 (r32)	contains entry_point
+# in1 (r33)	contains pcb
+#
+# Jump to a program entry point
+program_run:
+	# Pass pcb to the entry point in r2
+
+	mov b6 = r32
+	mov r2 = r33 ;;
+	br b6 ;;
Index: uspace/srv/loader/arch/mips32/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/mips32/Makefile.inc	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/mips32/Makefile.inc	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2008 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+CFLAGS += -D__32_BITS__
+ARCH_SOURCES := arch/$(ARCH)/mips32.s
Index: uspace/srv/loader/arch/mips32/_link.ld.in
===================================================================
--- uspace/srv/loader/arch/mips32/_link.ld.in	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/mips32/_link.ld.in	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,66 @@
+/* 
+ * The only difference from _link.ld.in for regular statically-linked apps
+ * is the base address.
+ */
+STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
+ENTRY(__entry)
+
+PHDRS {
+	interp PT_INTERP;
+	text PT_LOAD FLAGS(5);
+	data PT_LOAD FLAGS(6);
+}
+
+SECTIONS {
+	.interp : {
+		*(.interp);
+	} :interp
+
+	. = 0x70004000;
+	
+	.init ALIGN(0x4000) : SUBALIGN(0x4000) {
+		*(.init);
+	} :text
+	.text : {
+	        *(.text);
+		*(.rodata*);
+	} :text
+
+	.data : {
+		*(.data);
+		*(.data.rel*);
+	} :data
+
+	.got : {
+		_gp = .;
+		*(.got);
+	} :data
+
+	.tdata : {
+		_tdata_start = .;
+		*(.tdata);
+		_tdata_end = .;
+	} :data
+	.tbss : {
+		_tbss_start = .;
+		*(.tbss);
+		_tbss_end = .;
+	} :data
+	_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
+
+	.sbss : {
+		*(.scommon);
+		*(.sbss);
+	}	
+	.bss : {
+		*(.bss);
+		*(COMMON);
+	} :data
+
+	. = ALIGN(0x4000);
+	_heap = .;
+
+	/DISCARD/ : {
+		*(*);
+	}
+}
Index: uspace/srv/loader/arch/mips32/mips32.s
===================================================================
--- uspace/srv/loader/arch/mips32/mips32.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/mips32/mips32.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2008 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+.text
+.section .text
+.global program_run
+.set noreorder
+
+## void program_run(void *entry_point, void *pcb);
+#
+# $a0 (=$4)	contains entry_point
+# $a1 (=$5)	contains pcb
+#
+# Jump to a program entry point
+.ent program_run
+program_run:
+	# tmp := entry_point
+	move $25, $a0
+
+	# Pass pcb to the entry point in $a0
+	move $a0, $a1
+	jr $25
+	nop
+.end
Index: uspace/srv/loader/arch/ppc32/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/ppc32/Makefile.inc	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/ppc32/Makefile.inc	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2008 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+CFLAGS += -D__32_BITS__
+ARCH_SOURCES := arch/$(ARCH)/ppc32.s
Index: uspace/srv/loader/arch/ppc32/_link.ld.in
===================================================================
--- uspace/srv/loader/arch/ppc32/_link.ld.in	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/ppc32/_link.ld.in	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,57 @@
+/* 
+ * The only difference from _link.ld.in for regular statically-linked apps
+ * is the base address.
+ */
+STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
+ENTRY(__entry)
+
+PHDRS {
+	interp PT_INTERP;
+	text PT_LOAD FLAGS(5);
+	data PT_LOAD FLAGS(6);
+}
+
+SECTIONS {
+	.interp : {
+		*(.interp);
+	} :interp
+
+	. = 0x70001000;
+
+	.init ALIGN(0x1000) : SUBALIGN(0x1000) {
+		*(.init);
+	} :text
+	.text : {
+		*(.text);
+		*(.rodata*);
+	} :text
+	
+	.data ALIGN(0x1000) : SUBALIGN(0x1000) {
+		*(.data);
+		*(.sdata);
+	} :data
+	.tdata : {
+		_tdata_start = .;
+		*(.tdata);
+		_tdata_end = .;
+	} :data
+	.tbss : {
+		_tbss_start = .;
+		*(.tbss);
+		_tbss_end = .;
+	} :data
+	_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
+	.bss : {
+		*(.sbss);
+		*(COMMON);
+		*(.bss);
+	} :data
+
+	. = ALIGN(0x1000);
+	_heap = .;
+	
+	/DISCARD/ : {
+		*(*);
+	}
+
+}
Index: uspace/srv/loader/arch/ppc32/ppc32.s
===================================================================
--- uspace/srv/loader/arch/ppc32/ppc32.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/ppc32/ppc32.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2008 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+.globl program_run
+
+## void program_run(void *entry_point, void *pcb);
+#
+# %r3	contains entry_point
+# %r4	contains pcb
+#
+# Jump to a program entry point
+program_run:
+	mtctr %r3
+	mr %r3, %r4	# Pass pcb to the entry point in %r3
+	bctr
Index: uspace/srv/loader/arch/sparc64/Makefile.inc
===================================================================
--- uspace/srv/loader/arch/sparc64/Makefile.inc	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/sparc64/Makefile.inc	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2008 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+CFLAGS += -D__64_BITS__
+ARCH_SOURCES := arch/$(ARCH)/sparc64.s
Index: uspace/srv/loader/arch/sparc64/_link.ld.in
===================================================================
--- uspace/srv/loader/arch/sparc64/_link.ld.in	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/sparc64/_link.ld.in	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,59 @@
+STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o)
+ENTRY(__entry)
+
+PHDRS {
+	interp PT_INTERP;
+	text PT_LOAD FLAGS(5);
+	data PT_LOAD FLAGS(6);
+}
+
+SECTIONS {
+	.interp : {
+		*(.interp);
+	} :interp
+
+	. = 0x70004000 + SIZEOF_HEADERS;
+
+	.init : {
+		*(.init);
+	} :text
+	.text : {
+		*(.text);
+		*(.rodata*);
+	} :text
+
+	. = . + 0x4000;
+
+	.got : {
+		 _gp = .;
+		 *(.got*);
+	} :data
+	.data : {
+		*(.data);
+		*(.sdata);
+	} :data
+	.tdata : {
+		_tdata_start = .;
+		*(.tdata);
+		_tdata_end = .;
+	} :data
+	.tbss : {
+		_tbss_start = .;
+		*(.tbss);
+		_tbss_end = .;
+	} :data
+	_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
+	.bss : {
+		*(.sbss);
+		*(COMMON);
+		*(.bss);
+	} :data
+
+	. = ALIGN(0x4000);
+	_heap = .;
+	
+	/DISCARD/ : {
+		*(*);
+	}
+
+}
Index: uspace/srv/loader/arch/sparc64/sparc64.s
===================================================================
--- uspace/srv/loader/arch/sparc64/sparc64.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/arch/sparc64/sparc64.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2008 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+.globl program_run
+
+## void program_run(void *entry_point, void *pcb);
+#
+# %o0	contains entry_point
+# %o1	contains pcb
+#
+# Jump to a program entry point
+program_run:
+	# Pass pcb pointer to entry point in %o1. As it is already
+	# there, no action is needed.
+	call %o0
+	nop
+	# fixme: use branch instead of call
Index: uspace/srv/loader/elf_load.c
===================================================================
--- uspace/srv/loader/elf_load.c	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/elf_load.c	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,451 @@
+/*
+ * Copyright (c) 2006 Sergey Bondari
+ * Copyright (c) 2006 Jakub Jermar
+ * Copyright (c) 2008 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup generic	
+ * @{
+ */
+
+/**
+ * @file
+ * @brief	Userspace ELF loader.
+ *
+ * This module allows loading ELF binaries (both executables and
+ * shared objects) from VFS. The current implementation allocates
+ * anonymous memory, fills it with segment data and then adjusts
+ * the memory areas' flags to the final value. In the future,
+ * the segments will be mapped directly from the file.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <align.h>
+#include <assert.h>
+#include <as.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <smc.h>
+#include <loader/pcb.h>
+
+#include "elf.h"
+#include "elf_load.h"
+#include "arch.h"
+
+static char *error_codes[] = {
+	"no error",
+	"invalid image",
+	"address space error",
+	"incompatible image",
+	"unsupported image type",
+	"irrecoverable error"
+};
+
+static unsigned int elf_load(elf_ld_t *elf, size_t so_bias);
+static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry);
+static int section_header(elf_ld_t *elf, elf_section_header_t *entry);
+static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
+
+/** Load ELF binary from a file.
+ *
+ * Load an ELF binary from the specified file. If the file is
+ * an executable program, it is loaded unbiased. If it is a shared
+ * object, it is loaded with the bias @a so_bias. Some information
+ * extracted from the binary is stored in a elf_info_t structure
+ * pointed to by @a info.
+ *
+ * @param file_name	Path to the ELF file.
+ * @param so_bias	Bias to use if the file is a shared object.
+ * @param info		Pointer to a structure for storing information
+ *			extracted from the binary.
+ *
+ * @return EOK on success or negative error code.
+ */
+int elf_load_file(char *file_name, size_t so_bias, elf_info_t *info)
+{
+	elf_ld_t elf;
+
+	int fd;
+	int rc;
+
+//	printf("open and read '%s'...\n", file_name);
+
+	fd = open(file_name, O_RDONLY);
+	if (fd < 0) {
+		printf("failed opening file\n");
+		return -1;
+	}
+
+	elf.fd = fd;
+	elf.info = info;
+
+	rc = elf_load(&elf, so_bias);
+
+	close(fd);
+
+	return rc;
+}
+
+/** Run an ELF executable.
+ *
+ * Transfers control to the entry point of an ELF executable loaded
+ * earlier with elf_load_file(). This function does not return.
+ *
+ * @param info	Info structure filled earlier by elf_load_file()
+ */
+void elf_run(elf_info_t *info, pcb_t *pcb)
+{
+	program_run(info->entry, pcb);
+
+	/* not reached */
+}
+
+/** Create the program control block (PCB).
+ *
+ * Fills the program control block @a pcb with information from
+ * @a info.
+ *
+ * @param info	Program info structure
+ * @return EOK on success or negative error code
+ */
+void elf_create_pcb(elf_info_t *info, pcb_t *pcb)
+{
+	pcb->entry = info->entry;
+	pcb->dynamic = info->dynamic;
+}
+
+
+/** Load an ELF binary.
+ *
+ * The @a elf structure contains the loader state, including
+ * an open file, from which the binary will be loaded,
+ * a pointer to the @c info structure etc.
+ *
+ * @param elf		Pointer to loader state buffer.
+ * @param so_bias	Bias to use if the file is a shared object.
+ * @return EE_OK on success or EE_xx error code.
+ */
+static unsigned int elf_load(elf_ld_t *elf, size_t so_bias)
+{
+	elf_header_t header_buf;
+	elf_header_t *header = &header_buf;
+	int i, rc;
+
+	rc = read(elf->fd, header, sizeof(elf_header_t));
+	if (rc < 0) {
+		printf("read error\n"); 
+		return EE_INVALID;
+	}
+
+	elf->header = header;
+
+//	printf("ELF-load:");
+	/* Identify ELF */
+	if (header->e_ident[EI_MAG0] != ELFMAG0 ||
+	    header->e_ident[EI_MAG1] != ELFMAG1 || 
+	    header->e_ident[EI_MAG2] != ELFMAG2 ||
+	    header->e_ident[EI_MAG3] != ELFMAG3) {
+		printf("invalid header\n");
+		return EE_INVALID;
+	}
+	
+	/* Identify ELF compatibility */
+	if (header->e_ident[EI_DATA] != ELF_DATA_ENCODING ||
+	    header->e_machine != ELF_MACHINE || 
+	    header->e_ident[EI_VERSION] != EV_CURRENT ||
+	    header->e_version != EV_CURRENT ||
+	    header->e_ident[EI_CLASS] != ELF_CLASS) {
+		printf("incompatible data/version/class\n");
+		return EE_INCOMPATIBLE;
+	}
+
+	if (header->e_phentsize != sizeof(elf_segment_header_t)) {
+		printf("e_phentsize:%d != %d\n", header->e_phentsize,
+		    sizeof(elf_segment_header_t));
+		return EE_INCOMPATIBLE;
+	}
+
+	if (header->e_shentsize != sizeof(elf_section_header_t)) {
+		printf("e_shentsize:%d != %d\n", header->e_shentsize,
+		    sizeof(elf_section_header_t));
+		return EE_INCOMPATIBLE;
+	}
+
+	/* Check if the object type is supported. */
+	if (header->e_type != ET_EXEC && header->e_type != ET_DYN) {
+		printf("Object type %d is not supported\n", header->e_type);
+		return EE_UNSUPPORTED;
+	}
+
+	/* Shared objects can be loaded with a bias */
+//	printf("Object type: %d\n", header->e_type);
+	if (header->e_type == ET_DYN)
+		elf->bias = so_bias;
+	else
+		elf->bias = 0;
+
+//	printf("Bias set to 0x%x\n", elf->bias);
+	elf->info->interp = NULL;
+	elf->info->dynamic = NULL;
+
+//	printf("parse segments\n");
+
+	/* Walk through all segment headers and process them. */
+	for (i = 0; i < header->e_phnum; i++) {
+		elf_segment_header_t segment_hdr;
+
+		/* Seek to start of segment header */
+		lseek(elf->fd, header->e_phoff
+		        + i * sizeof(elf_segment_header_t), SEEK_SET);
+
+		rc = read(elf->fd, &segment_hdr, sizeof(elf_segment_header_t));
+		if (rc < 0) { printf("read error\n"); return EE_INVALID; }
+
+		rc = segment_header(elf, &segment_hdr);
+		if (rc != EE_OK)
+			return rc;
+	}
+
+//	printf("parse sections\n");
+
+	/* Inspect all section headers and proccess them. */
+	for (i = 0; i < header->e_shnum; i++) {
+		elf_section_header_t section_hdr;
+
+		/* Seek to start of section header */
+		lseek(elf->fd, header->e_shoff
+		    + i * sizeof(elf_section_header_t), SEEK_SET);
+
+		rc = read(elf->fd, &section_hdr, sizeof(elf_section_header_t));
+		if (rc < 0) { printf("read error\n"); return EE_INVALID; }
+
+		rc = section_header(elf, &section_hdr);
+		if (rc != EE_OK)
+			return rc;
+	}
+
+	elf->info->entry =
+	    (entry_point_t)((uint8_t *)header->e_entry + elf->bias);
+
+//	printf("done\n");
+
+	return EE_OK;
+}
+
+/** Print error message according to error code.
+ *
+ * @param rc Return code returned by elf_load().
+ *
+ * @return NULL terminated description of error.
+ */
+char *elf_error(unsigned int rc)
+{
+	assert(rc < sizeof(error_codes) / sizeof(char *));
+
+	return error_codes[rc];
+}
+
+/** Process segment header.
+ *
+ * @param entry	Segment header.
+ *
+ * @return EE_OK on success, error code otherwise.
+ */
+static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry)
+{
+	switch (entry->p_type) {
+	case PT_NULL:
+	case PT_PHDR:
+		break;
+	case PT_LOAD:
+		return load_segment(elf, entry);
+		break;
+	case PT_INTERP:
+		/* Assume silently interp == "/rtld.so" */
+		elf->info->interp = "/rtld.so";
+		break;
+	case PT_DYNAMIC:
+	case PT_SHLIB:
+	case PT_NOTE:
+	case PT_LOPROC:
+	case PT_HIPROC:
+	default:
+		printf("segment p_type %d unknown\n", entry->p_type);
+		return EE_UNSUPPORTED;
+		break;
+	}
+	return EE_OK;
+}
+
+/** Load segment described by program header entry.
+ *
+ * @param elf	Loader state.
+ * @param entry Program header entry describing segment to be loaded.
+ *
+ * @return EE_OK on success, error code otherwise.
+ */
+int load_segment(elf_ld_t *elf, elf_segment_header_t *entry)
+{
+	void *a;
+	int flags = 0;
+	uintptr_t bias;
+	uintptr_t base;
+	size_t mem_sz;
+	int rc;
+
+//	printf("load segment at addr 0x%x, size 0x%x\n", entry->p_vaddr,
+//		entry->p_memsz);
+	
+	bias = elf->bias;
+
+	if (entry->p_align > 1) {
+		if ((entry->p_offset % entry->p_align) !=
+		    (entry->p_vaddr % entry->p_align)) {
+			printf("align check 1 failed offset%%align=%d, vaddr%%align=%d\n",
+			entry->p_offset % entry->p_align,
+			entry->p_vaddr % entry->p_align
+			);
+			return EE_INVALID;
+		}
+	}
+
+	/* Final flags that will be set for the memory area */
+
+	if (entry->p_flags & PF_X)
+		flags |= AS_AREA_EXEC;
+	if (entry->p_flags & PF_W)
+		flags |= AS_AREA_WRITE;
+	if (entry->p_flags & PF_R)
+		flags |= AS_AREA_READ;
+	flags |= AS_AREA_CACHEABLE;
+	
+	base = ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE);
+	mem_sz = entry->p_memsz + (entry->p_vaddr - base);
+
+//	printf("map to p_vaddr=0x%x-0x%x...\n", entry->p_vaddr + bias,
+//	entry->p_vaddr + bias + ALIGN_UP(entry->p_memsz, PAGE_SIZE));
+
+	/*
+	 * For the course of loading, the area needs to be readable
+	 * and writeable.
+	 */
+	a = as_area_create((uint8_t *)base + bias,
+		mem_sz, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
+	if (a == (void *)(-1)) {
+		printf("memory mapping failed\n");
+		return EE_MEMORY;
+	}
+
+//	printf("as_area_create(0x%lx, 0x%x, %d) -> 0x%lx\n",
+//		entry->p_vaddr+bias, entry->p_memsz, flags, (uintptr_t)a);
+
+	/*
+	 * Load segment data
+	 */
+//	printf("seek to %d\n", entry->p_offset);
+	rc = lseek(elf->fd, entry->p_offset, SEEK_SET);
+	if (rc < 0) { printf("seek error\n"); return EE_INVALID; }
+
+//	printf("read 0x%x bytes to address 0x%x\n", entry->p_filesz, entry->p_vaddr+bias);
+/*	rc = read(fd, (void *)(entry->p_vaddr + bias), entry->p_filesz);
+	if (rc < 0) { printf("read error\n"); return EE_INVALID; }*/
+
+	/* Long reads are not possible yet. Load segment picewise */
+
+	unsigned left, now;
+	uint8_t *dp;
+
+	left = entry->p_filesz;
+	dp = (uint8_t *)(entry->p_vaddr + bias);
+
+	while (left > 0) {
+		now = 16384;
+		if (now > left) now = left;
+
+//		printf("read %d...", now);
+		rc = read(elf->fd, dp, now);
+//		printf("->%d\n", rc);
+
+		if (rc < 0) { printf("read error\n"); return EE_INVALID; }
+
+		left -= now;
+		dp += now;
+	}
+
+//	printf("set area flags to %d\n", flags);
+	rc = as_area_change_flags((uint8_t *)entry->p_vaddr + bias, flags);
+	if (rc != 0) {
+		printf("failed to set memory area flags\n");
+		return EE_MEMORY;
+	}
+
+	if (flags & AS_AREA_EXEC) {
+		/* Enforce SMC coherence for the segment */
+		if (smc_coherence(entry->p_vaddr + bias, entry->p_filesz))
+			return EE_MEMORY;
+	}
+
+	return EE_OK;
+}
+
+/** Process section header.
+ *
+ * @param elf	Loader state.
+ * @param entry Segment header.
+ *
+ * @return EE_OK on success, error code otherwise.
+ */
+static int section_header(elf_ld_t *elf, elf_section_header_t *entry)
+{
+	switch (entry->sh_type) {
+	case SHT_PROGBITS:
+		if (entry->sh_flags & SHF_TLS) {
+			/* .tdata */
+		}
+		break;
+	case SHT_NOBITS:
+		if (entry->sh_flags & SHF_TLS) {
+			/* .tbss */
+		}
+		break;
+	case SHT_DYNAMIC:
+		/* Record pointer to dynamic section into info structure */
+		elf->info->dynamic =
+		    (void *)((uint8_t *)entry->sh_addr + elf->bias);
+		printf("dynamic section found at 0x%x\n",
+			(uintptr_t)elf->info->dynamic);
+		break;
+	default:
+		break;
+	}
+	
+	return EE_OK;
+}
+
+/** @}
+ */
Index: uspace/srv/loader/include/arch.h
===================================================================
--- uspace/srv/loader/include/arch.h	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/include/arch.h	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2008 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup fs
+ * @{
+ */
+/** @file
+ * @brief
+ */
+
+#ifndef LOADER_ARCH_H_
+#define LOADER_ARCH_H_
+
+void program_run(void *entry_point, void *pcb);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/srv/loader/include/elf.h
===================================================================
--- uspace/srv/loader/include/elf.h	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/include/elf.h	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2006 Sergey Bondari
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup generic	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef ELF_H_
+#define ELF_H_
+
+#include <arch/elf.h>
+#include <sys/types.h>
+
+/**
+ * current ELF version
+ */
+#define	EV_CURRENT	1
+
+/** 
+ * ELF types 
+ */
+#define ET_NONE		0	/* No type */
+#define ET_REL		1	/* Relocatable file */
+#define ET_EXEC		2	/* Executable */
+#define ET_DYN		3	/* Shared object */
+#define ET_CORE		4	/* Core */
+#define ET_LOPROC	0xff00	/* Processor specific */
+#define ET_HIPROC	0xffff	/* Processor specific */
+
+/** 
+ * ELF machine types
+ */
+#define EM_NO		0	/* No machine */
+#define EM_SPARC	2	/* SPARC */
+#define EM_386		3	/* i386 */
+#define EM_MIPS		8	/* MIPS RS3000 */
+#define EM_MIPS_RS3_LE	10	/* MIPS RS3000 LE */
+#define EM_PPC		20	/* PPC32 */
+#define EM_PPC64	21	/* PPC64 */
+#define EM_ARM		40	/* ARM */
+#define EM_SPARCV9	43	/* SPARC64 */
+#define EM_IA_64	50	/* IA-64 */
+#define EM_X86_64	62	/* AMD64/EMT64 */
+
+/**
+ * ELF identification indexes
+ */
+#define EI_MAG0		0
+#define EI_MAG1		1
+#define EI_MAG2		2
+#define EI_MAG3		3
+#define EI_CLASS	4		/* File class */
+#define EI_DATA		5		/* Data encoding */
+#define EI_VERSION	6		/* File version */
+#define EI_OSABI	7
+#define EI_ABIVERSION	8
+#define EI_PAD		9		/* Start of padding bytes */
+#define EI_NIDENT	16		/* ELF identification table size */
+
+/**
+ * ELF magic number
+ */
+#define ELFMAG0		0x7f
+#define ELFMAG1		'E'
+#define ELFMAG2		'L'
+#define ELFMAG3		'F'
+
+/**
+ * ELF file classes
+ */
+#define ELFCLASSNONE	0
+#define ELFCLASS32	1
+#define ELFCLASS64	2
+
+/**
+ * ELF data encoding types
+ */
+#define ELFDATANONE	0
+#define ELFDATA2LSB	1		/* Least significant byte first (little endian) */
+#define ELFDATA2MSB	2		/* Most signigicant byte first (big endian) */
+
+/**
+ * ELF error return codes
+ */
+#define EE_OK			0	/* No error */
+#define EE_INVALID		1	/* Invalid ELF image */
+#define	EE_MEMORY		2	/* Cannot allocate address space */
+#define EE_INCOMPATIBLE		3	/* ELF image is not compatible with current architecture */
+#define EE_UNSUPPORTED		4	/* Non-supported ELF (e.g. dynamic ELFs) */
+#define EE_IRRECOVERABLE	5
+
+/**
+ * ELF section types
+ */
+#define SHT_NULL		0
+#define SHT_PROGBITS		1
+#define SHT_SYMTAB		2
+#define SHT_STRTAB		3
+#define SHT_RELA		4
+#define SHT_HASH		5
+#define SHT_DYNAMIC		6
+#define SHT_NOTE		7
+#define SHT_NOBITS		8
+#define SHT_REL			9
+#define SHT_SHLIB		10
+#define SHT_DYNSYM		11
+#define SHT_LOOS		0x60000000
+#define SHT_HIOS		0x6fffffff
+#define SHT_LOPROC		0x70000000
+#define SHT_HIPROC		0x7fffffff
+#define SHT_LOUSER		0x80000000
+#define SHT_HIUSER		0xffffffff
+
+/**
+ * ELF section flags
+ */
+#define SHF_WRITE		0x1 
+#define SHF_ALLOC		0x2
+#define SHF_EXECINSTR		0x4
+#define SHF_TLS			0x400
+#define SHF_MASKPROC		0xf0000000
+
+/**
+ * Symbol binding
+ */
+#define STB_LOCAL		0
+#define STB_GLOBAL		1
+#define STB_WEAK		2
+#define STB_LOPROC		13
+#define STB_HIPROC		15
+
+/**
+ * Symbol types
+ */
+#define STT_NOTYPE		0
+#define STT_OBJECT		1
+#define STT_FUNC		2
+#define STT_SECTION		3
+#define STT_FILE		4
+#define STT_LOPROC		13
+#define STT_HIPROC		15
+
+/**
+ * Program segment types
+ */
+#define PT_NULL			0
+#define PT_LOAD			1
+#define PT_DYNAMIC		2
+#define PT_INTERP		3
+#define PT_NOTE			4
+#define PT_SHLIB		5
+#define PT_PHDR			6
+#define PT_LOPROC		0x70000000
+#define PT_HIPROC		0x7fffffff
+
+/**
+ * Program segment attributes.
+ */
+#define PF_X	1
+#define PF_W	2
+#define PF_R	4
+
+/**
+ * ELF data types
+ *
+ * These types are found to be identical in both 32-bit and 64-bit
+ * ELF object file specifications. They are the only types used
+ * in ELF header.
+ */
+typedef uint64_t elf_xword;
+typedef int64_t elf_sxword;
+typedef uint32_t elf_word;
+typedef int32_t elf_sword;
+typedef uint16_t elf_half;
+
+/**
+ * 32-bit ELF data types.
+ *
+ * These types are specific for 32-bit format.
+ */
+typedef uint32_t elf32_addr;
+typedef uint32_t elf32_off;
+
+/**
+ * 64-bit ELF data types.
+ *
+ * These types are specific for 64-bit format.
+ */
+typedef uint64_t elf64_addr;
+typedef uint64_t elf64_off;
+
+/** ELF header */
+struct elf32_header {
+	uint8_t e_ident[EI_NIDENT];
+	elf_half e_type;
+	elf_half e_machine;
+	elf_word e_version;
+	elf32_addr e_entry;
+	elf32_off e_phoff;
+	elf32_off e_shoff;
+	elf_word e_flags;
+	elf_half e_ehsize;
+	elf_half e_phentsize;
+	elf_half e_phnum;
+	elf_half e_shentsize;
+	elf_half e_shnum;
+	elf_half e_shstrndx;
+};
+struct elf64_header {
+	uint8_t e_ident[EI_NIDENT];
+	elf_half e_type;
+	elf_half e_machine;
+	elf_word e_version;
+	elf64_addr e_entry;
+	elf64_off e_phoff;
+	elf64_off e_shoff;
+	elf_word e_flags;
+	elf_half e_ehsize;
+	elf_half e_phentsize;
+	elf_half e_phnum;
+	elf_half e_shentsize;
+	elf_half e_shnum;
+	elf_half e_shstrndx;
+};
+
+/*
+ * ELF segment header.
+ * Segments headers are also known as program headers.
+ */
+struct elf32_segment_header {
+	elf_word p_type;
+	elf32_off p_offset;
+	elf32_addr p_vaddr;
+	elf32_addr p_paddr;
+	elf_word p_filesz;
+	elf_word p_memsz;
+	elf_word p_flags;
+	elf_word p_align;
+};
+struct elf64_segment_header {
+	elf_word p_type;
+	elf_word p_flags;
+	elf64_off p_offset;
+	elf64_addr p_vaddr;
+	elf64_addr p_paddr;
+	elf_xword p_filesz;
+	elf_xword p_memsz;
+	elf_xword p_align;
+};
+
+/*
+ * ELF section header
+ */
+struct elf32_section_header {
+	elf_word sh_name;
+	elf_word sh_type;
+	elf_word sh_flags;
+	elf32_addr sh_addr;
+	elf32_off sh_offset;
+	elf_word sh_size;
+	elf_word sh_link;
+	elf_word sh_info;
+	elf_word sh_addralign;
+	elf_word sh_entsize;
+};
+struct elf64_section_header {
+	elf_word sh_name;
+	elf_word sh_type;
+	elf_xword sh_flags;
+	elf64_addr sh_addr;
+	elf64_off sh_offset;
+	elf_xword sh_size;
+	elf_word sh_link;
+	elf_word sh_info;
+	elf_xword sh_addralign;
+	elf_xword sh_entsize;
+};
+
+/*
+ * ELF symbol table entry
+ */
+struct elf32_symbol {
+	elf_word st_name;
+	elf32_addr st_value;
+	elf_word st_size;
+	uint8_t st_info;
+	uint8_t st_other;
+	elf_half st_shndx;
+};
+struct elf64_symbol {
+	elf_word st_name;
+	uint8_t st_info;
+	uint8_t st_other;
+	elf_half st_shndx;
+	elf64_addr st_value;
+	elf_xword st_size;
+};
+
+#ifdef __32_BITS__ 
+typedef struct elf32_header elf_header_t;
+typedef struct elf32_segment_header elf_segment_header_t;
+typedef struct elf32_section_header elf_section_header_t;
+typedef struct elf32_symbol elf_symbol_t;
+#endif
+#ifdef __64_BITS__
+typedef struct elf64_header elf_header_t;
+typedef struct elf64_segment_header elf_segment_header_t;
+typedef struct elf64_section_header elf_section_header_t;
+typedef struct elf64_symbol elf_symbol_t;
+#endif
+
+extern char *elf_error(unsigned int rc);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/loader/include/elf_load.h
===================================================================
--- uspace/srv/loader/include/elf_load.h	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/include/elf_load.h	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup generic	
+ * @{
+ */
+/** @file
+ * @brief ELF loader structures and public functions.
+ */
+
+#ifndef ELF_LOAD_H_
+#define ELF_LOAD_H_
+
+#include <arch/elf.h>
+#include <sys/types.h>
+#include <loader/pcb.h>
+
+#include "elf.h"
+
+/**
+ * Some data extracted from the headers are stored here
+ */
+typedef struct {
+	/** Entry point */
+	entry_point_t entry;
+
+	/** ELF interpreter name or NULL if statically-linked */
+	char *interp;
+
+	/** Pointer to the dynamic section */
+	void *dynamic;
+} elf_info_t;
+
+/**
+ * Holds information about an ELF binary being loaded.
+ */
+typedef struct {
+	/** Filedescriptor of the file from which we are loading */
+	int fd;
+
+	/** Difference between run-time addresses and link-time addresses */
+	uintptr_t bias;
+
+	/** A copy of the ELF file header */
+	elf_header_t *header;
+
+	/** Store extracted info here */
+	elf_info_t *info;
+} elf_ld_t;
+
+int elf_load_file(char *file_name, size_t so_bias, elf_info_t *info);
+void elf_run(elf_info_t *info, pcb_t *pcb);
+void elf_create_pcb(elf_info_t *info, pcb_t *pcb);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/loader/interp.s
===================================================================
--- uspace/srv/loader/interp.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/interp.s	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,7 @@
+#
+# Provide a string to be included in a special DT_INTERP header, even though
+# this is a statically-linked executable. This will mark the binary as
+# the program loader.
+#
+.section .interp , ""
+	.string "kernel"
Index: uspace/srv/loader/main.c
===================================================================
--- uspace/srv/loader/main.c	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
+++ uspace/srv/loader/main.c	(revision c98e6ee244a8e271a395a052069c23bca4f8b538)
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2008 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup loader
+ * @brief	Loads and runs programs from VFS.
+ * @{
+ */ 
+/**
+ * @file
+ * @brief	Loads and runs programs from VFS.
+ *
+ * The program loader is a special init binary. Its image is used
+ * to create a new task upon a @c task_spawn syscall. The syscall
+ * returns the id of a phone connected to the newly created task.
+ *
+ * The caller uses this phone to send the pathname and various other
+ * information to the loader. This is normally done by the C library
+ * and completely hidden from applications.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <ipc/ipc.h>
+#include <ipc/loader.h>
+#include <loader/pcb.h>
+#include <errno.h>
+#include <async.h>
+#include <as.h>
+
+#include <elf.h>
+#include <elf_load.h>
+
+/** 
+ * Bias used for loading the dynamic linker. This will be soon replaced
+ * by automatic placement.
+ */
+#define RTLD_BIAS 0x80000
+
+/** Pathname of the file that will be loaded */
+static char *pathname = NULL;
+
+/** The Program control block */
+static pcb_t pcb;
+
+/** Number of arguments */
+static int argc = 0;
+/** Argument vector */
+static char **argv = NULL;
+/** Buffer holding all arguments */
+static char *arg_buf = NULL;
+
+/** Receive a call setting pathname of the program to execute.
+ *
+ * @param rid
+ * @param request
+ */
+static void loader_set_pathname(ipc_callid_t rid, ipc_call_t *request)
+{
+	ipc_callid_t callid;
+	size_t len;
+	char *name_buf;
+
+	if (!ipc_data_write_receive(&callid, &len)) {
+		ipc_answer_0(callid, EINVAL);
+		ipc_answer_0(rid, EINVAL);
+		return;
+	}
+
+	name_buf = malloc(len + 1);
+	if (!name_buf) {
+		ipc_answer_0(callid, ENOMEM);
+		ipc_answer_0(rid, ENOMEM);
+		return;
+	}
+
+	ipc_data_write_finalize(callid, name_buf, len);
+	ipc_answer_0(rid, EOK);
+
+	if (pathname != NULL) {
+		free(pathname);
+		pathname = NULL;
+	}
+
+	name_buf[len] = '\0';
+	pathname = name_buf;
+}
+
+/** Receive a call setting arguments of the program to execute.
+ *
+ * @param rid
+ * @param request
+ */
+static void loader_set_args(ipc_callid_t rid, ipc_call_t *request)
+{
+	ipc_callid_t callid;
+	size_t buf_len, arg_len;
+	char *p;
+	int n;
+
+	if (!ipc_data_write_receive(&callid, &buf_len)) {
+		ipc_answer_0(callid, EINVAL);
+		ipc_answer_0(rid, EINVAL);
+		return;
+	}
+
+	if (arg_buf != NULL) {
+		free(arg_buf);
+		arg_buf = NULL;
+	}
+
+	if (argv != NULL) {
+		free(argv);
+		argv = NULL;
+	}
+
+	arg_buf = malloc(buf_len + 1);
+	if (!arg_buf) {
+		ipc_answer_0(callid, ENOMEM);
+		ipc_answer_0(rid, ENOMEM);
+		return;
+	}
+
+	ipc_data_write_finalize(callid, arg_buf, buf_len);
+	ipc_answer_0(rid, EOK);
+
+	arg_buf[buf_len] = '\0';
+
+	/*
+	 * Count number of arguments
+	 */
+	p = arg_buf;
+	n = 0;
+	while (p < arg_buf + buf_len) {
+		arg_len = strlen(p);
+		p = p + arg_len + 1;
+		++n;
+	}
+
+	/* Allocate argv */
+	argv = malloc((n + 1) * sizeof(char *));
+
+	if (argv == NULL) {
+		free(arg_buf);
+		ipc_answer_0(callid, ENOMEM);
+		ipc_answer_0(rid, ENOMEM);
+		return;
+	}
+
+	/*
+	 * Fill argv with argument pointers
+	 */
+	p = arg_buf;
+	n = 0;
+	while (p < arg_buf + buf_len) {
+		argv[n] = p;
+
+		arg_len = strlen(p);
+		p = p + arg_len + 1;
+		++n;
+	}
+
+	argc = n;
+	argv[n] = NULL;
+}
+
+
+/** Load and run the previously selected program.
+ *
+ * @param rid
+ * @param request
+ * @return 0 on success, !0 on error.
+ */
+static int loader_run(ipc_callid_t rid, ipc_call_t *request)
+{
+	int rc;
+
+	elf_info_t prog_info;
+	elf_info_t interp_info;
+
+//	printf("Load program '%s'\n", pathname);
+
+	rc = elf_load_file(pathname, 0, &prog_info);
+	if (rc < 0) {
+		printf("failed to load program\n");
+		ipc_answer_0(rid, EINVAL);
+		return 1;
+	}
+
+//	printf("Create PCB\n");
+	elf_create_pcb(&prog_info, &pcb);
+
+	pcb.argc = argc;
+	pcb.argv = argv;
+
+	if (prog_info.interp == NULL) {
+		/* Statically linked program */
+//		printf("Run statically linked program\n");
+//		printf("entry point: 0x%llx\n", prog_info.entry);
+		ipc_answer_0(rid, EOK);
+		close_console();
+		elf_run(&prog_info, &pcb);
+		return 0;
+	}
+
+	printf("Load dynamic linker '%s'\n", prog_info.interp);
+	rc = elf_load_file("/rtld.so", RTLD_BIAS, &interp_info);
+	if (rc < 0) {
+		printf("failed to load dynamic linker\n");
+		ipc_answer_0(rid, EINVAL);
+		return 1;
+	}
+
+	/*
+	 * Provide dynamic linker with some useful data
+	 */
+	pcb.rtld_dynamic = interp_info.dynamic;
+	pcb.rtld_bias = RTLD_BIAS;
+
+	printf("run dynamic linker\n");
+	printf("entry point: 0x%llx\n", interp_info.entry);
+	close_console();
+
+	ipc_answer_0(rid, EOK);
+	elf_run(&interp_info, &pcb);
+
+	/* Not reached */
+	return 0;
+}
+
+/** Handle loader connection.
+ *
+ * Receive and carry out commands (of which the last one should be
+ * to execute the loaded program).
+ */
+static void loader_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipc_callid_t callid;
+	ipc_call_t call;
+	int retval;
+
+	/* Ignore parameters, the connection is already open */
+	(void)iid; (void)icall;
+
+	while (1) {
+		callid = async_get_call(&call);
+//		printf("received call from phone %d, method=%d\n",
+//			call.in_phone_hash, IPC_GET_METHOD(call));
+		switch (IPC_GET_METHOD(call)) {
+		case LOADER_SET_PATHNAME:
+			loader_set_pathname(callid, &call);
+			continue;
+		case LOADER_SET_ARGS:
+			loader_set_args(callid, &call);
+		case LOADER_RUN:
+			loader_run(callid, &call);
+			exit(0);
+			continue;
+		default:
+			retval = ENOENT;
+			break;
+		}
+		if ((callid & IPC_CALLID_NOTIFICATION) == 0 &&
+		    IPC_GET_METHOD(call) != IPC_M_PHONE_HUNGUP) {
+			printf("responding EINVAL to method %d\n", 
+			    IPC_GET_METHOD(call));
+			ipc_answer_0(callid, EINVAL);
+		}
+	}
+}
+
+/** Program loader main function.
+ */
+int main(int argc, char *argv[])
+{
+	ipc_callid_t callid;
+	ipc_call_t call;
+	ipcarg_t phone_hash;
+
+	/* The first call only communicates the incoming phone hash */
+	callid = ipc_wait_for_call(&call);
+
+	if (IPC_GET_METHOD(call) != LOADER_HELLO) {
+		if (IPC_GET_METHOD(call) != IPC_M_PHONE_HUNGUP)
+			ipc_answer_0(callid, EINVAL);
+		return 1;
+	}
+
+	ipc_answer_0(callid, EOK);
+	phone_hash = call.in_phone_hash;
+
+	/* 
+	 * Up until now async must not be used as it couldn't
+	 * handle incoming requests. (Which means e.g. printf() 
+	 * cannot be used)
+	 */
+	async_new_connection(phone_hash, 0, NULL, loader_connection);
+	async_manager();
+
+	/* not reached */
+	return 0;
+}
+
+/** @}
+ */
