git: 2c7d84795628 - main - libkldelf: add elf_lookup_symbol function

From: Ka Ho Ng <khng_at_FreeBSD.org>
Date: Tue, 08 Oct 2024 04:29:34 UTC
The branch main has been updated by khng:

URL: https://cgit.FreeBSD.org/src/commit/?id=2c7d84795628cb9c7a266718b99b6bca68e0a135

commit 2c7d84795628cb9c7a266718b99b6bca68e0a135
Author:     Ka Ho Ng <khng@FreeBSD.org>
AuthorDate: 2024-10-08 04:24:37 +0000
Commit:     Ka Ho Ng <khng@FreeBSD.org>
CommitDate: 2024-10-08 04:29:10 +0000

    libkldelf: add elf_lookup_symbol function
    
    The elf_lookup_symbol function looks up the symbol with a given symbol
    name. A pointer to the GElf_Sym of the symbol is returned if the symbol
    exists in the opened ELF file.
    
    Sponsored by:   Juniper Networks, Inc.
    Reviewed by:    markj
    Differential Revision:  https://reviews.freebsd.org/D46764
---
 lib/libkldelf/ef.c     |  1 +
 lib/libkldelf/ef_obj.c |  1 +
 lib/libkldelf/elf.c    |  6 ++++++
 lib/libkldelf/kldelf.h | 13 +++++++++++++
 4 files changed, 21 insertions(+)

diff --git a/lib/libkldelf/ef.c b/lib/libkldelf/ef.c
index 052798ee31e4..dcd87fe2bf83 100644
--- a/lib/libkldelf/ef.c
+++ b/lib/libkldelf/ef.c
@@ -89,6 +89,7 @@ static struct elf_file_ops ef_file_ops = {
 	.seg_read_string	= ef_seg_read_string,
 	.symaddr		= ef_symaddr,
 	.lookup_set		= ef_lookup_set,
+	.lookup_symbol		= ef_lookup_symbol,
 };
 
 static void
diff --git a/lib/libkldelf/ef_obj.c b/lib/libkldelf/ef_obj.c
index e09bd036b71e..32a7c17127ed 100644
--- a/lib/libkldelf/ef_obj.c
+++ b/lib/libkldelf/ef_obj.c
@@ -109,6 +109,7 @@ static struct elf_file_ops ef_obj_file_ops = {
 	.seg_read_string	= ef_obj_seg_read_string,
 	.symaddr		= ef_obj_symaddr,
 	.lookup_set		= ef_obj_lookup_set,
+	.lookup_symbol		= ef_obj_lookup_symbol,
 };
 
 static GElf_Off
diff --git a/lib/libkldelf/elf.c b/lib/libkldelf/elf.c
index da319ffc6c98..8af02622de13 100644
--- a/lib/libkldelf/elf.c
+++ b/lib/libkldelf/elf.c
@@ -686,3 +686,9 @@ elf_reloc(struct elf_file *efile, const void *reldata, Elf_Type reltype,
 	return (efile->ef_reloc(efile, reldata, reltype, relbase, dataoff, len,
 	    dest));
 }
+
+int
+elf_lookup_symbol(struct elf_file *efile, const char *name, GElf_Sym **sym)
+{
+	return (EF_LOOKUP_SYMBOL(efile, name, sym));
+}
diff --git a/lib/libkldelf/kldelf.h b/lib/libkldelf/kldelf.h
index e0a8cc627ff2..71de31a94291 100644
--- a/lib/libkldelf/kldelf.h
+++ b/lib/libkldelf/kldelf.h
@@ -48,6 +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)
 
 /* XXX, should have a different name. */
 typedef struct ef_file *elf_file_t;
@@ -67,6 +69,7 @@ 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);
 };
 
 typedef int (elf_reloc_t)(struct elf_file *ef, const void *reldata,
@@ -310,6 +313,16 @@ int	elf_read_mod_pnp_match_info(struct elf_file *efile, GElf_Addr addr,
 int	elf_reloc(struct elf_file *ef, const void *reldata, Elf_Type reltype,
     GElf_Addr relbase, GElf_Addr dataoff, size_t len, void *dest);
 
+/*
+ * 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);
+
 __END_DECLS
 
 #endif /* _KLDELF_H_*/