From 92bb331ce71cfc33d933ebeabdbe9b5721c0ec75 Mon Sep 17 00:00:00 2001 From: Zhipeng Xie Date: Wed, 26 Feb 2020 07:09:50 -0500 Subject: [PATCH 02/21] kpatch-build: support build patch for aarch64 use R_AARCH64_ABS64 for aarch64 exclude line only change for arm64 by compare mov instruction except immediate part. add find_special_section_data_arm64 for arm64: arm64 kernel have no paravirt_patch_site or orc_entry structure in vmlinux, we don't need to check these two struct for arm64. support cross compile for aarch64 Signed-off-by: Zhipeng Xie --- kpatch-build/create-diff-object.c | 191 +++++++++++++++++++++++++--- kpatch-build/create-kpatch-module.c | 24 +++- kpatch-build/kpatch-build | 116 ++++++++++++++++- kpatch-build/kpatch-gcc | 4 +- 4 files changed, 306 insertions(+), 29 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 2707cdb..7a27b58 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -76,6 +76,31 @@ enum subsection { enum loglevel loglevel = NORMAL; +#ifndef EM_X86_64 +#define EM_X86_64 62 +#endif + +#ifndef EM_AARCH64 +#define EM_AARCH64 183 +#endif + +#ifndef R_AARCH64_ABS64 +#define R_AARCH64_NONE 0 +#define R_AARCH64_ABS64 257 +#define R_AARCH64_CALL26 283 +#endif + +static unsigned int arch; +static unsigned int absolute_rela_type; + +static unsigned int arch_of_elf(Elf *elf) +{ + GElf_Ehdr eh; + if (!gelf_getehdr(elf, &eh)) + ERROR("gelf_getehdr"); + return eh.e_machine; +} + /******************* * Data structures * ****************/ @@ -652,6 +677,67 @@ static int kpatch_line_macro_change_only(struct section *sec) return 1; } #endif +#define ARM64_INSTR_LEN 4 +static int arm64_kpatch_line_macro_change_only(struct section *sec) +{ + unsigned long start1, start2, size, offset; + struct rela *rela; + int lineonly = 0, found; + unsigned int mov_imm_mask = ((1<<16) - 1)<<5; + + if (sec->status != CHANGED || + is_rela_section(sec) || + !is_text_section(sec) || + sec->sh.sh_size != sec->twin->sh.sh_size || + !sec->rela || + sec->rela->status != SAME) + return 0; + + start1 = (unsigned long)sec->twin->data->d_buf; + start2 = (unsigned long)sec->data->d_buf; + size = sec->sh.sh_size; + for (offset = 0; offset < size; offset += ARM64_INSTR_LEN) { + if (!memcmp((void *)start1 + offset, (void *)start2 + offset, + ARM64_INSTR_LEN)) + continue; + + /* verify it's a mov immediate to w1 */ + if ((*(int *)(start1 + offset) & ~mov_imm_mask) != + (*(int *)(start2 + offset) & ~mov_imm_mask)) + return 0; + + found = 0; + list_for_each_entry(rela, &sec->rela->relas, list) { + if (rela->offset < offset + ARM64_INSTR_LEN) + continue; + if (rela->string) + continue; + if (!strncmp(rela->sym->name, "__warned.", 9)) + continue; + if (!strncmp(rela->sym->name, "warn_slowpath_", 14) || + (!strcmp(rela->sym->name, "__warn_printk")) || + (!strcmp(rela->sym->name, "__might_sleep")) || + (!strcmp(rela->sym->name, "___might_sleep")) || + (!strcmp(rela->sym->name, "__might_fault")) || + (!strcmp(rela->sym->name, "printk")) || + (!strcmp(rela->sym->name, "lockdep_rcu_suspicious"))) { + found = 1; + break; + } + return 0; + } + if (!found) + return 0; + + lineonly = 1; + } + + if (!lineonly) + ERROR("no instruction changes detected for changed section %s", + sec->name); + + return 1; +} static void kpatch_compare_sections(struct list_head *seclist) { @@ -667,7 +753,16 @@ static void kpatch_compare_sections(struct list_head *seclist) /* exclude WARN-only, might_sleep changes */ list_for_each_entry(sec, seclist, list) { - if (kpatch_line_macro_change_only(sec)) { + int line_only; + + if (arch == EM_X86_64) + line_only = kpatch_line_macro_change_only(sec); + else if (arch == EM_AARCH64) + line_only = arm64_kpatch_line_macro_change_only(sec); + else + line_only = 0; + + if (line_only) { log_debug("reverting macro / line number section %s status to SAME\n", sec->name); sec->status = SAME; @@ -727,6 +822,8 @@ static void kpatch_compare_correlated_symbol(struct symbol *sym) if ((sym2->sec->twin && sym2->sec->twin->ignore) || kpatch_subsection_changed(sym1->sec, sym2->sec)) sym->status = CHANGED; + else if (sym1->name[0] == '$') /* reserved symbols in aarch64 */ + log_debug("maping symbols: %s", sym1->name); /* do nothing just ignogre */ else DIFF_FATAL("symbol changed sections: %s", sym1->name); } @@ -1302,9 +1399,8 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf) continue; } -#ifdef __powerpc64__ add_off = 0; -#else + if (arch == EM_X86_64) { if (rela->type == R_X86_64_PC32 || rela->type == R_X86_64_PLT32) { struct insn insn; @@ -1317,7 +1413,7 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf) add_off = 0; else continue; -#endif + } /* * Attempt to replace references to unbundled sections @@ -2415,7 +2511,7 @@ static void kpatch_create_kpatch_arch_section(struct kpatch_elf *kelf, char *obj /* entries[index].sec */ ALLOC_LINK(rela, &karch_sec->rela->relas); rela->sym = sec->secsym; - rela->type = ABSOLUTE_RELA_TYPE; + rela->type = absolute_rela_type; rela->addend = 0; rela->offset = (unsigned int)(index * sizeof(struct kpatch_arch) + \ offsetof(struct kpatch_arch, sec)); @@ -2423,7 +2519,7 @@ static void kpatch_create_kpatch_arch_section(struct kpatch_elf *kelf, char *obj /* entries[index].objname */ ALLOC_LINK(rela, &karch_sec->rela->relas); rela->sym = strsym; - rela->type = ABSOLUTE_RELA_TYPE; + rela->type = absolute_rela_type; rela->addend = offset_of_string(&kelf->strings, objname); rela->offset = (unsigned int)(index * sizeof(struct kpatch_arch) + \ offsetof(struct kpatch_arch, objname)); @@ -2622,7 +2718,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf, */ ALLOC_LINK(rela, &relasec->relas); rela->sym = sym; - rela->type = ABSOLUTE_RELA_TYPE; + rela->type = absolute_rela_type; rela->addend = 0; rela->offset = (unsigned int)(index * sizeof(*funcs)); @@ -2632,7 +2728,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf, */ ALLOC_LINK(rela, &relasec->relas); rela->sym = strsym; - rela->type = ABSOLUTE_RELA_TYPE; + rela->type = absolute_rela_type; rela->addend = offset_of_string(&kelf->strings, sym->name); rela->offset = (unsigned int)(index * sizeof(*funcs) + offsetof(struct kpatch_patch_func, name)); @@ -2643,7 +2739,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf, */ ALLOC_LINK(rela, &relasec->relas); rela->sym = strsym; - rela->type = ABSOLUTE_RELA_TYPE; + rela->type = absolute_rela_type; rela->addend = objname_offset; rela->offset = (unsigned int)(index * sizeof(*funcs) + offsetof(struct kpatch_patch_func,objname)); @@ -2701,7 +2797,10 @@ static int function_ptr_rela(const struct rela *rela) rela_toc->addend == (int)rela_toc->sym->sym.st_value && (rela->type == R_X86_64_32S || rela->type == R_PPC64_TOC16_HA || - rela->type == R_PPC64_TOC16_LO_DS)); + rela->type == R_PPC64_TOC16_LO_DS || + rela->type == R_AARCH64_ADR_PREL_PG_HI21 || + rela->type == R_AARCH64_ADD_ABS_LO12_NC)); + } static int may_need_dynrela(const struct rela *rela) @@ -2955,7 +3054,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, /* add rela to fill in ksyms[index].name field */ ALLOC_LINK(rela2, &ksym_sec->rela->relas); rela2->sym = strsym; - rela2->type = ABSOLUTE_RELA_TYPE; + rela2->type = absolute_rela_type; rela2->addend = offset_of_string(&kelf->strings, rela->sym->name); rela2->offset = (unsigned int)(index * sizeof(*ksyms) + \ offsetof(struct kpatch_symbol, name)); @@ -2963,7 +3062,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, /* add rela to fill in ksyms[index].objname field */ ALLOC_LINK(rela2, &ksym_sec->rela->relas); rela2->sym = strsym; - rela2->type = ABSOLUTE_RELA_TYPE; + rela2->type = absolute_rela_type; rela2->addend = offset_of_string(&kelf->strings, sym_objname); rela2->offset = (unsigned int)(index * sizeof(*ksyms) + \ offsetof(struct kpatch_symbol, objname)); @@ -2984,7 +3083,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, ERROR("can't create dynrela for section %s (symbol %s): no bundled or section symbol", sec->name, rela->sym->name); - rela2->type = ABSOLUTE_RELA_TYPE; + rela2->type = absolute_rela_type; rela2->addend = rela->offset; rela2->offset = (unsigned int)(index * sizeof(*krelas) + \ offsetof(struct kpatch_relocation, dest)); @@ -2992,7 +3091,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, /* add rela to fill in krelas[index].objname field */ ALLOC_LINK(rela2, &krela_sec->rela->relas); rela2->sym = strsym; - rela2->type = ABSOLUTE_RELA_TYPE; + rela2->type = absolute_rela_type; rela2->addend = offset_of_string(&kelf->strings, objname); rela2->offset = (unsigned int)(index * sizeof(*krelas) + \ offsetof(struct kpatch_relocation, objname)); @@ -3000,7 +3099,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf, /* add rela to fill in krelas[index].ksym field */ ALLOC_LINK(rela2, &krela_sec->rela->relas); rela2->sym = ksym_sec_sym; - rela2->type = ABSOLUTE_RELA_TYPE; + rela2->type = absolute_rela_type; rela2->addend = (unsigned int)(index * sizeof(*ksyms)); rela2->offset = (unsigned int)(index * sizeof(*krelas) + \ offsetof(struct kpatch_relocation, ksym)); @@ -3063,7 +3162,7 @@ static void kpatch_create_callbacks_objname_rela(struct kpatch_elf *kelf, char * if (!strcmp(callbackp->name, sec->name)) { ALLOC_LINK(rela, &sec->relas); rela->sym = strsym; - rela->type = ABSOLUTE_RELA_TYPE; + rela->type = absolute_rela_type; rela->addend = objname_offset; rela->offset = callbackp->offset; break; @@ -3116,6 +3215,7 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf) /* add rela in .rela__mcount_loc to fill in function pointer */ ALLOC_LINK(rela, &relasec->relas); rela->sym = sym; + if (arch == EM_X86_64) { rela->type = R_X86_64_64; rela->addend = 0; rela->offset = (unsigned int)(index * sizeof(void*)); @@ -3151,6 +3251,40 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf) rela->type = R_X86_64_PC32; } + } else if (arch == EM_AARCH64) { + unsigned int *insnp; + rela->type = R_AARCH64_ABS64; + /* bl <__fentry__> is the second insn */ + rela->addend = 4; + rela->offset = (unsigned int)(index * sizeof(void*)); + + newdata = malloc(sym->sec->data->d_size); + if (!newdata) + ERROR("malloc"); + + memcpy(newdata, sym->sec->data->d_buf, sym->sec->data->d_size); + sym->sec->data->d_buf = newdata; + insnp = newdata; + + /* + * mov x9, x30 + * nop //function in .text., so it be replaced with nop by recordmcount + * mov x30, x9 + */ + if (insnp[0] != 0xaa1e03e9 || insnp[1] != 0xd503201f || insnp[2] != 0xaa0903fe) + ERROR("%s: unexpected instruction at the start of the function", + sym->name); + + /* change the nop to bl __fentry__ */ + insnp[1] = 0x94000000; + rela = list_first_entry(&sym->sec->rela->relas, struct rela, + list); + rela->type = R_AARCH64_CALL26; + rela->offset = 4; + + } else { + ERROR("unsupport arch %d\n", arch); + } index++; } @@ -3349,6 +3483,8 @@ int main(int argc, char *argv[]) char *hint = NULL, *orig_obj, *patched_obj, *parent_name; char *parent_symtab, *mod_symvers, *patch_name, *output_obj; struct sym_compare_type *base_locals, *sym_comp; + char *no_profiling_calls = NULL; + char *gcc_add_option = NULL, *mlongcall = NULL; arguments.debug = 0; argp_parse (&argp, argc, argv, 0, NULL, &arguments); @@ -3369,6 +3505,13 @@ int main(int argc, char *argv[]) kelf_base = kpatch_elf_open(orig_obj); kelf_patched = kpatch_elf_open(patched_obj); + arch = arch_of_elf(kelf_base->elf); + if (arch == EM_X86_64) + absolute_rela_type = R_X86_64_64; + else if (arch == EM_AARCH64) + absolute_rela_type = R_AARCH64_ABS64; + else + ERROR("only arch x86_64 and arm64 be supported\n"); kpatch_compare_elf_headers(kelf_base->elf, kelf_patched->elf); kpatch_check_program_headers(kelf_base->elf); @@ -3407,7 +3550,12 @@ int main(int argc, char *argv[]) */ kpatch_mark_ignored_sections(kelf_patched); kpatch_compare_correlated_elements(kelf_patched); - kpatch_check_func_profiling_calls(kelf_patched); + no_profiling_calls = getenv("NO_PROFILING_CALLS"); + if (!no_profiling_calls) + kpatch_check_func_profiling_calls(kelf_patched); + else + log_debug("NO_PROFILING_CALLS set\n"); + kpatch_elf_teardown(kelf_base); kpatch_elf_free(kelf_base); @@ -3467,7 +3615,14 @@ int main(int argc, char *argv[]) kpatch_create_callbacks_objname_rela(kelf_out, parent_name); kpatch_build_strings_section_data(kelf_out); - kpatch_create_mcount_sections(kelf_out); + gcc_add_option = getenv("GCC_ADD_OPTION"); + if (gcc_add_option) + mlongcall = strstr(gcc_add_option, "-mlong-calls"); + if (arch == EM_AARCH64 && mlongcall) { + printf("-mlong-calls found, no need to create mcount section\n"); + } else { + kpatch_create_mcount_sections(kelf_out); + } /* * At this point, the set of output sections and symbols is diff --git a/kpatch-build/create-kpatch-module.c b/kpatch-build/create-kpatch-module.c index 3d197a7..758630b 100644 --- a/kpatch-build/create-kpatch-module.c +++ b/kpatch-build/create-kpatch-module.c @@ -31,6 +31,17 @@ char *childobj; enum loglevel loglevel = NORMAL; +static unsigned int arch; +static unsigned int absolute_rela_type; + +static unsigned int arch_of_elf(Elf *elf) +{ + GElf_Ehdr eh; + if (!gelf_getehdr(elf, &eh)) + ERROR("gelf_getehdr"); + return eh.e_machine; +} + /* * Create .kpatch.dynrelas from .kpatch.relocations and .kpatch.symbols sections * @@ -102,14 +113,14 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section /* dest */ ALLOC_LINK(rela, &dynsec->rela->relas); rela->sym = sym; - rela->type = R_X86_64_64; + rela->type = absolute_rela_type; rela->addend = dest_offset; rela->offset = (unsigned int)(index * sizeof(*dynrelas)); /* name */ ALLOC_LINK(rela, &dynsec->rela->relas); rela->sym = strsec->secsym; - rela->type = R_X86_64_64; + rela->type = absolute_rela_type; rela->addend = name_offset; rela->offset = (unsigned int)(index * sizeof(*dynrelas) + \ offsetof(struct kpatch_patch_dynrela, name)); @@ -117,7 +128,7 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section /* objname */ ALLOC_LINK(rela, &dynsec->rela->relas); rela->sym = strsec->secsym; - rela->type = R_X86_64_64; + rela->type = absolute_rela_type; rela->addend = objname_offset; rela->offset = (unsigned int)(index * sizeof(*dynrelas) + \ offsetof(struct kpatch_patch_dynrela, objname)); @@ -200,6 +211,13 @@ int main(int argc, char *argv[]) childobj = basename(arguments.args[0]); kelf = kpatch_elf_open(arguments.args[0]); + arch = arch_of_elf(kelf->elf); + if (arch == EM_X86_64) + absolute_rela_type = R_X86_64_64; + else if (arch == EM_AARCH64) + absolute_rela_type = R_AARCH64_ABS64; + else + ERROR("only arch x86_64 and arm64 be supported\n"); /* * Sanity checks: diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build index ae0733c..17a5e11 100755 --- a/kpatch-build/kpatch-build +++ b/kpatch-build/kpatch-build @@ -299,12 +299,72 @@ find_special_section_data_ppc64le() { return } +find_special_section_data_arm64() { + + [[ "$CONFIG_JUMP_LABEL" -eq 0 ]] && AWK_OPTIONS="$AWK_OPTIONS -vskip_j=1" + + # If $AWK_OPTIONS are blank gawk would treat "" as a blank script + # shellcheck disable=SC2086 + SPECIAL_VARS="$(readelf -wi "$VMLINUX" | + gawk --non-decimal-data $AWK_OPTIONS ' + BEGIN { a = b = e = j = c = f = s = i = r = t = h = 0 } + + # Set state if name matches + a == 0 && /DW_AT_name.* alt_instr[[:space:]]*$/ {a = 1; next} + b == 0 && /DW_AT_name.* bug_entry[[:space:]]*$/ {b = 1; next} + e == 0 && /DW_AT_name.* exception_table_entry[[:space:]]*$/ {e = 1; next} + j == 0 && /DW_AT_name.* jump_entry[[:space:]]*$/ {j = 1; next} + c == 0 && /DW_AT_name.* klp_func[[:space:]]*$/ {c = 1; next} + t == 0 && /DW_AT_name.* klp_object[[:space:]]*$/ {t = 1; next} + + # Reset state unless this abbrev describes the struct size + a == 1 && !/DW_AT_byte_size/ { a = 0; next } + b == 1 && !/DW_AT_byte_size/ { b = 0; next } + e == 1 && !/DW_AT_byte_size/ { e = 0; next } + j == 1 && !/DW_AT_byte_size/ { j = 0; next } + c == 1 && /DW_TAG_structure_type/ { c = 3; next } + t == 1 && /DW_TAG_structure_type/ { t = 3; next } + c == 1 && /DW_AT_name.* force[[:space:]]*$/ {f = 2; next} + c == 1 && /DW_AT_name.* old_sympos[[:space:]]*$/ {s = 2; next} + i == 1 && /DW_AT_name.* immediate[[:space:]]*$/ {i = 2; next} + t == 1 && /DW_AT_name.* relocs[[:space:]]*$/ {r = 2; next} + t == 1 && /DW_AT_name.* hooks_load[[:space:]]*$/ {h = 2; next} + + # Now that we know the size, stop parsing for it + a == 1 {printf("export ALT_STRUCT_SIZE=%d\n", $4); a = 2} + b == 1 {printf("export BUG_STRUCT_SIZE=%d\n", $4); b = 2} + e == 1 {printf("export EX_STRUCT_SIZE=%d\n", $4); e = 2} + j == 1 {printf("export JUMP_STRUCT_SIZE=%d\n", $4); j = 2} + f == 2 {printf("export KLP_SUPPORT_FORCE=y\n"); f = 3} + s == 2 {printf("export KLP_SUPPORT_OLD_SYMPOS=y\n"); s = 3} + i == 2 {printf("export KLP_SUPPORT_IMMEDIATE=y\n"); i = 3} + r == 2 {printf("export KLP_SUPPORT_RELOCS=y\n"); r = 3} + h == 2 {printf("export KLP_SUPPORT_LOADHOOKS=y\n"); h = 3} + + # Bail out once we have everything + a == 2 && b == 2 && e == 2 && (j == 2 || skip_j) && c == 3 && t == 3 {exit}')" + + [[ -n "$SPECIAL_VARS" ]] && eval "$SPECIAL_VARS" + + [[ -z "$ALT_STRUCT_SIZE" ]] && die "can't find special struct alt_instr size" + [[ -z "$BUG_STRUCT_SIZE" ]] && die "can't find special struct bug_entry size" + [[ -z "$EX_STRUCT_SIZE" ]] && die "can't find special struct exception_table_entry size" + [[ -z "$JUMP_STRUCT_SIZE" && "$CONFIG_JUMP_LABEL" -ne 0 ]] && die "can't find special struct jump_entry size" + + return +} + find_special_section_data() { if [[ "$ARCH" = "ppc64le" ]]; then find_special_section_data_ppc64le return fi + if [[ "$ARCH" = "arm64" ]]; then + find_special_section_data_arm64 + return + fi + [[ "$CONFIG_PARAVIRT" -eq 0 ]] && AWK_OPTIONS="-vskip_p=1" [[ "$CONFIG_UNWINDER_ORC" -eq 0 ]] && AWK_OPTIONS="$AWK_OPTIONS -vskip_o=1" [[ "$CONFIG_JUMP_LABEL" -eq 0 ]] && AWK_OPTIONS="$AWK_OPTIONS -vskip_j=1" @@ -428,6 +488,29 @@ find_kobj() { done } +arch_export() { + E_MACHINE=$(od -An -j18 -N2 -d $VMLINUX) + if [[ $E_MACHINE -eq 62 ]]; then + export ARCH=x86_64 + export ARCH_COMPILE= + export ENDIAN=little + export GCC_ADD_OPTION= + elif [[ $E_MACHINE -eq 183 ]]; then + export ARCH=arm64 + if [ $(arch) != "aarch64" ]; then + export ARCH_COMPILE=aarch64-linux-gnu- + fi + export ENDIAN=little + if grep "\-mlong-calls" /lib/modules/$ARCHVERSION/build//Makefile > /dev/null; then + export GCC_ADD_OPTION="-fno-section-anchors -mlong-calls" + else + export GCC_ADD_OPTION="-fno-section-anchors" + fi + else + die "only support arm64 or x86_64 architecture" + fi +} + # Only allow alphanumerics and '_' and '-' in the module name. Everything else # is replaced with '-'. Also truncate to 48 chars so the full name fits in the # kernel's 56-byte module name array. @@ -786,13 +869,13 @@ apply_patches remove_patches cp -LR "$DATADIR/patch" "$TEMPDIR" || die - +arch_export if [[ "$ARCH" = "ppc64le" ]]; then ARCH_KCFLAGS="-mcmodel=large -fplugin=$PLUGINDIR/ppc64le-plugin.so" fi export KCFLAGS="-I$DATADIR/patch -ffunction-sections -fdata-sections \ - $ARCH_KCFLAGS $DEBUG_KCFLAGS" + $ARCH_KCFLAGS $DEBUG_KCFLAGS ${GCC_ADD_OPTION}" echo "Reading special section data" find_special_section_data @@ -806,7 +889,7 @@ echo "Building original source" unset KPATCH_GCC_TEMPDIR # $TARGETS used as list, no quotes. # shellcheck disable=SC2086 -CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make "-j$CPUS" $TARGETS 2>&1 | logger || die +CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" make "-j$CPUS" $TARGETS 2>&1 | logger || die echo "Building patched source" apply_patches @@ -817,7 +900,7 @@ KPATCH_GCC_SRCDIR="$SRCDIR" export KPATCH_GCC_SRCDIR # $TARGETS used as list, no quotes. # shellcheck disable=SC2086 -CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " \ +CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" \ KBUILD_MODPOST_WARN=1 \ make "-j$CPUS" $TARGETS 2>&1 | logger || die @@ -950,6 +1033,26 @@ if "$KPATCH_MODULE"; then export KCPPFLAGS="-D__KPATCH_MODULE__" fi +if [[ -n "$KLP_SUPPORT_FORCE" ]];then + export KCPPFLAGS="-D__KLP_SUPPORT_FORCE__ $KCPPFLAGS" +fi + +if [[ -n "$KLP_SUPPORT_OLD_SYMPOS" ]];then + export KCPPFLAGS="-DHAVE_SYMPOS $KCPPFLAGS" +fi + +if [[ -n "$KLP_SUPPORT_IMMEDIATE" ]];then + export KCPPFLAGS="-DHAVE_IMMEDIATE $KCPPFLAGS" +fi + +if [[ -n "$KLP_SUPPORT_RELOCS" ]];then + export KCPPFLAGS="-DHAVE_ELF_RELOCS $KCPPFLAGS" +fi + +if [[ -n "$KLP_SUPPORT_LOADHOOKS" ]];then + export KCPPFLAGS="-DHAVE_LOADHOOKS $KCPPFLAGS" +fi + echo "Building patch module: $MODNAME.ko" if [[ -z "$USERSRCDIR" ]] && [[ "$DISTRO" = ubuntu ]]; then @@ -962,12 +1065,12 @@ fi cd "$TEMPDIR/output" || die # $KPATCH_LDFLAGS and result of find used as list, no quotes. # shellcheck disable=SC2086,SC2046 -ld -r $KPATCH_LDFLAGS -o ../patch/tmp_output.o $(find . -name "*.o") 2>&1 | logger || die +${ARCH_COMPILE}ld -r $KPATCH_LDFLAGS -o ../patch/tmp_output.o $(find . -name "*.o") 2>&1 | logger || die if "$KPATCH_MODULE"; then # Add .kpatch.checksum for kpatch script md5sum ../patch/tmp_output.o | awk '{printf "%s\0", $1}' > checksum.tmp || die - objcopy --add-section .kpatch.checksum=checksum.tmp --set-section-flags .kpatch.checksum=alloc,load,contents,readonly ../patch/tmp_output.o || die + ${ARCH_COMPILE}objcopy --add-section .kpatch.checksum=checksum.tmp --set-section-flags .kpatch.checksum=alloc,load,contents,readonly ../patch/tmp_output.o || die rm -f checksum.tmp "$TOOLSDIR"/create-kpatch-module "$TEMPDIR"/patch/tmp_output.o "$TEMPDIR"/patch/output.o 2>&1 | logger 1 check_pipe_status create-kpatch-module @@ -984,6 +1087,7 @@ fi KPATCH_BUILD="$KPATCH_BUILD" KPATCH_NAME="$MODNAME" \ KBUILD_EXTRA_SYMBOLS="$KBUILD_EXTRA_SYMBOLS" \ KPATCH_LDFLAGS="$KPATCH_LDFLAGS" \ +CROSS_COMPILE="$ARCH_COMPILE" \ make 2>&1 | logger || die if ! "$KPATCH_MODULE"; then diff --git a/kpatch-build/kpatch-gcc b/kpatch-build/kpatch-gcc index 9663290..35d7c1c 100755 --- a/kpatch-build/kpatch-gcc +++ b/kpatch-build/kpatch-gcc @@ -13,7 +13,7 @@ fi declare -a args=("$@") -if [[ "$TOOLCHAINCMD" =~ "gcc" ]] ; then +if [[ "$TOOLCHAINCMD" =~ "${ARCH_COMPILE}gcc" ]] ; then while [ "$#" -gt 0 ]; do if [ "$1" = "-o" ]; then obj="$2" @@ -60,7 +60,7 @@ if [[ "$TOOLCHAINCMD" =~ "gcc" ]] ; then fi shift done -elif [[ "$TOOLCHAINCMD" = "ld" ]] ; then +elif [[ "$TOOLCHAINCMD" = "${ARCH_COMPILE}ld" ]] ; then while [ "$#" -gt 0 ]; do if [ "$1" = "-o" ]; then obj="$2" -- 2.18.1