Index: uspace/srv/loader/elf_load.c
===================================================================
--- uspace/srv/loader/elf_load.c	(revision 5e8b8817c2e227d5b8010916d5891c9eb9bbaf8e)
+++ uspace/srv/loader/elf_load.c	(revision 1d465bf4b98a5bc5b790ecab106baa34aa9d68ee)
@@ -103,5 +103,6 @@
  *
  */
-int elf_load_file(const char *file_name, size_t so_bias, elf_info_t *info)
+int elf_load_file(const char *file_name, size_t so_bias, eld_flags_t flags,
+    elf_info_t *info)
 {
 	elf_ld_t elf;
@@ -118,4 +119,5 @@
 	elf.fd = fd;
 	elf.info = info;
+	elf.flags = flags;
 
 	rc = elf_load(&elf, so_bias);
@@ -124,19 +126,4 @@
 
 	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 */
 }
 
@@ -153,4 +140,5 @@
 	pcb->entry = info->entry;
 	pcb->dynamic = info->dynamic;
+	pcb->rtld_runtime = NULL;
 }
 
@@ -306,11 +294,20 @@
 		break;
 	case PT_INTERP:
-		/* Assume silently interp == "/rtld.so" */
-		elf->info->interp = "/rtld.so";
+		/* Assume silently interp == "/app/dload" */
+		elf->info->interp = "/app/dload";
 		break;
 	case PT_DYNAMIC:
+		/* Record pointer to dynamic section into info structure */
+		elf->info->dynamic =
+		    (void *)((uint8_t *)entry->p_vaddr + elf->bias);
+		DPRINTF("dynamic section found at 0x%x\n",
+			(uintptr_t)elf->info->dynamic);
+		break;
+	case 0x70000000:
+		/* FIXME: MIPS reginfo */
+		break;
 	case PT_SHLIB:
-	case PT_LOPROC:
-	case PT_HIPROC:
+//	case PT_LOPROC:
+//	case PT_HIPROC:
 	default:
 		DPRINTF("Segment p_type %d unknown.\n", entry->p_type);
@@ -383,5 +380,6 @@
 	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
 	if (a == (void *)(-1)) {
-		DPRINTF("Memory mapping failed.\n");
+		DPRINTF("memory mapping failed (0x%x, %d)\n",
+			base+bias, mem_sz);
 		return EE_MEMORY;
 	}
@@ -425,4 +423,11 @@
 	}
 
+	/*
+	 * The caller wants to modify the segments first. He will then
+	 * need to set the right access mode and ensure SMC coherence.
+	 */
+	if ((elf->flags & ELDF_RW) != 0) return EE_OK;
+
+//	printf("set area flags to %d\n", flags);
 	rc = as_area_change_flags(seg_ptr, flags);
 	if (rc != 0) {
Index: uspace/srv/loader/include/elf_load.h
===================================================================
--- uspace/srv/loader/include/elf_load.h	(revision 5e8b8817c2e227d5b8010916d5891c9eb9bbaf8e)
+++ uspace/srv/loader/include/elf_load.h	(revision 1d465bf4b98a5bc5b790ecab106baa34aa9d68ee)
@@ -43,4 +43,9 @@
 #include "elf.h"
 
+typedef enum {
+	/** Leave all segments in RW access mode. */
+	ELDF_RW = 1
+} eld_flags_t;
+
 /**
  * Some data extracted from the headers are stored here
@@ -67,4 +72,7 @@
 	uintptr_t bias;
 
+	/** Flags passed to the ELF loader. */
+	eld_flags_t flags;
+
 	/** A copy of the ELF file header */
 	elf_header_t *header;
@@ -74,6 +82,6 @@
 } elf_ld_t;
 
-int elf_load_file(const char *file_name, size_t so_bias, elf_info_t *info);
-void elf_run(elf_info_t *info, pcb_t *pcb);
+int elf_load_file(const char *file_name, size_t so_bias, eld_flags_t flags,
+    elf_info_t *info);
 void elf_create_pcb(elf_info_t *info, pcb_t *pcb);
 
Index: uspace/srv/loader/main.c
===================================================================
--- uspace/srv/loader/main.c	(revision 5e8b8817c2e227d5b8010916d5891c9eb9bbaf8e)
+++ uspace/srv/loader/main.c	(revision 1d465bf4b98a5bc5b790ecab106baa34aa9d68ee)
@@ -65,4 +65,6 @@
 #define DPRINTF(...)
 
+void program_run(void *entry, pcb_t *pcb);
+
 /** Pathname of the file that will be loaded */
 static char *pathname = NULL;
@@ -283,5 +285,5 @@
 	int rc;
 	
-	rc = elf_load_file(pathname, 0, &prog_info);
+	rc = elf_load_file(pathname, 0, 0, &prog_info);
 	if (rc != EE_OK) {
 		DPRINTF("Failed to load executable '%s'.\n", pathname);
@@ -307,5 +309,6 @@
 	}
 	
-	rc = elf_load_file(prog_info.interp, 0, &interp_info);
+	printf("Load ELF interpreter '%s'\n", prog_info.interp);
+	rc = elf_load_file(prog_info.interp, 0, 0, &interp_info);
 	if (rc != EE_OK) {
 		DPRINTF("Failed to load interpreter '%s.'\n",
@@ -315,4 +318,9 @@
 	}
 	
+	printf("Run interpreter.\n");
+	printf("entry point: 0x%lx\n", (unsigned long) interp_info.entry);
+	printf("pcb address: 0x%lx\n", (unsigned long) &pcb);
+	printf("prog dynamic: 0x%lx\n", (unsigned long) prog_info.dynamic);
+
 	is_dyn_linked = true;
 	async_answer_0(rid, EOK);
@@ -343,9 +351,9 @@
 		
 		async_answer_0(rid, EOK);
-		elf_run(&interp_info, &pcb);
+		program_run(interp_info.entry, &pcb);
 	} else {
 		/* Statically linked program */
 		async_answer_0(rid, EOK);
-		elf_run(&prog_info, &pcb);
+		program_run(prog_info.entry, &pcb);
 	}
 	
