diff options
Diffstat (limited to 'sys/kern/link_elf.c')
-rw-r--r-- | sys/kern/link_elf.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c index 89a8971..bdaa636 100644 --- a/sys/kern/link_elf.c +++ b/sys/kern/link_elf.c @@ -27,6 +27,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_ddb.h" #include "opt_gdb.h" #include "opt_mac.h" @@ -62,6 +63,10 @@ __FBSDID("$FreeBSD$"); #include <sys/link_elf.h> +#ifdef DDB_CTF +#include <net/zlib.h> +#endif + #include "linker_if.h" #define MAXSEGS 4 @@ -98,11 +103,18 @@ typedef struct elf_file { long ddbstrcnt; /* number of bytes in string table */ caddr_t symbase; /* malloc'ed symbold base */ caddr_t strbase; /* malloc'ed string base */ + caddr_t ctftab; /* CTF table */ + long ctfcnt; /* number of bytes in CTF table */ + caddr_t ctfoff; /* CTF offset table */ + caddr_t typoff; /* Type offset table */ + long typlen; /* Number of type entries. */ #ifdef GDB struct link_map gdb; /* hooks for gdb */ #endif } *elf_file_t; +#include <kern/kern_ctf.c> + static int link_elf_link_common_finish(linker_file_t); static int link_elf_link_preload(linker_class_t cls, const char*, linker_file_t*); @@ -121,6 +133,9 @@ static int link_elf_lookup_set(linker_file_t, const char *, static int link_elf_each_function_name(linker_file_t, int (*)(const char *, void *), void *); +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 Elf_Addr elf_lookup(linker_file_t lf, Elf_Size symidx, int deps); @@ -134,6 +149,8 @@ static kobj_method_t link_elf_methods[] = { 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), + KOBJMETHOD(linker_each_function_nameval, link_elf_each_function_nameval), + KOBJMETHOD(linker_ctf_get, link_elf_ctf_get), { 0, 0 } }; @@ -910,6 +927,12 @@ link_elf_unload_file(linker_file_t file) free(ef->symbase, M_LINKER); if (ef->strbase) free(ef->strbase, M_LINKER); + if (ef->ctftab) + free(ef->ctftab, M_LINKER); + if (ef->ctfoff) + free(ef->ctfoff, M_LINKER); + if (ef->typoff) + free(ef->typoff, M_LINKER); } static void @@ -1227,6 +1250,30 @@ link_elf_each_function_name(linker_file_t file, return (0); } +static int +link_elf_each_function_nameval(linker_file_t file, + linker_function_nameval_callback_t callback, void *opaque) +{ + linker_symval_t symval; + 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 = link_elf_symbol_values(file, (c_linker_sym_t) symp, &symval); + if (error) + return (error); + error = callback(file, i, &symval, opaque); + if (error) + return (error); + } + } + return (0); +} + #ifdef __ia64__ /* * Each KLD has its own GP. The GP value for each load module is given by |