Provide libdl.

Create libdl.so.1 as a filter for libc.so.7 which exports public dl*
functions. The functions are resolved from the rtld instead, the goal
of creating library is to avoid errors from the static linker due to
missed libdl. For static binaries, an empty .o is compiled into
libdl.a so that static binaries still get dl stubs from libc.a.

Right now lld cannot create filter objects, disable libdl on arm64
when binutils are not used.

Reviewed by:	bdrewery, dim (previos version); emaste
Exp run:	PR 220525, done by antoine
Sponsored by:	The FreeBSD Foundation
MFC after:	1 month
Differential revision:	https://reviews.freebsd.org/D11504
This commit is contained in:
Konstantin Belousov 2017-07-10 14:59:21 +00:00
parent 16d02c733f
commit 99ac8154ff
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=320872
9 changed files with 65 additions and 1 deletions

View file

@ -46,6 +46,7 @@ LINE("libdevctl", "Device Control Library (libdevctl, \\-ldevctl)")
LINE("libdevinfo", "Device and Resource Information Utility Library (libdevinfo, \\-ldevinfo)")
LINE("libdevstat", "Device Statistics Library (libdevstat, \\-ldevstat)")
LINE("libdisk", "Interface to Slice and Partition Labels Library (libdisk, \\-ldisk)")
LINE("libdl", "Dynamic Linker Services Filter (libdl, \\-ldl)")
LINE("libdm", "Device Mapper Library (libdm, \\-ldm)")
LINE("libdwarf", "DWARF Access Library (libdwarf, \\-ldwarf)")
LINE("libedit", "Command Line Editor Library (libedit, \\-ledit)")

View file

@ -40,6 +40,7 @@ SUBDIR= ${SUBDIR_BOOTSTRAP} \
libdevctl \
libdevinfo \
libdevstat \
${_libdl} \
libdwarf \
libedit \
libevent \
@ -183,6 +184,10 @@ _libproc= libproc
_librtld_db= librtld_db
.endif
.if defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mfilter}
_libdl= libdl
.endif
SUBDIR.${MK_OPENSSL}+= libmp
SUBDIR.${MK_PMC}+= libpmc
SUBDIR.${MK_RADIUS_SUPPORT}+= libradius

View file

@ -27,6 +27,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#if !defined(IN_LIBDL) || defined(PIC)
/*
* Linkage to services provided by the dynamic linker.
*/
@ -157,6 +159,7 @@ _rtld_thread_init(void *li __unused)
_rtld_error(sorry);
}
#ifndef IN_LIBDL
static pthread_once_t dl_phdr_info_once = PTHREAD_ONCE_INIT;
static struct dl_phdr_info phdr_info;
@ -192,6 +195,7 @@ dl_init_phdr_info(void)
}
phdr_info.dlpi_adds = 1;
}
#endif
#pragma weak dl_iterate_phdr
int
@ -199,11 +203,15 @@ dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *) __unused,
void *data __unused)
{
#ifndef IN_LIBDL
__init_elf_aux_vector();
if (__elf_aux_vector == NULL)
return (1);
_once(&dl_phdr_info_once, dl_init_phdr_info);
return (callback(&phdr_info, sizeof(phdr_info), data));
#else
return (0);
#endif
}
#pragma weak fdlopen
@ -251,3 +259,5 @@ _rtld_is_dlopened(void *arg __unused)
return (0);
}
#endif /* !defined(IN_LIBDL) || defined(PIC) */

View file

@ -32,7 +32,7 @@
.\" @(#) dlopen.3 1.6 90/01/31 SMI
.\" $FreeBSD$
.\"
.Dd February 14, 2015
.Dd July 7, 2017
.Dt DLOPEN 3
.Os
.Sh NAME
@ -377,6 +377,14 @@ option to
for symbols defined in the executable to become visible to
.Fn dlsym .
.Pp
Other ELF platforms require linking with
.Lb libdl
to provide
.Fn dlopen
and other functions.
.Fx
does not require linking with the library, but supports it for compatibility.
.Pp
In previous implementations, it was necessary to prepend an underscore
to all external symbols in order to gain symbol
compatibility with object code compiled from the C language.

15
lib/libdl/Makefile Normal file
View file

@ -0,0 +1,15 @@
# $FreeBSD$
LIB=dl
SHLIB_MAJOR=1
.PATH: ${SRCTOP}/lib/libc/gen
CFLAGS+=-I${SRCTOP}/lib/libc/include
CFLAGS+=-DIN_LIBDL
LDFLAGS+=-Wl,-F,libc.so.7
VERSION_DEF=${SRCTOP}/lib/libc/Versions.def
SYMBOL_MAPS=${.CURDIR}/Symbol.map
SRCS = dlfcn.c
.include <bsd.lib.mk>

20
lib/libdl/Symbol.map Normal file
View file

@ -0,0 +1,20 @@
/*
* $FreeBSD$
*/
FBSD_1.0 {
dladdr;
dlclose;
dlerror;
dlfunc;
dlopen;
dlsym;
dlvsym;
dlinfo;
dl_iterate_phdr;
};
FBSD_1.3 {
fdlopen;
};

View file

@ -56,6 +56,7 @@ LIBDEVDCTL?= ${LIBDESTDIR}${LIBDIR_BASE}/libdevdctl.a
LIBDEVINFO?= ${LIBDESTDIR}${LIBDIR_BASE}/libdevinfo.a
LIBDEVSTAT?= ${LIBDESTDIR}${LIBDIR_BASE}/libdevstat.a
LIBDIALOG?= ${LIBDESTDIR}${LIBDIR_BASE}/libdialog.a
LIBDL?= ${LIBDESTDIR}${LIBDIR_BASE}/libdl.a
LIBDNS?= ${LIBDESTDIR}${LIBDIR_BASE}/libdns.a
LIBDPV?= ${LIBDESTDIR}${LIBDIR_BASE}/libdpv.a
LIBDTRACE?= ${LIBDESTDIR}${LIBDIR_BASE}/libdtrace.a

View file

@ -70,6 +70,9 @@ ${X_}LINKER_FEATURES=
.if ${${X_}LINKER_TYPE} != "bfd" || ${${X_}LINKER_VERSION} > 21750
${X_}LINKER_FEATURES+= build-id
.endif
.if ${${X_}LINKER_TYPE} == "bfd"
${X_}LINKER_FEATURES+= filter
.endif
.endif
.else
# Use LD's values

View file

@ -88,6 +88,7 @@ _LIBRARIES= \
devinfo \
devstat \
dialog \
dl \
dpv \
dtrace \
dwarf \