Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Add support for DF_1_BIND_NOW, DF_1_NODELETE and DF_1_NOOPEN...
details: https://anonhg.NetBSD.org/src/rev/466ddeff3880
branches: trunk
changeset: 760018:466ddeff3880
user: skrll <skrll%NetBSD.org@localhost>
date: Fri Dec 24 12:41:42 2010 +0000
description:
Add support for DF_1_BIND_NOW, DF_1_NODELETE and DF_1_NOOPEN marked
objects, and the RTLD_NODELETE and RTLD_NOLOAD flags to dlopen(3).
Mark libpthread as DF_1_NOOPEN and use it to test the functionality.
Somewhat taken from FreeBSD.
Fixes PR 42029.
OK from christos and joerg.
diffstat:
distrib/sets/lists/tests/mi | 7 +++-
include/dlfcn.h | 4 +-
lib/libpthread/Makefile | 4 +-
libexec/ld.elf_so/headers.c | 12 ++++-
libexec/ld.elf_so/load.c | 49 +++++++++++++++++++-----
libexec/ld.elf_so/reloc.c | 6 +-
libexec/ld.elf_so/rtld.c | 55 +++++++++++++++++++++++----
libexec/ld.elf_so/rtld.h | 24 ++++++++++--
libexec/ld.elf_so/search.c | 29 ++++++++++----
share/man/man3/dlfcn.3 | 48 +++++++++++++++++------
sys/sys/exec_elf.h | 5 ++-
tests/libexec/ld.elf_so/Makefile | 12 ++++++
tests/libexec/ld.elf_so/h_df_1_noopen.c | 46 +++++++++++++++++++++++
tests/libexec/ld.elf_so/t_df_1_noopen.sh | 64 ++++++++++++++++++++++++++++++++
14 files changed, 310 insertions(+), 55 deletions(-)
diffs (truncated from 822 to 300 lines):
diff -r fbef68fb0d56 -r 466ddeff3880 distrib/sets/lists/tests/mi
--- a/distrib/sets/lists/tests/mi Fri Dec 24 10:11:39 2010 +0000
+++ b/distrib/sets/lists/tests/mi Fri Dec 24 12:41:42 2010 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.187 2010/12/23 15:27:44 pgoyette Exp $
+# $NetBSD: mi,v 1.188 2010/12/24 12:41:42 skrll Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@@ -387,6 +387,8 @@
./usr/libdata/debug/usr/tests/lib/libutil/t_sockaddr_snprintf.debug tests-lib-debug debug,atf
./usr/libdata/debug/usr/tests/libexec tests-lib-debug
./usr/libdata/debug/usr/tests/libexec/ld.elf_so tests-libexec-debug
+./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_df_1_noopen1.debug tests-libexec-debug debug,atf
+./usr/libdata/debug/usr/tests/libexec/ld.elf_so/h_df_1_noopen2.debug tests-libexec-debug debug,atf
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_dlerror-cleared.debug tests-libexec-debug debug,atf
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_dlerror-false.debug tests-libexec-debug debug,atf
./usr/libdata/debug/usr/tests/libexec/ld.elf_so/t_dlinfo.debug tests-libexec-debug debug,atf
@@ -1632,6 +1634,9 @@
./usr/tests/libexec/Atffile tests-lib-tests atf
./usr/tests/libexec/ld.elf_so tests-libexec-tests
./usr/tests/libexec/ld.elf_so/Atffile tests-libexec-tests atf
+./usr/tests/libexec/ld.elf_so/h_df_1_noopen1 tests-libexec-tests atf
+./usr/tests/libexec/ld.elf_so/h_df_1_noopen2 tests-libexec-tests atf
+./usr/tests/libexec/ld.elf_so/t_df_1_noopen tests-libexec-tests atf
./usr/tests/libexec/ld.elf_so/t_dlerror-cleared tests-libexec-tests atf
./usr/tests/libexec/ld.elf_so/t_dlerror-false tests-libexec-tests atf
./usr/tests/libexec/ld.elf_so/t_dlinfo tests-libexec-tests atf
diff -r fbef68fb0d56 -r 466ddeff3880 include/dlfcn.h
--- a/include/dlfcn.h Fri Dec 24 10:11:39 2010 +0000
+++ b/include/dlfcn.h Fri Dec 24 12:41:42 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: dlfcn.h,v 1.21 2010/01/07 07:35:35 skrll Exp $ */
+/* $NetBSD: dlfcn.h,v 1.22 2010/12/24 12:41:42 skrll Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -64,6 +64,8 @@
#define RTLD_NOW 2
#define RTLD_GLOBAL 0x100 /* Allow global searches in object */
#define RTLD_LOCAL 0x200
+#define RTLD_NODELETE 0x01000 /* Do not remove members. */
+#define RTLD_NOLOAD 0x02000 /* Do not load if not already loaded. */
#if defined(_NETBSD_SOURCE)
#define DL_LAZY RTLD_LAZY /* Compat */
#endif
diff -r fbef68fb0d56 -r 466ddeff3880 lib/libpthread/Makefile
--- a/lib/libpthread/Makefile Fri Dec 24 10:11:39 2010 +0000
+++ b/lib/libpthread/Makefile Fri Dec 24 12:41:42 2010 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.70 2010/08/06 05:35:42 christos Exp $
+# $NetBSD: Makefile,v 1.71 2010/12/24 12:41:42 skrll Exp $
#
WARNS= 4
@@ -33,6 +33,8 @@
LIB= pthread
+LDFLAGS+= -Wl,-znodlopen
+
#
# NOTE: When you create a new file for libpthread, make sure that pthread.c
# gets a reference to a symbol in that file. Otherwise, Unix's stupid static
diff -r fbef68fb0d56 -r 466ddeff3880 libexec/ld.elf_so/headers.c
--- a/libexec/ld.elf_so/headers.c Fri Dec 24 10:11:39 2010 +0000
+++ b/libexec/ld.elf_so/headers.c Fri Dec 24 12:41:42 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: headers.c,v 1.37 2010/10/16 17:48:12 skrll Exp $ */
+/* $NetBSD: headers.c,v 1.38 2010/12/24 12:41:43 skrll Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: headers.c,v 1.37 2010/10/16 17:48:12 skrll Exp $");
+__RCSID("$NetBSD: headers.c,v 1.38 2010/12/24 12:41:43 skrll Exp $");
#endif /* not lint */
#include <err.h>
@@ -242,8 +242,14 @@
break;
#endif
case DT_FLAGS_1:
- obj->initfirst =
+ obj->z_now =
+ ((dynp->d_un.d_val & DF_1_BIND_NOW) != 0);
+ obj->z_nodelete =
+ ((dynp->d_un.d_val & DF_1_NODELETE) != 0);
+ obj->z_initfirst =
((dynp->d_un.d_val & DF_1_INITFIRST) != 0);
+ obj->z_noopen =
+ ((dynp->d_un.d_val & DF_1_NOOPEN) != 0);
break;
}
}
diff -r fbef68fb0d56 -r 466ddeff3880 libexec/ld.elf_so/load.c
--- a/libexec/ld.elf_so/load.c Fri Dec 24 10:11:39 2010 +0000
+++ b/libexec/ld.elf_so/load.c Fri Dec 24 12:41:42 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: load.c,v 1.41 2010/12/19 17:26:51 skrll Exp $ */
+/* $NetBSD: load.c,v 1.42 2010/12/24 12:41:43 skrll Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: load.c,v 1.41 2010/12/19 17:26:51 skrll Exp $");
+__RCSID("$NetBSD: load.c,v 1.42 2010/12/24 12:41:43 skrll Exp $");
#endif /* not lint */
#include <err.h>
@@ -109,7 +109,7 @@
* on failure.
*/
Obj_Entry *
-_rtld_load_object(const char *filepath, int mode)
+_rtld_load_object(const char *filepath, int flags)
{
Obj_Entry *obj;
int fd = -1;
@@ -153,6 +153,18 @@
return NULL;
_rtld_digest_dynamic(filepath, obj);
+ if (flags & _RTLD_DLOPEN) {
+ if (obj->z_noopen || (flags & _RTLD_NOLOAD)) {
+ dbg(("refusing to load non-loadable \"%s\"",
+ obj->path));
+ _rtld_error("Cannot dlopen non-loadable %s",
+ obj->path);
+ munmap(obj->mapbase, obj->mapsize);
+ _rtld_obj_free(obj);
+ return OBJ_ERR;
+ }
+ }
+
*_rtld_objtail = obj;
_rtld_objtail = &obj->next;
_rtld_objcount++;
@@ -168,12 +180,12 @@
++obj->refcount;
#ifdef RTLD_LOADER
- if (mode & RTLD_MAIN && !obj->mainref) {
+ if (flags & _RTLD_MAIN && !obj->mainref) {
obj->mainref = 1;
dbg(("adding %p (%s) to _rtld_list_main", obj, obj->path));
_rtld_objlist_push_tail(&_rtld_list_main, obj);
}
- if (mode & RTLD_GLOBAL && !obj->globalref) {
+ if (flags & _RTLD_GLOBAL && !obj->globalref) {
obj->globalref = 1;
dbg(("adding %p (%s) to _rtld_list_global", obj, obj->path));
_rtld_objlist_push_tail(&_rtld_list_global, obj);
@@ -183,7 +195,8 @@
}
static bool
-_rtld_load_by_name(const char *name, Obj_Entry *obj, Needed_Entry **needed, int mode)
+_rtld_load_by_name(const char *name, Obj_Entry *obj, Needed_Entry **needed,
+ int flags)
{
Library_Xform *x = _rtld_xforms;
Obj_Entry *o = NULL;
@@ -240,7 +253,7 @@
for (j = 0; j < RTLD_MAX_LIBRARY &&
x->entry[i].library[j] != NULL; j++) {
o = _rtld_load_library(x->entry[i].library[j], obj,
- mode);
+ flags);
if (o == NULL) {
xwarnx("could not load %s for %s",
x->entry[i].library[j], name);
@@ -266,7 +279,7 @@
if (got)
return true;
- return ((*needed)->obj = _rtld_load_library(name, obj, mode)) != NULL;
+ return ((*needed)->obj = _rtld_load_library(name, obj, flags)) != NULL;
}
@@ -276,7 +289,7 @@
* returns -1 on failure.
*/
int
-_rtld_load_needed_objects(Obj_Entry *first, int mode)
+_rtld_load_needed_objects(Obj_Entry *first, int flags)
{
Obj_Entry *obj;
int status = 0;
@@ -287,11 +300,25 @@
for (needed = obj->needed; needed != NULL;
needed = needed->next) {
const char *name = obj->strtab + needed->name;
- if (!_rtld_load_by_name(name, obj, &needed, mode))
+#ifdef RTLD_LOADER
+ Obj_Entry *nobj;
+#endif
+ if (!_rtld_load_by_name(name, obj, &needed,
+ flags & ~_RTLD_NOLOAD))
status = -1; /* FIXME - cleanup */
#ifdef RTLD_LOADER
if (status == -1)
return status;
+
+ if (flags & _RTLD_MAIN)
+ continue;
+
+ nobj = needed->obj;
+ if (nobj->z_nodelete && !obj->ref_nodel) {
+ dbg(("obj %s nodelete", nobj->path));
+ _rtld_ref_dag(nobj);
+ nobj->ref_nodel = true;
+ }
#endif
}
}
@@ -310,7 +337,7 @@
if (preload_path != NULL && *preload_path != '\0') {
cp = buf = xstrdup(preload_path);
while ((path = strsep(&cp, " :")) != NULL && status == 0) {
- if (!_rtld_load_object(path, RTLD_MAIN))
+ if (!_rtld_load_object(path, _RTLD_MAIN))
status = -1;
else
dbg((" preloaded \"%s\"", path));
diff -r fbef68fb0d56 -r 466ddeff3880 libexec/ld.elf_so/reloc.c
--- a/libexec/ld.elf_so/reloc.c Fri Dec 24 10:11:39 2010 +0000
+++ b/libexec/ld.elf_so/reloc.c Fri Dec 24 12:41:42 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: reloc.c,v 1.102 2010/04/05 14:01:26 joerg Exp $ */
+/* $NetBSD: reloc.c,v 1.103 2010/12/24 12:41:43 skrll Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -39,7 +39,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: reloc.c,v 1.102 2010/04/05 14:01:26 joerg Exp $");
+__RCSID("$NetBSD: reloc.c,v 1.103 2010/12/24 12:41:43 skrll Exp $");
#endif /* not lint */
#include <err.h>
@@ -195,7 +195,7 @@
#if defined(__hppa__)
bind_now = 1;
#endif
- if (bind_now) {
+ if (obj->z_now || bind_now) {
dbg(("doing immediate PLT binding"));
if (_rtld_relocate_plt_objects(obj) < 0)
ok = 0;
diff -r fbef68fb0d56 -r 466ddeff3880 libexec/ld.elf_so/rtld.c
--- a/libexec/ld.elf_so/rtld.c Fri Dec 24 10:11:39 2010 +0000
+++ b/libexec/ld.elf_so/rtld.c Fri Dec 24 12:41:42 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld.c,v 1.136 2010/12/19 17:26:51 skrll Exp $ */
+/* $NetBSD: rtld.c,v 1.137 2010/12/24 12:41:43 skrll Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: rtld.c,v 1.136 2010/12/19 17:26:51 skrll Exp $");
+__RCSID("$NetBSD: rtld.c,v 1.137 2010/12/24 12:41:43 skrll Exp $");
#endif /* not lint */
#include <err.h>
@@ -147,7 +147,7 @@
if (obj->refcount > 0 && !force) {
continue;
}
- if (obj->fini == NULL || obj->fini_called || obj->initfirst) {
+ if (obj->fini == NULL || obj->fini_called || obj->z_initfirst) {
continue;
}
dbg (("calling fini function %s at %p", obj->path,
@@ -188,7 +188,7 @@
/* First pass: objects marked with DF_1_INITFIRST. */
SIMPLEQ_FOREACH(elm, &initlist, link) {
obj = elm->obj;
- if (obj->init == NULL || obj->init_called || !obj->initfirst) {
+ if (obj->init == NULL || obj->init_called || !obj->z_initfirst) {
continue;
}
dbg (("calling init function %s at %p (DF_1_INITFIRST)",
@@ -568,7 +568,7 @@
}
dbg(("loading needed objects"));
- if (_rtld_load_needed_objects(_rtld_objmain, RTLD_MAIN) == -1)
Home |
Main Index |
Thread Index |
Old Index