Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F133125532
D32878.id99649.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D32878.id99649.diff
View Options
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -912,7 +912,7 @@
linker_file_t lf;
TAILQ_FOREACH(lf, &linker_files, link) {
- if (LINKER_LOOKUP_SYMBOL(lf, symstr, sym) == 0)
+ if (LINKER_LOOKUP_DEBUG_SYMBOL(lf, symstr, sym) == 0)
return (0);
}
return (ENOENT);
@@ -956,7 +956,7 @@
linker_file_t lf;
TAILQ_FOREACH(lf, &linker_files, link) {
- if (LINKER_SYMBOL_VALUES(lf, sym, symval) == 0)
+ if (LINKER_DEBUG_SYMBOL_VALUES(lf, sym, symval) == 0)
return (0);
}
return (ENOENT);
diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c
--- a/sys/kern/link_elf.c
+++ b/sys/kern/link_elf.c
@@ -144,8 +144,12 @@
linker_file_t *);
static int link_elf_lookup_symbol(linker_file_t, const char *,
c_linker_sym_t *);
+static int link_elf_lookup_debug_symbol(linker_file_t, const char *,
+ c_linker_sym_t *);
static int link_elf_symbol_values(linker_file_t, c_linker_sym_t,
linker_symval_t *);
+static int link_elf_debug_symbol_values(linker_file_t, c_linker_sym_t,
+ linker_symval_t*);
static int link_elf_search_symbol(linker_file_t, caddr_t,
c_linker_sym_t *, long *);
@@ -164,7 +168,9 @@
static kobj_method_t link_elf_methods[] = {
KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol),
+ KOBJMETHOD(linker_lookup_debug_symbol, link_elf_lookup_debug_symbol),
KOBJMETHOD(linker_symbol_values, link_elf_symbol_values),
+ KOBJMETHOD(linker_debug_symbol_values, link_elf_debug_symbol_values),
KOBJMETHOD(linker_search_symbol, link_elf_search_symbol),
KOBJMETHOD(linker_unload, link_elf_unload_file),
KOBJMETHOD(linker_load_file, link_elf_load_file),
@@ -188,6 +194,11 @@
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);
@@ -1490,14 +1501,14 @@
}
static int
-link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym)
+link_elf_lookup_symbol1(linker_file_t lf, const char *name, c_linker_sym_t *sym,
+ bool see_local)
{
elf_file_t ef = (elf_file_t) lf;
unsigned long symnum;
const Elf_Sym* symp;
const char *strp;
unsigned long hash;
- int i;
/* If we don't have a hash, bail. */
if (ef->buckets == NULL || ef->nbuckets == 0) {
@@ -1528,8 +1539,11 @@
(symp->st_value != 0 &&
(ELF_ST_TYPE(symp->st_info) == STT_FUNC ||
ELF_ST_TYPE(symp->st_info) == STT_GNU_IFUNC))) {
- *sym = (c_linker_sym_t) symp;
- return (0);
+ if (see_local ||
+ ELF_ST_BIND(symp->st_info) != STB_LOCAL) {
+ *sym = (c_linker_sym_t) symp;
+ return (0);
+ }
}
return (ENOENT);
}
@@ -1537,11 +1551,29 @@
symnum = ef->chains[symnum];
}
- /* If we have not found it, look at the full table (if loaded) */
- if (ef->symtab == ef->ddbsymtab)
- return (ENOENT);
+ return (ENOENT);
+}
+
+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));
+}
+
+static int
+link_elf_lookup_debug_symbol(linker_file_t lf, const char *name,
+ c_linker_sym_t *sym)
+{
+ elf_file_t ef = (elf_file_t)lf;
+ const Elf_Sym* symp;
+ const char *strp;
+ int i;
+
+ if (link_elf_lookup_symbol1(lf, name, sym, true) == 0)
+ return (0);
- /* Exhaustive search */
for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
strp = ef->ddbstrtab + symp->st_name;
if (strcmp(name, strp) == 0) {
@@ -1560,8 +1592,8 @@
}
static int
-link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym,
- linker_symval_t *symval)
+link_elf_symbol_values1(linker_file_t lf, c_linker_sym_t sym,
+ linker_symval_t *symval, bool see_local)
{
elf_file_t ef;
const Elf_Sym *es;
@@ -1569,7 +1601,9 @@
ef = (elf_file_t)lf;
es = (const Elf_Sym *)sym;
- if (es >= ef->symtab && es < (ef->symtab + ef->nchains)) {
+ if (es >= ef->symtab && es < ef->symtab + ef->nchains) {
+ if (!see_local && ELF_ST_BIND(es->st_info) == STB_LOCAL)
+ return (ENOENT);
symval->name = ef->strtab + es->st_name;
val = (caddr_t)ef->address + es->st_value;
if (ELF_ST_TYPE(es->st_info) == STT_GNU_IFUNC)
@@ -1578,8 +1612,31 @@
symval->size = es->st_size;
return (0);
}
+ return (ENOENT);
+}
+
+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));
+}
+
+static int
+link_elf_debug_symbol_values(linker_file_t lf, c_linker_sym_t sym,
+ linker_symval_t *symval)
+{
+ elf_file_t ef = (elf_file_t)lf;
+ const Elf_Sym *es = (const Elf_Sym *)sym;
+ caddr_t val;
+
+ if (link_elf_symbol_values1(lf, sym, symval, true) == 0)
+ return (0);
if (ef->symtab == ef->ddbsymtab)
return (ENOENT);
+
if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) {
symval->name = ef->ddbstrtab + es->st_name;
val = (caddr_t)ef->address + es->st_value;
@@ -1597,7 +1654,7 @@
c_linker_sym_t *sym, long *diffp)
{
elf_file_t ef = (elf_file_t)lf;
- u_long off = (uintptr_t) (void *)value;
+ u_long off = (uintptr_t)(void *)value;
u_long diff = off;
u_long st_value;
const Elf_Sym *es;
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
--- a/sys/kern/link_elf_obj.c
+++ b/sys/kern/link_elf_obj.c
@@ -44,6 +44,7 @@
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/rwlock.h>
+#include <sys/sysctl.h>
#include <sys/vnode.h>
#include <machine/elf.h>
@@ -131,8 +132,12 @@
static int link_elf_load_file(linker_class_t, const char *, linker_file_t *);
static int link_elf_lookup_symbol(linker_file_t, const char *,
c_linker_sym_t *);
+static int link_elf_lookup_debug_symbol(linker_file_t, const char *,
+ c_linker_sym_t *);
static int link_elf_symbol_values(linker_file_t, c_linker_sym_t,
linker_symval_t *);
+static int link_elf_debug_symbol_values(linker_file_t, c_linker_sym_t,
+ linker_symval_t *);
static int link_elf_search_symbol(linker_file_t, caddr_t value,
c_linker_sym_t *sym, long *diffp);
@@ -153,7 +158,9 @@
static kobj_method_t link_elf_methods[] = {
KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol),
+ KOBJMETHOD(linker_lookup_debug_symbol, link_elf_lookup_debug_symbol),
KOBJMETHOD(linker_symbol_values, link_elf_symbol_values),
+ KOBJMETHOD(linker_debug_symbol_values, link_elf_debug_symbol_values),
KOBJMETHOD(linker_search_symbol, link_elf_search_symbol),
KOBJMETHOD(linker_unload, link_elf_unload_file),
KOBJMETHOD(linker_load_file, link_elf_load_file),
@@ -177,6 +184,11 @@
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);
@@ -1424,9 +1436,10 @@
}
static int
-link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym)
+link_elf_lookup_symbol1(linker_file_t lf, const char *name, c_linker_sym_t *sym,
+ bool see_local)
{
- elf_file_t ef = (elf_file_t) lf;
+ elf_file_t ef = (elf_file_t)lf;
const Elf_Sym *symp;
const char *strp;
int i;
@@ -1434,16 +1447,34 @@
for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) {
strp = ef->ddbstrtab + symp->st_name;
if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0) {
- *sym = (c_linker_sym_t) symp;
- return 0;
+ if (see_local ||
+ ELF_ST_BIND(symp->st_info) == STB_GLOBAL) {
+ *sym = (c_linker_sym_t) symp;
+ return (0);
+ }
+ return (ENOENT);
}
}
return (ENOENT);
}
static int
-link_elf_symbol_values(linker_file_t lf, c_linker_sym_t sym,
- linker_symval_t *symval)
+link_elf_lookup_symbol(linker_file_t lf, const char *name, c_linker_sym_t *sym)
+{
+ return (link_elf_lookup_symbol1(lf, name, sym,
+ link_elf_obj_leak_locals));
+}
+
+static int
+link_elf_lookup_debug_symbol(linker_file_t lf, const char *name,
+ c_linker_sym_t *sym)
+{
+ return (link_elf_lookup_symbol1(lf, name, sym, true));
+}
+
+static int
+link_elf_symbol_values1(linker_file_t lf, c_linker_sym_t sym,
+ linker_symval_t *symval, bool see_local)
{
elf_file_t ef;
const Elf_Sym *es;
@@ -1453,6 +1484,8 @@
es = (const Elf_Sym*) sym;
val = (caddr_t)es->st_value;
if (es >= ef->ddbsymtab && es < (ef->ddbsymtab + ef->ddbsymcnt)) {
+ if (!see_local && ELF_ST_BIND(es->st_info) == STB_LOCAL)
+ return (ENOENT);
symval->name = ef->ddbstrtab + es->st_name;
val = (caddr_t)es->st_value;
if (ELF_ST_TYPE(es->st_info) == STT_GNU_IFUNC)
@@ -1464,6 +1497,21 @@
return (ENOENT);
}
+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,
+ link_elf_obj_leak_locals));
+}
+
+static int
+link_elf_debug_symbol_values(linker_file_t lf, c_linker_sym_t sym,
+ linker_symval_t *symval)
+{
+ return (link_elf_symbol_values1(lf, sym, symval, true));
+}
+
static int
link_elf_search_symbol(linker_file_t lf, caddr_t value,
c_linker_sym_t *sym, long *diffp)
diff --git a/sys/kern/linker_if.m b/sys/kern/linker_if.m
--- a/sys/kern/linker_if.m
+++ b/sys/kern/linker_if.m
@@ -40,12 +40,24 @@
c_linker_sym_t* symp;
};
+METHOD int lookup_debug_symbol {
+ linker_file_t file;
+ const char* name;
+ c_linker_sym_t* symp;
+};
+
METHOD int symbol_values {
linker_file_t file;
c_linker_sym_t sym;
linker_symval_t* valp;
};
+METHOD int debug_symbol_values {
+ linker_file_t file;
+ c_linker_sym_t sym;
+ linker_symval_t* valp;
+};
+
METHOD int search_symbol {
linker_file_t file;
caddr_t value;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Oct 24, 4:35 AM (8 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24119411
Default Alt Text
D32878.id99649.diff (10 KB)
Attached To
Mode
D32878: kernel linker: do not read debug symbol tables for non-debug symbols
Attached
Detach File
Event Timeline
Log In to Comment