Ich versuche zu erkunden, wie diese Funktionen von gcc funktionieren.Schwache Symbole und Schwachstellen
Ich habe eine Bibliothek mit einer Funktion erstellt, die entweder sigprocmask
oder pthread_sigmask
aufrufen sollte, je nachdem, ob libpthread
verknüpft ist oder nicht.
Meine weakref Version des Codes funktioniert wie erwartet, aber meine Version mit schwachem Symbol scheint nicht durch das echte pthread_sigmask
Symbol übersteuert zu werden, wie ich es erwarten würde.
Könnten Sie bitte darauf hinweisen, was ich falsch mache?
WeakRef Version:
#!/bin/sh
cat > lib.c <<EOF
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <pthread.h>
#include <stdlib.h>
__attribute__((weakref("pthread_sigmask")))
static int pthread_sigmask_ref(int How, sigset_t const *Set, sigset_t *Oldset);
int call_pthread_sigmask(int How, sigset_t const *Set, sigset_t *Oldset)
{
puts("calling pthread_sigmask");
if(pthread_sigmask_ref){
return pthread_sigmask_ref(How, Set, Oldset);
}else{
puts("SIGPROCMASK");
return sigprocmask(How, Set, Oldset);
}
}
EOF
cat > main.c <<EOF
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <pthread.h>
#include <stdlib.h>
int call_pthread_sigmask(int How, sigset_t const *Set, sigset_t *Oldset);
int main()
{
sigset_t all_sigs, old_mask;
sigemptyset(&all_sigs);
sigaddset(&all_sigs, SIGTERM);
call_pthread_sigmask(SIG_SETMASK, &all_sigs, &old_mask);
#if 0
pthread_mutex_t mx;
pthread_mutex_init(&mx,0);
#endif
}
EOF
gcc -c -fpic lib.c
gcc lib.o -o lib.so -shared
gcc main.c $PWD/lib.so -lpthread -o wrap
gcc main.c $PWD/lib.so -Wl,--no-as-needed -lpthread -o real
echo wrap
ldd ./wrap
./wrap
echo real
ldd ./real
./real
Beispiel Ausgang:
wrap
linux-vdso.so.1 => (0x00007ffd5dda0000)
/home/user/tmp/lib.so (0x00007faa4f8cf000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007faa4f507000)
/lib64/ld-linux-x86-64.so.2 (0x00007faa4fad1000)
calling pthread_sigmask
SIGPROCMASK
real
linux-vdso.so.1 => (0x00007ffc7f51e000)
/home/user/tmp/lib.so (0x00007f6ff23b2000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f6ff2194000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6ff1dcc000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6ff25b4000)
calling pthread_sigmask
Weak-Symbol, Version:
#!/bin/sh
cat > lib.c <<EOF
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <pthread.h>
#include <stdlib.h>
__attribute__((weak,noinline))
int pthread_sigmask(int How, sigset_t const *Set, sigset_t *Oldset)
{
puts("SIGPROCMASK");
return sigprocmask(How, Set, Oldset);
}
int call_pthread_sigmask(int How, sigset_t const *Set, sigset_t *Oldset)
{
puts("calling pthread_sigmask");
return pthread_sigmask(How, Set, Oldset);
}
EOF
cat > main.c <<EOF
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <pthread.h>
#include <stdlib.h>
int call_pthread_sigmask(int How, sigset_t const *Set, sigset_t *Oldset);
int main()
{
sigset_t all_sigs, old_mask;
sigemptyset(&all_sigs);
sigaddset(&all_sigs, SIGTERM);
call_pthread_sigmask(SIG_SETMASK, &all_sigs, &old_mask);
#if 0
pthread_mutex_t mx;
pthread_mutex_init(&mx,0);
#endif
}
EOF
gcc -c -fpic lib.c
gcc lib.o -o lib.so -shared
gcc main.c $PWD/lib.so -lpthread -o wrap
gcc main.c $PWD/lib.so -Wl,--no-as-needed -lpthread -o real
echo wrap
ldd ./wrap
./wrap
echo real
ldd ./real
./real
Beispiel Ausgang:
wrap
linux-vdso.so.1 => (0x00007ffd19d23000)
/home/user/tmp/lib.so (0x00007fdd24b46000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdd2477e000)
/lib64/ld-linux-x86-64.so.2 (0x00007fdd24d48000)
calling pthread_sigmask
SIGPROCMASK
real
linux-vdso.so.1 => (0x00007fff115f6000)
/home/user/tmp/lib.so (0x00007fb22be95000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb22bc77000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb22b8af000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb22c097000)
calling pthread_sigmask
SIGPROCMASK
(Behinderte Block mit dem 'pthread_mutex_init' ist nur eine andere Art libpthread zu Link zu zwingen - eine Alternative zu' -Wl, - no-as-needed') – PSkocik