mailing list of musl libc
 help / color / mirror / code / Atom feed
* [PATCH] Add comments to i386 assembly source
@ 2017-12-23  9:45 Markus Wichmann
  2017-12-31  4:15 ` John Reiser
  0 siblings, 1 reply; 13+ messages in thread
From: Markus Wichmann @ 2017-12-23  9:45 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 1110 bytes --]

Hello everyone,

all the other arch's (I cared to look at) have well-commented or rather
clear assembly sources. Even where it wasn't really needed (PPC's
set_thread_area() would be clear enough without comments, as it's only
two instructions, neither of which complex).

But then there's i386. Without comments, and pulling off some very black
magic, I thought it would be worth commenting the files at least in the
threads directory.

While commenting the files, I noticed something: GS can refer to either
the GDT or the LDT, depending on whether the set_thread_area() syscall
failed or not. If GS refers to the LDT, then the offset portion of it
is 0, so the __clone() function will push an index of 0 on stack. Is
Linux smart enough to notice this, or will the clone() syscall then fail
with EINVAL? It's not documented, but set_thread_area() will fail with
EINVAL if index is out of bounds, and 0 is not a valid value (reason
being that the GDT index 0 is never valid; it's actually the null
selector and causes a GPF if referenced, or, in case of CS, if loaded).

Anyway, enjoy the patch.

Ciao,
Markus

[-- Attachment #2: 0001-Add-comments-to-i386-threading-assembly-files.patch --]
[-- Type: text/x-diff, Size: 4029 bytes --]

From afb818ccc3d565de95903f0b1cde39b6e437f6bf Mon Sep 17 00:00:00 2001
From: Markus Wichmann <nullplan@gmx.net>
Date: Sat, 23 Dec 2017 10:34:31 +0100
Subject: [PATCH] Add comments to i386 threading assembly files.

---
 src/thread/i386/__set_thread_area.s | 22 ++++++++---------
 src/thread/i386/clone.s             | 48 +++++++++++++++++++++----------------
 2 files changed, 39 insertions(+), 31 deletions(-)

diff --git a/src/thread/i386/__set_thread_area.s b/src/thread/i386/__set_thread_area.s
index 3a558fb0..d3eac89e 100644
--- a/src/thread/i386/__set_thread_area.s
+++ b/src/thread/i386/__set_thread_area.s
@@ -6,20 +6,20 @@ __set_thread_area:
 	push $0x51
 	push $0xfffff
 	push 16(%esp)
-	call 1f
-1:	addl $4f-1b,(%esp)
+	call 1f                 /* ebx : 0x51 : 0xfffff : arg : 1f */
+1:	addl $4f-1b,(%esp)      /* ebx : 0x51 : 0xfffff : arg : 4f */
 	pop %ecx
 	mov (%ecx),%edx
-	push %edx
+	push %edx               /* ebx : 0x51 : 0xfffff : arg : [4f] */
 	mov %esp,%ebx
 	xor %eax,%eax
 	mov $243,%al
-	int $128
+	int $128                /* set_thread_area({.index = [4f], .base = arg, .limit=0xfffff, .seg32_bits, .limit_in_pages, .usable}) */
 	testl %eax,%eax
-	jnz 2f
+	jnz 2f                  /* if that failed, go to 2 */
 	movl (%esp),%edx
-	movl %edx,(%ecx)
-	leal 3(,%edx,8),%edx
+	movl %edx,(%ecx)        /* save index in [4f] */
+	leal 3(,%edx,8),%edx    /* multiply index by 8 to get offset for segment selector, add 3 to get CPL 3 */
 3:	movw %dx,%gs
 1:
 	addl $16,%esp
@@ -33,11 +33,11 @@ __set_thread_area:
 	mov $1,%bl
 	mov $16,%dl
 	mov $123,%al
-	int $128
+	int $128                /* modify_ldt(1, {.index = 0, .base = arg, .limit=0xfffff, .seg32_bits, .limit_in_pages, .usable}, 16)*/
 	testl %eax,%eax
-	jnz 1b
-	mov $7,%dl
-	inc %al
+	jnz 1b                  /* if that failed, just clean up and return */
+	mov $7,%dl              /* else the segment selector has offset 0, is in the LDT, and CPL 3 */
+	inc %al                 /* and return 1 */
 	jmp 3b
 
 .data
diff --git a/src/thread/i386/clone.s b/src/thread/i386/clone.s
index 52fe7efb..4e25e52d 100644
--- a/src/thread/i386/clone.s
+++ b/src/thread/i386/clone.s
@@ -1,44 +1,52 @@
 .text
 .global __clone
 .type   __clone,@function
+/* args: 8 - fn
+12 - stack
+16 - flags
+20 - td ptr
+24 - TID ptr
+28 - thread pointer
+32 - TID ptr (again?)
+*/
 __clone:
-	push %ebp
+	push %ebp       /* function intro */
 	mov %esp,%ebp
 	push %ebx
 	push %esi
 	push %edi
 
 	xor %eax,%eax
-	push $0x51
+	push $0x51      /* 0x51 */
 	mov %gs,%ax
-	push $0xfffff
+	push $0xfffff   /* 0x51 : 0xfffff */
 	shr $3,%eax
-	push 28(%ebp)
-	push %eax
-	mov $120,%al
+	push 28(%ebp)   /* 0x51 : 0xfffff : thread pointer */
+	push %eax       /* 0x51 : 0xfffff : thread pointer : current gs index */
+	mov $120,%al    /* __NR_clone */
 
-	mov 12(%ebp),%ecx
-	mov 16(%ebp),%ebx
+	mov 12(%ebp),%ecx   /* ecx = stack */
+	mov 16(%ebp),%ebx   /* ebx = flags */
 	and $-16,%ecx
-	sub $16,%ecx
-	mov 20(%ebp),%edi
-	mov %edi,(%ecx)
-	mov 24(%ebp),%edx
-	mov %esp,%esi
-	mov 32(%ebp),%edi
-	mov 8(%ebp),%ebp
-	int $128
+	sub $16,%ecx        /* align stack */
+	mov 20(%ebp),%edi   /* edi = td pointer */
+	mov %edi,(%ecx)     /* push td pointer to new stack */
+	mov 24(%ebp),%edx   /* edx = TID pointer */
+	mov %esp,%esi       /* esi = esp */
+	mov 32(%ebp),%edi   /* edi = TID pointer */
+	mov 8(%ebp),%ebp    /* ebp = start function (for safe-keeping) */
+	int $128            /* clone(flags, stack, TID pointer, {.index = current gs index, .base = thread pointer, .limit=0xfffff, .seg32_bit, .limit_in_pages, .usable}, td pointer) */
 	test %eax,%eax
-	jnz 1f
+	jnz 1f              /* if that's not 0, just return the return value */
 
-	mov %ebp,%eax
+	mov %ebp,%eax       /* in child: zero out ebp, then call function */
 	xor %ebp,%ebp
 	call *%eax
-	mov %eax,%ebx
+	mov %eax,%ebx       /* exit(rv from function) */
 	xor %eax,%eax
 	inc %eax
 	int $128
-	hlt
+	hlt                 /* exit didn't exit? Crash! */
 
 1:	add $16,%esp
 	pop %edi
-- 
2.14.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2018-01-03  2:51 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-23  9:45 [PATCH] Add comments to i386 assembly source Markus Wichmann
2017-12-31  4:15 ` John Reiser
2017-12-31  6:54   ` Markus Wichmann
2017-12-31 15:49   ` Rich Felker
2018-01-01 19:52     ` Markus Wichmann
2018-01-01 22:57       ` John Reiser
2018-01-02  1:49         ` Rich Felker
2018-01-02  3:15           ` John Reiser
2018-01-02 19:49             ` Rich Felker
2018-01-02 18:24           ` a third bug in musl clone() John Reiser
2018-01-02 19:58             ` Rich Felker
2018-01-02 22:09               ` Florian Weimer
2018-01-03  2:51                 ` Rich Felker

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).