summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authorsjg <sjg@FreeBSD.org>2013-10-13 02:35:19 +0000
committersjg <sjg@FreeBSD.org>2013-10-13 02:35:19 +0000
commit7fcd33c1faf567506b5c0b4148c7a15a10788a5d (patch)
tree2c6f4d1ca5d1c643faea64e1f4c90105a1ab406a /libexec
parent2a59274eda20cc626e28052fff7aa8b7bf6a3683 (diff)
parent5cca672bb0892f1c5da630c34a1f98e2de4d7064 (diff)
downloadFreeBSD-src-7fcd33c1faf567506b5c0b4148c7a15a10788a5d.zip
FreeBSD-src-7fcd33c1faf567506b5c0b4148c7a15a10788a5d.tar.gz
Merge head@256284
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/libmap.c2
-rw-r--r--libexec/rtld-elf/libmap.h2
-rw-r--r--libexec/rtld-elf/rtld.c50
-rw-r--r--libexec/rtld-elf/rtld.h1
4 files changed, 39 insertions, 16 deletions
diff --git a/libexec/rtld-elf/libmap.c b/libexec/rtld-elf/libmap.c
index 29dc538..2e1f3c6 100644
--- a/libexec/rtld-elf/libmap.c
+++ b/libexec/rtld-elf/libmap.c
@@ -396,7 +396,6 @@ lm_find (const char *p, const char *f)
/* Given a libmap translation list and a library name, return the
replacement library, or NULL */
-#ifdef COMPAT_32BIT
char *
lm_findn (const char *p, const char *f, const int n)
{
@@ -413,7 +412,6 @@ lm_findn (const char *p, const char *f, const int n)
free(s);
return (t);
}
-#endif
static char *
lml_find (struct lm_list *lmh, const char *f)
diff --git a/libexec/rtld-elf/libmap.h b/libexec/rtld-elf/libmap.h
index 53b2ba1..54b4a2f 100644
--- a/libexec/rtld-elf/libmap.h
+++ b/libexec/rtld-elf/libmap.h
@@ -5,6 +5,4 @@
int lm_init (char *);
void lm_fini (void);
char * lm_find (const char *, const char *);
-#ifdef COMPAT_32BIT
char * lm_findn (const char *, const char *, const int);
-#endif
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 2da990c..fa6dc2a 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -116,6 +116,7 @@ static Objlist_Entry *objlist_find(Objlist *, const Obj_Entry *);
static void objlist_init(Objlist *);
static void objlist_push_head(Objlist *, Obj_Entry *);
static void objlist_push_tail(Objlist *, Obj_Entry *);
+static void objlist_put_after(Objlist *, Obj_Entry *, Obj_Entry *);
static void objlist_remove(Objlist *, Obj_Entry *);
static void *path_enumerate(const char *, path_enum_proc, void *);
static int relocate_object_dag(Obj_Entry *root, bool bind_now,
@@ -323,6 +324,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
Objlist_Entry *entry;
Obj_Entry *obj;
Obj_Entry **preload_tail;
+ Obj_Entry *last_interposer;
Objlist initlist;
RtldLockState lockstate;
char *library_path_rpath;
@@ -537,8 +539,14 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
die();
/* Make a list of all objects loaded at startup. */
+ last_interposer = obj_main;
for (obj = obj_list; obj != NULL; obj = obj->next) {
- objlist_push_tail(&list_main, obj);
+ if (obj->z_interpose && obj != obj_main) {
+ objlist_put_after(&list_main, last_interposer, obj);
+ last_interposer = obj;
+ } else {
+ objlist_push_tail(&list_main, obj);
+ }
obj->refcount++;
}
@@ -1111,11 +1119,7 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
break;
case DT_MIPS_RLD_MAP:
-#ifdef notyet
- if (!early)
- dbg("Filling in DT_DEBUG entry");
- ((Elf_Dyn*)dynp)->d_un.d_ptr = (Elf_Addr) &r_debug;
-#endif
+ *((Elf_Addr *)(dynp->d_un.d_ptr)) = (Elf_Addr) &r_debug;
break;
#endif
@@ -1132,6 +1136,8 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
obj->z_nodelete = true;
if (dynp->d_un.d_val & DF_1_LOADFLTR)
obj->z_loadfltr = true;
+ if (dynp->d_un.d_val & DF_1_INTERPOSE)
+ obj->z_interpose = true;
if (dynp->d_un.d_val & DF_1_NODEFLIB)
obj->z_nodeflib = true;
break;
@@ -1980,6 +1986,7 @@ static int
load_preload_objects(void)
{
char *p = ld_preload;
+ Obj_Entry *obj;
static const char delim[] = " \t:;";
if (p == NULL)
@@ -1992,8 +1999,10 @@ load_preload_objects(void)
savech = p[len];
p[len] = '\0';
- if (load_object(p, -1, NULL, 0) == NULL)
+ obj = load_object(p, -1, NULL, 0);
+ if (obj == NULL)
return -1; /* XXX - cleanup */
+ obj->z_interpose = true;
p[len] = savech;
p += len;
p += strspn(p, delim);
@@ -2382,6 +2391,23 @@ objlist_push_tail(Objlist *list, Obj_Entry *obj)
}
static void
+objlist_put_after(Objlist *list, Obj_Entry *listobj, Obj_Entry *obj)
+{
+ Objlist_Entry *elm, *listelm;
+
+ STAILQ_FOREACH(listelm, list, link) {
+ if (listelm->obj == listobj)
+ break;
+ }
+ elm = NEW(Objlist_Entry);
+ elm->obj = obj;
+ if (listelm != NULL)
+ STAILQ_INSERT_AFTER(list, listelm, elm, link);
+ else
+ STAILQ_INSERT_TAIL(list, elm, link);
+}
+
+static void
objlist_remove(Objlist *list, Obj_Entry *obj)
{
Objlist_Entry *elm;
@@ -2581,12 +2607,14 @@ rtld_exit(void)
lock_release(rtld_bind_lock, &lockstate);
}
+/*
+ * Iterate over a search path, translate each element, and invoke the
+ * callback on the result.
+ */
static void *
path_enumerate(const char *path, path_enum_proc callback, void *arg)
{
-#ifdef COMPAT_32BIT
const char *trans;
-#endif
if (path == NULL)
return (NULL);
@@ -2596,13 +2624,11 @@ path_enumerate(const char *path, path_enum_proc callback, void *arg)
char *res;
len = strcspn(path, ":;");
-#ifdef COMPAT_32BIT
trans = lm_findn(NULL, path, len);
if (trans)
res = callback(trans, strlen(trans), arg);
else
-#endif
- res = callback(path, len, arg);
+ res = callback(path, len, arg);
if (res != NULL)
return (res);
diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h
index 0aba7cd..083f5a4 100644
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -259,6 +259,7 @@ typedef struct Struct_Obj_Entry {
bool z_nodelete : 1; /* Do not unload the object and dependencies */
bool z_noopen : 1; /* Do not load on dlopen */
bool z_loadfltr : 1; /* Immediately load filtees */
+ bool z_interpose : 1; /* Interpose all objects but main */
bool z_nodeflib : 1; /* Don't search default library path */
bool ref_nodel : 1; /* Refcount increased to prevent dlclose */
bool init_scanned: 1; /* Object is already on init list. */
OpenPOWER on IntegriCloud