mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-23 07:31:31 +00:00
libkldelf: add see_local parameter to elf_lookup_symbol
This gives the function the ability to return only global symbols. Sponsored by: Juniper Networks, Inc. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D47206
This commit is contained in:
parent
3ceba58a75
commit
72e15f76a1
@ -81,7 +81,7 @@ static GElf_Addr ef_symaddr(elf_file_t ef, GElf_Size symidx);
|
||||
static int ef_lookup_set(elf_file_t ef, const char *name,
|
||||
GElf_Addr *startp, GElf_Addr *stopp, long *countp);
|
||||
static int ef_lookup_symbol(elf_file_t ef, const char *name,
|
||||
GElf_Sym **sym);
|
||||
GElf_Sym **sym, bool see_local);
|
||||
|
||||
static struct elf_file_ops ef_file_ops = {
|
||||
.close = ef_close,
|
||||
@ -126,7 +126,7 @@ ef_get_offset(elf_file_t ef, GElf_Addr addr)
|
||||
* next two functions copied from link_elf.c
|
||||
*/
|
||||
static int
|
||||
ef_lookup_symbol(elf_file_t ef, const char *name, GElf_Sym **sym)
|
||||
ef_lookup_symbol(elf_file_t ef, const char *name, GElf_Sym **sym, bool see_local)
|
||||
{
|
||||
unsigned long hash, symnum;
|
||||
GElf_Sym *symp;
|
||||
@ -156,8 +156,11 @@ ef_lookup_symbol(elf_file_t ef, const char *name, GElf_Sym **sym)
|
||||
if (symp->st_shndx != SHN_UNDEF ||
|
||||
(symp->st_value != 0 &&
|
||||
GELF_ST_TYPE(symp->st_info) == STT_FUNC)) {
|
||||
*sym = symp;
|
||||
return (0);
|
||||
if (see_local ||
|
||||
GELF_ST_BIND(symp->st_info) != STB_LOCAL) {
|
||||
*sym = symp;
|
||||
return (0);
|
||||
}
|
||||
} else
|
||||
return (ENOENT);
|
||||
}
|
||||
@ -183,14 +186,14 @@ ef_lookup_set(elf_file_t ef, const char *name, GElf_Addr *startp,
|
||||
|
||||
/* get address of first entry */
|
||||
snprintf(setsym, len, "%s%s", "__start_set_", name);
|
||||
error = ef_lookup_symbol(ef, setsym, &sym);
|
||||
error = ef_lookup_symbol(ef, setsym, &sym, true);
|
||||
if (error != 0)
|
||||
goto out;
|
||||
*startp = sym->st_value;
|
||||
|
||||
/* get address of last entry */
|
||||
snprintf(setsym, len, "%s%s", "__stop_set_", name);
|
||||
error = ef_lookup_symbol(ef, setsym, &sym);
|
||||
error = ef_lookup_symbol(ef, setsym, &sym, true);
|
||||
if (error != 0)
|
||||
goto out;
|
||||
*stopp = sym->st_value;
|
||||
|
@ -101,7 +101,7 @@ static GElf_Addr ef_obj_symaddr(elf_file_t ef, GElf_Size symidx);
|
||||
static int ef_obj_lookup_set(elf_file_t ef, const char *name,
|
||||
GElf_Addr *startp, GElf_Addr *stopp, long *countp);
|
||||
static int ef_obj_lookup_symbol(elf_file_t ef, const char *name,
|
||||
GElf_Sym **sym);
|
||||
GElf_Sym **sym, bool see_local);
|
||||
|
||||
static struct elf_file_ops ef_obj_file_ops = {
|
||||
.close = ef_obj_close,
|
||||
@ -129,7 +129,8 @@ ef_obj_get_offset(elf_file_t ef, GElf_Addr addr)
|
||||
}
|
||||
|
||||
static int
|
||||
ef_obj_lookup_symbol(elf_file_t ef, const char *name, GElf_Sym **sym)
|
||||
ef_obj_lookup_symbol(elf_file_t ef, const char *name, GElf_Sym **sym,
|
||||
bool see_local)
|
||||
{
|
||||
GElf_Sym *symp;
|
||||
const char *strp;
|
||||
@ -138,8 +139,11 @@ ef_obj_lookup_symbol(elf_file_t ef, const char *name, GElf_Sym **sym)
|
||||
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 = symp;
|
||||
return (0);
|
||||
if (see_local ||
|
||||
GELF_ST_BIND(symp->st_info) != STB_LOCAL) {
|
||||
*sym = symp;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (ENOENT);
|
||||
|
@ -688,7 +688,8 @@ elf_reloc(struct elf_file *efile, const void *reldata, Elf_Type reltype,
|
||||
}
|
||||
|
||||
int
|
||||
elf_lookup_symbol(struct elf_file *efile, const char *name, GElf_Sym **sym)
|
||||
elf_lookup_symbol(struct elf_file *efile, const char *name, GElf_Sym **sym,
|
||||
bool see_local)
|
||||
{
|
||||
return (EF_LOOKUP_SYMBOL(efile, name, sym));
|
||||
return (EF_LOOKUP_SYMBOL(efile, name, sym, see_local));
|
||||
}
|
||||
|
@ -48,8 +48,8 @@
|
||||
(ef)->ef_ops->symaddr((ef)->ef_ef, symidx)
|
||||
#define EF_LOOKUP_SET(ef, name, startp, stopp, countp) \
|
||||
(ef)->ef_ops->lookup_set((ef)->ef_ef, name, startp, stopp, countp)
|
||||
#define EF_LOOKUP_SYMBOL(ef, name, sym) \
|
||||
(ef)->ef_ops->lookup_symbol((ef)->ef_ef, name, sym)
|
||||
#define EF_LOOKUP_SYMBOL(ef, name, sym, see_local) \
|
||||
(ef)->ef_ops->lookup_symbol((ef)->ef_ef, name, sym, see_local)
|
||||
|
||||
/* XXX, should have a different name. */
|
||||
typedef struct ef_file *elf_file_t;
|
||||
@ -69,7 +69,8 @@ struct elf_file_ops {
|
||||
GElf_Addr (*symaddr)(elf_file_t ef, GElf_Size symidx);
|
||||
int (*lookup_set)(elf_file_t ef, const char *name, GElf_Addr *startp,
|
||||
GElf_Addr *stopp, long *countp);
|
||||
int (*lookup_symbol)(elf_file_t ef, const char *name, GElf_Sym **sym);
|
||||
int (*lookup_symbol)(elf_file_t ef, const char *name, GElf_Sym **sym,
|
||||
bool see_local);
|
||||
};
|
||||
|
||||
typedef int (elf_reloc_t)(struct elf_file *ef, const void *reldata,
|
||||
@ -317,11 +318,9 @@ int elf_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype,
|
||||
* Find the symbol with the specified symbol name 'name' within the given
|
||||
* 'efile'. 0 is returned when such a symbol is found, otherwise ENOENT is
|
||||
* returned.
|
||||
*
|
||||
* XXX: This only return the first symbol being found when traversing symtab.
|
||||
*/
|
||||
int elf_lookup_symbol(struct elf_file *efile, const char *name,
|
||||
GElf_Sym **sym);
|
||||
GElf_Sym **sym, bool see_local);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user