Seeing your e-mail reminded me that I had asked Philip about adding support for RTLD_NOLOAD / RTLD_NODELETE last year after seeing instances of their usage in the tree here and there.
----- Forwarded message from Philip Guenther <[email protected]> ----- Date: Thu, 24 Sep 2020 23:19:27 -0700 From: Philip Guenther <[email protected]> To: Brad Smith <[email protected]> Subject: Re: dlopen & RTLD_NOLOAD / RTLD_NODELETE User-Agent: Alpine 2.21 (BSO 202 2017-01-01) On Sat, 19 Sep 2020, Brad Smith wrote: > On 8/31/2020 12:24 AM, Philip Guenther wrote: > > On Sun, 30 Aug 2020, Brad Smith wrote: > > > Is there any chance that OpenBSD's dlopen() could have support for > > > RTLD_NOLOAD / RTLD_NODELETE added? Specifically RTLD_NOLOAD as I've had > > > a patch in MariaDB for ages to allow building on OpenBSD. > > Sigh. The hard part is writing the regress. > > Is that a no? The noload bits are completely untested. Index: include/dlfcn.h =================================================================== RCS file: /data/src/openbsd/src/include/dlfcn.h,v retrieving revision 1.14 diff -u -p -r1.14 dlfcn.h --- include/dlfcn.h 28 Nov 2017 17:19:47 -0000 1.14 +++ include/dlfcn.h 31 Aug 2020 00:55:55 -0000 @@ -42,6 +42,8 @@ #define RTLD_GLOBAL 0x100 #define RTLD_LOCAL 0x000 #define RTLD_TRACE 0x200 +#define RTLD_NODELETE 0x400 +#define RTLD_NOLOAD 0x800 /* * Special handle arguments for dlsym(). Index: libexec/ld.so/dlfcn.c =================================================================== RCS file: /data/src/openbsd/src/libexec/ld.so/dlfcn.c,v retrieving revision 1.106 diff -u -p -r1.106 dlfcn.c --- libexec/ld.so/dlfcn.c 4 Oct 2019 17:42:16 -0000 1.106 +++ libexec/ld.so/dlfcn.c 1 Sep 2020 05:04:40 -0000 @@ -46,6 +46,15 @@ static int _dl_real_close(void *handle); static lock_cb *_dl_thread_fnc = NULL; static elf_object_t *obj_from_addr(const void *addr); +#define OK_FLAGS (0 \ + | RTLD_TRACE \ + | RTLD_LAZY \ + | RTLD_NOW \ + | RTLD_GLOBAL \ + | RTLD_NODELETE \ + | RTLD_NOLOAD \ + ) + void * dlopen(const char *libname, int flags) { @@ -54,7 +63,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 & ~OK_FLAGS) { _dl_errno = DL_INVALID_MODE; return NULL; } @@ -79,7 +88,10 @@ dlopen(const char *libname, int flags) _dl_loading_object = NULL; obj_flags = (flags & RTLD_NOW ? DF_1_NOW : 0) - | (flags & RTLD_GLOBAL ? DF_1_GLOBAL : 0); + | (flags & RTLD_GLOBAL ? DF_1_GLOBAL : 0) + | (flags & RTLD_NODELETE ? DF_1_NODELETE : 0) + | (flags & RTLD_NOLOAD ? DF_1_NOOPEN : 0) + ; object = _dl_load_shlib(libname, _dl_objects, OBJTYPE_DLO, obj_flags); if (object == 0) { DL_DEB(("dlopen: failed to open %s\n", libname)); @@ -93,6 +105,10 @@ dlopen(const char *libname, int flags) /* if opened but grpsym_vec has not been filled in */ if (object->grpsym_vec.len == 0) _dl_cache_grpsym_list_setup(object); + if (flags & RTLD_NODELETE) { + object->obj_flags |= DF_1_NODELETE; + _dl_handle_nodelete(object); + } goto loaded; } Index: libexec/ld.so/library.c =================================================================== RCS file: /data/src/openbsd/src/libexec/ld.so/library.c,v retrieving revision 1.85 diff -u -p -r1.85 library.c --- libexec/ld.so/library.c 9 Dec 2019 22:15:15 -0000 1.85 +++ libexec/ld.so/library.c 31 Aug 2020 01:36:06 -0000 @@ -127,17 +127,14 @@ _dl_tryload_shlib(const char *libname, i for (object = _dl_objects; object != NULL; object = object->next) { if (object->dev == sb.st_dev && object->inode == sb.st_ino) { - object->obj_flags |= flags & DF_1_GLOBAL; _dl_close(libfile); - if (_dl_loading_object == NULL) - _dl_loading_object = object; - if (object->load_object != _dl_objects && - object->load_object != _dl_loading_object) { - _dl_link_grpref(object->load_object, - _dl_loading_object); - } + _dl_handle_already_loaded(object, flags); return(object); } + } + if (flags & DF_1_NOOPEN) { + _dl_close(libfile); + return NULL; } _dl_read(libfile, hbuf, sizeof(hbuf)); Index: libexec/ld.so/library_mquery.c =================================================================== RCS file: /data/src/openbsd/src/libexec/ld.so/library_mquery.c,v retrieving revision 1.64 diff -u -p -r1.64 library_mquery.c --- libexec/ld.so/library_mquery.c 9 Dec 2019 23:15:03 -0000 1.64 +++ libexec/ld.so/library_mquery.c 31 Aug 2020 01:36:00 -0000 @@ -134,15 +134,13 @@ _dl_tryload_shlib(const char *libname, i object->inode == sb.st_ino) { object->obj_flags |= flags & DF_1_GLOBAL; _dl_close(libfile); - if (_dl_loading_object == NULL) - _dl_loading_object = object; - if (object->load_object != _dl_objects && - object->load_object != _dl_loading_object) { - _dl_link_grpref(object->load_object, - _dl_loading_object); - } + _dl_handle_already_loaded(object, flags); return(object); } + } + if (flags & DF_1_NOOPEN) { + _dl_close(libfile); + return NULL; } _dl_read(libfile, hbuf, sizeof(hbuf)); Index: libexec/ld.so/library_subr.c =================================================================== RCS file: /data/src/openbsd/src/libexec/ld.so/library_subr.c,v retrieving revision 1.50 diff -u -p -r1.50 library_subr.c --- libexec/ld.so/library_subr.c 4 Oct 2019 17:42:16 -0000 1.50 +++ libexec/ld.so/library_subr.c 25 Sep 2020 06:13:30 -0000 @@ -241,6 +241,18 @@ _dl_lookup_object(const char *req_name, return(NULL); } +void +_dl_handle_already_loaded(elf_object_t *object, int flags) +{ + object->obj_flags |= flags & DF_1_GLOBAL; + if (_dl_loading_object == NULL) + _dl_loading_object = object; + if (object->load_object != _dl_objects && + object->load_object != _dl_loading_object) { + _dl_link_grpref(object->load_object, _dl_loading_object); + } +} + static elf_object_t * _dl_find_loaded_shlib(const char *req_name, struct sod req_sod, int flags) { @@ -262,15 +274,8 @@ _dl_find_loaded_shlib(const char *req_na req_sod.sod_minor, orig_minor); } - if (object) { /* Already loaded */ - object->obj_flags |= flags & DF_1_GLOBAL; - if (_dl_loading_object == NULL) - _dl_loading_object = object; - if (object->load_object != _dl_objects && - object->load_object != _dl_loading_object) { - _dl_link_grpref(object->load_object, _dl_loading_object); - } - } + if (object) + _dl_handle_already_loaded(object, flags); return (object); } Index: libexec/ld.so/resolve.c =================================================================== RCS file: /data/src/openbsd/src/libexec/ld.so/resolve.c,v retrieving revision 1.94 diff -u -p -r1.94 resolve.c --- libexec/ld.so/resolve.c 4 Oct 2019 17:42:16 -0000 1.94 +++ libexec/ld.so/resolve.c 25 Sep 2020 06:13:26 -0000 @@ -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: libexec/ld.so/resolve.h =================================================================== RCS file: /data/src/openbsd/src/libexec/ld.so/resolve.h,v retrieving revision 1.96 diff -u -p -r1.96 resolve.h --- libexec/ld.so/resolve.h 4 Oct 2019 17:42:16 -0000 1.96 +++ libexec/ld.so/resolve.h 31 Aug 2020 01:26:30 -0000 @@ -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, @@ -251,6 +252,7 @@ elf_object_t *_dl_finalize_object(const void _dl_remove_object(elf_object_t *object); void _dl_cleanup_objects(void); +void _dl_handle_already_loaded(elf_object_t *_object, int _flags); elf_object_t *_dl_load_shlib(const char *, elf_object_t *, int, int); elf_object_t *_dl_tryload_shlib(const char *libname, int type, int flags); ----- End forwarded message -----
