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
This commit is contained in:
Paul Pluzhnikov 2017-09-20 19:37:45 -07:00
parent ae8372d7e4
commit 1cc9e59a93
5 changed files with 108 additions and 23 deletions

View file

@ -1,3 +1,11 @@
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.
2017-09-20 Joseph Myers <joseph@codesourcery.com>
[BZ #20142]

View file

@ -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

View file

@ -65,6 +65,7 @@ libsupport-routines = \
xchroot \
xclose \
xconnect \
xdlfcn \
xdup2 \
xfclose \
xfopen \

58
support/xdlfcn.c Normal file
View file

@ -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 ();
}

34
support/xdlfcn.h Normal file
View file

@ -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 */