diff --git a/MCONFIG.embedded b/MCONFIG.embedded
index b5c8f5d..b74d8da 100644
--- a/MCONFIG.embedded
+++ b/MCONFIG.embedded
@@ -19,8 +19,12 @@ include $(topdir)/MCONFIG
 GCCOPT    := $(call gcc_ok,-m32,)
 GCCOPT    += $(call gcc_ok,-ffreestanding,)
 GCCOPT	  += $(call gcc_ok,-fno-stack-protector,)
+GCCOPT	  += $(call gcc_ok,-fwrapv,)
+GCCOPT	  += $(call gcc_ok,-freg-struct-return,)
 GCCOPT    += -march=i386 -Os -fomit-frame-pointer -mregparm=3 -DREGPARM=3 \
 	     -msoft-float
+GCCOPT    += $(call gcc_ok,-fno-exceptions,)
+GCCOPT	  += $(call gcc_ok,-fno-asynchronous-unwind-tables,)
 GCCOPT	  += $(call gcc_ok,-falign-functions=0,-malign-functions=0)
 GCCOPT    += $(call gcc_ok,-falign-jumps=0,-malign-jumps=0)
 GCCOPT    += $(call gcc_ok,-falign-labels=0,-malign-labels=0)
diff --git a/com32/MCONFIG b/com32/MCONFIG
index 22040f6..5d2e747 100644
--- a/com32/MCONFIG
+++ b/com32/MCONFIG
@@ -20,7 +20,11 @@ include $(topdir)/MCONFIG
 GCCOPT := $(call gcc_ok,-std=gnu99,)
 GCCOPT += $(call gcc_ok,-m32,)
 GCCOPT += $(call gcc_ok,-fno-stack-protector,)
-GCCOPT += -mregparm=3 -DREGPARM=3 -march=i386 -Os
+GCCOPT += $(call gcc_ok,-fwrapv,)
+GCCOPT += $(call gcc_ok,-freg-struct-return,)
+GCCOPT += -march=i386 -Os -fomit-frame-pointer -mregparm=3 -DREGPARM=3
+GCCOPT += $(call gcc_ok,-fno-exceptions,)
+GCCOPT += $(call gcc_ok,-fno-asynchronous-unwind-tables,)
 GCCOPT += $(call gcc_ok,-fPIE,-fPIC)
 GCCOPT += $(call gcc_ok,-falign-functions=0,-malign-functions=0)
 GCCOPT += $(call gcc_ok,-falign-jumps=0,-malign-jumps=0)
@@ -48,8 +52,8 @@ SFLAGS     = $(GCCOPT) -W -Wall -march=i386 \
 	     -nostdinc -iwithprefix include \
 	     -I$(com32)/libutil/include -I$(com32)/include $(GPLINCLUDE)
 
-COM32LD	   = $(com32)/lib/com32.ld
-LDFLAGS    = -m elf_i386 --emit-relocs -T $(COM32LD)
+COM32LD	   = $(com32)/lib/elf32.ld
+LDFLAGS    = -m elf_i386 -shared --hash-style=gnu -T $(COM32LD)
 LIBGCC    := $(shell $(CC) $(GCCOPT) --print-libgcc)
 
 LNXCFLAGS  = -I$(com32)/libutil/include -W -Wall -O -g -D_GNU_SOURCE
@@ -87,6 +91,5 @@ C_LNXLIBS  = $(com32)/libutil/libutil_lnx.a
 	$(CC) $(LNXCFLAGS) -o $@ $^
 
 %.c32: %.elf
-	$(OBJCOPY) -O binary $< $@
-	$(RELOCS) $< >> $@ || ( rm -f $@ ; false )
+	$(OBJCOPY) --strip-debug --strip-unneeded $< $@
 
diff --git a/com32/elflink/modules/MCONFIG b/com32/elflink/modules/MCONFIG
index 1b9a972..7157e1b 100644
--- a/com32/elflink/modules/MCONFIG
+++ b/com32/elflink/modules/MCONFIG
@@ -16,10 +16,20 @@
 
 include $(topdir)/MCONFIG
 
-GCCOPT := $(call gcc_ok,-std=gnu99,) \
-	  $(call gcc_ok,-m32,) \
-	  $(call gcc_ok,-fno-stack-protector,) \
-	  -mregparm=3 -DREGPARM=3 -march=i386 -Os
+GCCOPT := $(call gcc_ok,-std=gnu99,)
+GCCOPT += $(call gcc_ok,-m32,)
+GCCOPT += $(call gcc_ok,-fno-stack-protector,)
+GCCOPT += $(call gcc_ok,-fwrapv,)
+GCCOPT += $(call gcc_ok,-freg-struct-return,)
+GCCOPT += -march=i386 -Os -fomit-frame-pointer -mregparm=3 -DREGPARM=3
+GCCOPT += $(call gcc_ok,-fno-exceptions,)
+GCCOPT += $(call gcc_ok,-fno-asynchronous-unwind-tables,)
+GCCOPT += $(call gcc_ok,-fPIE,-fPIC)
+GCCOPT += $(call gcc_ok,-falign-functions=0,-malign-functions=0)
+GCCOPT += $(call gcc_ok,-falign-jumps=0,-malign-jumps=0)
+GCCOPT += $(call gcc_ok,-falign-labels=0,-malign-labels=0)
+GCCOPT += $(call gcc_ok,-falign-loops=0,-malign-loops=0)
+GCCOPT += $(call gcc_ok,-mpreferred-stack-boundary=2,)
 
 com32 = $(topdir)/com32
 
@@ -28,7 +38,7 @@ CFLAGS     = $(GCCOPT) -W -Wall -march=i386 \
 	     -nostdinc -iwithprefix include \
 	     -I$(com32)/libutil/include -I$(com32)/include
 SFLAGS     = $(GCCOPT) -D__COM32__ -march=i386
-LDFLAGS    = -m elf_i386 -shared -T $(com32)/lib/elf32.ld
+LDFLAGS    = -m elf_i386 -shared --hash-style=gnu -T $(com32)/lib/elf32.ld
 LIBGCC    := $(shell $(CC) $(GCCOPT) --print-libgcc)
 
 LNXCFLAGS  = -I$(com32)/libutil/include -W -Wall -O -g -D_GNU_SOURCE
diff --git a/com32/include/stdlib.h b/com32/include/stdlib.h
index fad0082..98a1028 100644
--- a/com32/include/stdlib.h
+++ b/com32/include/stdlib.h
@@ -44,24 +44,25 @@ __extern int posix_memalign(void **memptr, size_t alignment,
 
 __extern void free(void *);
 
-__extern void *__malloc_global_tag;
+typedef const void *malloc_tag_t;
+__extern malloc_tag_t __malloc_global_tag;
 
-static __inline__ void *__mem_get_tag_global(void)
+static __inline__ malloc_tag_t __mem_get_tag_global(void)
 {
     return __malloc_global_tag;
 }
 
-static __inline__ void __mem_set_tag_global(void *__tag)
+static __inline__ void __mem_set_tag_global(malloc_tag_t __tag)
 {
     __malloc_global_tag = __tag;
 }
 
-__extern void *__mem_get_tag(void *);
-__extern void __mem_set_tag(void *, void *);
+__extern malloc_tag_t __mem_get_tag(void *);
+__extern void __mem_set_tag(void *, malloc_tag_t);
 
 __extern void __free_tagged(void *);
 
-static __inline__ void *__malloc_tagged(size_t __size, void *__tag)
+static __inline__ void *__malloc_tagged(size_t __size, malloc_tag_t __tag)
 {
     void *__result = malloc(__size);
     __mem_set_tag(__result, __tag);
diff --git a/com32/include/sys/module.h b/com32/include/sys/module.h
index 64f1827..87440ab 100644
--- a/com32/include/sys/module.h
+++ b/com32/include/sys/module.h
@@ -11,9 +11,9 @@
 #include <stdio.h>
 #include <elf.h>
 #include <stdint.h>
+#include <setjmp.h>
 #include <linux/list.h>
 
-
 /*
  * The maximum length of the module file name (including path), stored
  * in the struct module descriptor.
@@ -77,6 +77,7 @@ typedef int (*module_main_t)(int, char**);
  *  predecessors and successors. There is also a global linked list containing all
  *  the modules currently loaded.
  */
+struct atexit;
 struct elf_module {
 	char				name[MODULE_NAME_SIZE]; 		// The module name
 
@@ -88,7 +89,7 @@ struct elf_module {
 
 	module_init_t		*init_func;	// The initialization entry point
 	module_exit_t		*exit_func;	// The module finalization code
-	module_main_t		*main_func; // The main function (for executable modules)
+        module_main_t		*main_func; // The main function (for executable modules)
 
 
 	void				*module_addr; // The module location in the memory
@@ -106,10 +107,19 @@ struct elf_module {
 	Elf32_Word			syment_size;	// The size of a symbol entry
 	Elf32_Word			symtable_size;	// The size of the symbol table
 
-
-	// Transient - Data available while the module is loading
-	FILE				*_file;	// The file object of the open file
-	Elf32_Off			_cr_offset; // The current offset in the open file
+	union {
+		// Transient - Data available while the module is loading
+		struct {
+			FILE		*_file;		// The file object of the open file
+			Elf32_Off	_cr_offset;	// The current offset in the open file
+		} l;
+
+		// Process execution data
+		struct {
+			jmp_buf		process_exit;	// Exit state
+			struct atexit  *atexit_list;	// atexit() chain
+		} x;
+	} u;
 };
 
 /**
@@ -312,6 +322,15 @@ static inline void *module_get_absolute(Elf32_Addr addr, struct elf_module *modu
 	return (void*)(module->base_addr + addr);
 }
 
+/**
+ * syslinux_current - get the current module process
+ */
+extern struct elf_module *__syslinux_current;
+static inline const struct elf_module *syslinux_current(void)
+{
+	return __syslinux_current;
+}
+
 #endif // DYNAMIC_MODULE
 
 #endif // MODULE_H_
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index 77bda08..8f79325 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -67,8 +67,7 @@ LIBSYSLINUX_OBJS = \
 	syslinux/setadv.o
 
 DYNENTRY_OBJS = \
-	sys/entry.o atexit.o exit.o onexit.o	\
-	sys/exit.o abort.o 
+	atexit.o onexit.o abort.o 
 
 ## CORE OBJECTS, INCLUDED IN THE ROOT COM32 MODULE
 LIBENTRY_OBJS = \
@@ -78,7 +77,9 @@ LIBENTRY_OBJS = \
 	sys/close.o sys/open.o sys/fileread.o sys/fileclose.o		\
 	sys/isatty.o sys/fstat.o	\
 	\
-	syslinux/idle.o
+	syslinux/idle.o \
+	\
+	exit.o
 	
 LIBMODULE_OBJS = \
 	sys/module/common.o sys/module/elf_module.o		\
diff --git a/com32/lib/elf32.ld b/com32/lib/elf32.ld
index e41f9c9..8bde8c3 100644
--- a/com32/lib/elf32.ld
+++ b/com32/lib/elf32.ld
@@ -102,7 +102,7 @@ SECTIONS
   
   .dtors          :
   {
-  	__dtors_start = .;
+   	__dtors_start = .;
     KEEP (*(SORT(.dtors.*)))
     KEEP (*(.dtors))
     LONG(0x00000000)
@@ -181,4 +181,5 @@ SECTIONS
   .debug_ranges   0 : { *(.debug_ranges) }
   .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
   /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) }
+  /DISCARD/ : { *(.eh_frame) }
 }
diff --git a/com32/lib/exit.c b/com32/lib/exit.c
index ccd6f1e..a5aba18 100644
--- a/com32/lib/exit.c
+++ b/com32/lib/exit.c
@@ -31,11 +31,28 @@
  * The regular exit
  */
 
+#include <sys/module.h>
 #include <stdlib.h>
-
-extern __noreturn(*__exit_handler) (int);
+#include <unistd.h>
+#include "atexit.h"
 
 __noreturn exit(int rv)
 {
-    __exit_handler(rv);
+    struct atexit *ap;
+
+    for (ap = __syslinux_current->u.x.atexit_list; ap; ap = ap->next) {
+	ap->fctn(rv, ap->arg);	/* This assumes extra args are harmless */
+    }
+
+    _exit(rv);
+}    
+
+__noreturn _Exit(int rv)
+{
+    _exit(rv);
+}
+
+__noreturn _exit(int rv)
+{
+    longjmp(__syslinux_current->u.x.process_exit, rv+1);
 }
diff --git a/com32/lib/malloc.c b/com32/lib/malloc.c
index 5035993..b81eb8f 100644
--- a/com32/lib/malloc.c
+++ b/com32/lib/malloc.c
@@ -15,7 +15,7 @@
 /**
  * The global tag used to label all the new allocations
  */
-void *__malloc_global_tag = NULL;
+malloc_tag_t __malloc_global_tag = NULL;
 
 struct free_arena_header __malloc_head =
 {
@@ -196,8 +196,9 @@ int posix_memalign(void **memptr, size_t alignment, size_t size)
 
 	*memptr = NULL;
 
-	for (fp = __malloc_head.next_free; ARENA_TYPE_GET(fp->a.attrs) != ARENA_TYPE_HEAD;
-		fp = fp->next_free) {
+	for (fp = __malloc_head.next_free;
+	     ARENA_TYPE_GET(fp->a.attrs) != ARENA_TYPE_HEAD;
+	     fp = fp->next_free) {
 
 		if (ARENA_SIZE_GET(fp->a.attrs) <= size)
 			continue;
@@ -251,12 +252,18 @@ int posix_memalign(void **memptr, size_t alignment, size_t size)
 	return 0;
 }
 
-void *__mem_get_tag(void *memptr) {
-	struct arena_header *ah = (struct arena_header *)memptr - 1;
-	return ah->tag;
+malloc_tag_t __mem_get_tag(void *memptr) {
+	if (memptr) {
+		struct arena_header *ah = (struct arena_header *)memptr - 1;
+		return ah->tag;
+	} else {
+		return NULL;
+	}
 }
 
-void __mem_set_tag(void *memptr, void *tag) {
-	struct arena_header *ah = (struct arena_header *)memptr - 1;
-	ah->tag = tag;
+void __mem_set_tag(void *memptr, malloc_tag_t tag) {
+	if (memptr) {
+		struct arena_header *ah = (struct arena_header *)memptr - 1;
+		ah->tag = tag;
+	}
 }
diff --git a/com32/lib/malloc.h b/com32/lib/malloc.h
index 9665d83..58c5497 100644
--- a/com32/lib/malloc.h
+++ b/com32/lib/malloc.h
@@ -22,7 +22,7 @@ struct free_arena_header;
  * alignment unit.
  */
 struct arena_header {
-    void *tag;
+    malloc_tag_t tag;
     size_t attrs;			/* Bits 0..1: Type, 2..3: Unused, 4..31: MSB of the size  */
     struct free_arena_header *next, *prev;
 };
diff --git a/com32/lib/onexit.c b/com32/lib/onexit.c
index d409e82..8c45e3b 100644
--- a/com32/lib/onexit.c
+++ b/com32/lib/onexit.c
@@ -4,22 +4,9 @@
 
 #include <stdlib.h>
 #include <unistd.h>
+#include <sys/module.h>
 #include "atexit.h"
 
-extern __noreturn(*__exit_handler) (int);
-static struct atexit *__atexit_list;
-
-static __noreturn on_exit_exit(int rv)
-{
-    struct atexit *ap;
-
-    for (ap = __atexit_list; ap; ap = ap->next) {
-	ap->fctn(rv, ap->arg);	/* This assumes extra args are harmless */
-    }
-
-    _exit(rv);
-}
-
 int on_exit(void (*fctn) (int, void *), void *arg)
 {
     struct atexit *as = malloc(sizeof(struct atexit));
@@ -30,10 +17,8 @@ int on_exit(void (*fctn) (int, void *), void *arg)
     as->fctn = fctn;
     as->arg = arg;
 
-    as->next = __atexit_list;
-    __atexit_list = as;
-
-    __exit_handler = on_exit_exit;
+    as->next = __syslinux_current->u.x.atexit_list;
+    __syslinux_current->u.x.atexit_list = as;
 
     return 0;
 }
diff --git a/com32/lib/sys/entry.S b/com32/lib/sys/entry.S
deleted file mode 100644
index a3a1eaa..0000000
--- a/com32/lib/sys/entry.S
+++ /dev/null
@@ -1,118 +0,0 @@
-/* -----------------------------------------------------------------------
- *
- *   Copyright 2003-2008 H. Peter Anvin - All Rights Reserved
- *
- *   Permission is hereby granted, free of charge, to any person
- *   obtaining a copy of this software and associated documentation
- *   files (the "Software"), to deal in the Software without
- *   restriction, including without limitation the rights to use,
- *   copy, modify, merge, publish, distribute, sublicense, and/or
- *   sell copies of the Software, and to permit persons to whom
- *   the Software is furnished to do so, subject to the following
- *   conditions:
- *
- *   The above copyright notice and this permission notice shall
- *   be included in all copies or substantial portions of the Software.
- *
- *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *   OTHER DEALINGS IN THE SOFTWARE.
- *
- * ----------------------------------------------------------------------- */
-
-/*
- * COM32 start up code - must be linked first in the binary
- */
-
-/* Number of arguments in our version of the entry structure */
-#define COM32_ARGS 7
-
-		.section ".init","ax"
-		.globl _start
-		.type _start, @function
-_start:
-		/* This first instruction acts as COM32R magic number */
-		movl $0x21cd4cfe,%eax
-
-		/* Upwards string operations */
-		cld
-
-		/* Find our own location */
-		call 1f
-1:		popl %ebx
-		addl $_GLOBAL_OFFSET_TABLE_ + (. - 1b), %ebx
-	
-		/* Process relocations (which overlay the .bss segment) */
-		leal _edata@GOTOFF(%ebx),%esi
-		leal _start@GOTOFF(%ebx),%edx
-2:		lodsl
-		andl %eax,%eax
-		jz 3f
-		addl %edx,(%eax,%edx)
-		jmp 2b
-3:
-		/* Relocate the GOT (is this right?) */
-		leal __got_start@GOTOFF(%ebx),%esi
-		leal __got_end@GOTOFF(%ebx),%edi
-4:
-		addl %edx,(%esi)
-		addl $4,%esi
-		cmpl %edi,%esi
-		jb 4b
-	
-		/* Zero the .bss segment */
-		xorl %eax,%eax
-		leal __bss_start@GOTOFF(%ebx),%edi
-		leal _end+3@GOTOFF(%ebx),%ecx
-		subl %edi,%ecx
-		shrl $2,%ecx
-		rep ; stosl
-
-		/* Copy COM32 invocation parameters */
-		leal 4(%esp),%esi		# Argument list
-		leal __com32@GOTOFF(%ebx),%edi
-		movl $(COM32_ARGS),%ecx
-		movl %esp,-4(%edi)		# Save the initial stack ptr
-		cmpl (%esi),%ecx
-		jbe 5f
-		movl (%esi),%ecx
-5:		inc %ecx			# Copy the argument count, too
-		rep ; movsl
-
-		/* Parse the command line (assumes REGPARM) */
-		movl __com32+4@GOTOFF(%ebx),%edx	# Command line
-		pushl %edx				# Make space for argv
-		movl %esp,%eax
-		call __parse_argv
-		pushl %eax				# Save argc
-
-		/* Look for library initialization functions */
-		leal __ctors_start@GOTOFF(%ebx),%esi
-		leal __ctors_end@GOTOFF(%ebx),%edi
-6:
-		cmpl %edi,%esi
-		jae 7f
-		call *(%esi)
-		addl $4,%esi
-		jmp 6b
-/*
- * Actually run main.  This assumes REGPARM is used!!!!
- */
-7:
-		popl %eax			# argc
-		popl %edx			# argv
-		call main
-		call *__exit_handler@GOTOFF(%ebx)
-		hlt
-		.size _start, .-_start
-
-		.bss
-		.globl __entry_esp
-__entry_esp:	.space 4
-		.globl __com32
-__com32:	.space 4*(COM32_ARGS+1)
diff --git a/com32/lib/sys/exit.S b/com32/lib/sys/exit.S
deleted file mode 100644
index 2ab8012..0000000
--- a/com32/lib/sys/exit.S
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Implementation of _exit() for com32 based on c32entry.S
- */
-	.text
-
-	.globl _Exit
-	.type _Exit, @function
-_Exit:
-	/* Just fall through to _exit */
-	.size _Exit, .-_Exit
-
-	.globl _exit
-	.type _exit, @function
-_exit:
-#ifdef REGPARM
-	pushl %eax
-#endif
-
-	/* Run any destructors */
-	movl $__dtors_start, %esi
-2:
-	cmpl $__dtors_end, %esi
-	jae 1f
-	call *(%esi)
-	addl $4,%esi
-	jmp 2b
-
-1:
-#ifdef REGPARM
-	popl %eax
-#else
-	movl 4(%esp),%eax		# Exit code in %eax = return value
-#endif
-	movl (__entry_esp),%esp		# Return stack pointer to entry value
-	ret				# Return to termination address
-	.size _exit, .-_exit
-
-	.data
-__exit_handler:
-	.globl __exit_handler
-	.long _exit
diff --git a/com32/lib/sys/module/common.c b/com32/lib/sys/module/common.c
index ad17efa..5c8d34d 100644
--- a/com32/lib/sys/module/common.c
+++ b/com32/lib/sys/module/common.c
@@ -59,21 +59,21 @@ void print_elf_symbols(struct elf_module *module) {
  */
 
 int image_load(struct elf_module *module) {
-	module->_file = fopen(module->name, "rb");
+	module->u.l._file = fopen(module->name, "rb");
 
-	if (module->_file == NULL) {
+	if (module->u.l._file == NULL) {
 		DBG_PRINT("Could not open object file '%s'\n", module->name);
 		goto error;
 	}
 
-	module->_cr_offset = 0;
+	module->u.l._cr_offset = 0;
 
 	return 0;
 
 error:
-	if (module->_file != NULL) {
-		fclose(module->_file);
-		module->_file = NULL;
+	if (module->u.l._file != NULL) {
+		fclose(module->u.l._file);
+		module->u.l._file = NULL;
 	}
 
 	return -1;
@@ -81,22 +81,22 @@ error:
 
 
 int image_unload(struct elf_module *module) {
-	if (module->_file != NULL) {
-		fclose(module->_file);
-		module->_file = NULL;
+	if (module->u.l._file != NULL) {
+		fclose(module->u.l._file);
+		module->u.l._file = NULL;
 	}
-	module->_cr_offset = 0;
+	module->u.l._cr_offset = 0;
 
 	return 0;
 }
 
 int image_read(void *buff, size_t size, struct elf_module *module) {
-	size_t result = fread(buff, size, 1, module->_file);
+	size_t result = fread(buff, size, 1, module->u.l._file);
 
 	if (result < 1)
 		return -1;
 
-	module->_cr_offset += size;
+	module->u.l._cr_offset += size;
 	return 0;
 }
 
@@ -108,21 +108,21 @@ int image_skip(size_t size, struct elf_module *module) {
 		return 0;
 
 	skip_buff = malloc(size);
-	result = fread(skip_buff, size, 1, module->_file);
+	result = fread(skip_buff, size, 1, module->u.l._file);
 	free(skip_buff);
 
 	if (result < 1)
 		return -1;
 
-	module->_cr_offset += size;
+	module->u.l._cr_offset += size;
 	return 0;
 }
 
 int image_seek(Elf32_Off offset, struct elf_module *module) {
-	if (offset < module->_cr_offset) // Cannot seek backwards
+	if (offset < module->u.l._cr_offset) // Cannot seek backwards
 		return -1;
 
-	return image_skip(offset - module->_cr_offset, module);
+	return image_skip(offset - module->u.l._cr_offset, module);
 }
 
 
diff --git a/com32/lib/sys/module/elf_module.c b/com32/lib/sys/module/elf_module.c
index bf3e4a4..25066e0 100644
--- a/com32/lib/sys/module/elf_module.c
+++ b/com32/lib/sys/module/elf_module.c
@@ -128,11 +128,12 @@ static int load_segments(struct elf_module *module, Elf32_Ehdr *elf_hdr) {
 
 		if (cr_pht->p_type == PT_LOAD) {
 			// Copy the segment at its destination
-			if (cr_pht->p_offset < module->_cr_offset) {
+			if (cr_pht->p_offset < module->u.l._cr_offset) {
 				// The segment contains data before the current offset
 				// It can be discarded without worry - it would contain only
 				// headers
-				Elf32_Off aux_off = module->_cr_offset - cr_pht->p_offset;
+				Elf32_Off aux_off = module->u.l._cr_offset
+					- cr_pht->p_offset;
 
 				if (image_read(module_get_absolute(cr_pht->p_vaddr, module) + aux_off,
 						cr_pht->p_filesz - aux_off, module) < 0) {
@@ -470,12 +471,10 @@ int module_load(struct elf_module *module) {
 	// Perform the relocations
 	resolve_symbols(module);
 
-
-
 	// The file image is no longer needed
 	image_unload(module);
 
-	DBG_PRINT("MODULE %s LOADED SUCCESSFULLY (main@0x%08X, init@0x%08X, exit@0x%08X)\n",
+	DBG_PRINT("MODULE %s LOADED SUCCESSFULLY (main@%p, init@%p, exit@%p)\n",
 			module->name,
 			(module->main_func == NULL) ? NULL : *(module->main_func),
 			(module->init_func == NULL) ? NULL : *(module->init_func),
@@ -494,5 +493,8 @@ error:
 
 	image_unload(module);
 
+	// Clear the execution part of the module buffer
+	memset(&module->u, 0, sizeof module->u);
+
 	return res;
 }
diff --git a/com32/lib/sys/module/exec.c b/com32/lib/sys/module/exec.c
index 34578ed..b83b974 100644
--- a/com32/lib/sys/module/exec.c
+++ b/com32/lib/sys/module/exec.c
@@ -8,18 +8,16 @@
 #include <sys/module.h>
 #include <sys/exec.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
-
-// The symbol declared in the linker script that indicates the loading point
-// of the COM32R module
-extern char _start[];
-
+#include <setjmp.h>
+#include <alloca.h>
 
 #define DBG_PRINT(fmt, args...)	fprintf(stderr, "[EXEC] " fmt, ##args)
 
-
 static struct elf_module    *mod_root = NULL;
+struct elf_module *__syslinux_current = NULL;
 
 int exec_init(void)
 {
@@ -36,7 +34,7 @@ int exec_init(void)
 	if (mod_root == NULL)
 		return -1;
 
-	res = module_load_shallow(mod_root, (Elf32_Addr)_start);
+	res = module_load_shallow(mod_root, 0);
 
 	if (res != 0) {
 		mod_root = NULL;
@@ -56,7 +54,6 @@ int load_library(const char *name)
 
 	res = module_load(module);
 
-
 	if (res != 0) {
 		module_unload(module);
 		return res;
@@ -107,8 +104,12 @@ int unload_library(const char *name)
 int spawnv(const char *name, const char **argv)
 {
 	int res, ret_val = 0;
-
+	const char **arg;
+	int argc;
+	char **argp, **args;
 	struct elf_module *module = module_alloc(name);
+	struct elf_module *previous;
+	malloc_tag_t prev_mem_tag;
 
 	if (module == NULL)
 		return -1;
@@ -120,28 +121,44 @@ int spawnv(const char *name, const char **argv)
 		return res;
 	}
 
-	if (module->main_func != NULL) {
-		const char **last_arg = argv;
-		void *old_tag;
-		while (*last_arg != NULL)
-			last_arg++;
-
-		// Setup the memory allocation context
-		old_tag = __mem_get_tag_global();
-		__mem_set_tag_global(module);
-
-		// Execute the program
-		ret_val = (*(module->main_func))(last_arg - argv, argv);
-
-		// Clean up the allocation context
-		__free_tagged(module);
-		// Restore the allocation context
-		__mem_set_tag_global(old_tag);
-	} else {
-		// We can't execute without a main function
-		module_unload(module);
-		return -1;
+	// Set up the process context
+	previous = __syslinux_current;
+	prev_mem_tag = __mem_get_tag_global();
+
+	// Setup the new process context
+	__syslinux_current = module;
+	__mem_set_tag_global((malloc_tag_t)module);
+
+	// Generate a new process copy of argv (on the stack)
+	argc = 0;
+	for (arg = argv; *arg; arg++)
+		argc++;
+
+	args = alloca((argc+1) * sizeof(char *));
+	
+	for (arg = argv, argp = args; *arg; arg++, argp++) {
+		size_t l = strlen(*arg)+1;
+		*args = alloca(l);
+		memcpy(*args, *arg, l);
 	}
+	*args = NULL;
+
+	// Execute the program
+	ret_val = setjmp(module->u.x.process_exit);
+
+	if (ret_val)
+		ret_val--;		/* Valid range is 0-255 */
+	else if (!module->main_func)
+		ret_val = -1;
+	else
+		exit((*module->main_func)(argc, args)); /* Actually run! */
+	
+	// Clean up the allocation context
+	__free_tagged(module);
+	// Restore the allocation context
+	__mem_set_tag_global(prev_mem_tag);
+	// Restore the process context
+	__syslinux_current = previous;
 
 	res = module_unload(module);
 
diff --git a/com32/lib/sys/module/shallow_module.c b/com32/lib/sys/module/shallow_module.c
index fdcb20f..3e14e5a 100644
--- a/com32/lib/sys/module/shallow_module.c
+++ b/com32/lib/sys/module/shallow_module.c
@@ -7,6 +7,7 @@
 
 
 
+#include <string.h>
 #include <sys/module.h>
 
 #include "common.h"
@@ -48,7 +49,7 @@ static int load_shallow_sections(struct elf_module *module, Elf32_Ehdr *elf_hdr)
 	char *sh_strtable;
 
 	// We buffer the data up to the SHT
-	buff_offset = module->_cr_offset;
+	buff_offset = module->u.l._cr_offset;
 
 	buffer = malloc(elf_hdr->e_shoff - buff_offset);
 	// Get to the SHT
diff --git a/core/Makefile b/core/Makefile
index baf768d..585f9c2 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -50,8 +50,8 @@ COBJ	 := $(patsubst %.c,%.o,$(CSRC))
 SOBJ	 := $(patsubst %.S,%.o,$(SSRC))
 
 LIB	 = libcore.a 
-LIBS    = --whole-archive $(LIB) $(com32)/lib/libcom32min.a \
-          --no-whole-archive $(LIBGCC)
+LIBS     = $(LIB) --whole-archive $(com32)/lib/libcom32min.a
+#          --no-whole-archive $(LIBGCC)
 LIBDEP   = $(filter-out -% %start%,$(LIBS))
 LIBOBJS	 = $(COBJ) $(SOBJ)
 
diff --git a/core/syslinux.ld b/core/syslinux.ld
index a00142b..4601714 100644
--- a/core/syslinux.ld
+++ b/core/syslinux.ld
@@ -43,6 +43,7 @@ SECTIONS
 	__earlybss_dwords = (__earlybss_len + 3) >> 2;
 
 	. = ALIGN(4);
+	__bss16_lma = .;
 	.bss16 (NOLOAD) : {
 		__bss16_start = .;
 		*(.bss16)
@@ -149,6 +150,7 @@ SECTIONS
 	__pm_code_lma = .;
 
 	__high_clear_start = .;
+	__high_clear_lma = .;
 
 	. = ALIGN(512);
 	.adv (NOLOAD) : {
@@ -162,6 +164,7 @@ SECTIONS
 	/* Late uninitialized sections */
 
 	. = ALIGN(4);
+	__uibss_lma = .;
 	.uibss (NOLOAD) : {
 		__uibss_start = .;
 		*(.uibss)
