diff options
Diffstat (limited to 'libebl')
-rw-r--r-- | libebl/Makefile.am | 2 | ||||
-rw-r--r-- | libebl/ebl-hooks.h | 9 | ||||
-rw-r--r-- | libebl/eblgetsymbol.c | 57 | ||||
-rw-r--r-- | libebl/libebl.h | 28 | ||||
-rw-r--r-- | libebl/libeblP.h | 3 |
5 files changed, 98 insertions, 1 deletions
diff --git a/libebl/Makefile.am b/libebl/Makefile.am index 4487c5f9..1fb3da31 100644 --- a/libebl/Makefile.am +++ b/libebl/Makefile.am @@ -54,7 +54,7 @@ gen_SOURCES = eblopenbackend.c eblclosebackend.c eblstrtab.c \ eblreginfo.c eblnonerelocp.c eblrelativerelocp.c \ eblsysvhashentrysize.c eblauxvinfo.c eblcheckobjattr.c \ ebl_check_special_section.c ebl_syscall_abi.c eblabicfi.c \ - eblstother.c eblinitreg.c + eblstother.c eblinitreg.c eblgetsymbol.c libebl_a_SOURCES = $(gen_SOURCES) diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h index cb52fee4..7204514b 100644 --- a/libebl/ebl-hooks.h +++ b/libebl/ebl-hooks.h @@ -162,5 +162,14 @@ bool EBLHOOK(set_initial_registers_tid) (pid_t tid, ebl_tid_registers_t *setfunc, void *arg); +/* See ebl_init_symbols. */ +bool EBLHOOK(init_symbols) (Ebl *ebl, size_t syments, GElf_Addr main_bias, + ebl_getsym_t *getsym, void *arg, + size_t *ebl_symentsp, int *ebl_first_globalp); + +/* See ebl_get_symbol. */ +const char *EBLHOOK(get_symbol) (Ebl *ebl, size_t ndx, GElf_Sym *symp, + GElf_Word *shndxp); + /* Destructor for ELF backend handle. */ void EBLHOOK(destr) (struct ebl *); diff --git a/libebl/eblgetsymbol.c b/libebl/eblgetsymbol.c new file mode 100644 index 00000000..ef664bf6 --- /dev/null +++ b/libebl/eblgetsymbol.c @@ -0,0 +1,57 @@ +/* Provide virtual symbols from backend. + Copyright (C) 2013 Red Hat, Inc. + This file is part of elfutils. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at + your option) any later version + + or both in parallel, as here. + + elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libeblP.h> +#include <assert.h> + +bool +ebl_init_symbols (Ebl *ebl, size_t syments, GElf_Addr main_bias, + ebl_getsym_t *getsym, void *arg, size_t *ebl_symentsp, + int *ebl_first_globalp) +{ + *ebl_symentsp = 0; + *ebl_first_globalp = 0; + if (ebl == NULL) + return false; + if (ebl->init_symbols == NULL) + return true; + return ebl->init_symbols (ebl, syments, main_bias, getsym, arg, ebl_symentsp, + ebl_first_globalp); +} + +const char * +ebl_get_symbol (Ebl *ebl, size_t ndx, GElf_Sym *symp, GElf_Word *shndxp) +{ + if (ebl == NULL || ebl->get_symbol == NULL) + return NULL; + return ebl->get_symbol (ebl, ndx, symp, shndxp); +} diff --git a/libebl/libebl.h b/libebl/libebl.h index 045a1980..d8171532 100644 --- a/libebl/libebl.h +++ b/libebl/libebl.h @@ -402,6 +402,34 @@ extern bool ebl_set_initial_registers_tid (Ebl *ebl, extern size_t ebl_frame_nregs (Ebl *ebl) __nonnull_attribute__ (1); +/* Callback type for ebl_init_symbols, + it is forwarded to dwfl_module_getsym_elf. */ +typedef const char *(ebl_getsym_t) (void *arg, int ndx, GElf_Sym *symp, + GElf_Word *shndxp, Elf **elfp) + __nonnull_attribute__ (3); + +/* Initialize virtual backend symbol table for EBL->elf currently containing + SYMENTS symbols, EBL->elf is using MAIN_BIAS. GETSYM is a callback to fetch + the existing EBL->elf symbols, ARG is an opaque parameter for GETSYM. + Fill in *EBL_SYMENTSP with the total number of virtual symbols found, + *EBL_FIRST_GLOBALP of them are local. Function must be called exactly once + for new EBL. Function returns false if there was an error; *EBL_SYMENTSP + and *EBL_FIRST_GLOBALP are left as zero in such case. If function returns + true (success) *EBL_SYMENTSP and *EBL_FIRST_GLOBALP still can be zero, + if the file does not contain any matching symbols. */ +extern bool ebl_init_symbols (Ebl *ebl, size_t syments, Dwarf_Addr symbias, + ebl_getsym_t *getsym, void *arg, + size_t *ebl_symentsp, int *ebl_first_globalp) + __nonnull_attribute__ (1, 4, 6, 7); + +/* Return NDXth virtual backend symbol from MOD, store it to *SYM and its + section to *SHNDX. Return its name. NDX must be less than *EBL_SYMENTSP + returned by init_symbols above. SHNDXP may be NULL. Returned name is valid + as long as EBL is valid. */ +extern const char *ebl_get_symbol (Ebl *ebl, size_t ndx, GElf_Sym *symp, + GElf_Word *shndxp) + __nonnull_attribute__ (1, 3); + #ifdef __cplusplus } #endif diff --git a/libebl/libeblP.h b/libebl/libeblP.h index 4f4137d5..32820507 100644 --- a/libebl/libeblP.h +++ b/libebl/libeblP.h @@ -66,6 +66,9 @@ struct ebl /* Internal data. */ void *dlhandle; + + /* Data specific to the backend. */ + void *backend; }; |