add RTLD_NODELETE support
authorsemarie <semarie@openbsd.org>
Wed, 2 Jun 2021 07:29:03 +0000 (07:29 +0000)
committersemarie <semarie@openbsd.org>
Wed, 2 Jun 2021 07:29:03 +0000 (07:29 +0000)
if RTLD_NODELETE isn't POSIX, it is widely deployed: at least linux,
freebsd, dragonfly, netbsd, solaris, illumos, apple, and fuchsia have
it.

ok kettenis@ on previous version
with help from and ok guenther@

diff partially inspired from a diff from brad@

include/dlfcn.h
lib/libc/shlib_version
libexec/ld.so/dlfcn.c
libexec/ld.so/resolve.c
libexec/ld.so/resolve.h
share/man/man3/dlfcn.3

index 431065f..4cee447 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dlfcn.h,v 1.14 2017/11/28 17:19:47 kettenis Exp $     */
+/*     $OpenBSD: dlfcn.h,v 1.15 2021/06/02 07:29:03 semarie Exp $      */
 /*     $NetBSD: dlfcn.h,v 1.2 1995/06/05 19:38:00 pk Exp $     */
 
 /*
@@ -42,6 +42,7 @@
 #define RTLD_GLOBAL    0x100
 #define RTLD_LOCAL     0x000
 #define RTLD_TRACE     0x200
+#define RTLD_NODELETE  0x400
 
 /*
  * Special handle arguments for dlsym().
index 06f98b0..5fb0770 100644 (file)
@@ -1,4 +1,4 @@
 major=96
-minor=0
+minor=1
 # note: If changes were made to include/thread_private.h or if system calls
 # were added/changed then librthread/shlib_version must also be updated.
index b8d5512..384b5ea 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dlfcn.c,v 1.106 2019/10/04 17:42:16 guenther Exp $ */
+/*     $OpenBSD: dlfcn.c,v 1.107 2021/06/02 07:29:03 semarie Exp $ */
 
 /*
  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -54,7 +54,7 @@ dlopen(const char *libname, int flags)
        int failed = 0;
        int obj_flags;
 
-       if (flags & ~(RTLD_TRACE|RTLD_LAZY|RTLD_NOW|RTLD_GLOBAL)) {
+       if (flags & ~(RTLD_TRACE|RTLD_LAZY|RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE)) {
                _dl_errno = DL_INVALID_MODE;
                return NULL;
        }
@@ -87,9 +87,14 @@ dlopen(const char *libname, int flags)
                goto loaded;
        }
 
+       if (flags & RTLD_NODELETE)
+               object->obj_flags |= DF_1_NODELETE;
+       
        _dl_link_dlopen(object);
 
        if (OBJECT_REF_CNT(object) > 1) {
+               _dl_handle_nodelete(object);
+
                /* if opened but grpsym_vec has not been filled in */
                if (object->grpsym_vec.len == 0)
                        _dl_cache_grpsym_list_setup(object);
index 1d882d2..4d0928b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: resolve.c,v 1.94 2019/10/04 17:42:16 guenther Exp $ */
+/*     $OpenBSD: resolve.c,v 1.95 2021/06/02 07:29:03 semarie Exp $ */
 
 /*
  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -57,11 +57,8 @@ int object_count;
 static elf_object_t *_dl_last_object;
 elf_object_t *_dl_loading_object;
 
-/*
- * Add a new dynamic object to the object list.
- */
 void
-_dl_add_object(elf_object_t *object)
+_dl_handle_nodelete(elf_object_t *object)
 {
        /*
         * If a .so is marked nodelete, then the entire load group that it's
@@ -76,6 +73,15 @@ _dl_add_object(elf_object_t *object)
                object->load_object->opencount++;
                object->load_object->status |= STAT_NODELETE;
        }
+}
+
+/*
+ * Add a new dynamic object to the object list.
+ */
+void
+_dl_add_object(elf_object_t *object)
+{
+       _dl_handle_nodelete(object);
 
        /*
         * if this is a new object, prev will be NULL
index 6c7380f..7c14005 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: resolve.h,v 1.97 2021/03/16 18:03:06 kurt Exp $ */
+/*     $OpenBSD: resolve.h,v 1.98 2021/06/02 07:29:03 semarie Exp $ */
 
 /*
  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -244,6 +244,7 @@ void        _dl_debug_state(void);
 extern char *__progname;
 
 __BEGIN_HIDDEN_DECLS
+void _dl_handle_nodelete(elf_object_t *_object);
 void _dl_add_object(elf_object_t *object);
 elf_object_t *_dl_finalize_object(const char *objname, Elf_Dyn *dynp,
     Elf_Phdr *phdrp, int phdrc, const int objtype, const long lbase,
index afdf60f..f613f0d 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: dlfcn.3,v 1.30 2020/12/03 22:47:22 jmc Exp $
+.\"    $OpenBSD: dlfcn.3,v 1.31 2021/06/02 07:29:03 semarie Exp $
 .\"    $NetBSD: dlfcn.3,v 1.3 1996/01/09 19:43:34 pk Exp $
 .\"
 .\" Copyright (c) 1995 Paul Kranenburg
@@ -29,7 +29,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd $Mdocdate: December 3 2020 $
+.Dd $Mdocdate: June 2 2021 $
 .Dt DLOPEN 3
 .Os
 .Sh NAME
@@ -124,6 +124,14 @@ each of the above values together.
 If an object was opened with RTLD_LOCAL and later opened with RTLD_GLOBAL,
 then it is promoted to RTLD_GLOBAL.
 .Pp
+Additionally, the following flag may be ORed into the mode argument:
+.Pp
+.Bl -tag -width "RTLD_NODELETE" -compact -offset indent
+.It Sy RTLD_NODELETE
+Prevents unload of the loaded object on
+.Fn dlclose .
+.El
+.Pp
 The main executable's symbols are normally invisible to
 .Fn dlopen
 symbol resolution.