145 lines
5.1 KiB
Diff
145 lines
5.1 KiB
Diff
From fac8aa17d540e54fa0443015089cdc72c5da72e3 Mon Sep 17 00:00:00 2001
|
|
From: renoseven <dev@renoseven.net>
|
|
Date: Sat, 11 May 2024 17:31:46 +0800
|
|
Subject: [PATCH] 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.34.1
|
|
|