Index: uspace/lib/c/generic/elf/elf_load.c
===================================================================
--- uspace/lib/c/generic/elf/elf_load.c	(revision accdf8823a3853db4616f504c82346a216b4eef0)
+++ uspace/lib/c/generic/elf/elf_load.c	(revision e43acd38c0225c4fac18ac08d9da30ca442ef906)
@@ -60,29 +60,31 @@
 	rtld_t *env;
 #endif
-	errno_t rc;
+	errno_t rc = EOK;
+	elf_finfo_t *finfo = &info->finfo;
 
-	rc = elf_load_file(file, 0, &info->finfo);
+	rc = elf_load_file(file, 0, finfo);
 	if (rc != EOK) {
-		DPRINTF("Failed to load executable '%s'.\n", file_name);
+		DPRINTF("Failed to load executable.\n");
 		return rc;
 	}
 
+#ifdef CONFIG_RTLD
+	DPRINTF("- prog dynamic: %p\n", finfo->dynamic);
+	rc = rtld_prog_process(finfo, &env);
+	if (rc != EOK) {
+		DPRINTF("Failed to process executable.\n");
+		return rc;
+	}
+	info->env = env;
+	return EOK;
+#else
 	if (info->finfo.dynamic == NULL) {
-		/* Statically linked program */
-		DPRINTF("Binary is statically linked.\n");
 		info->env = NULL;
 		return EOK;
 	}
 
-	DPRINTF("Binary is dynamically linked.\n");
-#ifdef CONFIG_RTLD
-	DPRINTF("- prog dynamic: %p\n", info->finfo.dynamic);
-
-	rc = rtld_prog_process(&info->finfo, &env);
-	info->env = env;
-#else
-	rc = ENOTSUP;
+	DPRINTF("Error: trying to run a dynamically-linked executable with CONFIG_RTLD disabled.\n");
+	return ENOTSUP;
 #endif
-	return rc;
 }
 
Index: uspace/lib/c/generic/libc.c
===================================================================
--- uspace/lib/c/generic/libc.c	(revision accdf8823a3853db4616f504c82346a216b4eef0)
+++ uspace/lib/c/generic/libc.c	(revision e43acd38c0225c4fac18ac08d9da30ca442ef906)
@@ -96,9 +96,12 @@
 
 #ifdef CONFIG_RTLD
-	if (__pcb != NULL && __pcb->rtld_runtime != NULL) {
+	if (__pcb == NULL) {
+		/*
+		 * A binary loaded by kernel, not the loader.
+		 * Noop - code loaded by kernel doesn't need RTLD.
+		 */
+	} else {
+		assert(__pcb->rtld_runtime != NULL);
 		runtime_env = (rtld_t *) __pcb->rtld_runtime;
-	} else {
-		if (rtld_init_static() != EOK)
-			abort();
 	}
 #endif
Index: uspace/lib/c/generic/rtld/module.c
===================================================================
--- uspace/lib/c/generic/rtld/module.c	(revision accdf8823a3853db4616f504c82346a216b4eef0)
+++ uspace/lib/c/generic/rtld/module.c	(revision e43acd38c0225c4fac18ac08d9da30ca442ef906)
@@ -55,20 +55,35 @@
 #include "../private/libc.h"
 
-/** Create module for static executable.
- *
+/** Create the "entrypoint" module, of the program executable
+ *
+ * @param p_info Program ELF file info
  * @param rtld Run-time dynamic linker
  * @param rmodule Place to store pointer to new module or @c NULL
  * @return EOK on success, ENOMEM if out of memory
  */
-errno_t module_create_static_exec(rtld_t *rtld, module_t **rmodule)
+errno_t module_create_entrypoint(elf_finfo_t *p_info, rtld_t *rtld, module_t **rmodule)
 {
 	module_t *module;
+	bool is_dynamic = p_info->dynamic != NULL;
+	DPRINTF("module_create_entrypoint\n");
 
 	module = calloc(1, sizeof(module_t));
-	if (module == NULL) {
-		DPRINTF("malloc failed\n");
+	if (module == NULL)
 		return ENOMEM;
-	}
-
+
+	uintptr_t bias = elf_get_bias(p_info->base);
+
+	/*
+	 * First we need to process dynamic sections of the executable
+	 * program and insert it into the module graph.
+	 */
+	if (is_dynamic) {
+		DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic);
+		dynamic_parse(p_info->dynamic, bias, &module->dyn);
+	} else {
+		DPRINTF("Executable is not dynamically linked\n");
+	}
+
+	module->bias = bias;
 	module->id = rtld_get_next_id(rtld);
 	module->dyn.soname = "[program]";
@@ -76,21 +91,13 @@
 	module->rtld = rtld;
 	module->exec = true;
-	module->local = true;
-
-	const elf_segment_header_t *tls =
-	    elf_get_phdr(__progsymbols.elfstart, PT_TLS);
-
-	if (tls) {
-		uintptr_t bias = elf_get_bias(__progsymbols.elfstart);
-		module->tdata = (void *) (tls->p_vaddr + bias);
-		module->tdata_size = tls->p_filesz;
-		module->tbss_size = tls->p_memsz - tls->p_filesz;
-		module->tls_align = tls->p_align;
-	} else {
-		module->tdata = NULL;
-		module->tdata_size = 0;
-		module->tbss_size = 0;
-		module->tls_align = 1;
-	}
+	module->local = !is_dynamic;
+
+	module->tdata = p_info->tls.tdata;
+	module->tdata_size = p_info->tls.tdata_size;
+	module->tbss_size = p_info->tls.tbss_size;
+	module->tls_align = p_info->tls.tls_align;
+
+	DPRINTF("prog tdata at %p size %zu, tbss size %zu\n",
+	module->tdata, module->tdata_size, module->tbss_size);
 
 	list_append(&module->modules_link, &rtld->modules);
Index: uspace/lib/c/generic/rtld/rtld.c
===================================================================
--- uspace/lib/c/generic/rtld/rtld.c	(revision accdf8823a3853db4616f504c82346a216b4eef0)
+++ uspace/lib/c/generic/rtld/rtld.c	(revision e43acd38c0225c4fac18ac08d9da30ca442ef906)
@@ -43,27 +43,6 @@
 
 rtld_t *runtime_env;
-static rtld_t rt_env_static;
-
-/** Initialize the runtime linker for use in a statically-linked executable. */
-errno_t rtld_init_static(void)
-{
-	errno_t rc;
-
-	runtime_env = &rt_env_static;
-	list_initialize(&runtime_env->modules);
-	list_initialize(&runtime_env->imodules);
-	runtime_env->program = NULL;
-	runtime_env->next_id = 1;
-
-	rc = module_create_static_exec(runtime_env, NULL);
-	if (rc != EOK)
-		return rc;
-
-	modules_process_tls(runtime_env);
-
-	return EOK;
-}
-
-/** Initialize and process a dynamically linked executable.
+
+/** Initialize and process an executable.
  *
  * @param p_info Program info
@@ -73,7 +52,6 @@
 {
 	rtld_t *env;
-	module_t *prog;
-
-	DPRINTF("Load dynamically linked program.\n");
+	bool is_dynamic = p_info->dynamic != NULL;
+	DPRINTF("rtld_prog_process\n");
 
 	/* Allocate new RTLD environment to pass to the loaded program */
@@ -82,41 +60,17 @@
 		return ENOMEM;
 
-	env->next_id = 1;
-
-	prog = calloc(1, sizeof(module_t));
-	if (prog == NULL) {
-		free(env);
-		return ENOMEM;
-	}
-
-	/*
-	 * First we need to process dynamic sections of the executable
-	 * program and insert it into the module graph.
-	 */
-
-	DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic);
-	dynamic_parse(p_info->dynamic, 0, &prog->dyn);
-	prog->bias = 0;
-	prog->dyn.soname = "[program]";
-	prog->rtld = env;
-	prog->id = rtld_get_next_id(env);
-	prog->exec = true;
-	prog->local = false;
-
-	prog->tdata = p_info->tls.tdata;
-	prog->tdata_size = p_info->tls.tdata_size;
-	prog->tbss_size = p_info->tls.tbss_size;
-	prog->tls_align = p_info->tls.tls_align;
-
-	DPRINTF("prog tdata at %p size %zu, tbss size %zu\n",
-	    prog->tdata, prog->tdata_size, prog->tbss_size);
-
-	/* Initialize list of loaded modules */
 	list_initialize(&env->modules);
 	list_initialize(&env->imodules);
-	list_append(&prog->modules_link, &env->modules);
+	env->next_id = 1;
+
+	module_t *module;
+	errno_t rc = module_create_entrypoint(p_info, env, &module);
+	if (rc != EOK) {
+		free(env);
+		return rc;
+	}
 
 	/* Pointer to program module. Used as root of the module graph. */
-	env->program = prog;
+	env->program = module;
 
 	/*
@@ -124,8 +78,12 @@
 	 */
 
-	DPRINTF("Load all program dependencies\n");
-	errno_t rc = module_load_deps(prog, 0);
-	if (rc != EOK) {
-		return rc;
+	if (is_dynamic) {
+		DPRINTF("Load all program dependencies\n");
+		rc = module_load_deps(module, 0);
+		if (rc != EOK) {
+			free(module);
+			free(env);
+			return rc;
+		}
 	}
 
@@ -137,9 +95,12 @@
 	 */
 
-	/* Process relocations in all modules */
-	DPRINTF("Relocate all modules\n");
-	modules_process_relocs(env, prog);
-
-	*rre = env;
+	if (is_dynamic) {
+		/* Process relocations in all modules */
+		DPRINTF("Relocate all modules\n");
+		modules_process_relocs(env, module);
+	}
+
+	if (rre != NULL)
+		*rre = env;
 	return EOK;
 }
Index: uspace/lib/c/generic/thread/tls.c
===================================================================
--- uspace/lib/c/generic/thread/tls.c	(revision accdf8823a3853db4616f504c82346a216b4eef0)
+++ uspace/lib/c/generic/thread/tls.c	(revision e43acd38c0225c4fac18ac08d9da30ca442ef906)
@@ -74,5 +74,5 @@
 }
 
-/** Get address of static TLS block */
+/** Get address of static TLS block - only when RTLD is not initialized  */
 void *tls_get(void)
 {
Index: uspace/lib/c/include/rtld/module.h
===================================================================
--- uspace/lib/c/include/rtld/module.h	(revision accdf8823a3853db4616f504c82346a216b4eef0)
+++ uspace/lib/c/include/rtld/module.h	(revision e43acd38c0225c4fac18ac08d9da30ca442ef906)
@@ -41,5 +41,5 @@
 #include <types/rtld/rtld.h>
 
-extern errno_t module_create_static_exec(rtld_t *, module_t **);
+extern errno_t module_create_entrypoint(elf_finfo_t *, rtld_t *, module_t **);
 extern void module_process_relocs(module_t *);
 extern module_t *module_find(rtld_t *, const char *);
Index: uspace/lib/c/include/rtld/rtld.h
===================================================================
--- uspace/lib/c/include/rtld/rtld.h	(revision accdf8823a3853db4616f504c82346a216b4eef0)
+++ uspace/lib/c/include/rtld/rtld.h	(revision e43acd38c0225c4fac18ac08d9da30ca442ef906)
@@ -45,5 +45,4 @@
 extern rtld_t *runtime_env;
 
-extern errno_t rtld_init_static(void);
 extern errno_t rtld_prog_process(elf_finfo_t *, rtld_t **);
 extern tcb_t *rtld_tls_make(rtld_t *);
