From fac8aa17d540e54fa0443015089cdc72c5da72e3 Mon Sep 17 00:00:00 2001 From: renoseven Date: Sat, 11 May 2024 17:31:46 +0800 Subject: [PATCH 20/20] upatch-diff: fix 'lookup_relf failed' issue Signed-off-by: renoseven --- 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.34.1