Subject: Re: Text relocations in libpthread
To: None <tech-toolchain@netbsd.org>
From: Valeriy E. Ushakov <uwe@ptc.spbu.ru>
List: tech-toolchain
Date: 12/28/2005 03:11:09
On Tue, Dec 27, 2005 at 11:38:05 +0300, Valeriy E. Ushakov wrote:

> > Index: lib/libpthread/arch/x86_64/pthread_switch.S
> > ===================================================================
> > RCS file: /cvsroot/src/lib/libpthread/arch/x86_64/pthread_switch.S,v
> > retrieving revision 1.10
> > diff -u -p -u -r1.10 pthread_switch.S
> > --- lib/libpthread/arch/x86_64/pthread_switch.S	23 Apr 2004 02:58:27 -0000	1.10
> > +++ lib/libpthread/arch/x86_64/pthread_switch.S	27 Dec 2005 07:12:17 -0000
> > @@ -136,7 +136,11 @@ ENTRY(pthread__switch)
> >  	 * Edit the context so that it continues as if returning from
> >  	 * the _setcontext_u below.  
> >  	 */
> > +#ifdef PIC
> > +	movq	PIC_GOT(pthread__switch_return_point), %r15
> > +#else
> >  	leaq	pthread__switch_return_point(%rip), %r15
> > +#endif
> >  	movq	%r15, UC_RIP(%r14)
> >  	movq	%r14, PT_UC(%r12)

> I think these *_return_point symbols should be made .hidden, then
> these diffs will not be necessary.  As with cerror, I don't see a
> reason why we would want to make them globally visible/overridable.

I did a quick review of the arch/*/pthread_switch.S and the situation
seems to be quite messy.

pthread__switch_return_point is mentioned in pthread_sa.c as:

    extern void pthread__switch_return_point(void);

In pthread__upcall() the code checks if:

	psrp = pthread__switch_return_point;
        pc = (fptr_t)((intptr_t)
                pthread__uc_pc(victim->pt_uc));
        if ((victim->pt_spinlocks == 0) &&
            ((victim->pt_switchto != NULL) ||
                (pc == psrp))) {
		...
	}

Now, my reading of the pthread_switch.S files is that most of the
architectures set the pc (pthread__uc_pc(victim->pt_uc)) to the
absolute address of the pthread__switch_return_point label during the
pthread__switch.  But psrp = pthread__switch_return_point assignment
will set psrp to the PLT entry instead, b/c pthread__switch_return_point
is not .hidden, so (pc == psrp) will never be true.


PS: Then there's VAX on which pthread__switch_return_point is *not*
the label that pthread__switch use, so on VAX that (pc == psrp) will
never be true even for static linking, or pthread__switch_return_point
marked as .hidden.

SY, Uwe
-- 
uwe@ptc.spbu.ru                         |       Zu Grunde kommen
http://snark.ptc.spbu.ru/~uwe/          |       Ist zu Grunde gehen