aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2021-11-07 09:26:26 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2021-12-15 01:41:29 +0000
commit4305fd126c77143f3f3205e201ec413ae2012a0f (patch)
tree4ae28cb07f705be678fa6a57cee0ec1c01e30abb
parentda536d64b7ee713d0299d817db172ab0352d26a2 (diff)
downloadsrc-4305fd126c77143f3f3205e201ec413ae2012a0f.tar.gz
src-4305fd126c77143f3f3205e201ec413ae2012a0f.zip
Kernel linkers: add emergency sysctl to restore old behavior
PR: 207898 (cherry picked from commit ecd8245e0d7784bcd78dafce233f303eee765068)
-rw-r--r--sys/kern/link_elf.c9
-rw-r--r--sys/kern/link_elf_obj.c12
2 files changed, 19 insertions, 2 deletions
diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c
index 445260246946..245c8697cf79 100644
--- a/sys/kern/link_elf.c
+++ b/sys/kern/link_elf.c
@@ -194,6 +194,11 @@ static struct linker_class link_elf_class = {
link_elf_methods, sizeof(struct elf_file)
};
+static bool link_elf_leak_locals = true;
+SYSCTL_BOOL(_debug, OID_AUTO, link_elf_leak_locals,
+ CTLFLAG_RWTUN, &link_elf_leak_locals, 0,
+ "Allow local symbols to participate in global module symbol resolution");
+
typedef int (*elf_reloc_fn)(linker_file_t lf, Elf_Addr relocbase,
const void *data, int type, elf_lookup_fn lookup);
@@ -1552,6 +1557,8 @@ link_elf_lookup_symbol1(linker_file_t lf, const char *name, c_linker_sym_t *sym,
static int
link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym)
{
+ if (link_elf_leak_locals)
+ return (link_elf_lookup_debug_symbol(lf, name, sym));
return (link_elf_lookup_symbol1(lf, name, sym, false));
}
@@ -1612,6 +1619,8 @@ static int
link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym,
linker_symval_t *symval)
{
+ if (link_elf_leak_locals)
+ return (link_elf_debug_symbol_values(lf, sym, symval));
return (link_elf_symbol_values1(lf, sym, symval, false));
}
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
index 2c1b7713c346..689aeae86840 100644
--- a/sys/kern/link_elf_obj.c
+++ b/sys/kern/link_elf_obj.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/rwlock.h>
+#include <sys/sysctl.h>
#include <sys/vnode.h>
#include <machine/elf.h>
@@ -183,6 +184,11 @@ static struct linker_class link_elf_class = {
link_elf_methods, sizeof(struct elf_file)
};
+static bool link_elf_obj_leak_locals = true;
+SYSCTL_BOOL(_debug, OID_AUTO, link_elf_obj_leak_locals,
+ CTLFLAG_RWTUN, &link_elf_obj_leak_locals, 0,
+ "Allow local symbols to participate in global module symbol resolution");
+
static int relocate_file(elf_file_t ef);
static void elf_obj_cleanup_globals_cache(elf_file_t);
@@ -1455,7 +1461,8 @@ link_elf_lookup_symbol1(linker_file_t lf, const char *name, c_linker_sym_t *sym,
static int
link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym)
{
- return (link_elf_lookup_symbol1(lf, name, sym, false));
+ return (link_elf_lookup_symbol1(lf, name, sym,
+ link_elf_obj_leak_locals));
}
static int
@@ -1494,7 +1501,8 @@ static int
link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym,
linker_symval_t *symval)
{
- return (link_elf_symbol_values1(lf, sym, symval, false));
+ return (link_elf_symbol_values1(lf, sym, symval,
+ link_elf_obj_leak_locals));
}
static int