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
This commit is contained in:
Konstantin Belousov 2021-11-07 11:26:26 +02:00
parent 95c20faf11
commit ecd8245e0d
2 changed files with 19 additions and 2 deletions

View File

@ -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));
}

View File

@ -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