Index: uspace/lib/c/generic/elf/elf_load.c
===================================================================
--- uspace/lib/c/generic/elf/elf_load.c	(revision bdcf71e7108c1065465bbc29a3666276eef4f7a4)
+++ uspace/lib/c/generic/elf/elf_load.c	(revision acb14ce73e1510c20bc30d63392df26f9f253026)
@@ -69,24 +69,22 @@
 	}
 
+#ifdef CONFIG_RTLD
+	DPRINTF("- prog dynamic: %p\n", finfo->dynamic);
+	rc = rtld_prog_process(finfo, &env);
+	if (rc != EOK) {
+		DPRINTF("Failed to process executable '%s'.\n", file_name);
+		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;
-#ifdef CONFIG_RTLD
-		rc = rtld_init_static(finfo, &env);
-		info->env = env;
-#endif
 		return EOK;
 	}
 
-	DPRINTF("Binary is dynamically linked.\n");
-#ifdef CONFIG_RTLD
-	DPRINTF("- prog dynamic: %p\n", finfo->dynamic);
-	rc = rtld_prog_process(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/rtld/module.c
===================================================================
--- uspace/lib/c/generic/rtld/module.c	(revision bdcf71e7108c1065465bbc29a3666276eef4f7a4)
+++ uspace/lib/c/generic/rtld/module.c	(revision acb14ce73e1510c20bc30d63392df26f9f253026)
@@ -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(const void *elf, rtld_t *rtld)
+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,23 +91,18 @@
 	module->rtld = rtld;
 	module->exec = true;
-	module->local = true;
-
-	const elf_segment_header_t *tls =
-	    elf_get_phdr(elf, PT_TLS);
-
-	if (tls) {
-		uintptr_t bias = elf_get_bias(elf);
-		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);
+
+	if (rmodule != NULL)
+		*rmodule = module;
 	return EOK;
 }
Index: uspace/lib/c/generic/rtld/rtld.c
===================================================================
--- uspace/lib/c/generic/rtld/rtld.c	(revision bdcf71e7108c1065465bbc29a3666276eef4f7a4)
+++ uspace/lib/c/generic/rtld/rtld.c	(revision acb14ce73e1510c20bc30d63392df26f9f253026)
@@ -44,30 +44,5 @@
 rtld_t *runtime_env;
 
-/** Initialize the runtime linker for use in a statically-linked executable. */
-errno_t rtld_init_static(elf_finfo_t *finfo, rtld_t **rre)
-{
-	rtld_t *env;
-	errno_t rc;
-
-	env = calloc(1, sizeof(rtld_t));
-	if (env == NULL)
-		return ENOMEM;
-
-	list_initialize(&env->modules);
-	list_initialize(&env->imodules);
-	env->program = NULL;
-	env->next_id = 1;
-
-	rc = module_create_static_exec(finfo->base, env);
-	if (rc != EOK)
-		return rc;
-
-	modules_process_tls(env);
-
-	*rre = env;
-	return EOK;
-}
-
-/** Initialize and process a dynamically linked executable.
+/** Initialize and process an executable.
  *
  * @param p_info Program info
@@ -77,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 */
@@ -86,54 +60,32 @@
 		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);
-
-	/* Pointer to program module. Used as root of the module graph. */
-	env->program = prog;
-
-	/*
-	 * Now we can continue with loading all other modules.
-	 */
-
-	DPRINTF("Load all program dependencies\n");
-	errno_t rc = module_load_deps(prog, 0);
+	env->next_id = 1;
+
+	module_t *module;
+	errno_t rc = module_create_entrypoint(p_info, env, &module);
 	if (rc != EOK) {
-		free(prog);
 		free(env);
 		return rc;
 	}
 
+	/* Pointer to program module. Used as root of the module graph. */
+	env->program = module;
+
+	/*
+	 * Now we can continue with loading all other modules.
+	 */
+
+	if (is_dynamic) {
+		DPRINTF("Load all program dependencies\n");
+		rc = module_load_deps(module, 0);
+		if (rc != EOK) {
+			free(module);
+			free(env);
+			return rc;
+		}
+	}
+
 	/* Compute static TLS size */
 	modules_process_tls(env);
@@ -143,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/include/rtld/module.h
===================================================================
--- uspace/lib/c/include/rtld/module.h	(revision bdcf71e7108c1065465bbc29a3666276eef4f7a4)
+++ uspace/lib/c/include/rtld/module.h	(revision acb14ce73e1510c20bc30d63392df26f9f253026)
@@ -41,5 +41,5 @@
 #include <types/rtld/rtld.h>
 
-extern errno_t module_create_static_exec(const void *, rtld_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 bdcf71e7108c1065465bbc29a3666276eef4f7a4)
+++ uspace/lib/c/include/rtld/rtld.h	(revision acb14ce73e1510c20bc30d63392df26f9f253026)
@@ -45,5 +45,4 @@
 extern rtld_t *runtime_env;
 
-extern errno_t rtld_init_static(elf_finfo_t *, rtld_t **);
 extern errno_t rtld_prog_process(elf_finfo_t *, rtld_t **);
 extern tcb_t *rtld_tls_make(rtld_t *);
