git: ecd8245e0d77 - main - Kernel linkers: add emergency sysctl to restore old behavior

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Wed, 08 Dec 2021 21:59:29 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=ecd8245e0d7784bcd78dafce233f303eee765068

commit ecd8245e0d7784bcd78dafce233f303eee765068
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-11-07 09:26:26 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2021-12-08 21:32:30 +0000

    Kernel linkers: add emergency sysctl to restore old behavior
    
    allowing linking to static symbols from other files.  Default the new
    settings to true, delaying the change of the kernel linker behavior
    for other day.
    
    Suggested by:   emaste
    PR:     207898
    Reviewed by:    emaste, markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D32878
---
 sys/kern/link_elf.c     |  9 +++++++++
 sys/kern/link_elf_obj.c | 12 ++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c
index dc8002be0e89..cbd30bef4087 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 ec2319ffad47..9be5f7913b49 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