From a7140a02d69b50d57403f2c769767e5365a6aa34 Mon Sep 17 00:00:00 2001 From: renoseven Date: Sat, 11 May 2024 08:26:33 +0800 Subject: [PATCH 16/20] upatch-diff: optimize log output Signed-off-by: renoseven --- upatch-diff/create-diff-object.c | 177 ++++++++++++++++++------------- upatch-diff/elf-compare.c | 2 +- upatch-diff/elf-correlate.c | 4 +- upatch-diff/log.h | 18 ++-- upatch-diff/running-elf.c | 6 +- upatch-diff/running-elf.h | 6 +- upatch-diff/upatch-elf.c | 2 +- upatch-diff/upatch-elf.h | 4 +- 8 files changed, 122 insertions(+), 97 deletions(-) diff --git a/upatch-diff/create-diff-object.c b/upatch-diff/create-diff-object.c index 5dc7522..01c58b8 100644 --- a/upatch-diff/create-diff-object.c +++ b/upatch-diff/create-diff-object.c @@ -62,9 +62,10 @@ #define PROG_VERSION "upatch-diff "BUILD_VERSION -enum loglevel loglevel = NORMAL; -char *logprefix; -char *upatch_elf_name; +enum LogLevel g_loglevel = NORMAL; +char *g_logprefix; +char *g_uelf_name; +char *g_relf_name; struct arguments { char *source_obj; @@ -334,72 +335,87 @@ enum LOCAL_MATCH { EMPTY, }; -static enum LOCAL_MATCH locals_match(struct running_elf *relf, int idx, - struct symbol *file_sym, struct list_head *sym_list) +static enum LOCAL_MATCH locals_match( + struct upatch_elf *uelf, struct running_elf *relf, + struct symbol *file_sym, int file_sym_idx) { - struct symbol *sym; - struct object_symbol *running_sym; - int i; + struct symbol *uelf_sym = NULL; + struct debug_symbol *relf_sym = NULL; enum LOCAL_MATCH found = EMPTY; - for (i = idx + 1; i < relf->obj_nr; ++i) { - running_sym = &relf->obj_syms[i]; - if (running_sym->type == STT_FILE) - break; - if (running_sym->bind != STB_LOCAL) + for (int i = file_sym_idx + 1; i < relf->obj_nr; i++) { + relf_sym = &relf->obj_syms[i]; + + if (relf_sym->type == STT_FILE) { + break; // find until next file + } + if (relf_sym->bind != STB_LOCAL) { continue; - if (running_sym->type != STT_FUNC && running_sym->type != STT_OBJECT) + } + if ((relf_sym->type != STT_FUNC) && + (relf_sym->type != STT_OBJECT)) { continue; + } found = NOT_FOUND; - sym = file_sym; - list_for_each_entry_continue(sym, sym_list, list) { - if (sym->type == STT_FILE) - break; - if(sym->bind != STB_LOCAL) + uelf_sym = file_sym; + list_for_each_entry_continue(uelf_sym, &uelf->symbols, list) { + if (uelf_sym->type == STT_FILE) { + break; // find until next file + } + if(uelf_sym->bind != STB_LOCAL) { continue; - - if (sym->type == running_sym->type && - !strcmp(sym->name, running_sym->name)) { - found = FOUND; - break; + } + if ((uelf_sym->type == relf_sym->type) && + (strcmp(uelf_sym->name, relf_sym->name) == 0)) { + found = FOUND; + break; } } if (found == NOT_FOUND) { - log_warn("Cannot find symbol '%s' in running binary\n", running_sym->name); + log_warn("Cannot find symbol '%s' in %s\n", + relf_sym->name, g_relf_name); return NOT_FOUND; } } - sym = file_sym; - list_for_each_entry_continue(sym, sym_list, list) { - if (sym->type == STT_FILE) - break; - if(sym->bind != STB_LOCAL) + uelf_sym = file_sym; + list_for_each_entry_continue(uelf_sym, &uelf->symbols, list) { + if (uelf_sym->type == STT_FILE) { + break; // find until next file + } + if(uelf_sym->bind != STB_LOCAL) { continue; - if (sym->type != STT_FUNC && sym->type != STT_OBJECT) + } + if ((relf_sym->type != STT_FUNC) && + (relf_sym->type != STT_OBJECT)) { continue; - if (discarded_sym(relf, sym)) + } + if (discarded_sym(relf, uelf_sym)) { continue; + } found = NOT_FOUND; - for (i = idx + 1; i < relf->obj_nr; ++i) { - running_sym = &relf->obj_syms[i]; - if (running_sym->type == STT_FILE) - break; - if (running_sym->bind != STB_LOCAL) - continue; + for (int i = file_sym_idx + 1; i < relf->obj_nr; i++) { + relf_sym = &relf->obj_syms[i]; - if (sym->type == running_sym->type && - !strcmp(sym->name, running_sym->name)) { - found = FOUND; - break; + if (relf_sym->type == STT_FILE) { + break; // find until next file + } + if (relf_sym->bind != STB_LOCAL) { + continue; + } + if ((uelf_sym->type == relf_sym->type) && + (strcmp(uelf_sym->name, relf_sym->name) == 0)) { + found = FOUND; + break; } } - if (found == NOT_FOUND){ - log_warn("Cannot find symbol '%s' in object\n", sym->name); + if (found == NOT_FOUND) { + log_warn("Cannot find symbol '%s' in %s\n", + uelf_sym->name, g_uelf_name); return NOT_FOUND; } } @@ -407,41 +423,48 @@ static enum LOCAL_MATCH locals_match(struct running_elf *relf, int idx, return found; } -static void find_local_syms(struct running_elf *relf, struct symbol *file_sym, - struct list_head *sym_list) +static void find_local_syms(struct upatch_elf *uelf, struct running_elf *relf, + struct symbol *file_sym) { - struct object_symbol *running_sym; - struct object_symbol *lookup_running_file_sym = NULL; - int i; + struct debug_symbol *relf_sym = NULL; + struct debug_symbol *found_sym = NULL; enum LOCAL_MATCH found; - for (i = 0; i < relf->obj_nr; ++i) { - running_sym = &relf->obj_syms[i]; - if (running_sym->type != STT_FILE) + for (int i = 0; i < relf->obj_nr; i++) { + relf_sym = &relf->obj_syms[i]; + + if (relf_sym->type != STT_FILE) { continue; - if (strcmp(file_sym->name, running_sym->name)) + } + if (strcmp(file_sym->name, relf_sym->name)) { continue; - found = locals_match(relf, i, file_sym, sym_list); + } + + found = locals_match(uelf, relf, file_sym, i); if (found == NOT_FOUND) { continue; - } else if (found == EMPTY) { - lookup_running_file_sym = running_sym; + } + else if (found == EMPTY) { + found_sym = relf_sym; break; - } else { - if (lookup_running_file_sym) - ERROR("Found duplicate local symbols in '%s'", file_sym->name); - - lookup_running_file_sym = running_sym; + } + else { + if (found_sym) { + ERROR("Found duplicate local symbols in '%s'", g_relf_name); + } + found_sym = relf_sym; } } - if (!lookup_running_file_sym) - ERROR("Cannot find a local symbol in '%s'", file_sym->name); + if (!found_sym) { + ERROR("Cannot find local symbol in '%s'", g_relf_name); + } - list_for_each_entry_continue(file_sym, sym_list, list) { - if (file_sym->type == STT_FILE) + list_for_each_entry_continue(file_sym, &uelf->symbols, list) { + if (file_sym->type == STT_FILE) { break; - file_sym->lookup_running_file_sym = lookup_running_file_sym; + } + file_sym->relf_sym = found_sym; } } @@ -453,13 +476,14 @@ static void find_local_syms(struct running_elf *relf, struct symbol *file_sym, * We then compare local symbol lists from both blocks and store the pointer * to STT_FILE symbol in running elf for later using. */ -static void find_file_symbol(struct upatch_elf *uelf, struct running_elf *relf) +static void find_debug_symbol(struct upatch_elf *uelf, struct running_elf *relf) { - struct symbol *sym; + struct symbol *file_sym = NULL; - list_for_each_entry(sym, &uelf->symbols, list) { - if (sym->type == STT_FILE) - find_local_syms(relf, sym, &uelf->symbols); + list_for_each_entry(file_sym, &uelf->symbols, list) { + if (file_sym->type == STT_FILE) { + find_local_syms(uelf, relf, file_sym); + } } } @@ -735,7 +759,7 @@ static int include_changed_functions(struct upatch_elf *uelf) if (sym->status == CHANGED && sym->type == STT_SECTION && sym->sec && is_except_section(sym->sec)) { - log_warn("Exeception section '%s' is changed\n", sym->sec->name); + log_warn("Exception section '%s' is changed\n", sym->sec->name); changed_nr++; include_symbol(sym); } @@ -886,15 +910,16 @@ int main(int argc, char*argv[]) argp_parse(&argp, argc, argv, 0, NULL, &arguments); if (arguments.debug) - loglevel = DEBUG; - logprefix = basename(arguments.source_obj); + g_loglevel = DEBUG; + g_logprefix = basename(arguments.source_obj); show_program_info(&arguments); if (elf_version(EV_CURRENT) == EV_NONE) ERROR("ELF library initialization failed"); /* TODO: with debug info, this may changed */ - upatch_elf_name = arguments.running_elf; + g_uelf_name = arguments.source_obj; + g_relf_name = arguments.running_elf; /* check error in log, since errno may be from libelf */ upatch_elf_open(&uelf_source, arguments.source_obj); @@ -912,7 +937,7 @@ int main(int argc, char*argv[]) detect_child_functions(&uelf_source); detect_child_functions(&uelf_patched); - find_file_symbol(&uelf_source, &relf); + find_debug_symbol(&uelf_source, &relf); mark_grouped_sections(&uelf_patched); diff --git a/upatch-diff/elf-compare.c b/upatch-diff/elf-compare.c index 054f16a..9b857b1 100644 --- a/upatch-diff/elf-compare.c +++ b/upatch-diff/elf-compare.c @@ -177,7 +177,7 @@ bool upatch_handle_redis_line(const char *symname) /* TODO: let user support this list or generate by the compiler ? */ bool check_line_func(struct upatch_elf *uelf, const char *symname) { - if (!strncmp(basename(upatch_elf_name), "redis-server", 12)) + if (!strncmp(basename(g_relf_name), "redis-server", 12)) return upatch_handle_redis_line(symname); return false; diff --git a/upatch-diff/elf-correlate.c b/upatch-diff/elf-correlate.c index f25f252..a0fe669 100644 --- a/upatch-diff/elf-correlate.c +++ b/upatch-diff/elf-correlate.c @@ -40,8 +40,8 @@ static void correlate_symbol(struct symbol *sym_orig, struct symbol *sym_patched if (!sym_patched->name) ERROR("strdup"); } - if (sym_orig->lookup_running_file_sym && !sym_patched->lookup_running_file_sym) - sym_patched->lookup_running_file_sym = sym_orig->lookup_running_file_sym; + if (sym_orig->relf_sym && !sym_patched->relf_sym) + sym_patched->relf_sym = sym_orig->relf_sym; } void upatch_correlate_symbols(struct upatch_elf *uelf_source, struct upatch_elf *uelf_patched) diff --git a/upatch-diff/log.h b/upatch-diff/log.h index 5af3e34..34b58bf 100644 --- a/upatch-diff/log.h +++ b/upatch-diff/log.h @@ -28,9 +28,9 @@ #include #include -/* Files that include log.h must define loglevel and logprefix */ -extern enum loglevel loglevel; -extern char *logprefix; +/* Files that include log.h must define g_loglevel and g_logprefix */ +extern enum LogLevel g_loglevel; +extern char *g_logprefix; enum exit_status{ EXIT_STATUS_SUCCESS = 0, @@ -41,19 +41,19 @@ enum exit_status{ /* Since upatch-build is an one-shot program, we do not care about failure handler */ #define ERROR(format, ...) \ - error(EXIT_STATUS_ERROR, 0, "ERROR: %s: %s: %d: " format, logprefix, __FUNCTION__, __LINE__, ##__VA_ARGS__) + error(EXIT_STATUS_ERROR, 0, "ERROR: %s: %s: %d: " format, g_logprefix, __FUNCTION__, __LINE__, ##__VA_ARGS__) #define DIFF_FATAL(format, ...) \ - error(EXIT_STATUS_DIFF_FATAL, 0, "ERROR: %s: %s: %d: " format, logprefix, __FUNCTION__, __LINE__, ##__VA_ARGS__) + error(EXIT_STATUS_DIFF_FATAL, 0, "ERROR: %s: %s: %d: " format, g_logprefix, __FUNCTION__, __LINE__, ##__VA_ARGS__) /* it is time cost */ #define log_debug(format, ...) log(DEBUG, format, ##__VA_ARGS__) -#define log_normal(format, ...) log(NORMAL, "%s: " format, logprefix, ##__VA_ARGS__) -#define log_warn(format, ...) log(WARN, "%s: " format, logprefix, ##__VA_ARGS__) +#define log_normal(format, ...) log(NORMAL, "%s: " format, g_logprefix, ##__VA_ARGS__) +#define log_warn(format, ...) log(WARN, "%s: " format, g_logprefix, ##__VA_ARGS__) #define log(level, format, ...) \ ({ \ - if (loglevel <= (level)) \ + if (g_loglevel <= (level)) \ printf(format, ##__VA_ARGS__); \ }) @@ -63,7 +63,7 @@ enum exit_status{ ERROR(message); \ while (0) -enum loglevel { +enum LogLevel { DEBUG, NORMAL, WARN, diff --git a/upatch-diff/running-elf.c b/upatch-diff/running-elf.c index e190691..037f5fc 100644 --- a/upatch-diff/running-elf.c +++ b/upatch-diff/running-elf.c @@ -84,7 +84,7 @@ void relf_init(char *elf_name, struct running_elf *relf) ERROR("elf_getdata with error %s", elf_errmsg(0)); relf->obj_nr = shdr.sh_size / shdr.sh_entsize; - relf->obj_syms = calloc(relf->obj_nr, sizeof(struct object_symbol)); + relf->obj_syms = calloc(relf->obj_nr, sizeof(struct debug_symbol)); if (!relf->obj_syms) ERROR("calloc with errno = %d", errno); @@ -117,7 +117,7 @@ bool lookup_relf(struct running_elf *relf, struct symbol *lookup_sym, struct lookup_result *result) { int i; - struct object_symbol *sym; + struct debug_symbol *sym; unsigned long sympos = 0; bool in_file = false; @@ -128,7 +128,7 @@ bool lookup_relf(struct running_elf *relf, struct symbol *lookup_sym, if (sym->bind == STB_LOCAL && !strcmp(sym->name, lookup_sym->name)) sympos ++; - if (lookup_sym->lookup_running_file_sym == sym) { + if (lookup_sym->relf_sym == sym) { in_file = true; continue; } diff --git a/upatch-diff/running-elf.h b/upatch-diff/running-elf.h index 0eb5c70..0646780 100644 --- a/upatch-diff/running-elf.h +++ b/upatch-diff/running-elf.h @@ -35,12 +35,12 @@ struct symbol; struct lookup_result { - struct object_symbol *symbol; + struct debug_symbol *symbol; unsigned long sympos; bool global; }; -struct object_symbol { +struct debug_symbol { char *name; unsigned char type, bind; unsigned int shndx; @@ -50,7 +50,7 @@ struct object_symbol { struct running_elf { int obj_nr; - struct object_symbol *obj_syms; + struct debug_symbol *obj_syms; int fd; Elf *elf; bool is_exec; diff --git a/upatch-diff/upatch-elf.c b/upatch-diff/upatch-elf.c index e39fb6a..fc4396a 100644 --- a/upatch-diff/upatch-elf.c +++ b/upatch-diff/upatch-elf.c @@ -206,7 +206,7 @@ static void create_rela_list(struct upatch_elf *uelf, struct section *relasec) if (skip) continue; - log_debug("offset %d, type %d, %s %s %ld \n", rela->offset, + log_debug("offset %d, type %d, %s %s %ld", rela->offset, rela->type, rela->sym->name, (rela->addend < 0) ? "-" : "+", labs(rela->addend)); if (rela->string) // rela->string is not utf8 diff --git a/upatch-diff/upatch-elf.h b/upatch-diff/upatch-elf.h index 2f7c777..b2d038b 100644 --- a/upatch-diff/upatch-elf.h +++ b/upatch-diff/upatch-elf.h @@ -32,7 +32,7 @@ #include "list.h" #include "running-elf.h" -extern char *upatch_elf_name; +extern char *g_relf_name; // these data structs contain each other struct section; @@ -102,7 +102,7 @@ struct symbol { struct section *sec; GElf_Sym sym; char *name; - struct object_symbol *lookup_running_file_sym; + struct debug_symbol *relf_sym; unsigned int index; unsigned char bind; unsigned char type; -- 2.34.1