Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20211229100229.GG1949@voyager>
Date: Wed, 29 Dec 2021 11:02:29 +0100
From: Markus Wichmann <nullplan@....net>
To: Rich Felker <dalias@...c.org>
Cc: musl@...ts.openwall.com
Subject: Re: ASM-to-C conversion for i386

On Mon, Dec 27, 2021 at 10:00:11AM -0500, Rich Felker wrote:
> On Sun, Dec 26, 2021 at 09:42:38PM +0100, Markus Wichmann wrote:
> > So I've converted __set_thread_area(). That was pretty straightforward
> > once I found SYSCALL_NO_TLS. The generated assembly generated by clang
> > 6.0.0 hits the same notes as the handwritten code, so I'm willing to
> > count that as a win.
>
> Somewhere I had an old version of this which didn't fare so well, so
> it will be interesting to compare.
>

Not quite sure what you mean by "didn't fare so well". I just fixed a
bug, and looked at the disassembly. Here's clang's output
(v6.0.0-ubuntu):


0005a482 <__set_thread_area>:
   5a482:	53                   	push   %ebx
   5a483:	56                   	push   %esi
   5a484:	83 ec 10             	sub    $0x10,%esp
   5a487:	e8 00 00 00 00       	call   5a48c <__set_thread_area+0xa>
   5a48c:	59                   	pop    %ecx
   5a48d:	81 c1 74 2b 04 00    	add    $0x42b74,%ecx
   5a493:	8b 44 24 1c          	mov    0x1c(%esp),%eax
   5a497:	8b b1 74 02 00 00    	mov    0x274(%ecx),%esi
   5a49d:	89 e2                	mov    %esp,%edx
   5a49f:	89 32                	mov    %esi,(%edx)
   5a4a1:	89 42 04             	mov    %eax,0x4(%edx)
   5a4a4:	c7 42 08 ff ff 0f 00 	movl   $0xfffff,0x8(%edx)
   5a4ab:	c7 42 0c 51 00 00 00 	movl   $0x51,0xc(%edx)
   5a4b2:	b8 f3 00 00 00       	mov    $0xf3,%eax
   5a4b7:	87 da                	xchg   %ebx,%edx
   5a4b9:	cd 80                	int    $0x80
   5a4bb:	87 da                	xchg   %ebx,%edx
   5a4bd:	85 c0                	test   %eax,%eax
   5a4bf:	74 22                	je     5a4e3 <__set_thread_area+0x61>
   5a4c1:	31 f6                	xor    %esi,%esi
   5a4c3:	46                   	inc    %esi
   5a4c4:	89 e1                	mov    %esp,%ecx
   5a4c6:	b8 7b 00 00 00       	mov    $0x7b,%eax
   5a4cb:	ba 10 00 00 00       	mov    $0x10,%edx
   5a4d0:	89 f3                	mov    %esi,%ebx
   5a4d2:	cd 80                	int    $0x80
   5a4d4:	b9 07 00 00 00       	mov    $0x7,%ecx
   5a4d9:	85 c0                	test   %eax,%eax
   5a4db:	74 18                	je     5a4f5 <__set_thread_area+0x73>
   5a4dd:	89 c6                	mov    %eax,%esi
   5a4df:	79 14                	jns    5a4f5 <__set_thread_area+0x73>
   5a4e1:	eb 14                	jmp    5a4f7 <__set_thread_area+0x75>
   5a4e3:	8b 04 24             	mov    (%esp),%eax
   5a4e6:	89 81 74 02 00 00    	mov    %eax,0x274(%ecx)
   5a4ec:	8d 0c c5 03 00 00 00 	lea    0x3(,%eax,8),%ecx
   5a4f3:	31 f6                	xor    %esi,%esi
   5a4f5:	8e e9                	mov    %ecx,%gs
   5a4f7:	89 f0                	mov    %esi,%eax
   5a4f9:	83 c4 10             	add    $0x10,%esp
   5a4fc:	5e                   	pop    %esi
   5a4fd:	5b                   	pop    %ebx
   5a4fe:	c3                   	ret

And here's gcc's (version 7.5.0-3ubuntu1):

00054908 <__set_thread_area>:
   54908:	56                   	push   %esi
   54909:	53                   	push   %ebx
   5490a:	e8 b0 3a fc ff       	call   183bf <__x86.get_pc_thunk.bx>
   5490f:	81 c3 f1 16 04 00    	add    $0x416f1,%ebx
   54915:	83 ec 10             	sub    $0x10,%esp
   54918:	8b 83 fc 02 00 00    	mov    0x2fc(%ebx),%eax
   5491e:	89 e1                	mov    %esp,%ecx
   54920:	c7 44 24 08 ff ff 0f 	movl   $0xfffff,0x8(%esp)
   54927:	00
   54928:	c7 44 24 0c 51 00 00 	movl   $0x51,0xc(%esp)
   5492f:	00
   54930:	89 ca                	mov    %ecx,%edx
   54932:	89 04 24             	mov    %eax,(%esp)
   54935:	8b 44 24 1c          	mov    0x1c(%esp),%eax
   54939:	89 44 24 04          	mov    %eax,0x4(%esp)
   5493d:	b8 f3 00 00 00       	mov    $0xf3,%eax
   54942:	87 da                	xchg   %ebx,%edx
   54944:	cd 80                	int    $0x80
   54946:	87 da                	xchg   %ebx,%edx
   54948:	85 c0                	test   %eax,%eax
   5494a:	75 14                	jne    54960 <__set_thread_area+0x58>
   5494c:	8b 04 24             	mov    (%esp),%eax
   5494f:	89 83 fc 02 00 00    	mov    %eax,0x2fc(%ebx)
   54955:	8d 34 c5 03 00 00 00 	lea    0x3(,%eax,8),%esi
   5495c:	31 c0                	xor    %eax,%eax
   5495e:	eb 23                	jmp    54983 <__set_thread_area+0x7b>
   54960:	b8 7b 00 00 00       	mov    $0x7b,%eax
   54965:	bb 01 00 00 00       	mov    $0x1,%ebx
   5496a:	ba 10 00 00 00       	mov    $0x10,%edx
   5496f:	cd 80                	int    $0x80
   54971:	85 c0                	test   %eax,%eax
   54973:	74 04                	je     54979 <__set_thread_area+0x71>
   54975:	78 0e                	js     54985 <__set_thread_area+0x7d>
   54977:	eb 0a                	jmp    54983 <__set_thread_area+0x7b>
   54979:	be 07 00 00 00       	mov    $0x7,%esi
   5497e:	b8 01 00 00 00       	mov    $0x1,%eax
   54983:	8e ee                	mov    %esi,%gs
   54985:	83 c4 10             	add    $0x10,%esp
   54988:	5b                   	pop    %ebx
   54989:	5e                   	pop    %esi
   5498a:	c3                   	ret

So no, it's not the same as the hand-written assembler (but then, I
don't think there's a way to make a C compiler emit that code), but it
does hit the right notes. The system calls are called with the right
values, and the correct thing is moved into GS in the end. And isn't
that what counts?

Not quite sure why that is a 32-bit move, when I explicitly requested
the operand be a 16-bit value, but in this case it does not matter, as
the high sixteen bits are discarded in that instruction.

Ciao,
Markus

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.