2017-06-05 4 views
3

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 
+0

(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

Antwort

1

tauschen Sie einfach Bibliothek bestellen:

gcc main.c -lpthread $PWD/lib.so -o real