[PATCH] libm/x86: use call instead of jump for wrappers

Timo Teräs timo.teras at iki.fi
Mon Nov 1 06:53:22 UTC 2010


On 11/01/2010 03:16 AM, Denys Vlasenko wrote:
> On Sunday 31 October 2010 23:07, Timo Teräs wrote:
>> On 10/31/2010 05:10 PM, Denys Vlasenko wrote:
>>> Since by breaking long double wrappers I proved that no one actually
>>> runs math testsuite (does anyone runs ANY part of testsuite?),
>>> I decided that now it is my obligation to fix math testsuite first,
>>> so that in the future it will be easier to catch breakatge.
>>>
>>> I fixed it to a certain degree already.
>>>
>>> Then I reverted your fix, and _verified_ that it works with both
>>> static and shared build.
>>
>> Your code crashed. Mine version did not. I did not run the test suite
> 
> I think we all neglected testsuite for too long. It has bit rotted.
> Needs work to restore to runnable state...
> 
>> nor test the call thingy. Sorry about that. Just build failed by
>> segfault vs. succeed was enough for me.
> 
> Yes, I know how the failure must have looked on your side.
> What is unclear is what caused gcc to emit a prologue
> with some stack pushes...
> 
> 
>>> It needs to be saved/restored *if ebx is used*. In these stubs it is
>>> not used, thus it is not saved by gcc, and therefore tail jump is ok
>>> even with __PIC__.
>>>
>>> I do not merely think so. I tested it. Try in the directory
>>> where you successfully built shared uclibc using PIC:
>>
>> I remember that the original crash I fixed was caused by PIC and not
>> SSP. The issue is that the jmp target name is outside __asm__ "" and
>> translated by gcc to ebx+xxx. So you use implicitly ebx in your __asm__
>> block. And thus gcc will save/restore and calculate the local ebx for
>> you automatically.
> 
> Uhhuh... so it will happen only if function gets called through
> inter-library stub. This should not happen with __GI_foo symbols, though -
> those are hidden and should be linked directly intra-library.
> 
> BTW, there were no __GI_foo calls originally, I just called foo directly
> at first. Then affed __GI_ prefix. Maybe *that* fixed the problem.

I think you had __GI_ prefix all the time. I rebuilt again with the
original buggy config. It had both PIC and SSP enabled. The SSP abort
__stack_chk_fail is called via plt and causes the ebx load. So using
__SSP_ALL__ fixed this specific build.

>>> Thanks, replaced:
>>>
>>> -#if defined __i386__ && defined __OPTIMIZE__ && !defined __UCLIBC_HAS_SSP__
>>> +#if defined __i386__ && defined __OPTIMIZE__ && !defined __SSP_ALL__
>>>
>>> and pushed to git.
>>
>> Please add __PIC__ test.
> 
> Do you see the failure with current git? I did __PIC__ test, it wroks for me...

Yes, regular PIC and PIC+SSP now works. BUT, several other features do not.

If I'm building with "-fPIC -pg" it instruments all C functions with
profiler stuff which is called via PLT and causes EBX reloads
 --> crash

-fno-omit-frame-pointer is sometimes useful for profiling too
 --> crash

Also the upcoming -fsplit-stack will be broken by this too (that might
need additional uclibc support though).

And I'm pretty sure there's also other similar compiler features.
There's no predefined #defines in gcc for any of these.

What I'm trying to say that there are *numerous* situations when the
compiler can create stack frame for you without you ever knowing it. And
if you want to do a tail jump, you really should be doing it from .S
file where you control fully the prologue/epilogue code. (GCC naked
attribute does not seem to work on x86.)


More information about the uClibc mailing list