Index: uspace/lib/c/generic/rtld/module.c
===================================================================
--- uspace/lib/c/generic/rtld/module.c	(revision 2c4e1cc2aa4f1a4b249af5c661e93ac170ba5158)
+++ uspace/lib/c/generic/rtld/module.c	(revision 66855b2198cfc74d61f61da3149b75b7e8a013b1)
@@ -35,4 +35,5 @@
  */
 
+#include <align.h>
 #include <adt/list.h>
 #include <elf/elf_load.h>
@@ -42,4 +43,5 @@
 #include <stdlib.h>
 #include <str.h>
+#include <macros.h>
 
 #include <rtld/rtld.h>
@@ -72,10 +74,17 @@
 	const elf_segment_header_t *tls =
 	    elf_get_phdr(__executable_start, PT_TLS);
-	uintptr_t bias = elf_get_bias(__executable_start);
-
-	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;
+
+	if (tls) {
+		uintptr_t bias = elf_get_bias(__executable_start);
+		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;
+	}
 
 	list_append(&module->modules_link, &rtld->modules);
@@ -324,22 +333,40 @@
 {
 #ifdef CONFIG_TLS_VARIANT_1
-	list_foreach(rtld->modules, modules_link, module_t, m) {
-		m->ioffs = rtld->tls_size;
-		list_append(&m->imodules_link, &rtmd->imodules);
+	rtld->tls_size = sizeof(tcb_t);
+	rtld->tls_align = _Alignof(tcb_t);
+
+	list_foreach(rtld->modules, modules_link, module_t, m) {
+		list_append(&m->imodules_link, &rtld->imodules);
+		rtld->tls_align = max(rtld->tls_align, m->tls_align);
+
+		rtld->tls_size = ALIGN_UP(rtld->tls_size, m->tls_align);
+		m->tpoff = rtld->tls_size;
 		rtld->tls_size += m->tdata_size + m->tbss_size;
 	}
-#else /* CONFIG_TLS_VARIANT_2 */
-	size_t offs;
-
-	list_foreach(rtld->modules, modules_link, module_t, m) {
+
+#else
+	rtld->tls_size = 0;
+	rtld->tls_align = _Alignof(tcb_t);
+
+	list_foreach(rtld->modules, modules_link, module_t, m) {
+		list_append(&m->imodules_link, &rtld->imodules);
+		rtld->tls_align = max(rtld->tls_align, m->tls_align);
+
+		/* We are allocating spans "backwards", here,
+		 * as described in U. Drepper's paper.
+		 */
 		rtld->tls_size += m->tdata_size + m->tbss_size;
-	}
-
-	offs = 0;
-	list_foreach(rtld->modules, modules_link, module_t, m) {
-		offs += m->tdata_size + m->tbss_size;
-		m->ioffs = rtld->tls_size - offs;
-		list_append(&m->imodules_link, &rtld->imodules);
-	}
+		rtld->tls_size = ALIGN_UP(rtld->tls_size, m->tls_align);
+		m->tpoff = -(ptrdiff_t) rtld->tls_size;
+	}
+
+	/* We are in negative offsets. In order for the alignments to
+	 * be correct, "zero" offset (i.e. the total size) must be aligned
+	 * to the strictest alignment present.
+	 */
+	rtld->tls_size = ALIGN_UP(rtld->tls_size, rtld->tls_align);
+
+	/* Space for the TCB. */
+	rtld->tls_size += sizeof(tcb_t);
 #endif
 }
