From 06a7b099a67de722d197951becd63e744d54e499 Mon Sep 17 00:00:00 2001
From: renoseven <dev@renoseven.net>
Date: Mon, 28 Apr 2025 17:24:03 +0800
Subject: [PATCH] upatch-diff: ignore debug sections
Signed-off-by: renoseven <dev@renoseven.net>
upatch-diff/create-diff-object.c | 44 ++++++++++++++++++++------------
upatch-diff/elf-common.h | 5 ++++
upatch-diff/elf-compare.c | 32 +++++++++++++----------
upatch-diff/elf-correlate.c | 3 +++
upatch-diff/elf-create.c | 16 ++++++++++--
upatch-diff/elf-debug.c | 7 +++--
6 files changed, 71 insertions(+), 36 deletions(-)
@@ -681,20 +681,28 @@ static void replace_section_syms(struct upatch_elf *uelf)
static void mark_ignored_sections(struct upatch_elf *uelf)
{
static const char *const IGNORED_SECTIONS[] = {
+ ".eh_frame",
+ ".note",
+ ".debug_",
".comment",
".discard",
".rela.discard",
".GCC.command.line",
};
+ static const size_t IGNORED_SECTION_NUM =
+ sizeof(IGNORED_SECTIONS) / sizeof(IGNORED_SECTIONS[0]);
- for (size_t i = 0; i < ARRAY_SIZE(IGNORED_SECTIONS); i++) {
- const char *const ignored_name = IGNORED_SECTIONS[i];
- const size_t name_len = strlen(ignored_name);
-
- struct section *sec = NULL;
- list_for_each_entry(sec, &uelf->sections, list) {
- if (strncmp(sec->name, ignored_name, name_len) == 0) {
- sec->status = SAME;
+ struct section *sec = NULL;
+ list_for_each_entry(sec, &uelf->sections, list) {
+ for (size_t i = 0; i < IGNORED_SECTION_NUM; i++) {
+ const char *const ignored_name = IGNORED_SECTIONS[i];
+ const size_t name_len = strlen(ignored_name);
+ const char *sec_name = is_rela_section(sec) ?
+ sec->base->name : sec->name;
+ if (strncmp(sec_name, ignored_name, name_len) == 0) {
+ sec->ignored = true;
+ log_debug("Marking section '%s' (%d) as ignored\n",
+ sec->name, sec->index);
break;
}
}
@@ -790,6 +798,9 @@ static void include_standard_elements(struct upatch_elf *uelf)
struct section *sec = NULL;
list_for_each_entry(sec, &uelf->sections, list) {
+ if (sec->ignored) {
+ continue;
+ }
if (is_symtab_section(sec) || is_strtab_section(sec)) {
include_section(sec);
}
@@ -804,7 +815,7 @@ static int include_changes(struct upatch_elf *uelf)
struct symbol *sym = NULL;
list_for_each_entry(sym, &uelf->symbols, list) {
- if (sym->status == SAME) {
+ if ((sym->status == SAME) || is_symbol_ignored(sym)) {
continue;
}
@@ -816,8 +827,7 @@ static int include_changes(struct upatch_elf *uelf)
include_symbol(sym);
count++;
} else if (sym->type == STT_SECTION) {
- if ((sym->sec != NULL) &&
- (is_rela_section(sym->sec) || is_debug_section(sym->sec))) {
+ if ((sym->sec != NULL) && is_rela_section(sym->sec)) {
continue;
}
include_symbol(sym);
@@ -853,6 +863,9 @@ static int verify_section_patchability(struct upatch_elf *uelf)
struct section *sec = NULL;
list_for_each_entry(sec, &uelf->sections, list) {
+ if (sec->ignored) {
+ continue;
+ }
if ((sec->status == NEW) && !sec->include) {
// new sections should be included
log_warn("Section '%s' is %s, but it is not included\n",
@@ -860,7 +873,7 @@ static int verify_section_patchability(struct upatch_elf *uelf)
err_count++;
} else if ((sec->status == CHANGED) && !sec->include) {
// changed sections should be included
- if (is_rela_section(sec) || is_debug_section(sec)) {
+ if (is_rela_section(sec)) {
continue;
}
log_warn("Section '%s' is %s, but it is not included\n",
@@ -995,6 +1008,9 @@ int main(int argc, char*argv[])
detect_child_functions(&uelf_source);
detect_child_functions(&uelf_patched);
+ mark_ignored_sections(&uelf_source);
+ mark_ignored_sections(&uelf_patched);
+
mark_grouped_sections(&uelf_patched);
replace_section_syms(&uelf_source);
@@ -1003,10 +1019,6 @@ int main(int argc, char*argv[])
upatch_correlate_elf(&uelf_source, &uelf_patched);
upatch_correlate_static_local_variables(&uelf_source, &uelf_patched);
- /* Now, we can only check uelf_patched, all we need is in the twin part */
- /* Also, we choose part of uelf_patched and output new object */
- mark_ignored_sections(&uelf_patched);
-
upatch_compare_correlated_elements(&uelf_patched);
mark_file_symbols(&uelf_source);
find_debug_symbol(&uelf_source, &relf);
@@ -150,6 +150,11 @@ static inline bool is_debug_section(struct section *sec)
!strncmp(name, ".eh_frame", 9);
}
+static inline bool is_symbol_ignored(struct symbol *sym)
+{
+ return (sym->sec != NULL) && sym->sec->ignored;
+}
+
static inline struct symbol *find_symbol_by_index(struct list_head *list, unsigned int index)
{
struct symbol *sym;
@@ -78,6 +78,9 @@ void upatch_compare_symbols(struct upatch_elf *uelf)
struct symbol *sym;
list_for_each_entry(sym, &uelf->symbols, list) {
+ if (is_symbol_ignored(sym)) {
+ continue;
+ }
if (sym->twin) {
compare_correlated_symbol(sym, sym->twin);
} else {
@@ -141,20 +144,18 @@ static void compare_correlated_nonrela_section(struct section *sec,
static int compare_correlated_section(struct section *sec, struct section *twin)
{
/* compare section headers */
- if (!is_debug_section(sec)) {
- if ((sec->sh.sh_type != twin->sh.sh_type) ||
- (sec->sh.sh_flags != twin->sh.sh_flags) ||
- (sec->sh.sh_entsize != twin->sh.sh_entsize) ||
- ((sec->sh.sh_addralign != twin->sh.sh_addralign) &&
- !is_text_section(sec) &&
- !is_string_section(sec) &&
- !is_rodata_section(sec))) {
- /* shaddralign of .rodata may be changed from 0 to 8 bytes
- once string length is over 30 */
- ERROR("%s section header details differ from %s",
- sec->name, twin->name);
- return -1;
- }
+ if ((sec->sh.sh_type != twin->sh.sh_type) ||
+ (sec->sh.sh_flags != twin->sh.sh_flags) ||
+ (sec->sh.sh_entsize != twin->sh.sh_entsize) ||
+ ((sec->sh.sh_addralign != twin->sh.sh_addralign) &&
+ !is_text_section(sec) &&
+ !is_string_section(sec) &&
+ !is_rodata_section(sec))) {
+ /* shaddralign of .rodata may be changed from 0 to 8 bytes
+ once string length is over 30 */
+ ERROR("%s section header details differ from %s",
+ sec->name, twin->name);
+ return -1;
}
if (is_note_section(sec)) {
@@ -213,6 +214,9 @@ void upatch_compare_sections(struct upatch_elf *uelf)
struct section *sec = NULL;
list_for_each_entry(sec, &uelf->sections, list) {
+ if (sec->ignored) {
+ continue;
+ }
if (sec->twin == NULL) {
sec->status = NEW;
} else {
@@ -54,6 +54,9 @@ void upatch_correlate_symbols(struct upatch_elf *uelf_source,
struct symbol *sym_patched;
list_for_each_entry(sym_orig, &uelf_source->symbols, list) {
+ if (is_symbol_ignored(sym_orig)) {
+ continue;
+ }
if (sym_orig->twin) {
continue;
}
@@ -221,8 +221,7 @@ static bool need_dynrela(struct running_elf *relf, struct section *relasec,
{
struct lookup_result symbol;
- if (is_debug_section(relasec) ||
- is_note_section(relasec)) {
+ if (relasec->ignored) {
return false;
}
@@ -521,6 +520,9 @@ void upatch_create_shstrtab(struct upatch_elf *uelf)
/* determine size of string table */
size = 1;
list_for_each_entry(sec, &uelf->sections, list) {
+ if (sec->ignored) {
+ continue;
+ }
size += strlen(sec->name) + 1;
}
@@ -531,6 +533,9 @@ void upatch_create_shstrtab(struct upatch_elf *uelf)
offset = 1;
list_for_each_entry(sec, &uelf->sections, list) {
+ if (sec->ignored) {
+ continue;
+ }
len = strlen(sec->name) + 1;
sec->sh.sh_name = (unsigned int)offset;
memcpy(buf + offset, sec->name, len);
@@ -551,6 +556,9 @@ void upatch_create_shstrtab(struct upatch_elf *uelf)
log_debug("\n");
list_for_each_entry(sec, &uelf->sections, list) {
+ if (sec->ignored) {
+ continue;
+ }
log_debug("%s @ shstrtab offset %d\n", sec->name, sec->sh.sh_name);
}
}
@@ -713,6 +721,10 @@ void upatch_write_output_elf(struct upatch_elf *uelf, Elf *elf,
/* add changed sections */
list_for_each_entry(sec, &uelf->sections, list) {
+ if (sec->ignored) {
+ continue;
+ }
+
scn = elf_newscn(elfout);
if (!scn) {
ERROR("elf_newscn failed.");
@@ -110,10 +110,10 @@ void upatch_dump_kelf(struct upatch_elf *uelf)
log_debug("%02d %s (%s)",
sec->index, sec->name, status_str(sec->status));
if (is_rela_section(sec)) {
- log_debug(", base-> %s\n", sec->base->name);
- if (is_debug_section(sec) || is_note_section(sec)) {
- goto next;
+ if (sec->ignored) {
+ continue;
}
+ log_debug(", base-> %s\n", sec->base->name);
log_debug("rela section expansion\n");
list_for_each_entry(rela, &sec->relas, list) {
log_debug("sym %d, offset %ld, type %d, %s %s %ld\n",
@@ -133,7 +133,6 @@ void upatch_dump_kelf(struct upatch_elf *uelf)
log_debug(", rela-> %s", sec->rela->name);
}
}
-next:
log_debug("\n");
}
--
2.43.0