Wrapping versioned glibc symbol

Tomash Brechko tomash.brechko@gmail.com
Fri Apr 24 10:05:00 GMT 2009


Hello,

To wrap glibc function (i.e. to create shared library that overrides
glibc function but calls the original one) you normally do something
like

  extern int __pthread_mutex_lock(pthread_mutex_t *mutex);

  int
  pthread_mutex_lock(pthread_mutex_t *mutex)
  {
    /* do something */
    int res = __pthread_mutex_lock(mutex);
    /* do something */

    return res;
  }

given underscored version is provided.  But sometimes symbol is
versioned, like

  pthread_cond_signal@GLIBC_2.0
  pthread_cond_signal@@GLIBC_2.3.2

Is there a way to wrap it?  I tried the following

  extern int __pthread_cond_signal(pthread_cond_t *cond);
  __asm__(".symver __pthread_cond_signal, pthread_cond_signal@GLIBC_2.3.2");

  int
  pthread_cond_signal(pthread_cond_t *cond)
  {
    /* do something */
    int res = __pthread_cond_signal(signal);
    /* do something */

    return res;
  }

(I'd prefer not having hardcoded version, but it's not a showstopper
either).  Assembler looks promising:

        .symver __pthread_cond_signal, pthread_cond_signal@GLIBC_2.3.2
        ...
  pthread_cond_signal:
        ...
        call    __pthread_cond_signal
        ...

nm .o shows

  00000420 T pthread_cond_signal
           U pthread_cond_signal@GLIBC_2.3.2

Alas, nm .so gives only

  00000d2c T pthread_cond_signal

Both references were merged, and my function recursively calls itself.
I played with .symver more, but the closest result in .so was

  00000420 t pthread_cond_signal@@
           U pthread_cond_signal@GLIBC_2.3.2

Almost what I want, but my wrapper is not exported (t)!  And when I
manage to export it, symbols are merged again :(.


So, is there a canonical way to wrap versioned functions?  Perhaps I
approach the problem from the wrong side...

Thanks in advance!

-- 
   Tomash Brechko



More information about the Libc-help mailing list