diff options
author | green <green@FreeBSD.org> | 2001-10-30 15:21:45 +0000 |
---|---|---|
committer | green <green@FreeBSD.org> | 2001-10-30 15:21:45 +0000 |
commit | e44401b785a1fffb6524e85f215bd99bfc778bf1 (patch) | |
tree | 04f5856e0de49a87ff73562b3145a85347ee7bcc /sys/kern/link_elf.c | |
parent | 8e31d7b2f43865c102269c5fe77a83fbc5fad376 (diff) | |
download | FreeBSD-src-e44401b785a1fffb6524e85f215bd99bfc778bf1.zip FreeBSD-src-e44401b785a1fffb6524e85f215bd99bfc778bf1.tar.gz |
Add the sysctl "kern.function_list", which currently exports all
function symbols in the kernel in a list of C strings, with an extra
nul-termination at the end.
This sysctl requires addition of a new linker operation. Now,
linker_file_t's need to respond to "each_function_name" to export
their function symbols.
Note that the sysctl doesn't currently allow distinguishing multiple
symbols with the same name from different modules, but could quite
easily without a change to the linker operation. This will be a nicety
to have when it can be used.
Obtained from: NAI Labs CBOSS project
Funded by: DARPA
Diffstat (limited to 'sys/kern/link_elf.c')
-rw-r--r-- | sys/kern/link_elf.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c index 888ce5e..5da9a83 100644 --- a/sys/kern/link_elf.c +++ b/sys/kern/link_elf.c @@ -113,6 +113,9 @@ static void link_elf_unload_file(linker_file_t); static void link_elf_unload_preload(linker_file_t); static int link_elf_lookup_set(linker_file_t, const char *, void ***, void ***, int *); +static int link_elf_each_function_name(linker_file_t, + int (*)(const char *, void *), + void *); static kobj_method_t link_elf_methods[] = { KOBJMETHOD(linker_lookup_symbol, link_elf_lookup_symbol), @@ -123,6 +126,7 @@ static kobj_method_t link_elf_methods[] = { KOBJMETHOD(linker_link_preload, link_elf_link_preload), KOBJMETHOD(linker_link_preload_finish, link_elf_link_preload_finish), KOBJMETHOD(linker_lookup_set, link_elf_lookup_set), + KOBJMETHOD(linker_each_function_name, link_elf_each_function_name), { 0, 0 } }; @@ -1149,3 +1153,22 @@ out: free(setsym, M_LINKER); return error; } + +static int +link_elf_each_function_name(linker_file_t file, + int (*callback)(const char *, void *), void *opaque) { + elf_file_t ef = (elf_file_t)file; + const Elf_Sym* symp; + int i, error; + + /* Exhaustive search */ + for (i = 0, symp = ef->ddbsymtab; i < ef->ddbsymcnt; i++, symp++) { + if (symp->st_value != 0 && + ELF_ST_TYPE(symp->st_info) == STT_FUNC) { + error = callback(ef->ddbstrtab + symp->st_name, opaque); + if (error) + return (error); + } + } + return (0); +} |