From c24d135f403cdaf71158b185705c4214fb9d6e3e Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Wed, 11 May 2022 14:02:58 -0700 Subject: [PATCH] create-diff-object: rename "sec" -> "relasec" for rela sections Several functions expect to take a ".rela" section as an argument. Make such cases more clear by renaming "sec" -> "relasec". Signed-off-by: Josh Poimboeuf --- kpatch-build/create-diff-object.c | 239 +++++++++++++++--------------- kpatch-build/create-klp-module.c | 46 +++--- kpatch-build/kpatch-elf.c | 31 ++-- 3 files changed, 159 insertions(+), 157 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 826741d..903b92c 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -506,7 +506,7 @@ static bool rela_equal(struct rela *rela1, struct rela *rela2) return !kpatch_mangled_strcmp(rela_toc1->sym->name, rela_toc2->sym->name); } -static void kpatch_compare_correlated_rela_section(struct section *sec) +static void kpatch_compare_correlated_rela_section(struct section *relasec) { struct rela *rela1, *rela2 = NULL; @@ -514,22 +514,22 @@ static void kpatch_compare_correlated_rela_section(struct section *sec) * On ppc64le, don't compare the .rela.toc section. The .toc and * .rela.toc sections are included as standard elements. */ - if (!strcmp(sec->name, ".rela.toc")) { - sec->status = SAME; + if (!strcmp(relasec->name, ".rela.toc")) { + relasec->status = SAME; return; } - rela2 = list_entry(sec->twin->relas.next, struct rela, list); - list_for_each_entry(rela1, &sec->relas, list) { + rela2 = list_entry(relasec->twin->relas.next, struct rela, list); + list_for_each_entry(rela1, &relasec->relas, list) { if (rela_equal(rela1, rela2)) { rela2 = list_entry(rela2->list.next, struct rela, list); continue; } - sec->status = CHANGED; + relasec->status = CHANGED; return; } - sec->status = SAME; + relasec->status = SAME; } static void kpatch_compare_correlated_nonrela_section(struct section *sec) @@ -1138,13 +1138,13 @@ static char *kpatch_section_function_name(struct section *sec) return sec->sym ? sec->sym->name : sec->name; } -static struct symbol *kpatch_find_uncorrelated_rela(struct section *rela_sec, +static struct symbol *kpatch_find_uncorrelated_rela(struct section *relasec, struct symbol *sym) { struct rela *rela, *rela_toc; /* find the patched object's corresponding variable */ - list_for_each_entry(rela, &rela_sec->relas, list) { + list_for_each_entry(rela, &relasec->relas, list) { struct symbol *patched_sym; rela_toc = toc_rela(rela); @@ -1198,34 +1198,34 @@ static struct symbol *kpatch_find_static_twin_in_children(struct symbol *parent, * in the base object, find a corresponding usage of a similarly named symbol * in the patched object. */ -static struct symbol *kpatch_find_static_twin(struct section *sec, +static struct symbol *kpatch_find_static_twin(struct section *relasec, struct symbol *sym) { struct symbol *res; - if (!sec->twin && sec->base->sym) { + if (!relasec->twin && relasec->base->sym) { struct symbol *parent = NULL; /* * The static twin might have been in a .part. symbol in the * original object that got removed in the patched object. */ - parent = kpatch_get_correlated_parent(sec->base->sym); + parent = kpatch_get_correlated_parent(relasec->base->sym); if (parent) - sec = parent->sec->rela; + relasec = parent->sec->rela; } - if (!sec->twin) + if (!relasec->twin) return NULL; - res = kpatch_find_uncorrelated_rela(sec->twin, sym); + res = kpatch_find_uncorrelated_rela(relasec->twin, sym); if (res != NULL) return res; /* Look if reference might have moved to child functions' sections */ - if (sec->twin->base->sym) - return kpatch_find_static_twin_in_children(sec->twin->base->sym, + if (relasec->twin->base->sym) + return kpatch_find_static_twin_in_children(relasec->twin->base->sym, sym); return NULL; @@ -1248,18 +1248,19 @@ static bool kpatch_is_normal_static_local(struct symbol *sym) return true; } -static struct rela *kpatch_find_static_twin_ref(struct section *rela_sec, struct symbol *sym) +static struct rela *kpatch_find_static_twin_ref(struct section *relasec, + struct symbol *sym) { struct rela *rela; - list_for_each_entry(rela, &rela_sec->relas, list) { + list_for_each_entry(rela, &relasec->relas, list) { if (rela->sym == sym->twin) return rela; } /* Reference to static variable might have moved to child function section */ - if (rela_sec->base->sym) { - struct symbol *parent = rela_sec->base->sym; + if (relasec->base->sym) { + struct symbol *parent = relasec->base->sym; struct symbol *child; list_for_each_entry(child, &parent->children, subfunction_node) { @@ -1305,7 +1306,7 @@ static void kpatch_correlate_static_local_variables(struct kpatch_elf *orig, struct kpatch_elf *patched) { struct symbol *sym, *patched_sym; - struct section *sec; + struct section *relasec; struct rela *rela; int bundled, patched_bundled; @@ -1338,14 +1339,14 @@ static void kpatch_correlate_static_local_variables(struct kpatch_elf *orig, * Do the correlations: for each section reference to a static local, * look for a corresponding reference in the section's twin. */ - list_for_each_entry(sec, &orig->sections, list) { + list_for_each_entry(relasec, &orig->sections, list) { - if (!is_rela_section(sec) || - is_debug_section(sec) || - !strcmp(sec->name, ".rela.toc")) + if (!is_rela_section(relasec) || + is_debug_section(relasec) || + !strcmp(relasec->name, ".rela.toc")) continue; - list_for_each_entry(rela, &sec->relas, list) { + list_for_each_entry(rela, &relasec->relas, list) { if (!toc_rela(rela)) continue; /* skip toc constants */ @@ -1358,7 +1359,7 @@ static void kpatch_correlate_static_local_variables(struct kpatch_elf *orig, continue; bundled = sym == sym->sec->sym; - if (bundled && sym->sec == sec->base) { + if (bundled && sym->sec == relasec->base) { /* * A rare case where a static local data * structure references itself. There's no @@ -1371,11 +1372,11 @@ static void kpatch_correlate_static_local_variables(struct kpatch_elf *orig, continue; } - patched_sym = kpatch_find_static_twin(sec, sym); + patched_sym = kpatch_find_static_twin(relasec, sym); if (!patched_sym) DIFF_FATAL("reference to static local variable %s in %s was removed", sym->name, - kpatch_section_function_name(sec)); + kpatch_section_function_name(relasec)); patched_bundled = patched_sym == patched_sym->sec->sym; if (bundled != patched_bundled) @@ -1401,23 +1402,23 @@ static void kpatch_correlate_static_local_variables(struct kpatch_elf *orig, * corresponding reference in the patched object (because a static * local can be referenced by more than one section). */ - list_for_each_entry(sec, &orig->sections, list) { + list_for_each_entry(relasec, &orig->sections, list) { - if (!is_rela_section(sec) || - is_debug_section(sec)) + if (!is_rela_section(relasec) || + is_debug_section(relasec)) continue; - list_for_each_entry(rela, &sec->relas, list) { - struct section *target_sec = sec; + list_for_each_entry(rela, &relasec->relas, list) { + struct section *target_sec = relasec; sym = rela->sym; if (!kpatch_is_normal_static_local(sym)) continue; - if (!sec->twin && sec->base->sym) { + if (!relasec->twin && relasec->base->sym) { struct symbol *parent = NULL; - parent = kpatch_get_correlated_parent(sec->base->sym); + parent = kpatch_get_correlated_parent(relasec->base->sym); if (parent) target_sec = parent->sec->rela; } @@ -1439,13 +1440,13 @@ static void kpatch_correlate_static_local_variables(struct kpatch_elf *orig, * static locals to see if we need to print any warnings about new * variables. */ - list_for_each_entry(sec, &patched->sections, list) { + list_for_each_entry(relasec, &patched->sections, list) { - if (!is_rela_section(sec) || - is_debug_section(sec)) + if (!is_rela_section(relasec) || + is_debug_section(relasec)) continue; - list_for_each_entry(rela, &sec->relas, list) { + list_for_each_entry(rela, &relasec->relas, list) { sym = rela->sym; if (!kpatch_is_normal_static_local(sym)) @@ -1456,7 +1457,7 @@ static void kpatch_correlate_static_local_variables(struct kpatch_elf *orig, log_normal("WARNING: unable to correlate static local variable %s used by %s, assuming variable is new\n", sym->name, - kpatch_section_function_name(sec)); + kpatch_section_function_name(relasec)); return; } } @@ -1476,13 +1477,13 @@ static void kpatch_compare_correlated_elements(struct kpatch_elf *kelf) kpatch_compare_symbols(&kelf->symbols); } -static void rela_insn(const struct section *sec, const struct rela *rela, +static void rela_insn(const struct section *relasec, const struct rela *rela, struct insn *insn) { unsigned long insn_addr, start, end, rela_addr; - start = (unsigned long)sec->base->data->d_buf; - end = start + sec->base->sh.sh_size; + start = (unsigned long)relasec->base->data->d_buf; + end = start + relasec->base->sh.sh_size; if (end <= start) ERROR("bad section size"); @@ -1493,7 +1494,7 @@ static void rela_insn(const struct section *sec, const struct rela *rela, insn_get_length(insn); if (!insn->length) ERROR("can't decode instruction in section %s at offset 0x%lx", - sec->base->name, insn_addr); + relasec->base->name, insn_addr); if (rela_addr >= insn_addr && rela_addr < insn_addr + insn->length) return; @@ -1531,19 +1532,19 @@ static bool is_callback_section(struct section *sec) { */ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf) { - struct section *sec; + struct section *relasec; struct rela *rela; struct symbol *sym; unsigned int add_off; log_debug("\n"); - list_for_each_entry(sec, &kelf->sections, list) { - if (!is_rela_section(sec) || - is_debug_section(sec)) + list_for_each_entry(relasec, &kelf->sections, list) { + if (!is_rela_section(relasec) || + is_debug_section(relasec)) continue; - list_for_each_entry(rela, &sec->relas, list) { + list_for_each_entry(rela, &relasec->relas, list) { if (rela->sym->type != STT_SECTION || !rela->sym->sec) continue; @@ -1577,9 +1578,9 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf) if (rela->type == R_X86_64_PC32 || rela->type == R_X86_64_PLT32) { struct insn insn; - rela_insn(sec, rela, &insn); + rela_insn(relasec, rela, &insn); add_off = (unsigned int)((long)insn.next_byte - - (long)sec->base->data->d_buf - + (long)relasec->base->data->d_buf - rela->offset); } else if (rela->type == R_X86_64_64 || rela->type == R_X86_64_32S) @@ -1647,7 +1648,7 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf) continue; log_debug("%s: replacing %s+%ld reference with %s+%ld\n", - sec->name, + relasec->name, rela->sym->name, rela->addend, sym->name, rela->addend - start); @@ -2164,17 +2165,17 @@ static int fixup_barrier_nospec_group_size(struct kpatch_elf *kelf, int offset) */ static int fixup_group_size(struct kpatch_elf *kelf, int offset) { - struct section *sec; + struct section *relasec; struct rela *rela; int found; - sec = find_section_by_name(&kelf->sections, ".rela__ex_table"); - if (!sec) + relasec = find_section_by_name(&kelf->sections, ".rela__ex_table"); + if (!relasec) ERROR("missing .rela__ex_table section"); /* find beginning of this group */ found = 0; - list_for_each_entry(rela, &sec->relas, list) { + list_for_each_entry(rela, &relasec->relas, list) { if (!strcmp(rela->sym->name, ".fixup") && rela->addend == offset) { found = 1; @@ -2187,7 +2188,7 @@ static int fixup_group_size(struct kpatch_elf *kelf, int offset) /* find beginning of next group */ found = 0; - list_for_each_entry_continue(rela, &sec->relas, list) { + list_for_each_entry_continue(rela, &relasec->relas, list) { if (!strcmp(rela->sym->name, ".fixup") && rela->addend > offset) { found = 1; @@ -2287,7 +2288,7 @@ static struct special_section special_sections[] = { }; static bool should_keep_jump_label(struct lookup_table *lookup, - struct section *sec, + struct section *relasec, unsigned int group_offset, unsigned int group_size, int *jump_labels_found) @@ -2302,7 +2303,7 @@ static bool should_keep_jump_label(struct lookup_table *lookup, * struct. It has three fields: code, target, and key. Each field has * a relocation associated with it. */ - list_for_each_entry(rela, &sec->relas, list) { + list_for_each_entry(rela, &relasec->relas, list) { if (rela->offset >= group_offset && rela->offset < group_offset + group_size) { if (i == 0) @@ -2389,29 +2390,29 @@ static bool should_keep_jump_label(struct lookup_table *lookup, } static bool should_keep_rela_group(struct lookup_table *lookup, - struct section *sec, unsigned int offset, + struct section *relasec, unsigned int offset, unsigned int size, int *jump_labels_found) { struct rela *rela; bool found = false; /* check if any relas in the group reference any changed functions */ - list_for_each_entry(rela, &sec->relas, list) { + list_for_each_entry(rela, &relasec->relas, list) { if (rela->offset >= offset && rela->offset < offset + size && rela->sym->type == STT_FUNC && rela->sym->sec->include) { found = true; log_debug("new/changed symbol %s found in special section %s\n", - rela->sym->name, sec->name); + rela->sym->name, relasec->name); } } if (!found) return false; - if (!strcmp(sec->name, ".rela__jump_table")) - return should_keep_jump_label(lookup, sec, offset, size, + if (!strcmp(relasec->name, ".rela__jump_table")) + return should_keep_jump_label(lookup, relasec, offset, size, jump_labels_found); return true; @@ -2428,13 +2429,13 @@ static void kpatch_update_ex_table_addend(struct kpatch_elf *kelf, int group_size) { struct rela *rela; - struct section *sec; + struct section *relasec; - sec = find_section_by_name(&kelf->sections, ".rela__ex_table"); - if (!sec) + relasec = find_section_by_name(&kelf->sections, ".rela__ex_table"); + if (!relasec) ERROR("missing .rela__ex_table section"); - list_for_each_entry(rela, &sec->relas, list) { + list_for_each_entry(rela, &relasec->relas, list) { if (!strcmp(rela->sym->name, ".fixup") && rela->addend >= src_offset && rela->addend < src_offset + group_size) @@ -2445,7 +2446,7 @@ static void kpatch_update_ex_table_addend(struct kpatch_elf *kelf, static void kpatch_regenerate_special_section(struct kpatch_elf *kelf, struct lookup_table *lookup, struct special_section *special, - struct section *sec) + struct section *relasec) { struct rela *rela, *safe; char *src, *dest; @@ -2454,15 +2455,15 @@ static void kpatch_regenerate_special_section(struct kpatch_elf *kelf, LIST_HEAD(newrelas); - src = sec->base->data->d_buf; + src = relasec->base->data->d_buf; /* alloc buffer for new base section */ - dest = malloc(sec->base->sh.sh_size); + dest = malloc(relasec->base->sh.sh_size); if (!dest) ERROR("malloc"); /* Restore the stashed r_addend from kpatch_update_ex_table_addend. */ if (!strcmp(special->name, "__ex_table")) { - list_for_each_entry(rela, &sec->relas, list) { + list_for_each_entry(rela, &relasec->relas, list) { if (!strcmp(rela->sym->name, ".fixup")) rela->addend = rela->rela.r_addend; } @@ -2470,7 +2471,7 @@ static void kpatch_regenerate_special_section(struct kpatch_elf *kelf, src_offset = 0; dest_offset = 0; - for ( ; src_offset < sec->base->sh.sh_size; src_offset += group_size) { + for ( ; src_offset < relasec->base->sh.sh_size; src_offset += group_size) { group_size = special->group_size(kelf, src_offset); @@ -2482,10 +2483,10 @@ static void kpatch_regenerate_special_section(struct kpatch_elf *kelf, * contains the data but doesn't go past the end of the * section. */ - if (src_offset + group_size > sec->base->sh.sh_size) - group_size = (unsigned int)(sec->base->sh.sh_size - src_offset); + if (src_offset + group_size > relasec->base->sh.sh_size) + group_size = (unsigned int)(relasec->base->sh.sh_size - src_offset); - if (!should_keep_rela_group(lookup, sec, src_offset, group_size, + if (!should_keep_rela_group(lookup, relasec, src_offset, group_size, &jump_labels_found)) continue; @@ -2494,7 +2495,7 @@ static void kpatch_regenerate_special_section(struct kpatch_elf *kelf, * aren't sorted (e.g. .rela.fixup), so go through the entire * rela list each time. */ - list_for_each_entry_safe(rela, safe, &sec->relas, list) { + list_for_each_entry_safe(rela, safe, &relasec->relas, list) { if (rela->offset >= src_offset && rela->offset < src_offset + group_size) { /* copy rela entry */ @@ -2525,21 +2526,21 @@ static void kpatch_regenerate_special_section(struct kpatch_elf *kelf, if (!dest_offset) { /* no changed or global functions referenced */ - sec->status = sec->base->status = SAME; - sec->include = sec->base->include = 0; + relasec->status = relasec->base->status = SAME; + relasec->include = relasec->base->include = 0; free(dest); return; } /* overwrite with new relas list */ - list_replace(&newrelas, &sec->relas); + list_replace(&newrelas, &relasec->relas); /* include both rela and base sections */ - sec->include = 1; - sec->base->include = 1; + relasec->include = 1; + relasec->base->include = 1; /* include secsym so .kpatch.arch relas can point to section symbols */ - if (sec->base->secsym) - sec->base->secsym->include = 1; + if (relasec->base->secsym) + relasec->base->secsym->include = 1; /* * Update text section data buf and size. @@ -2547,8 +2548,8 @@ static void kpatch_regenerate_special_section(struct kpatch_elf *kelf, * The rela section's data buf and size will be regenerated in * kpatch_rebuild_rela_section_data(). */ - sec->base->data->d_buf = dest; - sec->base->data->d_size = dest_offset; + relasec->base->data->d_buf = dest; + relasec->base->data->d_size = dest_offset; } #define ORC_IP_PTR_SIZE 4 @@ -2645,18 +2646,18 @@ next: static void kpatch_check_relocations(struct kpatch_elf *kelf) { struct rela *rela; - struct section *sec; + struct section *relasec; Elf_Data *sdata; - list_for_each_entry(sec, &kelf->sections, list) { - if (!is_rela_section(sec)) + list_for_each_entry(relasec, &kelf->sections, list) { + if (!is_rela_section(relasec)) continue; - list_for_each_entry(rela, &sec->relas, list) { + list_for_each_entry(rela, &relasec->relas, list) { if (rela->sym->sec) { sdata = rela->sym->sec->data; if ((long)rela->sym->sym.st_value + rela->addend > (long)sdata->d_size) { ERROR("out-of-range relocation %s+%lx in %s", rela->sym->name, - rela->addend, sec->name); + rela->addend, relasec->name); } } } @@ -3076,11 +3077,11 @@ static int function_ptr_rela(const struct rela *rela) } static bool need_dynrela(struct kpatch_elf *kelf, struct lookup_table *table, - struct section *sec, const struct rela *rela) + struct section *relasec, const struct rela *rela) { struct lookup_result symbol; - if (is_debug_section(sec)) + if (is_debug_section(relasec)) return false; /* @@ -3092,7 +3093,7 @@ static bool need_dynrela(struct kpatch_elf *kelf, struct lookup_table *table, return false; /* v5.13+ kernels use relative jump labels */ - if (rela->type == R_PPC64_REL64 && strcmp(sec->name, ".rela__jump_table")) + if (rela->type == R_PPC64_REL64 && strcmp(relasec->name, ".rela__jump_table")) return false; /* @@ -3249,7 +3250,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, char *pmod_name) { int nr, index; - struct section *sec, *ksym_sec, *krela_sec; + struct section *relasec, *ksym_sec, *krela_sec; struct rela *rela, *rela2, *safe; struct symbol *strsym, *ksym_sec_sym; struct kpatch_symbol *ksyms; @@ -3261,12 +3262,12 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, /* count rela entries that need to be dynamic */ nr = 0; - list_for_each_entry(sec, &kelf->sections, list) { - if (!is_rela_section(sec)) + list_for_each_entry(relasec, &kelf->sections, list) { + if (!is_rela_section(relasec)) continue; - if (!strcmp(sec->name, ".rela.kpatch.funcs")) + if (!strcmp(relasec->name, ".rela.kpatch.funcs")) continue; - list_for_each_entry(rela, &sec->relas, list) { + list_for_each_entry(rela, &relasec->relas, list) { /* upper bound on number of kpatch relas and symbols */ nr++; @@ -3282,7 +3283,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, * internal symbol function pointer check which is done * via .toc indirection in need_dynrela(). */ - if (need_dynrela(kelf, table, sec, rela)) + if (need_dynrela(kelf, table, relasec, rela)) toc_rela(rela)->need_dynrela = 1; } } @@ -3310,12 +3311,12 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, /* populate sections */ index = 0; - list_for_each_entry(sec, &kelf->sections, list) { - if (!is_rela_section(sec)) + list_for_each_entry(relasec, &kelf->sections, list) { + if (!is_rela_section(relasec)) continue; - if (!strcmp(sec->name, ".rela.kpatch.funcs") || - !strcmp(sec->name, ".rela.kpatch.relocations") || - !strcmp(sec->name, ".rela.kpatch.symbols")) + if (!strcmp(relasec->name, ".rela.kpatch.funcs") || + !strcmp(relasec->name, ".rela.kpatch.relocations") || + !strcmp(relasec->name, ".rela.kpatch.symbols")) continue; special = false; @@ -3323,11 +3324,11 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, if ((s->arch & kelf->arch) == 0) continue; - if (!strcmp(sec->base->name, s->name)) + if (!strcmp(relasec->base->name, s->name)) special = true; } - list_for_each_entry_safe(rela, safe, &sec->relas, list) { + list_for_each_entry_safe(rela, safe, &relasec->relas, list) { if (!rela->need_dynrela) { rela->sym->strip = SYMBOL_USED; continue; @@ -3348,7 +3349,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, */ if (!KLP_ARCH && !vmlinux && special) ERROR("unsupported dynrela reference to symbol '%s' in module-specific special section '%s'", - rela->sym->name, sec->base->name); + rela->sym->name, relasec->base->name); if (!lookup_symbol(table, rela->sym, &symbol)) ERROR("can't find symbol '%s' in symbol table", @@ -3394,11 +3395,11 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, /* add rela to fill in krelas[index].dest field */ ALLOC_LINK(rela2, &krela_sec->rela->relas); - if (sec->base->secsym) - rela2->sym = sec->base->secsym; + if (relasec->base->secsym) + rela2->sym = relasec->base->secsym; else ERROR("can't create dynrela for section %s (symbol %s): no bundled or section symbol", - sec->name, rela->sym->name); + relasec->name, rela->sym->name); rela2->type = absolute_rela_type(kelf); rela2->addend = rela->offset; @@ -3833,7 +3834,7 @@ int main(int argc, char *argv[]) struct arguments arguments; int num_changed, callbacks_exist, new_globals_exist; struct lookup_table *lookup; - struct section *sec, *symtab; + struct section *relasec, *symtab; char *orig_obj, *patched_obj, *parent_name; char *parent_symtab, *mod_symvers, *patch_name, *output_obj; @@ -3958,12 +3959,12 @@ int main(int argc, char *argv[]) if (!symtab) ERROR("missing .symtab section"); - list_for_each_entry(sec, &kelf_out->sections, list) { - if (!is_rela_section(sec)) + list_for_each_entry(relasec, &kelf_out->sections, list) { + if (!is_rela_section(relasec)) continue; - sec->sh.sh_link = symtab->index; - sec->sh.sh_info = sec->base->index; - kpatch_rebuild_rela_section_data(sec); + relasec->sh.sh_link = symtab->index; + relasec->sh.sh_info = relasec->base->index; + kpatch_rebuild_rela_section_data(relasec); } kpatch_check_relocations(kelf_out); diff --git a/kpatch-build/create-klp-module.c b/kpatch-build/create-klp-module.c index c036b94..e942b9e 100644 --- a/kpatch-build/create-klp-module.c +++ b/kpatch-build/create-klp-module.c @@ -122,37 +122,37 @@ static struct section *find_or_add_klp_relasec(struct kpatch_elf *kelf, struct section *base, char *objname) { - struct section *sec; + struct section *relasec; char buf[256]; /* .klp.rela.objname.secname */ snprintf(buf, 256, KLP_RELASEC_PREFIX "%s.%s", objname, base->name); - list_for_each_entry(sec, &kelf->sections, list) { - if (!strcmp(sec->name, buf)) - return sec; + list_for_each_entry(relasec, &kelf->sections, list) { + if (!strcmp(relasec->name, buf)) + return relasec; } - ALLOC_LINK(sec, &kelf->sections); - sec->name = strdup(buf); - if (!sec->name) + ALLOC_LINK(relasec, &kelf->sections); + relasec->name = strdup(buf); + if (!relasec->name) ERROR("strdup"); - sec->base = base; + relasec->base = base; - INIT_LIST_HEAD(&sec->relas); + INIT_LIST_HEAD(&relasec->relas); - sec->data = malloc(sizeof(*sec->data)); - if (!sec->data) + relasec->data = malloc(sizeof(*relasec->data)); + if (!relasec->data) ERROR("malloc"); - sec->data->d_type = ELF_T_RELA; + relasec->data->d_type = ELF_T_RELA; /* sh_info and sh_link are set when rebuilding rela sections */ - sec->sh.sh_type = SHT_RELA; - sec->sh.sh_entsize = sizeof(GElf_Rela); - sec->sh.sh_addralign = 8; - sec->sh.sh_flags = SHF_RELA_LIVEPATCH | SHF_INFO_LINK | SHF_ALLOC; + relasec->sh.sh_type = SHT_RELA; + relasec->sh.sh_entsize = sizeof(GElf_Rela); + relasec->sh.sh_addralign = 8; + relasec->sh.sh_flags = SHF_RELA_LIVEPATCH | SHF_INFO_LINK | SHF_ALLOC; - return sec; + return relasec; } /* @@ -429,7 +429,7 @@ static struct argp argp = { options, parse_opt, args_doc, 0 }; int main(int argc, char *argv[]) { struct kpatch_elf *kelf; - struct section *symtab, *sec; + struct section *symtab, *relasec; struct section *ksymsec, *krelasec, *strsec; struct arguments arguments; char *strings; @@ -493,12 +493,12 @@ int main(int argc, char *argv[]) if (!symtab) ERROR("missing .symtab section"); - list_for_each_entry(sec, &kelf->sections, list) { - if (!is_rela_section(sec)) + list_for_each_entry(relasec, &kelf->sections, list) { + if (!is_rela_section(relasec)) continue; - sec->sh.sh_link = symtab->index; - sec->sh.sh_info = sec->base->index; - kpatch_rebuild_rela_section_data(sec); + relasec->sh.sh_link = symtab->index; + relasec->sh.sh_info = relasec->base->index; + kpatch_rebuild_rela_section_data(relasec); } kpatch_create_shstrtab(kelf); diff --git a/kpatch-build/kpatch-elf.c b/kpatch-build/kpatch-elf.c index 1de8613..8a95259 100644 --- a/kpatch-build/kpatch-elf.c +++ b/kpatch-build/kpatch-elf.c @@ -164,7 +164,8 @@ int offset_of_string(struct list_head *list, char *name) return index; } -static void kpatch_create_rela_list(struct kpatch_elf *kelf, struct section *sec) +static void kpatch_create_rela_list(struct kpatch_elf *kelf, + struct section *relasec) { int index = 0, skip = 0; struct rela *rela; @@ -172,28 +173,28 @@ static void kpatch_create_rela_list(struct kpatch_elf *kelf, struct section *sec unsigned long rela_nr; /* find matching base (text/data) section */ - sec->base = find_section_by_index(&kelf->sections, sec->sh.sh_info); - if (!sec->base) - ERROR("can't find base section for rela section %s", sec->name); + relasec->base = find_section_by_index(&kelf->sections, relasec->sh.sh_info); + if (!relasec->base) + ERROR("can't find base section for rela section %s", relasec->name); /* create reverse link from base section to this rela section */ - sec->base->rela = sec; + relasec->base->rela = relasec; - rela_nr = sec->sh.sh_size / sec->sh.sh_entsize; + rela_nr = relasec->sh.sh_size / relasec->sh.sh_entsize; log_debug("\n=== rela list for %s (%ld entries) ===\n", - sec->base->name, rela_nr); + relasec->base->name, rela_nr); - if (is_debug_section(sec)) { + if (is_debug_section(relasec)) { log_debug("skipping rela listing for .debug_* section\n"); skip = 1; } /* read and store the rela entries */ while (rela_nr--) { - ALLOC_LINK(rela, &sec->relas); + ALLOC_LINK(rela, &relasec->relas); - if (!gelf_getrela(sec->data, index, &rela->rela)) + if (!gelf_getrela(relasec->data, index, &rela->rela)) ERROR("gelf_getrela"); index++; @@ -346,7 +347,7 @@ struct kpatch_elf *kpatch_elf_open(const char *name) Elf *elf; int fd; struct kpatch_elf *kelf; - struct section *sec; + struct section *relasec; GElf_Ehdr ehdr; fd = open(name, O_RDONLY); @@ -372,11 +373,11 @@ struct kpatch_elf *kpatch_elf_open(const char *name) kpatch_create_symbol_list(kelf); /* for each rela section, read and store the rela entries */ - list_for_each_entry(sec, &kelf->sections, list) { - if (!is_rela_section(sec)) + list_for_each_entry(relasec, &kelf->sections, list) { + if (!is_rela_section(relasec)) continue; - INIT_LIST_HEAD(&sec->relas); - kpatch_create_rela_list(kelf, sec); + INIT_LIST_HEAD(&relasec->relas); + kpatch_create_rela_list(kelf, relasec); } if (!gelf_getehdr(kelf->elf, &ehdr))