git: 72e15f76a1b3 - main - libkldelf: add see_local parameter to elf_lookup_symbol
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 25 Oct 2024 16:20:18 UTC
The branch main has been updated by khng: URL: https://cgit.FreeBSD.org/src/commit/?id=72e15f76a1b3e7bddb5fa1b0429e41d07950af65 commit 72e15f76a1b3e7bddb5fa1b0429e41d07950af65 Author: Ka Ho Ng <khng@FreeBSD.org> AuthorDate: 2024-10-25 16:19:57 +0000 Commit: Ka Ho Ng <khng@FreeBSD.org> CommitDate: 2024-10-25 16:20:16 +0000 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 --- lib/libkldelf/ef.c | 15 +++++++++------ lib/libkldelf/ef_obj.c | 12 ++++++++---- lib/libkldelf/elf.c | 5 +++-- lib/libkldelf/kldelf.h | 11 +++++------ 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/lib/libkldelf/ef.c b/lib/libkldelf/ef.c index dcd87fe2bf83..28576df99bf2 100644 --- a/lib/libkldelf/ef.c +++ b/lib/libkldelf/ef.c @@ -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; diff --git a/lib/libkldelf/ef_obj.c b/lib/libkldelf/ef_obj.c index 30e0d7886995..151bac74b17d 100644 --- a/lib/libkldelf/ef_obj.c +++ b/lib/libkldelf/ef_obj.c @@ -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); diff --git a/lib/libkldelf/elf.c b/lib/libkldelf/elf.c index 8af02622de13..cf43d9bfd5fd 100644 --- a/lib/libkldelf/elf.c +++ b/lib/libkldelf/elf.c @@ -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)); } diff --git a/lib/libkldelf/kldelf.h b/lib/libkldelf/kldelf.h index 71de31a94291..4fb5fcc5f5aa 100644 --- a/lib/libkldelf/kldelf.h +++ b/lib/libkldelf/kldelf.h @@ -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