Module Name: src
Committed By: skrll
Date: Sun Jan 10 07:29:47 UTC 2010
Modified Files:
src/libexec/ld.elf_so: map_object.c rtld.h symbol.c
Log Message:
Reset the COMBRELOC cache Obj_Entry if it was freed.
Fixes PR 41482. Done slightly differently to the patch in the PR.
To generate a diff of this commit:
cvs rdiff -u -r1.38 -r1.39 src/libexec/ld.elf_so/map_object.c
cvs rdiff -u -r1.82 -r1.83 src/libexec/ld.elf_so/rtld.h
cvs rdiff -u -r1.48 -r1.49 src/libexec/ld.elf_so/symbol.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/libexec/ld.elf_so/map_object.c
diff -u src/libexec/ld.elf_so/map_object.c:1.38 src/libexec/ld.elf_so/map_object.c:1.39
--- src/libexec/ld.elf_so/map_object.c:1.38 Tue May 19 20:44:52 2009
+++ src/libexec/ld.elf_so/map_object.c Sun Jan 10 07:29:47 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: map_object.c,v 1.38 2009/05/19 20:44:52 christos Exp $ */
+/* $NetBSD: map_object.c,v 1.39 2010/01/10 07:29:47 skrll Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -34,7 +34,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: map_object.c,v 1.38 2009/05/19 20:44:52 christos Exp $");
+__RCSID("$NetBSD: map_object.c,v 1.39 2010/01/10 07:29:47 skrll Exp $");
#endif /* not lint */
#include <errno.h>
@@ -325,6 +325,9 @@
xfree(elm);
}
xfree(obj);
+#ifdef COMBRELOC
+ _rtld_combreloc_reset(obj);
+#endif
}
Obj_Entry *
Index: src/libexec/ld.elf_so/rtld.h
diff -u src/libexec/ld.elf_so/rtld.h:1.82 src/libexec/ld.elf_so/rtld.h:1.83
--- src/libexec/ld.elf_so/rtld.h:1.82 Tue Nov 17 18:44:33 2009
+++ src/libexec/ld.elf_so/rtld.h Sun Jan 10 07:29:47 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld.h,v 1.82 2009/11/17 18:44:33 skrll Exp $ */
+/* $NetBSD: rtld.h,v 1.83 2010/01/10 07:29:47 skrll Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -278,6 +278,9 @@
const Obj_Entry *, const Obj_Entry **, bool);
const Elf_Sym *_rtld_symlook_needed(const char *, unsigned long,
const Needed_Entry *, const Obj_Entry **, bool);
+#ifdef COMBRELOC
+void _rtld_combreloc_reset(const Obj_Entry *);
+#endif
/* map_object.c */
Obj_Entry *_rtld_map_object(const char *, int, const struct stat *);
Index: src/libexec/ld.elf_so/symbol.c
diff -u src/libexec/ld.elf_so/symbol.c:1.48 src/libexec/ld.elf_so/symbol.c:1.49
--- src/libexec/ld.elf_so/symbol.c:1.48 Thu Sep 24 21:21:34 2009
+++ src/libexec/ld.elf_so/symbol.c Sun Jan 10 07:29:47 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: symbol.c,v 1.48 2009/09/24 21:21:34 pooka Exp $ */
+/* $NetBSD: symbol.c,v 1.49 2010/01/10 07:29:47 skrll Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: symbol.c,v 1.48 2009/09/24 21:21:34 pooka Exp $");
+__RCSID("$NetBSD: symbol.c,v 1.49 2010/01/10 07:29:47 skrll Exp $");
#endif /* not lint */
#include <err.h>
@@ -236,6 +236,21 @@
return NULL;
}
+#ifdef COMBRELOC
+static const Obj_Entry *_rtld_last_refobj;
+
+/*
+ * Called when an object is freed. Reset the cached symbol look up if
+ * our last referencing or definition object just got unloaded.
+ */
+void
+_rtld_combreloc_reset(const Obj_Entry *obj)
+{
+ if (_rtld_last_refobj == obj)
+ _rtld_last_refobj = NULL;
+}
+#endif
+
/*
* Given a symbol number in a referencing object, find the corresponding
* definition of the symbol. Returns a pointer to the symbol, or NULL if
@@ -261,11 +276,10 @@
* return the cached results.
*/
static unsigned long last_symnum;
- static const Elf_Sym *last_def;
- static const Obj_Entry *last_refobj;
static const Obj_Entry *last_defobj;
+ static const Elf_Sym *last_def;
- if (symnum == last_symnum && refobj == last_refobj
+ if (symnum == last_symnum && refobj == _rtld_last_refobj
&& in_plt == false) {
*defobj_out = last_defobj;
return last_def;
@@ -319,7 +333,7 @@
* non-PLT lookup.
*/
last_symnum = symnum;
- last_refobj = refobj;
+ _rtld_last_refobj = refobj;
last_def = def;
last_defobj = defobj;
}