Convert the callback-based iterate_sym_by_name() and
iterate_sym_by_demangled_name() callers to use new
for_each_sym_by[_demangled]_name() macros.  This eliminates the callback
structs and functions and makes the code more compact and readable.

Signed-off-by: Josh Poimboeuf <[email protected]>
---
 tools/objtool/elf.c                 | 80 ++++++-----------------------
 tools/objtool/include/objtool/elf.h | 40 ++++++++++++---
 tools/objtool/klp-checksum.c        | 20 +++-----
 tools/objtool/klp-diff.c            | 42 +++++----------
 4 files changed, 73 insertions(+), 109 deletions(-)

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 8a6e1338af97..8d823e96b7c9 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -27,27 +27,16 @@
 
 static ssize_t demangled_name_len(const char *name);
 
-static inline u32 str_hash(const char *str)
-{
-       return jhash(str, strlen(str), 0);
-}
-
-static inline u32 str_hash_demangled(const char *str)
+u32 str_hash_demangled(const char *str)
 {
        return jhash(str, demangled_name_len(str), 0);
 }
 
-#define __elf_table(name)      (elf->name##_hash)
-#define __elf_bits(name)       (elf->name##_bits)
-
-#define __elf_table_entry(name, key) \
-       __elf_table(name)[hash_min(key, __elf_bits(name))]
-
 #define elf_hash_add(name, node, key)                                  \
 ({                                                                     \
        struct elf_hash_node *__node = node;                            \
-       __node->next = __elf_table_entry(name, key);                    \
-       __elf_table_entry(name, key) = __node;                          \
+       __node->next = __elf_table_entry(elf, name, key);               \
+       __elf_table_entry(elf, name, key) = __node;                     \
 })
 
 static inline void __elf_hash_del(struct elf_hash_node *node,
@@ -69,30 +58,20 @@ static inline void __elf_hash_del(struct elf_hash_node 
*node,
 }
 
 #define elf_hash_del(name, node, key) \
-       __elf_hash_del(node, &__elf_table_entry(name, key))
-
-#define elf_list_entry(ptr, type, member)                              \
-({                                                                     \
-       typeof(ptr) __ptr = (ptr);                                      \
-       __ptr ? container_of(__ptr, type, member) : NULL;               \
-})
-
-#define elf_hash_for_each_possible(name, obj, member, key)             \
-       for (obj = elf_list_entry(__elf_table_entry(name, key), typeof(*obj), 
member); \
-            obj;                                                       \
-            obj = elf_list_entry(obj->member.next, typeof(*(obj)), member))
+       __elf_hash_del(node, &__elf_table_entry(elf, name, key))
 
 #define elf_alloc_hash(name, size)                                     \
 ({                                                                     \
-       __elf_bits(name) = max(10, ilog2(size));                        \
-       __elf_table(name) = mmap(NULL, sizeof(struct elf_hash_node *) << 
__elf_bits(name), \
+       __elf_bits(elf, name) = max(10, ilog2(size));                   \
+       __elf_table(elf, name) = mmap(NULL,                             \
+                                sizeof(struct elf_hash_node *) << 
__elf_bits(elf, name), \
                                 PROT_READ|PROT_WRITE,                  \
                                 MAP_PRIVATE|MAP_ANON, -1, 0);          \
-       if (__elf_table(name) == (void *)-1L) {                         \
+       if (__elf_table(elf, name) == (void *)-1L) {                    \
                ERROR_GLIBC("mmap fail " #name);                        \
-               __elf_table(name) = NULL;                               \
+               __elf_table(elf, name) = NULL;                          \
        }                                                               \
-       __elf_table(name);                                              \
+       __elf_table(elf, name);                                         \
 })
 
 static inline unsigned long __sym_start(struct symbol *s)
@@ -141,7 +120,7 @@ struct section *find_section_by_name(const struct elf *elf, 
const char *name)
 {
        struct section *sec;
 
-       elf_hash_for_each_possible(section_name, sec, name_hash, 
str_hash(name)) {
+       elf_hash_for_each_possible(elf, section_name, sec, name_hash, 
str_hash(name)) {
                if (!strcmp(sec->name, name))
                        return sec;
        }
@@ -154,7 +133,7 @@ static struct section *find_section_by_index(struct elf 
*elf,
 {
        struct section *sec;
 
-       elf_hash_for_each_possible(section, sec, hash, idx) {
+       elf_hash_for_each_possible(elf, section, sec, hash, idx) {
                if (sec->idx == idx)
                        return sec;
        }
@@ -166,7 +145,7 @@ static struct symbol *find_symbol_by_index(struct elf *elf, 
unsigned int idx)
 {
        struct symbol *sym;
 
-       elf_hash_for_each_possible(symbol, sym, hash, idx) {
+       elf_hash_for_each_possible(elf, symbol, sym, hash, idx) {
                if (sym->idx == idx)
                        return sym;
        }
@@ -285,7 +264,7 @@ struct symbol *find_symbol_by_name(const struct elf *elf, 
const char *name)
 {
        struct symbol *sym;
 
-       elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) 
{
+       elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, 
str_hash(name)) {
                if (!strcmp(sym->name, name))
                        return sym;
        }
@@ -300,7 +279,7 @@ static struct symbol 
*find_local_symbol_by_file_and_name(const struct elf *elf,
 {
        struct symbol *sym;
 
-       elf_hash_for_each_possible(symbol_name, sym, name_hash, 
str_hash_demangled(name)) {
+       elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, 
str_hash_demangled(name)) {
                if (sym->bind == STB_LOCAL && sym->file == file &&
                    !strcmp(sym->name, name)) {
                        return sym;
@@ -314,7 +293,7 @@ struct symbol *find_global_symbol_by_name(const struct elf 
*elf, const char *nam
 {
        struct symbol *sym;
 
-       elf_hash_for_each_possible(symbol_name, sym, name_hash, 
str_hash_demangled(name)) {
+       elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, 
str_hash_demangled(name)) {
                if (!strcmp(sym->name, name) && !is_local_sym(sym))
                        return sym;
        }
@@ -322,31 +301,6 @@ struct symbol *find_global_symbol_by_name(const struct elf 
*elf, const char *nam
        return NULL;
 }
 
-void iterate_global_symbol_by_demangled_name(const struct elf *elf,
-                                            const char *demangled_name,
-                                            void (*process)(struct symbol 
*sym, void *data),
-                                            void *data)
-{
-       struct symbol *sym;
-
-       elf_hash_for_each_possible(symbol_name, sym, name_hash, 
str_hash(demangled_name)) {
-               if (!strcmp(sym->demangled_name, demangled_name) && 
!is_local_sym(sym))
-                       process(sym, data);
-       }
-}
-
-void iterate_sym_by_name(const struct elf *elf, const char *name,
-                        void (*process)(struct symbol *sym, void *data),
-                        void *data)
-{
-       struct symbol *sym;
-
-       elf_hash_for_each_possible(symbol_name, sym, name_hash, 
str_hash_demangled(name)) {
-               if (!strcmp(sym->name, name))
-                       process(sym, data);
-       }
-}
-
 struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section 
*sec,
                                     unsigned long offset, unsigned int len)
 {
@@ -359,7 +313,7 @@ struct reloc *find_reloc_by_dest_range(const struct elf 
*elf, struct section *se
                return NULL;
 
        for_offset_range(o, offset, offset + len) {
-               elf_hash_for_each_possible(reloc, reloc, hash,
+               elf_hash_for_each_possible(elf, reloc, reloc, hash,
                                           sec_offset_hash(rsec, o)) {
                        if (reloc->sec != rsec)
                                continue;
diff --git a/tools/objtool/include/objtool/elf.h 
b/tools/objtool/include/objtool/elf.h
index 82b9fb05af26..ba13dd67cf26 100644
--- a/tools/objtool/include/objtool/elf.h
+++ b/tools/objtool/include/objtool/elf.h
@@ -21,6 +21,13 @@
 #define SEC_NAME_LEN           1024
 #define SYM_NAME_LEN           512
 
+static inline u32 str_hash(const char *str)
+{
+       return jhash(str, strlen(str), 0);
+}
+
+u32 str_hash_demangled(const char *str);
+
 #define bswap_if_needed(elf, val) __bswap_if_needed(&elf->ehdr, val)
 
 #ifdef LIBELF_USE_DEPRECATED
@@ -129,6 +136,23 @@ struct elf {
        struct symbol *symbol_data;
 };
 
+#define __elf_table(elf, name) ((elf)->name##_hash)
+#define __elf_bits(elf, name)  ((elf)->name##_bits)
+
+#define __elf_table_entry(elf, name, key) \
+       __elf_table(elf, name)[hash_min(key, __elf_bits(elf, name))]
+
+#define elf_list_entry(ptr, type, member)                              \
+({                                                                     \
+       typeof(ptr) __ptr = (ptr);                                      \
+       __ptr ? container_of(__ptr, type, member) : NULL;               \
+})
+
+#define elf_hash_for_each_possible(elf, name, obj, member, key)                
\
+       for (obj = elf_list_entry(__elf_table_entry(elf, name, key), 
typeof(*obj), member); \
+            obj;                                                       \
+            obj = elf_list_entry(obj->member.next, typeof(*(obj)), member))
+
 struct elf *elf_open_read(const char *name, int flags);
 struct elf *elf_create_file(GElf_Ehdr *ehdr, const char *name);
 
@@ -185,12 +209,6 @@ struct symbol *find_func_by_offset(struct section *sec, 
unsigned long offset);
 struct symbol *find_symbol_by_offset(struct section *sec, unsigned long 
offset);
 struct symbol *find_symbol_by_name(const struct elf *elf, const char *name);
 struct symbol *find_global_symbol_by_name(const struct elf *elf, const char 
*name);
-void iterate_global_symbol_by_demangled_name(const struct elf *elf, const char 
*demangled_name,
-                                            void (*process)(struct symbol 
*sym, void *data),
-                                            void *data);
-void iterate_sym_by_name(const struct elf *elf, const char *name,
-                        void (*process)(struct symbol *sym, void *data),
-                        void *data);
 struct symbol *find_symbol_containing(const struct section *sec, unsigned long 
offset);
 int find_symbol_hole_containing(const struct section *sec, unsigned long 
offset);
 struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, 
unsigned long offset);
@@ -485,6 +503,16 @@ static inline void set_sym_next_reloc(struct reloc *reloc, 
struct reloc *next)
 #define for_each_sym_continue(elf, sym)                                        
\
        list_for_each_entry_continue(sym, &elf->symbols, global_list)
 
+#define for_each_sym_by_name(elf, _name, sym)                          \
+       elf_hash_for_each_possible(elf, symbol_name, sym, name_hash,    \
+                                  str_hash_demangled(_name))           \
+               if (!strcmp(sym->name, _name))
+
+#define for_each_sym_by_demangled_name(elf, name, sym)                 \
+       elf_hash_for_each_possible(elf, symbol_name, sym, name_hash,    \
+                                  str_hash(name))                      \
+               if (!strcmp(sym->demangled_name, name))
+
 #define rsec_next_reloc(rsec, reloc)                                   \
        reloc_idx(reloc) < sec_num_entries(rsec) - 1 ? reloc + 1 : NULL
 
diff --git a/tools/objtool/klp-checksum.c b/tools/objtool/klp-checksum.c
index 4edd29028bff..e4a910f3211c 100644
--- a/tools/objtool/klp-checksum.c
+++ b/tools/objtool/klp-checksum.c
@@ -11,17 +11,6 @@
 #include <objtool/warn.h>
 #include <objtool/checksum.h>
 
-static void enable_debug_checksum_cb(struct symbol *sym, void *d)
-{
-       bool *found = d;
-
-       if (!is_func_sym(sym))
-               return;
-
-       sym->debug_checksum = 1;
-       *found = true;
-}
-
 static int checksum_debug_init(struct objtool_file *file)
 {
        char *dup, *s;
@@ -38,13 +27,20 @@ static int checksum_debug_init(struct objtool_file *file)
        s = dup;
        while (*s) {
                bool found = false;
+               struct symbol *sym;
                char *comma;
 
                comma = strchr(s, ',');
                if (comma)
                        *comma = '\0';
 
-               iterate_sym_by_name(file->elf, s, enable_debug_checksum_cb, 
&found);
+               for_each_sym_by_name(file->elf, s, sym) {
+                       if (!is_func_sym(sym))
+                               continue;
+                       sym->debug_checksum = 1;
+                       found = true;
+               }
+
                if (!found)
                        WARN("--debug-checksum: can't find '%s'", s);
 
diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c
index c903aa65d4b6..33e401b85001 100644
--- a/tools/objtool/klp-diff.c
+++ b/tools/objtool/klp-diff.c
@@ -46,11 +46,6 @@ static const struct option klp_diff_options[] = {
 
 static DEFINE_HASHTABLE(exports, 15);
 
-static inline u32 str_hash(const char *str)
-{
-       return jhash(str, strlen(str), 0);
-}
-
 static char *escape_str(const char *orig)
 {
        size_t len = 0;
@@ -398,22 +393,6 @@ static bool dont_correlate(struct symbol *sym)
               is_special_section_aux(sym->sec);
 }
 
-struct process_demangled_name_data {
-       struct symbol *ret;
-       int count;
-};
-
-static void process_demangled_name(struct symbol *sym, void *d)
-{
-       struct process_demangled_name_data *data = d;
-
-       if (sym->twin)
-               return;
-
-       data->count++;
-       data->ret = sym;
-}
-
 /*
  * When there is no full name match, try match demangled_name. This would
  * match original foo.llvm.123 to patched foo.llvm.456.
@@ -425,16 +404,23 @@ static void process_demangled_name(struct symbol *sym, 
void *d)
 static int find_global_symbol_by_demangled_name(struct elf *elf, struct symbol 
*sym,
                                                struct symbol **out_sym)
 {
-       struct process_demangled_name_data data = {};
+       struct symbol *sym2, *result = NULL;
+       int count = 0;
 
-       iterate_global_symbol_by_demangled_name(elf, sym->demangled_name,
-                                               process_demangled_name,
-                                               &data);
-       if (data.count > 1) {
-               ERROR("Multiple (%d) correlation candidates for %s", 
data.count, sym->name);
+       for_each_sym_by_demangled_name(elf, sym->demangled_name, sym2) {
+               if (is_local_sym(sym2) || sym2->twin)
+                       continue;
+
+               count++;
+               result = sym2;
+       }
+
+       if (count > 1) {
+               ERROR("Multiple (%d) correlation candidates for %s", count, 
sym->name);
                return -1;
        }
-       *out_sym = data.ret;
+
+       *out_sym = result;
        return 0;
 }
 
-- 
2.53.0


Reply via email to