Index: uspace/lib/c/generic/rtld/module.c
===================================================================
--- uspace/lib/c/generic/rtld/module.c	(revision eff458dc0610e2e236a23436d7688091d3843237)
+++ uspace/lib/c/generic/rtld/module.c	(revision b27ae65a2da551d62479289098f2eff893166010)
@@ -398,10 +398,13 @@
 	 * be correct, "zero" offset (i.e. the total size) must be aligned
 	 * to the strictest alignment present.
-	 * Note that the padding is actually in front of the TLS data,
-	 * not after it.
 	 */
 	rtld->tls_size = ALIGN_UP(rtld->tls_size, rtld->tls_align);
 
-	/* Space for the TCB. */
+	/*
+	 * Space for the TCB.
+	 * Later, the TLS zero offset is equal to the pointer to tcb_t, so
+	 * adding the sizeof(tcb_t) block AFTER we calculated the alignment
+	 * of the remainder above is correct.
+	 */
 	rtld->tls_size += sizeof(tcb_t);
 #endif
Index: uspace/lib/c/generic/thread/tls.c
===================================================================
--- uspace/lib/c/generic/thread/tls.c	(revision eff458dc0610e2e236a23436d7688091d3843237)
+++ uspace/lib/c/generic/thread/tls.c	(revision b27ae65a2da551d62479289098f2eff893166010)
@@ -59,8 +59,8 @@
 #endif
 
-static ptrdiff_t _tcb_data_offset(void)
+static ptrdiff_t _tcb_data_offset(const void* elf)
 {
 	const elf_segment_header_t *tls =
-	    elf_get_phdr(__progsymbols.elfstart, PT_TLS);
+	    elf_get_phdr(elf, PT_TLS);
 
 	size_t tls_align = tls ? tls->p_align : 1;
@@ -80,9 +80,13 @@
 	assert(runtime_env == NULL);
 #endif
-	return (uint8_t *)__tcb_get() + _tcb_data_offset();
+	return (uint8_t *)__tcb_get() + _tcb_data_offset(__progsymbols.elfstart);
 }
 
 static tcb_t *tls_make_generic(const void *elf, void *(*alloc)(size_t, size_t))
 {
+	/*
+	 * See also rtld/module.c -> modules_process_tls(), where we have less
+	 * messy code for the dynamic-linking version of this.
+	 */
 	assert(!elf_get_phdr(elf, PT_DYNAMIC));
 #ifdef CONFIG_RTLD
@@ -100,4 +104,11 @@
 	assert(tls_align <= PAGE_SIZE);
 
+	/*
+	 * FIXME: the calculation of alloc_size shouldn't include the alignment
+	 * of tcb_t (at least in Variant II)
+	 * See https://github.com/HelenOS/helenos/pull/240/files/4ef27ebf98a0656e09889b7d00efdec03343f1aa#r1929592924
+	 * (you will also need to fix _tcb_data_offset)
+	 */
+
 #ifdef CONFIG_TLS_VARIANT_1
 	size_t alloc_size =
@@ -114,9 +125,9 @@
 #ifdef CONFIG_TLS_VARIANT_1
 	tcb_t *tcb = area;
-	uint8_t *data = (uint8_t *)tcb + _tcb_data_offset();
+	uint8_t *data = (uint8_t *)tcb + _tcb_data_offset(elf);
 	memset(tcb, 0, sizeof(*tcb));
 #else
 	uint8_t *data = area;
-	tcb_t *tcb = (tcb_t *) (data - _tcb_data_offset());
+	tcb_t *tcb = (tcb_t *) (data - _tcb_data_offset(elf));
 	memset(tcb, 0, sizeof(tcb_t));
 	tcb->self = tcb;
