Message ID | CALoOobNav2YqSdG72zp27rJyBLftOdESWmdYbqU-zNrEn2hf8w@mail.gmail.com |
---|---|
State | New |
Headers | show |
Series | Add xdlopen/xdlsym/xdlclose support routines | expand |
On 09/20/2017 06:34 PM, Paul Pluzhnikov wrote: > Greetings, > > As suggested in > https://sourceware.org/ml/libc-alpha/2017-09/msg00799.html, this patch > implements xdlopen, xdlsym and xdlclose routines which terminate test > program with appropriate message if the corresponding dlfcn.h routine > returns an error. > > The patch also converts stdlib/tst-tls-atexit.c to the new routines > (to make sure they work). > > Suggested commit message: > > --- > Implement xdlopen, xdlsym and xdlclose routines which terminate test > program with appropriate message if the corresponding dlfcn.h routine > returns an error. > > Use them in stdlib/tst-tls-atexit.c > --- Looks good to me. Thanks for adding to the support functions! :-) > -- Paul Pluzhnikov > > > glibc-xdlfcn-20170920.txt > > > 2017-09-20 Paul Pluzhnikov <ppluzhnikov@google.com> > Carlos O'Donell <carlos@redhat.com> > > * support/xdlfcn.h: New file. > * support/xdlfcn.c: New file. > * support/Makefile (libsupport-routines): Add xdlfcn. > * stdlib/tst-tls-atexit.c: Use xdlopen, xdlsym, xdlclose. > > > diff --git a/stdlib/tst-tls-atexit.c b/stdlib/tst-tls-atexit.c > index 6dbf49d460..165909af98 100644 > --- a/stdlib/tst-tls-atexit.c > +++ b/stdlib/tst-tls-atexit.c > @@ -31,7 +31,6 @@ > second handle. In the end, the DSO should remain loaded due to the > RTLD_NODELETE flag being set in the second dlopen call. */ > > -#include <dlfcn.h> > #include <pthread.h> > #include <stdio.h> > #include <unistd.h> > @@ -39,6 +38,7 @@ > #include <errno.h> > #include <link.h> > #include <stdbool.h> > +#include <support/xdlfcn.h> > > #ifndef NO_DELETE > # define LOADED_IS_GOOD false > @@ -73,18 +73,12 @@ is_loaded (void) > static void * > reg_dtor_and_close (void *h) > { > - void (*reg_dtor) (void) = (void (*) (void)) dlsym (h, "reg_dtor"); > - > - if (reg_dtor == NULL) > - { > - printf ("Unable to find symbol: %s\n", dlerror ()); > - return (void *) (uintptr_t) 1; > - } > + void (*reg_dtor) (void) = (void (*) (void)) xdlsym (h, "reg_dtor"); > > reg_dtor (); > > #ifndef NO_DELETE > - dlclose (h); > + xdlclose (h); > #endif > > return NULL; > @@ -119,32 +113,22 @@ static int > do_test (void) > { > /* Load the DSO. */ > - void *h1 = dlopen (DSO_NAME, RTLD_LAZY); > - if (h1 == NULL) > - { > - printf ("h1: Unable to load DSO: %s\n", dlerror ()); > - return 1; > - } > + void *h1 = xdlopen (DSO_NAME, RTLD_LAZY); > > #ifndef NO_DELETE > if (spawn_thread (h1) != 0) > return 1; > #endif > > - void *h2 = dlopen (DSO_NAME, H2_RTLD_FLAGS); > - if (h2 == NULL) > - { > - printf ("h2: Unable to load DSO: %s\n", dlerror ()); > - return 1; > - } > + void *h2 = xdlopen (DSO_NAME, H2_RTLD_FLAGS); > > #ifdef NO_DELETE > if (spawn_thread (h1) != 0) > return 1; > > - dlclose (h1); > + xdlclose (h1); > #endif > - dlclose (h2); > + xdlclose (h2); > > /* Check link maps to ensure that the DSO has unloaded. In the normal case, > the DSO should be unloaded if there are no uses. However, if one of the > diff --git a/support/Makefile b/support/Makefile > index 2ace3fa8cc..4c01434afd 100644 > --- a/support/Makefile > +++ b/support/Makefile > @@ -66,6 +66,7 @@ libsupport-routines = \ > xclose \ > xconnect \ > xdup2 \ > + xdlfcn \ > xfclose \ > xfopen \ > xfork \ > diff --git a/support/xdlfcn.c b/support/xdlfcn.c > new file mode 100644 > index 0000000000..6e3979983d > --- /dev/null > +++ b/support/xdlfcn.c > @@ -0,0 +1,58 @@ > +/* Support functionality for using dlopen/dlclose/dlsym. > + Copyright (C) 2017 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <http://www.gnu.org/licenses/>. */ > + > +#include <support/check.h> > +#include <support/xdlfcn.h> > + > +void * > +xdlopen (const char *filename, int flags) > +{ > + void *dso = dlopen (filename, flags); > + > + if (dso == NULL) > + FAIL_EXIT1 ("error: dlopen: %s\n", dlerror ()); > + > + /* Clear any errors. */ > + dlerror (); > + > + return dso; > +} > + > +void * > +xdlsym (void *handle, const char *symbol) > +{ > + void *sym = dlsym (handle, symbol); > + > + if (sym == NULL) > + FAIL_EXIT1 ("error: dlsym: %s\n", dlerror ()); > + > + /* Clear any errors. */ > + dlerror (); > + > + return sym; > +} > + > +void > +xdlclose (void *handle) > +{ > + if (dlclose (handle) != 0) > + FAIL_EXIT1 ("error: dlclose: %s\n", dlerror ()); > + > + /* Clear any errors. */ > + dlerror (); > +} > diff --git a/support/xdlfcn.h b/support/xdlfcn.h > new file mode 100644 > index 0000000000..9bdcb38d3e > --- /dev/null > +++ b/support/xdlfcn.h > @@ -0,0 +1,34 @@ > +/* Support functionality for using dlopen/dlclose/dlsym. > + Copyright (C) 2017 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License, or (at your option) any later version. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <http://www.gnu.org/licenses/>. */ > + > +#ifndef SUPPORT_DLOPEN_H > +#define SUPPORT_DLOPEN_H > + > +#include <dlfcn.h> > + > +__BEGIN_DECLS > + > +/* Each of these terminates process on failure with relevant error message. */ > +void *xdlopen (const char *filename, int flags); > +void *xdlsym (void *handle, const char *symbol); > +void xdlclose (void *handle); > + > + > +__END_DECLS > + > +#endif /* SUPPORT_DLOPEN_H */
diff --git a/stdlib/tst-tls-atexit.c b/stdlib/tst-tls-atexit.c index 6dbf49d460..165909af98 100644 --- a/stdlib/tst-tls-atexit.c +++ b/stdlib/tst-tls-atexit.c @@ -31,7 +31,6 @@ second handle. In the end, the DSO should remain loaded due to the RTLD_NODELETE flag being set in the second dlopen call. */ -#include <dlfcn.h> #include <pthread.h> #include <stdio.h> #include <unistd.h> @@ -39,6 +38,7 @@ #include <errno.h> #include <link.h> #include <stdbool.h> +#include <support/xdlfcn.h> #ifndef NO_DELETE # define LOADED_IS_GOOD false @@ -73,18 +73,12 @@ is_loaded (void) static void * reg_dtor_and_close (void *h) { - void (*reg_dtor) (void) = (void (*) (void)) dlsym (h, "reg_dtor"); - - if (reg_dtor == NULL) - { - printf ("Unable to find symbol: %s\n", dlerror ()); - return (void *) (uintptr_t) 1; - } + void (*reg_dtor) (void) = (void (*) (void)) xdlsym (h, "reg_dtor"); reg_dtor (); #ifndef NO_DELETE - dlclose (h); + xdlclose (h); #endif return NULL; @@ -119,32 +113,22 @@ static int do_test (void) { /* Load the DSO. */ - void *h1 = dlopen (DSO_NAME, RTLD_LAZY); - if (h1 == NULL) - { - printf ("h1: Unable to load DSO: %s\n", dlerror ()); - return 1; - } + void *h1 = xdlopen (DSO_NAME, RTLD_LAZY); #ifndef NO_DELETE if (spawn_thread (h1) != 0) return 1; #endif - void *h2 = dlopen (DSO_NAME, H2_RTLD_FLAGS); - if (h2 == NULL) - { - printf ("h2: Unable to load DSO: %s\n", dlerror ()); - return 1; - } + void *h2 = xdlopen (DSO_NAME, H2_RTLD_FLAGS); #ifdef NO_DELETE if (spawn_thread (h1) != 0) return 1; - dlclose (h1); + xdlclose (h1); #endif - dlclose (h2); + xdlclose (h2); /* Check link maps to ensure that the DSO has unloaded. In the normal case, the DSO should be unloaded if there are no uses. However, if one of the diff --git a/support/Makefile b/support/Makefile index 2ace3fa8cc..4c01434afd 100644 --- a/support/Makefile +++ b/support/Makefile @@ -66,6 +66,7 @@ libsupport-routines = \ xclose \ xconnect \ xdup2 \ + xdlfcn \ xfclose \ xfopen \ xfork \ diff --git a/support/xdlfcn.c b/support/xdlfcn.c new file mode 100644 index 0000000000..6e3979983d --- /dev/null +++ b/support/xdlfcn.c @@ -0,0 +1,58 @@ +/* Support functionality for using dlopen/dlclose/dlsym. + Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <support/check.h> +#include <support/xdlfcn.h> + +void * +xdlopen (const char *filename, int flags) +{ + void *dso = dlopen (filename, flags); + + if (dso == NULL) + FAIL_EXIT1 ("error: dlopen: %s\n", dlerror ()); + + /* Clear any errors. */ + dlerror (); + + return dso; +} + +void * +xdlsym (void *handle, const char *symbol) +{ + void *sym = dlsym (handle, symbol); + + if (sym == NULL) + FAIL_EXIT1 ("error: dlsym: %s\n", dlerror ()); + + /* Clear any errors. */ + dlerror (); + + return sym; +} + +void +xdlclose (void *handle) +{ + if (dlclose (handle) != 0) + FAIL_EXIT1 ("error: dlclose: %s\n", dlerror ()); + + /* Clear any errors. */ + dlerror (); +} diff --git a/support/xdlfcn.h b/support/xdlfcn.h new file mode 100644 index 0000000000..9bdcb38d3e --- /dev/null +++ b/support/xdlfcn.h @@ -0,0 +1,34 @@ +/* Support functionality for using dlopen/dlclose/dlsym. + Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef SUPPORT_DLOPEN_H +#define SUPPORT_DLOPEN_H + +#include <dlfcn.h> + +__BEGIN_DECLS + +/* Each of these terminates process on failure with relevant error message. */ +void *xdlopen (const char *filename, int flags); +void *xdlsym (void *handle, const char *symbol); +void xdlclose (void *handle); + + +__END_DECLS + +#endif /* SUPPORT_DLOPEN_H */