[parisc-linux] r19 (aka pic-register akak ltp) not restored on entry back to libc from libpthread?

Carlos O'Donell carlos@baldric.uwo.ca
Fri, 19 Sep 2003 13:51:42 -0400


On Fri, Sep 19, 2003 at 12:56:46PM -0400, John David Anglin wrote:
> > Hold your horses here, we made it back into libc but our ltp is still
> > that which we loaded upon entry to libpthread? :(
> 
> That's ok.  It's the responsibility of the libc code to restore ltp
> after a call or exception.  However, as discussed previously, there
> is no restoration after a syscall.  That should be the system's job,
> although I believe you were going to introduce a hack/workaround to
> fix the syscalls that clobber r19.

For all syscalls whose wrappers are pure assembly or __asm(...) I have
placed restorations to follow ABI. This fixed all of the major failures.
It's a bit drastic, but it fixes the issue until I know exactly which
syscall numbers clobber r19. It looks like just fork and it's variants
that stick a return address into PT_REGS's r19. That's a side issue
about optimization though. 

> You need to step through the libc code from the return point in
> libc to see why ltp isn't being restored.  Possibly, libpthread is
> being called by assembly code that doesn't restore ltp.  Normally,
> r19 is restored quite soon after a call.

There should be no assembly code glue between the calls.
What about the gcc optimization where we don't restore r19 if it's not
used between the last call and the return?

mutex_unlock becomes:
__libc_maybe_call (__pthread_mutex_unlock, (m), (*(int *)(m) = 0))

Which is a big monstrosity that looks like it might be casting things
incorrectly for hppa...

===
#if defined _LIBC && defined IS_IN_libpthread
# define __libc_maybe_call(FUNC, ARGS, ELSE) FUNC ARGS
#else
# if defined __PIC__ || (defined _LIBC && defined SHARED)
#  define __libc_maybe_call(FUNC, ARGS, ELSE) \
  (__extension__ ({ __typeof (FUNC) *_fn = (FUNC); \
                    _fn != NULL ? (*_fn) ARGS : ELSE; }))
# else
#  define __libc_maybe_call(FUNC, ARGS, ELSE) \
  (FUNC != NULL ? FUNC ARGS : ELSE)
# endif
#endif
#if defined _LIBC && !defined NOT_IN_libc && defined SHARED
# define __libc_maybe_call2(FUNC, ARGS, ELSE) \
  ({__builtin_expect (__libc_pthread_functions.ptr_##FUNC != NULL, 0) \
    ? __libc_pthread_functions.ptr_##FUNC ARGS : ELSE; })
#else
# define __libc_maybe_call2(FUNC, ARGS, ELSE) __libc_maybe_call
# (__##FUNC, ARGS, ELSE)
#endif
===

I have class, then I'll be back to -E some of the malloc build to see
what this evaluates to and then try to determine if gcc did the right
thing.

c.