From ead06280df3586b022f31cabeb2459ed658755ae Mon Sep 17 00:00:00 2001 From: Seth Jennings Date: Thu, 27 Mar 2014 15:54:38 -0500 Subject: [PATCH] check for changed sections that are not included There are many cases where a section may have changed due to soure-level change but the inclusion logic has not selected it for output. Some of these cases are real no-go situations like changing data structures. Some are just situations that create-diff-object isn't smart enough to figure out (yet). Either way, it should be considered fatal when a changed section hasn't been selected for output. Signed-off-by: Seth Jennings --- kpatch-build/create-diff-object.c | 35 ++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 3b1951a..cfea7b8 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -720,6 +720,16 @@ void kpatch_dump_kelf(struct kpatch_elf *kelf) } } +void kpatch_verify_patchability(struct kpatch_elf *kelf) +{ + struct section *sec; + int i; + + for_each_section(i, sec, &kelf->sections) + if (sec->status == CHANGED && !sec->include) + DIFF_FATAL("changed section %s not selected for inclusion", sec->name); +} + int kpatch_find_changed_functions(struct kpatch_elf *kelf) { struct symbol *sym; @@ -782,6 +792,20 @@ out: return; } +void kpatch_include_standard_sections(struct kpatch_elf *kelf) +{ + struct section *sec; + int i; + + for_each_section(i, sec, &kelf->sections) { + /* include these sections even if they haven't changed */ + if (!strcmp(sec->name, ".shstrtab") || + !strcmp(sec->name, ".strtab") || + !strcmp(sec->name, ".symtab")) + sec->include = 1; + } +} + int kpatch_include_changed_functions(struct kpatch_elf *kelf) { struct symbol *sym; @@ -858,16 +882,9 @@ void kpatch_generate_output(struct kpatch_elf *kelf, struct kpatch_elf **kelfout struct kpatch_elf *out; /* count output sections */ - for_each_section(i, sec, &kelf->sections) { - /* include these sections even if they haven't changed */ - if (!strcmp(sec->name, ".shstrtab") || - !strcmp(sec->name, ".strtab") || - !strcmp(sec->name, ".symtab")) - sec->include = 1; - + for_each_section(i, sec, &kelf->sections) if (sec->include) sections_nr++; - } log_debug("outputting %d sections\n",sections_nr); @@ -1312,11 +1329,13 @@ int main(int argc, char *argv[]) */ kpatch_replace_sections_syms(kelf_patched); + kpatch_include_standard_sections(kelf_patched); if (!kpatch_include_changed_functions(kelf_patched)) { log_normal("no changed functions were found\n"); return 3; /* 1 is ERROR, 2 is DIFF_FATAL */ } kpatch_dump_kelf(kelf_patched); + kpatch_verify_patchability(kelf_patched); /* Generate the output elf */ kpatch_generate_output(kelf_patched, &kelf_out);