summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorsson <sson@FreeBSD.org>2009-05-26 21:39:09 +0000
committersson <sson@FreeBSD.org>2009-05-26 21:39:09 +0000
commit527dd575556c8d79007e7a35cd752f1b46343fd2 (patch)
tree626fb22e642e1f12607624578d9f484a88a1e405 /sys/kern
parente8484adb4444a310104af340656308e3b8d60088 (diff)
downloadFreeBSD-src-527dd575556c8d79007e7a35cd752f1b46343fd2.zip
FreeBSD-src-527dd575556c8d79007e7a35cd752f1b46343fd2.tar.gz
Add the ksyms(4) pseudo driver. The ksyms driver allows a process to
get a quick snapshot of the kernel's symbol table including the symbols from any loaded modules (the symbols are all merged into one symbol table). Unlike like other implementations, this ksyms driver maps memory in the process memory space to store the snapshot at the time /dev/ksyms is opened. It also checks to see if the process has already a snapshot open and won't allow it to open /dev/ksyms it again until it closes first. This prevents kernel and process memory from being exhausted. Note that /dev/ksyms is used by the lockstat(1) command. Reviewed by: gallatin kib (freebsd-arch) Approved by: gnn (mentor)
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/link_elf.c30
-rw-r--r--sys/kern/link_elf_obj.c30
-rw-r--r--sys/kern/linker_if.m18
3 files changed, 78 insertions, 0 deletions
diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c
index c17dd15..5ab1ce5 100644
--- a/sys/kern/link_elf.c
+++ b/sys/kern/link_elf.c
@@ -137,6 +137,8 @@ static int link_elf_each_function_nameval(linker_file_t,
linker_function_nameval_callback_t,
void *);
static void link_elf_reloc_local(linker_file_t);
+static long link_elf_symtab_get(linker_file_t, const Elf_Sym **);
+static long link_elf_strtab_get(linker_file_t, caddr_t *);
static Elf_Addr elf_lookup(linker_file_t lf, Elf_Size symidx, int deps);
static kobj_method_t link_elf_methods[] = {
@@ -151,6 +153,8 @@ static kobj_method_t link_elf_methods[] = {
KOBJMETHOD(linker_each_function_name, link_elf_each_function_name),
KOBJMETHOD(linker_each_function_nameval, link_elf_each_function_nameval),
KOBJMETHOD(linker_ctf_get, link_elf_ctf_get),
+ KOBJMETHOD(linker_symtab_get, link_elf_symtab_get),
+ KOBJMETHOD(linker_strtab_get, link_elf_strtab_get),
{ 0, 0 }
};
@@ -1390,3 +1394,29 @@ link_elf_reloc_local(linker_file_t lf)
}
}
}
+
+static long
+link_elf_symtab_get(linker_file_t lf, const Elf_Sym **symtab)
+{
+ elf_file_t ef = (elf_file_t)lf;
+
+ *symtab = ef->ddbsymtab;
+
+ if (*symtab == NULL)
+ return (0);
+
+ return (ef->ddbsymcnt);
+}
+
+static long
+link_elf_strtab_get(linker_file_t lf, caddr_t *strtab)
+{
+ elf_file_t ef = (elf_file_t)lf;
+
+ *strtab = ef->ddbstrtab;
+
+ if (*strtab == NULL)
+ return (0);
+
+ return (ef->ddbstrcnt);
+}
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
index 7734745..60c89d6 100644
--- a/sys/kern/link_elf_obj.c
+++ b/sys/kern/link_elf_obj.c
@@ -140,6 +140,8 @@ static int link_elf_each_function_nameval(linker_file_t,
linker_function_nameval_callback_t,
void *);
static void link_elf_reloc_local(linker_file_t);
+static long link_elf_symtab_get(linker_file_t, Elf_Sym **);
+static long link_elf_strtab_get(linker_file_t, caddr_t *);
static Elf_Addr elf_obj_lookup(linker_file_t lf, Elf_Size symidx, int deps);
@@ -155,6 +157,8 @@ static kobj_method_t link_elf_methods[] = {
KOBJMETHOD(linker_each_function_name, link_elf_each_function_name),
KOBJMETHOD(linker_each_function_nameval, link_elf_each_function_nameval),
KOBJMETHOD(linker_ctf_get, link_elf_ctf_get),
+ KOBJMETHOD(linker_symtab_get, link_elf_symtab_get),
+ KOBJMETHOD(linker_strtab_get, link_elf_strtab_get),
{ 0, 0 }
};
@@ -1286,3 +1290,29 @@ link_elf_reloc_local(linker_file_t lf)
}
}
}
+
+static long
+link_elf_symtab_get(linker_file_t lf, Elf_Sym **symtab)
+{
+ elf_file_t ef = (elf_file_t)lf;
+
+ *symtab = ef->ddbsymtab;
+
+ if (*symtab == NULL)
+ return (0);
+
+ return (ef->ddbsymcnt);
+}
+
+static long
+link_elf_strtab_get(linker_file_t lf, caddr_t *strtab)
+{
+ elf_file_t ef = (elf_file_t)lf;
+
+ *strtab = ef->ddbstrtab;
+
+ if (*strtab == NULL)
+ return (0);
+
+ return (ef->ddbstrcnt);
+}
diff --git a/sys/kern/linker_if.m b/sys/kern/linker_if.m
index aadcf04..379bc0e 100644
--- a/sys/kern/linker_if.m
+++ b/sys/kern/linker_if.m
@@ -105,6 +105,24 @@ METHOD int ctf_get {
};
#
+# Get the symbol table, returning it in **symtab. Return the
+# number of symbols, otherwise zero.
+#
+METHOD long symtab_get {
+ linker_file_t file;
+ Elf_Sym **symtab;
+};
+
+#
+# Get the string table, returning it in *strtab. Return the
+# size (in bytes) of the string table, otherwise zero.
+#
+METHOD long strtab_get {
+ linker_file_t file;
+ caddr_t *strtab;
+};
+
+#
# Load a file, returning the new linker_file_t in *result. If
# the class does not recognise the file type, zero should be
# returned, without modifying *result. If the file is
OpenPOWER on IntegriCloud