Patchwork [libitm] : GTM_longjmp: Jump indirect from memory address

login
register
mail settings
Submitter Uros Bizjak
Date Feb. 13, 2012, 10:54 p.m.
Message ID <CAFULd4b5gA0VgTiMzrFnY+tRKjNUoDDqJm7C1_PxENPfQ1dVzg@mail.gmail.com>
Download mbox | patch
Permalink /patch/141009/
State New
Headers show

Comments

Uros Bizjak - Feb. 13, 2012, 10:54 p.m.
Hello!

We can jump indirect from memory address, sparing a couple of cycles.

2012-02-14  Uros Bizjak  <ubizjak@gmail.com>

	* config/x86/target.h (GTM_longjmp): Jump indirect from memory address.

Tested on x86_64-pc-linux-gnu {,-m32}.

OK for mainline?

Uros.
Richard Henderson - Feb. 13, 2012, 10:57 p.m.
On 02/13/2012 02:54 PM, Uros Bizjak wrote:
> -	movq	56(%rsi), %rdx
>  	movl	%edi, %eax
>  	cfi_def_cfa(%rcx, 0)
> -	cfi_register(%rip, %rdx)
>  	movq	%rcx, %rsp
> -	jmp	*%rdx
> +	jmp	*56(%rsi)

If you're going to do that, the correct fix for the unwind info is 

- cfi_register(%rip, %rdx)
+ cfi_offset(%rip, 56)

Otherwise ok.


r~
Uros Bizjak - Feb. 14, 2012, 12:09 a.m.
On Mon, Feb 13, 2012 at 11:57 PM, Richard Henderson <rth@redhat.com> wrote:
> On 02/13/2012 02:54 PM, Uros Bizjak wrote:
>> -     movq    56(%rsi), %rdx
>>       movl    %edi, %eax
>>       cfi_def_cfa(%rcx, 0)
>> -     cfi_register(%rip, %rdx)
>>       movq    %rcx, %rsp
>> -     jmp     *%rdx
>> +     jmp     *56(%rsi)
>
> If you're going to do that, the correct fix for the unwind info is
>
> - cfi_register(%rip, %rdx)
> + cfi_offset(%rip, 56)

Hm, we just defined new CFA as rcx+0, so we should define location of
rip relative to new CFA. Since CFA points to stack slot just before
return address was pushed, new rip lies at CFA-8 for 64bit resp. CFA-4
for x86_32. Did I get these .cfi directives correctly?

SYM(GTM_longjmp):
	cfi_startproc
#ifdef __x86_64__
	movq	(%rsi), %rcx
	movq	8(%rsi), %rbx
	movq	16(%rsi), %rbp
	movq	24(%rsi), %r12
	movq	32(%rsi), %r13
	movq	40(%rsi), %r14
	movq	48(%rsi), %r15
	movl	%edi, %eax
	cfi_def_cfa(%rcx, 0)
	cfi_offset(%rip, -8)
	movq	%rcx, %rsp
	jmp	*56(%rsi)
#else
	movl	(%edx), %ecx
	movl	4(%edx), %ebx
	movl	8(%edx), %esi
	movl	12(%edx), %edi
	movl	16(%edx), %ebp
	cfi_def_cfa(%ecx, 0)
	cfi_offset(%eip, -4)
	movl	%ecx, %esp
	jmp	*20(%edx)
#endif
	cfi_endproc

Uros.
Richard Henderson - Feb. 14, 2012, 12:15 a.m.
On 02/13/2012 04:09 PM, Uros Bizjak wrote:
> On Mon, Feb 13, 2012 at 11:57 PM, Richard Henderson <rth@redhat.com> wrote:
>> On 02/13/2012 02:54 PM, Uros Bizjak wrote:
>>> -     movq    56(%rsi), %rdx
>>>       movl    %edi, %eax
>>>       cfi_def_cfa(%rcx, 0)
>>> -     cfi_register(%rip, %rdx)
>>>       movq    %rcx, %rsp
>>> -     jmp     *%rdx
>>> +     jmp     *56(%rsi)
>>
>> If you're going to do that, the correct fix for the unwind info is
>>
>> - cfi_register(%rip, %rdx)
>> + cfi_offset(%rip, 56)
> 
> Hm, we just defined new CFA as rcx+0, so we should define location of
> rip relative to new CFA. Since CFA points to stack slot just before
> return address was pushed, new rip lies at CFA-8 for 64bit resp. CFA-4
> for x86_32. Did I get these .cfi directives correctly?

No.  The value at %rcx-8 is total garbage.  There no guarantee that
the call stack leading to this abort has anything in common with the
call stack that created the jmpbuf, except *above* %rcx, the new CFA.

The new rip is at rsi+56.  You can see that in that you jump to it.


r~
Uros Bizjak - Feb. 14, 2012, 7:39 a.m.
On Tue, Feb 14, 2012 at 1:15 AM, Richard Henderson <rth@redhat.com> wrote:

>>>> -     movq    56(%rsi), %rdx
>>>>       movl    %edi, %eax
>>>>       cfi_def_cfa(%rcx, 0)
>>>> -     cfi_register(%rip, %rdx)
>>>>       movq    %rcx, %rsp
>>>> -     jmp     *%rdx
>>>> +     jmp     *56(%rsi)
>>>
>>> If you're going to do that, the correct fix for the unwind info is
>>>
>>> - cfi_register(%rip, %rdx)
>>> + cfi_offset(%rip, 56)
>>
>> Hm, we just defined new CFA as rcx+0, so we should define location of
>> rip relative to new CFA. Since CFA points to stack slot just before
>> return address was pushed, new rip lies at CFA-8 for 64bit resp. CFA-4
>> for x86_32. Did I get these .cfi directives correctly?
>
> No.  The value at %rcx-8 is total garbage.  There no guarantee that
> the call stack leading to this abort has anything in common with the
> call stack that created the jmpbuf, except *above* %rcx, the new CFA.
>
> The new rip is at rsi+56.  You can see that in that you jump to it.

Thanks for the explanation, I will commit the patch with your suggested change.

Uros.

Patch

Index: config/x86/sjlj.S
===================================================================
--- config/x86/sjlj.S	(revision 184177)
+++ config/x86/sjlj.S	(working copy)
@@ -119,23 +119,19 @@  SYM(GTM_longjmp):
 	movq	32(%rsi), %r13
 	movq	40(%rsi), %r14
 	movq	48(%rsi), %r15
-	movq	56(%rsi), %rdx
 	movl	%edi, %eax
 	cfi_def_cfa(%rcx, 0)
-	cfi_register(%rip, %rdx)
 	movq	%rcx, %rsp
-	jmp	*%rdx
+	jmp	*56(%rsi)
 #else
 	movl	(%edx), %ecx
 	movl	4(%edx), %ebx
 	movl	8(%edx), %esi
 	movl	12(%edx), %edi
 	movl	16(%edx), %ebp
-	movl	20(%edx), %edx
 	cfi_def_cfa(%ecx, 0)
-	cfi_register(%eip, %edx)
 	movl	%ecx, %esp
-	jmp	*%edx
+	jmp	*20(%edx)
 #endif
 	cfi_endproc