From e7baf4fef5dfa7ccbb0d639628a910a8099735ec Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Sat, 11 May 2024 17:31:46 +0800
Subject: [PATCH 19/21] upatch-diff: fix 'lookup_relf failed' issue

Signed-off-by: renoseven <dev@renoseven.net>
---
 upatch-diff/elf-create.c  | 24 ++++++++++-------
 upatch-diff/running-elf.c | 57 +++++++++++++--------------------------
 2 files changed, 32 insertions(+), 49 deletions(-)

diff --git a/upatch-diff/elf-create.c b/upatch-diff/elf-create.c
index de4cb57..873b3a9 100644
--- a/upatch-diff/elf-create.c
+++ b/upatch-diff/elf-create.c
@@ -135,8 +135,9 @@ void upatch_create_patches_sections(struct upatch_elf *uelf, struct running_elf
 
     /* find changed func */
     list_for_each_entry(sym, &uelf->symbols, list) {
-        if (sym->type != STT_FUNC || sym->status != CHANGED || sym->parent)
+        if (sym->type != STT_FUNC || sym->status != CHANGED || sym->parent) {
             continue;
+        }
         nr++;
     }
 
@@ -146,24 +147,27 @@ void upatch_create_patches_sections(struct upatch_elf *uelf, struct running_elf
     funcs = sec->data->d_buf;
 
     strsym = find_symbol_by_name(&uelf->symbols, ".upatch.strings");
-    if (!strsym)
-        ERROR("can't find .upatch.strings symbol.");
+    if (!strsym) {
+        ERROR("Cannot find symbol '.upatch.strings'");
+    }
 
     list_for_each_entry(sym, &uelf->symbols, list) {
-        if (sym->type != STT_FUNC || sym->status != CHANGED || sym->parent)
+        if (sym->type != STT_FUNC || sym->status != CHANGED || sym->parent) {
             continue;
+        }
 
-        if (!lookup_relf(relf, sym, &symbol))
-            ERROR("lookup_relf failed.");
+        if (!lookup_relf(relf, sym, &symbol)) {
+            ERROR("Cannot find symbol '%s' in %s", sym->name, g_relf_name);
+        }
 
-        if (sym->bind == STB_LOCAL && symbol.global)
-            ERROR("can't find local symbol '%s' in symbol table.", sym->name);
+        if (sym->bind == STB_LOCAL && symbol.global) {
+            ERROR("Cannot find local symbol '%s' in symbol table.", sym->name);
+        }
 
-        log_debug("lookup for %s: symbol name %s sympos=%lu size=%lu .\n",
+        log_debug("lookup for %s: symbol name %s sympos=%lu size=%lu.\n",
             sym->name, symbol.symbol->name, symbol.sympos, symbol.symbol->size);
 
         /* ATTENTION: kpatch convert global symbols to local symbols here. */
-
         funcs[index].old_addr = symbol.symbol->addr;
         funcs[index].old_size = symbol.symbol->size;
         funcs[index].new_size = sym->sym.st_size;
diff --git a/upatch-diff/running-elf.c b/upatch-diff/running-elf.c
index 037f5fc..3bb35e7 100644
--- a/upatch-diff/running-elf.c
+++ b/upatch-diff/running-elf.c
@@ -113,55 +113,34 @@ int relf_destroy(struct running_elf *relf)
     return 0;
 }
 
-bool lookup_relf(struct running_elf *relf, struct symbol *lookup_sym,
-                 struct lookup_result *result)
+bool lookup_relf(struct running_elf *relf,
+    struct symbol *lookup_sym, struct lookup_result *result)
 {
-    int i;
-    struct debug_symbol *sym;
+    struct debug_symbol *symbol = NULL;
     unsigned long sympos = 0;
-    bool in_file = false;
 
+    log_debug("looking up symbol '%s'\n", lookup_sym->name);
     memset(result, 0, sizeof(*result));
 
-    for (i = 0; i < relf->obj_nr; i ++) {
-        sym = &relf->obj_syms[i];
-        if (sym->bind == STB_LOCAL && !strcmp(sym->name, lookup_sym->name))
-            sympos ++;
+    for (int i = 0; i < relf->obj_nr; i++) {
+        symbol = &relf->obj_syms[i];
+        sympos++;
 
-        if (lookup_sym->relf_sym == sym) {
-            in_file = true;
+        if (strcmp(symbol->name, lookup_sym->name) != 0) {
             continue;
         }
-
-        if (!in_file)
-            continue;
-
-        if (sym->type == STT_FILE)
-            break;
-
-        if (sym->bind == STB_LOCAL && !strcmp(sym->name, lookup_sym->name)) {
-            if (result->symbol)
-                ERROR("duplicate local symbol found for %s", lookup_sym->name);
-
-            result->symbol = sym;
-            result->sympos = sympos;
-            result->global = false;
+        if ((result->symbol != NULL) &&
+            (result->symbol->bind == symbol->bind)) {
+            ERROR("Found duplicate symbol '%s' in %s",
+                lookup_sym->name, g_relf_name);
         }
-    }
-
-    if (!!result->symbol)
-        return !!result->symbol;
 
-    for (i = 0; i < relf->obj_nr; i ++) {
-        sym = &relf->obj_syms[i];
-        if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK) &&
-                !strcmp(sym->name, lookup_sym->name)) {
-            if (result->symbol)
-                ERROR("duplicated global symbol for %s \n", lookup_sym->name);
-            result->symbol = sym;
-            result->global = true;
-        }
+        result->symbol = symbol;
+        result->sympos = sympos;
+        result->global =
+            ((symbol->bind == STB_GLOBAL) || (symbol->bind == STB_WEAK));
+        log_normal("found symbol '%s'\n", lookup_sym->name);
     }
 
-    return !!result->symbol;
+    return (result->symbol != NULL);
 }
-- 
2.41.0

