> Date: Mon, 10 May 2021 09:00:37 +0200
> From: Sebastien Marie <[email protected]>
> Content-Type: text/plain; charset=us-ascii
> Content-Disposition: inline
>
> Hi,
>
> The following diff adds support for RTLD_NODELETE in ld.so(1).
>
> It helps Qt programs which is using RTLD_NODELETE per default for
> loading plugins.
>
> Without this patch, qgis (for example) is crashing systematically on
> exit. With it, it is fine.
>
> If RTLD_NODELETE isn't POSIX, it is widely deployed: at least linux,
> freebsd, dragonfly, netbsd, solaris, illumos, apple, and fuchsia have
> it.
>
> I built a full release on i386 with it and built several packages
> (most of dependencies of gqis which is including qt5).
>
> One drawback will be for ports: a build with the diff might change
> built code as RTLD_NODELETE will be present in headers. So it might
> deserves a libc bump to correctly update installed ports.
>
> Comments or OK ?
The code is ok kettenis@
However, I have a comment on the man page change...
> diff 393e7b397988bb6abe46729de1794883d2b9d5cf /home/semarie/repos/openbsd/src
> blob - 431065f3eab32299ad39766592e72a1765c8e8dc
> file + include/dlfcn.h
> --- include/dlfcn.h
> +++ include/dlfcn.h
> @@ -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().
> blob - b8d5512e32bf50351b432a539106b1695a51f10f
> file + libexec/ld.so/dlfcn.c
> --- libexec/ld.so/dlfcn.c
> +++ libexec/ld.so/dlfcn.c
> @@ -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;
> }
> @@ -89,6 +89,9 @@ dlopen(const char *libname, int flags)
>
> _dl_link_dlopen(object);
>
> + if (flags & RTLD_NODELETE)
> + object->obj_flags |= DF_1_NODELETE;
> +
> if (OBJECT_REF_CNT(object) > 1) {
> /* if opened but grpsym_vec has not been filled in */
> if (object->grpsym_vec.len == 0)
> blob - afdf60ff428680eabc76f667442934511a8576fb
> file + share/man/man3/dlfcn.3
> --- share/man/man3/dlfcn.3
> +++ share/man/man3/dlfcn.3
> @@ -124,6 +124,19 @@ 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 .
> +The same behaviour may be requested by
> +.Fl z
> +.Cm nodelete
> +option of the static linker
> +.Xr ld 1 .
> +.El
> +.Pp
Should -z nodelete be documented here? It is related but doesn't do
the same thing. RTLD_NODELETE lets the process that loads a module
make the decision, whereas -z nodelete puts a marker in the module
itself.
A similar relation exists between RTLD_NOW and -z now, but we don't
document that.
I'm leaning towards leaving out the sentence about -z nodelete.
Cheers,
Mark