diff --git a/0000-gensrc-skip-vector-instruction-in-str_do_gotpcrel.patch b/0000-gensrc-skip-vector-instruction-in-str_do_gotpcrel.patch new file mode 100644 index 0000000..f3b77b5 --- /dev/null +++ b/0000-gensrc-skip-vector-instruction-in-str_do_gotpcrel.patch @@ -0,0 +1,31 @@ +From ca5e000a30eae58e84c98fef9c511ef61ec00fbe Mon Sep 17 00:00:00 2001 +From: Chuan Zheng +Date: Mon, 26 Apr 2021 14:48:34 +0800 +Subject: [PATCH] gensrc: skip vector instruction in str_do_gotpcrel + +We might have "move (%rip) %0xmm0" in qemu hotpatch, which causes +gensrc failure in str_do_gotpcrel. +Fix it by skipping it because we do not need anything for vector command. +--- + src/kpatch_gensrc.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/kpatch_gensrc.c b/src/kpatch_gensrc.c +index a16b652..4f978f8 100644 +--- a/src/kpatch_gensrc.c ++++ b/src/kpatch_gensrc.c +@@ -291,6 +291,11 @@ void str_do_gotpcrel(struct kp_file *f, char *dst, char *src) + goto out; + } + ++ if (strstr(movdst.s, "%xmm") != NULL) { ++ /* Is SSE (%xmm0, etc), bail out */ ++ goto out; ++ } ++ + /* Use full 64-bit counterpart of the destination register + * as the auxiliary register */ + get_full_reg(&movdst, auxreg); +-- +2.27.0 + diff --git a/0001-gensrc-we-should-add-align-while-FLAGS_PUSH_SECTION-.patch b/0001-gensrc-we-should-add-align-while-FLAGS_PUSH_SECTION-.patch new file mode 100644 index 0000000..be5d8c0 --- /dev/null +++ b/0001-gensrc-we-should-add-align-while-FLAGS_PUSH_SECTION-.patch @@ -0,0 +1,32 @@ +From 9d601f4c697a9b2d926d92025bb43dd6ebf36033 Mon Sep 17 00:00:00 2001 +From: Bihong Yu +Date: Tue, 18 Jan 2022 19:29:12 +0800 +Subject: [PATCH] gensrc: we should add align while FLAGS_PUSH_SECTION flag is + set + +In order to ensure the .kpatch.text readable and executable and +the .kpatch.data readable and writeable, we should make sure the +.kpatch.data is page-align. So we should add align while the +.kpatch.data being pushed for the first time. + +Signed-off-by: Bihong Yu +--- + src/kpatch_gensrc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/kpatch_gensrc.c b/src/kpatch_gensrc.c +index 32c7afc..bf1832a 100644 +--- a/src/kpatch_gensrc.c ++++ b/src/kpatch_gensrc.c +@@ -448,7 +448,7 @@ static void change_section(struct kp_file *fout, struct section_desc *sect, int + s = ".kpatch.text,\"ax\",@progbits"; + else { + s = ".kpatch.data,\"aw\",@progbits"; +- if (!init_data_section && !(flags & FLAG_PUSH_SECTION)) { ++ if (!init_data_section && (flags & FLAG_PUSH_SECTION)) { + init_data_section = 1; + align = ".p2align\t12"; + } +-- +2.27.0 + diff --git a/0002-fix-cblock-parse-for-LCOLD-LHOT-.cold.NUM-.init_arra.patch b/0002-fix-cblock-parse-for-LCOLD-LHOT-.cold.NUM-.init_arra.patch new file mode 100644 index 0000000..9dcb918 --- /dev/null +++ b/0002-fix-cblock-parse-for-LCOLD-LHOT-.cold.NUM-.init_arra.patch @@ -0,0 +1,677 @@ +From c95f6cd656e9ccfd2e2b7169626cbc2f50b5e24b Mon Sep 17 00:00:00 2001 +From: ctyunsystem +Date: Tue, 18 Jan 2022 20:41:46 -0500 +Subject: [PATCH] fix cblock parse for LCOLD/LHOT/.cold.NUM, .init_array and + support gnu_unique_object + +--- + src/arch/aarch64/arch_parse.c | 24 +++- + src/arch/x86/arch_parse.c | 49 +++++++- + src/include/kpatch_parse.h | 2 + + src/kpatch_parse.c | 106 +++++++++++++++++- + tests/Makefile | 10 +- + tests/gcc_ge8_gensrc/Makefile | 26 +++++ + .../cold_func_suffix/cold_func_suffix.cpp | 48 ++++++++ + .../gcc_ge8_gensrc/cold_func_suffix/sub_desc | 13 +++ + .../gnu_unique_object/gnu_unique_object.cpp | 35 ++++++ + .../gcc_ge8_gensrc/gnu_unique_object/sub_desc | 23 ++++ + .../gcc_ge8_gensrc/init_array/init_array.cpp | 28 +++++ + tests/gcc_ge8_gensrc/init_array/sub_desc | 13 +++ + .../gcc_ge8_gensrc/run_gcc_ge8_gensrc_test.sh | 51 +++++++++ + 13 files changed, 419 insertions(+), 9 deletions(-) + create mode 100644 tests/gcc_ge8_gensrc/Makefile + create mode 100644 tests/gcc_ge8_gensrc/cold_func_suffix/cold_func_suffix.cpp + create mode 100644 tests/gcc_ge8_gensrc/cold_func_suffix/sub_desc + create mode 100644 tests/gcc_ge8_gensrc/gnu_unique_object/gnu_unique_object.cpp + create mode 100644 tests/gcc_ge8_gensrc/gnu_unique_object/sub_desc + create mode 100644 tests/gcc_ge8_gensrc/init_array/init_array.cpp + create mode 100644 tests/gcc_ge8_gensrc/init_array/sub_desc + create mode 100755 tests/gcc_ge8_gensrc/run_gcc_ge8_gensrc_test.sh + +diff --git a/src/arch/aarch64/arch_parse.c b/src/arch/aarch64/arch_parse.c +index f91ef0c..66ccc7e 100644 +--- a/src/arch/aarch64/arch_parse.c ++++ b/src/arch/aarch64/arch_parse.c +@@ -1,4 +1,10 @@ + /****************************************************************************** ++ * 2022.01.18 - add recog_func_attr() for count "%function" ++ * China Telecom, ++ * ++ * 2021.12.13 - support the type of C++ "gnu_unique_object" variable in is_variable_start() ++ * China Telecom, ++ * + * 2021.10.08 - enhance kpatch_gensrc and kpatch_elf and kpatch_cc code + * Huawei Technologies Co., Ltd. + * +@@ -43,11 +49,26 @@ int is_function_start(struct kp_file *f, int l, kpstr_t *nm) + func = func ? 1 : ctype(f, l) == DIRECTIVE_TYPE; + continue; + } ++ + break; + } + return func; + } + ++void recog_func_attr(struct kp_file *f, int i, kpstr_t *nm, int *cnt) ++{ ++ kpstr_t func_nm, func_attr; ++ ++ if(ctype(f, i) == DIRECTIVE_TYPE) { ++ kpstrset(&func_nm, "", 0); ++ kpstrset(&func_attr, "", 0); ++ ++ get_type_args(cline(f, i), &func_nm, &func_attr); ++ if(!kpstrcmpz(&func_attr, "%function") && !kpstrcmp(&func_nm, nm)) /* verify name matches */ ++ ++(*cnt); ++ } ++} ++ + int is_data_def(char *s, int type) + { + kpstr_t t; +@@ -127,6 +148,7 @@ int is_variable_start(struct kp_file *f, int l, int *e, int *pglobl, kpstr_t *nm + s = cline(f, l); + if (*s == '\0' && l != l0) + continue; ++ + switch (ctype(f, l)) { + case DIRECTIVE_TYPE: + case DIRECTIVE_GLOBL: +@@ -159,7 +181,7 @@ int is_variable_start(struct kp_file *f, int l, int *e, int *pglobl, kpstr_t *nm + return 1; + case DIRECTIVE_TYPE: + get_type_args(cline(f, l), &nm2, &attr); +- if (kpstrcmpz(&attr, "%object") && kpstrcmpz(&attr, "%tls_object")) ++ if (kpstrcmpz(&attr, "%object") && kpstrcmpz(&attr, "%tls_object") && kpstrcmpz(&attr, "%gnu_unique_object")) + return 0; + break; + case DIRECTIVE_GLOBL: +diff --git a/src/arch/x86/arch_parse.c b/src/arch/x86/arch_parse.c +index 15cf9fe..31caa46 100644 +--- a/src/arch/x86/arch_parse.c ++++ b/src/arch/x86/arch_parse.c +@@ -1,4 +1,13 @@ + /****************************************************************************** ++ * 2022.01.18 - add recog_func_attr() for count "@function" ++ * China Telecom, ++ * ++ * 2021.12.13 - support the type of C++ "gnu_unique_object" variable in is_variable_start() ++ * China Telecom, ++ * ++ * 2021.12.13 - support the appearance of ".LCOLD*" or ".LHOT*" label in is_function_start() and is_variable_start() ++ * China Telecom, ++ * + * 2021.10.08 - enhance kpatch_gensrc and kpatch_elf and kpatch_cc code + * Huawei Technologies Co., Ltd. + ******************************************************************************/ +@@ -37,11 +46,40 @@ int is_function_start(struct kp_file *f, int l, kpstr_t *nm) + func = func ? 1 : ctype(f, l) == DIRECTIVE_TYPE; + continue; + } ++ ++ /* particularly: for "-freorder-functions" optimization under -O2/-O3/-Os, ++ ".LCOLD*" or ".LHOT*" label may appear at the head of function or variable cblock, ++ it should not be divided into an independent cblock belonging to ATTR or OTHER */ ++ if(ctype(f, l) == DIRECTIVE_LABEL) { ++ s = cline(f, l); ++ if(strstr(s, ".LCOLD") || strstr(s, ".LHOT")) ++ continue; ++ } ++ + break; + } + return func; + } + ++void recog_func_attr(struct kp_file *f, int i, kpstr_t *nm, int *cnt) ++{ ++ kpstr_t func_nm, func_attr; ++ ++ if(ctype(f, i) == DIRECTIVE_TYPE) { ++ kpstrset(&func_nm, "", 0); ++ kpstrset(&func_attr, "", 0); ++ ++ get_type_args(cline(f, i), &func_nm, &func_attr); ++ if(!kpstrcmpz(&func_attr, "@function")) { ++ if(func_nm.l > nm->l) ++ remove_cold_hot_suffix(&func_nm); /* remove .cold. / .hot. */ ++ ++ if(!kpstrcmp(&func_nm, nm)) /* verify name matches */ ++ ++(*cnt); ++ } ++ } ++} ++ + int is_data_def(char *s, int type) + { + kpstr_t t; +@@ -90,6 +128,15 @@ int is_variable_start(struct kp_file *f, int l, int *e, int *pglobl, kpstr_t *nm + s = cline(f, l); + if (*s == '\0' && l != l0) + continue; ++ ++ /* particularly: for "-freorder-functions" optimization under -O2/-O3/-Os, ++ ".LCOLD*" or ".LHOT*" label may appear at the head of function or variable cblock, ++ it should not be divided into an independent cblock belonging to ATTR or OTHER */ ++ if(ctype(f, l) == DIRECTIVE_LABEL) { ++ if(strstr(s, ".LCOLD") || strstr(s, ".LHOT")) ++ continue; ++ } ++ + switch (ctype(f, l)) { + case DIRECTIVE_TYPE: + case DIRECTIVE_GLOBL: +@@ -115,7 +162,7 @@ int is_variable_start(struct kp_file *f, int l, int *e, int *pglobl, kpstr_t *nm + break; + case DIRECTIVE_TYPE: + get_type_args(cline(f, l), &nm2, &attr); +- if (kpstrcmpz(&attr, "@object")) ++ if (kpstrcmpz(&attr, "@object") && kpstrcmpz(&attr, "@gnu_unique_object")) + return 0; + break; + case DIRECTIVE_GLOBL: +diff --git a/src/include/kpatch_parse.h b/src/include/kpatch_parse.h +index a36a015..c52a1e3 100644 +--- a/src/include/kpatch_parse.h ++++ b/src/include/kpatch_parse.h +@@ -106,9 +106,11 @@ struct cblock { + + void get_token(char **str, kpstr_t *x); + void __get_token(char **str, kpstr_t *x, const char *delim); ++void remove_cold_hot_suffix(kpstr_t *nm); + + int is_function_start(struct kp_file *f, int l, kpstr_t *nm); + int is_function_end(struct kp_file *f, int l, kpstr_t *nm); ++void recog_func_attr(struct kp_file *f, int i, kpstr_t *nm, int *cnt); + + void get_type_args(char *s, kpstr_t *nm, kpstr_t *attr); + int is_variable_start(struct kp_file *f, int l, int *e, int *globl, kpstr_t *nm); +diff --git a/src/kpatch_parse.c b/src/kpatch_parse.c +index ddf58f8..0885cbe 100644 +--- a/src/kpatch_parse.c ++++ b/src/kpatch_parse.c +@@ -1,4 +1,10 @@ + /****************************************************************************** ++ * 2021.12.16 - kpatch_parse: enhance init_other_block() to extend function cblock to cover .init_array ++ * China Telecom, ++ * ++ * 2021.12.13 - kpatch_parse: adjust the judgment for the end of function cblock in init_func_block() ++ * China Telecom, ++ * + * 2021.10.11 - kpatch: fix code checker warning + * Huawei Technologies Co., Ltd. + * +@@ -72,6 +78,19 @@ void get_token(char **str, kpstr_t *x) + __get_token(str, x, delim); + } + ++/* remove .cold. / .hot. in function name */ ++void remove_cold_hot_suffix(kpstr_t *nm) ++{ ++ if(!nm->s) ++ return; ++ ++ char *suffix_loc = strstr(nm->s, ".cold."); ++ if(!suffix_loc) ++ suffix_loc = strstr(nm->s, ".hot."); ++ if(suffix_loc) ++ nm->l = suffix_loc - nm->s; /* remove .cold. / .hot. */ ++} ++ + /* ------------------------------ as directives parsing ---------------------------------- */ + + static struct { +@@ -303,13 +322,26 @@ static void init_func_block(struct kp_file *f, int *i, kpstr_t *nm) + int flags = 0; + struct cblock *blk; + +- while (e < f->nr_lines - 1 && !is_function_end(f, e, nm)) { ++ int func_cnt = 0; ++ ++ while (e < f->nr_lines - 1) { + if (ctype(f, e) == DIRECTIVE_GLOBL) + globl = 1; + if (ctype(f, e) == DIRECTIVE_KPFLAGS) { + flags |= get_kpatch_flags(cline(f, e)); + cline(f, e)[0] = 0; + } ++ ++ /* if compiling is optimized by -freorder-functions, e.g funcA, it will contains like ".type funcA.cold.xxx,@function" inside funcA, ++ and the end of funcA is not the first size directive matched with funcA. At present, use count for "@function" to judge*/ ++ recog_func_attr(f, e, nm, &func_cnt); ++ ++ if(is_function_end(f, e, nm)) { ++ --func_cnt; ++ if(!func_cnt) ++ break; ++ } ++ + e++; + } + +@@ -357,16 +389,76 @@ static void init_set_block(struct kp_file *f, int *i, kpstr_t *nm) + (*i)++; + } + ++/*if funcA is needed in initialization, e.g constructor in C++, the function pointer will be put into .init_array section. ++the directives will appear right after the function size directive like this, ++ ++ .size funcA, .-funcA ++ .section .init_array,"aw" ++ .align 8 ++ .quad funcA ++ ++since LCOLD* or LHOT* label may appear inside, and the label may change after patched, if classified as OTHER or VAR cblock, ++label change will conflict with the corresponding matching rules. also, we cannot set a proper VAR cblock name with no violation. ++it can only be treated as an extension of FUNC cblock. */ ++ ++#define EXT_INIARR_FLAG 1 ++#define EXT_UPDATE_FLAG 2 ++ + static void init_other_block(struct kp_file *f, int *i) + { + int s = *i, e = *i; ++ int flag = 0; ++ + kpstr_t nm; ++ kpstrset(&nm, "", 0); + +- while (e < f->nr_lines && !(is_function_start(f, e, &nm) || is_variable_start(f, e, NULL, NULL, &nm))) +- e++; ++ char *line = NULL; ++ kpstr_t nm2; ++ kpstrset(&nm2, "", 0); ++ ++ struct rb_node *node = NULL; ++ struct cblock *blk = NULL; ++ ++ while (e < f->nr_lines && !(is_function_start(f, e, &nm) || is_variable_start(f, e, NULL, NULL, &nm))) { ++ if(ctype(f, e) == DIRECTIVE_SECTION && !strcmp(csect(f, e)->name, ".init_array")) ++ flag = EXT_INIARR_FLAG; ++ ++ if(flag && ctype(f, e) == DIRECTIVE_OTHER) { ++ line = cline(f, e); ++ ++ if (is_data_def(line, DIRECTIVE_OTHER)) { ++ get_token(&line, &nm2); ++ get_token(&line, &nm2); ++ ++ node = rb_last(&f->cblocks_by_start); ++ if(!node) { ++ ++e; ++ break; ++ } ++ ++ blk = rb_entry(node, struct cblock, rbs); ++ if(blk->type == CBLOCK_FUNC && !kpstrcmp(&blk->name, &nm2)) { ++ kplog(LOG_DEBUG, "Extend cblock %.*s (%d: %d-%d) to (%d: %d-%d)\n", ++ blk->name.l, blk->name.s, f->id, blk->start, blk->end-1, f->id, blk->start, e); ++ blk->end = ++e; ++ flag = EXT_UPDATE_FLAG; ++ break; ++ } ++ } ++ } ++ ++e; ++ } ++ ++ if(flag == EXT_INIARR_FLAG) { ++ while (e < f->nr_lines && !(is_function_start(f, e, &nm) || is_variable_start(f, e, NULL, NULL, &nm))) ++ ++e; ++ } ++ ++ if(flag != EXT_UPDATE_FLAG) { ++ kpstrset(&nm, "", 0); ++ cblock_add(f, s, e, &nm, CBLOCK_OTHER, 0); ++ } + +- kpstrset(&nm, "", 0); +- cblock_add(f, s, e, &nm, CBLOCK_OTHER, 0); + *i = e; + } + +@@ -696,6 +788,10 @@ int is_function_end(struct kp_file *f, int l, kpstr_t *nm) + char *s = cline(f, l); + get_token(&s, &nm2); /* skip command */ + get_token(&s, &nm2); ++ ++ if(nm2.l > nm->l) ++ remove_cold_hot_suffix(&nm2); /* remove .cold. / .hot. */ ++ + if (kpstrcmp(nm, &nm2)) /* verify name matches */ + return 0; + +diff --git a/tests/Makefile b/tests/Makefile +index c9edaf3..ce97dbd 100644 +--- a/tests/Makefile ++++ b/tests/Makefile +@@ -8,13 +8,15 @@ ifeq ($(ARCH), aarch64) + SUBDIRS := $(filter-out $(AARCH64_NO_SUPPORT_TESTS), $(SUBDIRS)) + endif + ++GCC_GE8_GENSRC_TESTS := $(patsubst gcc_ge8_gensrc/%/sub_desc,%,$(wildcard gcc_ge8_gensrc/*/sub_desc)) ++ + KPATCH_PATH:=$(CURDIR)/../src + export KPATCH_PATH + + all: run + + list: +- @echo TESTS: $(SUBDIRS) ++ @echo TESTS: $(SUBDIRS) $(GCC_GE8_GENSRC_TESTS) + + fastsleep.so: CFLAGS += -fPIC + fastsleep.so: fastsleep.c +@@ -26,6 +28,7 @@ clean: $(addprefix clean-,$(SUBDIRS)) + $(CURDIR)/lpmakelevel-patchroot + rm -f fastsleep.so + make -C execve clean ++ make -C gcc_ge8_gensrc clean + + clean-%: FORCE + make -C $* clean +@@ -98,6 +101,9 @@ run-lpmakelevel: RUNTESTSFLAGS := -d lpmake -p $(CURDIR)/lpmakelevel-patchroot + run-lpmakelevel: fastsleep.so + run-lpmakelevel: run-startup-lpmakelevel + +-run: run-build run-patchlevel # run-lpmake run-lpmakelevel ++run-gcc_ge8_gensrc: ++ make -C gcc_ge8_gensrc ++ ++run: run-build run-patchlevel run-gcc_ge8_gensrc # run-lpmake run-lpmakelevel + + FORCE: +diff --git a/tests/gcc_ge8_gensrc/Makefile b/tests/gcc_ge8_gensrc/Makefile +new file mode 100644 +index 0000000..9b0a3d9 +--- /dev/null ++++ b/tests/gcc_ge8_gensrc/Makefile +@@ -0,0 +1,26 @@ ++.PHONY: all clean ++ ++SOURCE = $(wildcard */*.cpp) ++ASM_SOURCE = $(patsubst %.cpp, %.orig.s, $(SOURCE)) ++ ++GCC_REQUIRED=8 ++GCC_MAJOR = $(shell echo __GNUC__ | $(CXX) -E -x c - | tail -n 1) ++GCC_MAJOR_GTE8 = $(shell expr $(GCC_MAJOR) \>= $(GCC_REQUIRED)) ++ ++COMPILE_COMMAND = ++TEST_COMMAND = ++ ++ifeq ($(GCC_MAJOR_GTE8), 1) ++ COMPILE_COMMAND = $(CXX) $^ -S -O2 -std=c++17 -o $@ ++endif ++ ++all: test ++ ++test: $(ASM_SOURCE) ++ ./run_gcc_ge8_gensrc_test.sh $(GCC_MAJOR) $(GCC_REQUIRED) ++ ++clean: ++ rm -f $(shell find ./ -name *.s) ++ ++%.orig.s: %.cpp ++ $(COMPILE_COMMAND) +\ No newline at end of file +diff --git a/tests/gcc_ge8_gensrc/cold_func_suffix/cold_func_suffix.cpp b/tests/gcc_ge8_gensrc/cold_func_suffix/cold_func_suffix.cpp +new file mode 100644 +index 0000000..da1ed43 +--- /dev/null ++++ b/tests/gcc_ge8_gensrc/cold_func_suffix/cold_func_suffix.cpp +@@ -0,0 +1,48 @@ ++#include ++ ++extern int ext_func(int a, int b) __attribute__((cold)); ++ ++void swap(int &a, int &b) ++{ ++ int temp = a; ++ a = b; ++ b = temp; ++} ++ ++int cold_func(int a, int b) ++{ ++ int c = 0; ++ if(__builtin_expect(a > 0, false)) ++ c = a*2 + b; ++ else ++ c = ext_func(a, b) + 7; ++ ++ return c; ++} ++ ++void reverse(int &a) ++{ ++ int org = a; ++ int res = 0; ++ while(org > 0) ++ { ++ res *= 10; ++ res += org % 10; ++ org /= 10; ++ } ++ a = res; ++} ++ ++int main() ++{ ++ int i = 9527; ++ int m = i/9; ++ int n = i%9; ++ ++ int k = cold_func(m, n); ++ swap(m, n); ++ reverse(i); ++ ++ std::cout << "k=" << k << " i=" << i << std::endl; ++ return 0; ++} +diff --git a/tests/gcc_ge8_gensrc/cold_func_suffix/sub_desc b/tests/gcc_ge8_gensrc/cold_func_suffix/sub_desc +new file mode 100644 +index 0000000..0e25f29 +--- /dev/null ++++ b/tests/gcc_ge8_gensrc/cold_func_suffix/sub_desc +@@ -0,0 +1,13 @@ ++test LCOLD/LHOT func.cold.NUM for recent gcc(>=gcc 8) with __attribute__((cold)) and __builtin_expect ++ ++steps: ++1) compile the source code: ++ g++ cold_func_suffix.cpp -S -O2 -o cold_func_suffix.s ++ ++2) generate diff-asm file with no difference to check the result of cblock ++ kpatch_gensrc --os=rhel6 -i cold_func_suffix.s -i cold_func_suffix.s -o tmp.s ++ ++3) tmp.s should be the same as cold_func_suffix.s, except the "#---var----" and "#----func---" ++ sed '/^#/d' tmp.s > same.s ++ diff cold_func_suffix.s same.s | wc -l ++the result should be 0 +\ No newline at end of file +diff --git a/tests/gcc_ge8_gensrc/gnu_unique_object/gnu_unique_object.cpp b/tests/gcc_ge8_gensrc/gnu_unique_object/gnu_unique_object.cpp +new file mode 100644 +index 0000000..f1b432d +--- /dev/null ++++ b/tests/gcc_ge8_gensrc/gnu_unique_object/gnu_unique_object.cpp +@@ -0,0 +1,35 @@ ++#include ++ ++class StudentManage ++{ ++public: ++ void setStudent(int id, int age) ++ { ++ student.stu_id = id; ++ student.stu_age = age; ++ } ++ void displayStudent() ++ { ++ std::cout << "student " << student.stu_id << " age : " << student.stu_age << std::endl; ++ } ++ ++private: ++ struct Student ++ { ++ int stu_id; ++ int stu_age; ++ }; ++ ++ inline static thread_local Student student; ++}; ++ ++ ++int main() ++{ ++ StudentManage ms; ++ ms.setStudent(9581, 40); ++ ms.displayStudent(); ++ ms.setStudent(9587, 36); ++ ms.displayStudent(); ++ return 0; ++} +diff --git a/tests/gcc_ge8_gensrc/gnu_unique_object/sub_desc b/tests/gcc_ge8_gensrc/gnu_unique_object/sub_desc +new file mode 100644 +index 0000000..60194f5 +--- /dev/null ++++ b/tests/gcc_ge8_gensrc/gnu_unique_object/sub_desc +@@ -0,0 +1,23 @@ ++test var with @gnu_unique_object assigned in .tbss by using a "inline static thread_local" data member ++ ++note: ++1) the source code must compile with -std=c++17 ++2) the test situation also can be constructed with a thread_local var in c++ template, eg: ++template ++T func(T num1, T num2) ++{ ++ thread_local T s0; ++ ... ... ++} ++ ++steps: ++1) compile the source code: ++ g++ gnu_unique_object.cpp -S -O2 -std=c++17 -o gnu_unique_object.s ++ ++2) generate diff-asm file with no difference to check the result of cblock ++ kpatch_gensrc --os=rhel6 -i gnu_unique_object.s -i gnu_unique_object.s -o tmp.s ++ ++3) tmp.s should be the same as gnu_unique_object.s, except the "#---var----" and "#----func---" ++ sed '/^#/d' tmp.s > same.s ++ diff gnu_unique_object.s same.s | wc -l ++the result should be 0 +\ No newline at end of file +diff --git a/tests/gcc_ge8_gensrc/init_array/init_array.cpp b/tests/gcc_ge8_gensrc/init_array/init_array.cpp +new file mode 100644 +index 0000000..bfbe74c +--- /dev/null ++++ b/tests/gcc_ge8_gensrc/init_array/init_array.cpp +@@ -0,0 +1,28 @@ ++#include ++ ++class CTest ++{ ++public: ++ CTest():m_i2(1) {} ++ void print() ++ { ++ int sum = m_i1+m_i2; ++ std::cout << "sum is " << sum << std::endl; ++ ++ int sub = m_i1-m_i2; ++ std::cout << "sub is " << sub << std::endl; ++ } ++private: ++ static int m_i1; ++ int m_i2; ++}; ++ ++int CTest::m_i1 = 10; ++ ++int main() ++{ ++ CTest ct1; ++ ct1.print(); ++ ++ return 0; ++} +diff --git a/tests/gcc_ge8_gensrc/init_array/sub_desc b/tests/gcc_ge8_gensrc/init_array/sub_desc +new file mode 100644 +index 0000000..1ac5e0d +--- /dev/null ++++ b/tests/gcc_ge8_gensrc/init_array/sub_desc +@@ -0,0 +1,13 @@ ++test .init_array cblock partition ++ ++steps: ++1) compile the source code: ++ g++ init_array.cpp -S -O2 -o init_array.s ++ ++2) generate diff-asm file with no difference to check the result of cblock ++ kpatch_gensrc --os=rhel6 -i init_array.s -i init_array.s -o tmp.s ++ ++3) tmp.s should be the same as init_array.s, except the "#---var----" and "#----func---" ++ sed '/^#/d' tmp.s > same.s ++ diff init_array.s same.s | wc -l ++the result should be 0 +\ No newline at end of file +diff --git a/tests/gcc_ge8_gensrc/run_gcc_ge8_gensrc_test.sh b/tests/gcc_ge8_gensrc/run_gcc_ge8_gensrc_test.sh +new file mode 100755 +index 0000000..4534038 +--- /dev/null ++++ b/tests/gcc_ge8_gensrc/run_gcc_ge8_gensrc_test.sh +@@ -0,0 +1,51 @@ ++#/bin/sh ++ ++echo "the following case only for gcc $2 and later:" ++ ++CURDIR=$(cd $(dirname $0); pwd) ++SOURCE_SET=$(find $CURDIR -name *.orig.s) ++TOTAL_CASE=$(find $CURDIR -name sub_desc | wc -l) ++KPATCH_GENSRC=$CURDIR/../../src/kpatch_gensrc ++ ++OK_CNT=0 ++FAIL_CNT=0 ++SKIP_CNT=0 ++ ++if [ $1 -lt $2 ]; then ++ SKIP_CNT=$TOTAL_CASE ++ echo "gcc is too old to test, test: gcc $1 < required: gcc $2)" ++ echo "OK $OK_CNT FAIL $FAIL_CNT SKIP $SKIP_CNT TOTAL $TOTAL_CASE" ++ exit 0 ++fi ++ ++for SOURCE in $SOURCE_SET; do ++ FILENAME=${SOURCE##*/} ++ CASENAME=${FILENAME%.orig.s} ++ if [ $CASENAME == "cold_func_suffix" ]; then ++ KEY_WORD="\.cold." ++ else ++ KEY_WORD=$CASENAME ++ fi ++ ++ KEY_WORD_LINE=$(grep -c $KEY_WORD $SOURCE) ++ if [ $KEY_WORD_LINE -lt "2" ]; then ++ echo "SKIP: $CASENAME, $KEY_WORD not found" ++ SKIP_CNT=$(($SKIP_CNT+1)) ++ continue ++ fi ++ ++ $KPATCH_GENSRC --os=rhel6 -i $SOURCE -i $SOURCE -o ${SOURCE/.orig/.o} ++ sed -i '/^#/d' ${SOURCE/.orig/.o} ++ ++ DIFF_LINE=$(diff $SOURCE ${SOURCE/.orig/.o} | grep -c $KEY_WORD) ++ if [ $DIFF_LINE -gt "0" ]; then ++ echo "TEST $CASENAME IS FAIL" ++ FAIL_CNT=$(($FAIL_CNT+1)) ++ else ++ echo "TEST $CASENAME IS OK" ++ OK_CNT=$(($OK_CNT+1)) ++ fi ++done ++ ++echo "OK $OK_CNT FAIL $FAIL_CNT SKIP $SKIP_CNT TOTAL $TOTAL_CASE" ++exit 0 +\ No newline at end of file +-- +2.27.0 + diff --git a/0003-elf-add-section-adderss-for-STT_NOTYPE-type-of-symbo.patch b/0003-elf-add-section-adderss-for-STT_NOTYPE-type-of-symbo.patch new file mode 100644 index 0000000..4b05341 --- /dev/null +++ b/0003-elf-add-section-adderss-for-STT_NOTYPE-type-of-symbo.patch @@ -0,0 +1,30 @@ +From 55b659c0b52a7c5f3fc493dd9c19ac76f09d0ccb Mon Sep 17 00:00:00 2001 +From: Bihong Yu +Date: Sat, 22 Jan 2022 16:15:50 +0800 +Subject: [PATCH] elf: add section adderss for STT_NOTYPE type of symbol + +Sometimes, the symbol type of the new global static variable in the +patch may be STT_NOTYPE. We should add the section adderss to st_value +for this type symbol, otherwise, the calculated adderss for this type +symbol will be wrong, which may result in the patched process coredump. + +Signed-off-by: Bihong Yu +--- + src/kpatch_elf.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/kpatch_elf.c b/src/kpatch_elf.c +index 3ac56d9..5acf370 100644 +--- a/src/kpatch_elf.c ++++ b/src/kpatch_elf.c +@@ -789,6 +789,7 @@ symbol_resolve(struct object_file *o, + break; + + case STT_NOTYPE: // for Systemtap symbol _.stapsdt.base.kpatch ++ s->st_value += shdr[s->st_shndx].sh_addr; + break; + + default: +-- +2.27.0 + diff --git a/0004-elf-strip-adapt-to-new-gcc-version-10.3.1.patch b/0004-elf-strip-adapt-to-new-gcc-version-10.3.1.patch new file mode 100644 index 0000000..9e18e79 --- /dev/null +++ b/0004-elf-strip-adapt-to-new-gcc-version-10.3.1.patch @@ -0,0 +1,58 @@ +From abfc33435c25e1515e35768c9a2d684aa72dc780 Mon Sep 17 00:00:00 2001 +From: jiang-dawei15 +Date: Mon, 28 Feb 2022 15:34:11 +0800 +Subject: [PATCH 1/3] elf/strip: adapt to new gcc version(10.3.1) + +This patch fix the following problems: + 1. new libc so use new naming method,such as: libc.6.so -> libc.so.6; + 2. destroy .rela section sh_flags INFO property; + +Signed-off-by: Bihong Yu +--- + src/kpatch_elf.c | 9 +++------ + src/kpatch_strip.c | 5 +++-- + 2 files changed, 6 insertions(+), 8 deletions(-) + +diff --git a/src/kpatch_elf.c b/src/kpatch_elf.c +index 5acf370..260209a 100644 +--- a/src/kpatch_elf.c ++++ b/src/kpatch_elf.c +@@ -180,16 +180,13 @@ static int + elf_object_is_interp_exception(struct object_file *o) + { + /* libc */ +- if (!strncmp(o->name, "libc", 4) && +- !strncmp(o->name + strlen(o->name) - 3, ".so", 3)) ++ if (!strncmp(o->name, "libc.", 5)) + return 1; + /* libpthread */ +- if (!strncmp(o->name, "libpthread", 10) && +- !strncmp(o->name + strlen(o->name) - 3, ".so", 3)) ++ if (!strncmp(o->name, "libpthread.", 11)) + return 1; + /* libdl */ +- if (!strncmp(o->name, "libdl", 5) && +- !strncmp(o->name + strlen(o->name) - 3, ".so", 3)) ++ if (!strncmp(o->name, "libdl.", 6)) + return 1; + return 0; + } +diff --git a/src/kpatch_strip.c b/src/kpatch_strip.c +index 5717e5a..6420af9 100644 +--- a/src/kpatch_strip.c ++++ b/src/kpatch_strip.c +@@ -220,8 +220,9 @@ static int kpatch_strip(Elf *elfin, Elf *elfout) + } else { + kpinfo("don't need it\n"); + shout.sh_type = SHT_NOBITS; +- shout.sh_link = 0; +- shout.sh_info = 0; ++ /* destroy the .rela section sh_flags INFO property */ ++ if (!strncmp(scnname, ".rela", 5)) ++ shout.sh_flags = SHF_ALLOC; + } + if (!gelf_update_shdr(scnout, &shout)) { + kperr("Failed to do gelf_update_shdr need"); +-- +2.23.0.windows.1 + diff --git a/0005-gitignore-ignore-some-tests-and-binary.patch b/0005-gitignore-ignore-some-tests-and-binary.patch new file mode 100644 index 0000000..b636c5e --- /dev/null +++ b/0005-gitignore-ignore-some-tests-and-binary.patch @@ -0,0 +1,26 @@ +From 04c295b9ca272dbd3525a6fa4be4869fe65d59aa Mon Sep 17 00:00:00 2001 +From: jiang-dawei15 +Date: Mon, 28 Feb 2022 15:56:54 +0800 +Subject: [PATCH 2/3] gitignore: ignore some tests and binary + +Signed-off-by: Bihong Yu +--- + .gitignore | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/.gitignore b/.gitignore +index 065f093..696dfee 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -7,4 +7,8 @@ src/libcare-cc + src/libcare-client + src/libcare-ctl + src/libcare-stresstest ++src/libcare-server ++src/libcare-dump ++src/arch.desc + tags ++tests/* +-- +2.23.0.windows.1 + diff --git a/0006-libcare-patch-make-adapt-libcare-patch-make-to-meson.patch b/0006-libcare-patch-make-adapt-libcare-patch-make-to-meson.patch new file mode 100644 index 0000000..671ed68 --- /dev/null +++ b/0006-libcare-patch-make-adapt-libcare-patch-make-to-meson.patch @@ -0,0 +1,82 @@ +From 7b84765925c8b08f6bb061e66aabebdc814f0168 Mon Sep 17 00:00:00 2001 +From: jiang-dawei15 +Date: Mon, 28 Feb 2022 16:27:22 +0800 +Subject: [PATCH 3/3] libcare-patch-make: adapt libcare-patch-make to meson + +Signed-off-by: Bihong Yu +--- + src/libcare-patch-make | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +diff --git a/src/libcare-patch-make b/src/libcare-patch-make +index 320ab88..ad1b566 100755 +--- a/src/libcare-patch-make ++++ b/src/libcare-patch-make +@@ -53,6 +53,10 @@ prepare_env() { + LPMAKE_PATCHED_DIR="${LPMAKE_PATCHED_DIR-$PWD/.lpmaketmp/patched}" + LPMAKE_PATCHROOT="${LPMAKE_PATCHROOT-$PWD/patchroot}" + ++ LIBCARE_CC=$CC ++ SYMBOLINK_CC=$(which cc) ++ REAL_CC=$(realpath $SYMBOLINK_CC) ++ + export LPMAKE_ORIGINAL_DIR LPMAKE_PATCHED_DIR LPMAKE_PATCHROOT + mkdir -p "$LPMAKE_ORIGINAL_DIR" "$LPMAKE_PATCHED_DIR" "$LPMAKE_PATCHROOT" + +@@ -79,6 +83,26 @@ restore_origs() { + + trap "restore_origs" 0 + ++change_qemu_ld_flags() { ++ qemu_ld_flags=$(grep "^QEMU_LDFLAGS=" config-host.mak) ++ ret=$(echo $qemu_ld_flags | grep "\-Wl,-q") ++ if [[ "$ret" == "" ]];then ++ qemu_ld_flags="${qemu_ld_flags} -Wl,-q" ++ echo "change QEMU_LDFLAGS to '${qemu_ld_flags}'" ++ sed -i "/^QEMU_LDFLAGS=/c\\${qemu_ld_flags}" config-host.mak ++ fi ++} ++ ++replace_cc_symbolink() { ++ unlink $SYMBOLINK_CC ++ ln -s $LIBCARE_CC $SYMBOLINK_CC ++} ++ ++recover_cc_symbolink() { ++ unlink $SYMBOLINK_CC ++ ln -s $REAL_CC $SYMBOLINK_CC ++} ++ + build_objects() { + restore_origs + +@@ -93,6 +117,9 @@ build_objects() { + export KPATCH_STAGE=original + export KPCC_DBGFILTER_ARGS="" + ++ #add '-Wl,-q' to LD_FLAGS ++ change_qemu_ld_flags ++ + echo "${green}BUILDING ORIGINAL CODE${reset}" + make $LPMAKEFILE $JOBS_MAKE >$MAKE_OUTPUT 2>&1 + +@@ -237,10 +264,16 @@ main() { + + prepare_env + ++ # replace cc ++ replace_cc_symbolink ++ + if test -z "$only_update"; then + build_objects "$@" + fi + build_kpatches ++ ++ # recover cc ++ recover_cc_symbolink + } + + main "$@" +-- +2.23.0.windows.1 + diff --git a/0007-kpatch_elf-compatible-with-older-versions-of-the-so-.patch b/0007-kpatch_elf-compatible-with-older-versions-of-the-so-.patch new file mode 100644 index 0000000..219043f --- /dev/null +++ b/0007-kpatch_elf-compatible-with-older-versions-of-the-so-.patch @@ -0,0 +1,49 @@ +From b316ee94be9e6bdcda30400511593550de1eb29b Mon Sep 17 00:00:00 2001 +From: jiang-dawei15 +Date: Tue, 1 Mar 2022 16:07:37 +0800 +Subject: [PATCH 1/2] kpatch_elf: compatible with older versions of the so + naming rules + +New openEuler so naming rules have been changed, such as: + old so naming rules: libc-x.y.z.so + <-----> + new so naming rules: libc.so.x.y.z + +We need support this two version. +fix commit: abfc33435c25e1515e35768c9a2d684aa72dc780 + +Signed-off-by: Bihong Yu +--- + src/kpatch_elf.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/src/kpatch_elf.c b/src/kpatch_elf.c +index 260209a..833f8e1 100644 +--- a/src/kpatch_elf.c ++++ b/src/kpatch_elf.c +@@ -180,13 +180,19 @@ static int + elf_object_is_interp_exception(struct object_file *o) + { + /* libc */ +- if (!strncmp(o->name, "libc.", 5)) ++ if (!strncmp(o->name, "libc.so.", 8) || ++ (!strncmp(o->name, "libc-", 5) && ++ !strncmp(o->name + strlen(o->name) - 3, ".so", 3))) + return 1; + /* libpthread */ +- if (!strncmp(o->name, "libpthread.", 11)) ++ if (!strncmp(o->name, "libpthread.so.", 14) || ++ (!strncmp(o->name, "libpthread-", 11) && ++ !strncmp(o->name + strlen(o->name) - 3, ".so", 3))) + return 1; + /* libdl */ +- if (!strncmp(o->name, "libdl.", 6)) ++ if (!strncmp(o->name, "libdl.so.", 9) || ++ (!strncmp(o->name, "libdl-", 6) && ++ !strncmp(o->name + strlen(o->name) - 3, ".so", 3))) + return 1; + return 0; + } +-- +2.27.0 + diff --git a/0008-kpatch_parse-fix-failed-to-recognize-.cold.patch b/0008-kpatch_parse-fix-failed-to-recognize-.cold.patch new file mode 100644 index 0000000..0ab6315 --- /dev/null +++ b/0008-kpatch_parse-fix-failed-to-recognize-.cold.patch @@ -0,0 +1,123 @@ +From 6ebfe7d2af327dad9c9d4c5b2733ba55bd81571c Mon Sep 17 00:00:00 2001 +From: jiang-dawei15 +Date: Tue, 1 Mar 2022 20:00:58 +0800 +Subject: [PATCH 2/2] kpatch_parse: fix failed to recognize .cold + +the .cold suffix have two forms of expression: func.cold or +func.cold.NUM, we need to support recognizing both patterns. + +Signed-off-by: Bihong Yu +--- + src/arch/x86/arch_parse.c | 4 ++-- + src/include/kpatch_parse.h | 2 +- + src/kpatch_parse.c | 14 ++++++-------- + tests/gcc_ge8_gensrc/run_gcc_ge8_gensrc_test.sh | 11 +++++++---- + 4 files changed, 16 insertions(+), 15 deletions(-) + +diff --git a/src/arch/x86/arch_parse.c b/src/arch/x86/arch_parse.c +index 31caa46..aee82b8 100644 +--- a/src/arch/x86/arch_parse.c ++++ b/src/arch/x86/arch_parse.c +@@ -72,10 +72,10 @@ void recog_func_attr(struct kp_file *f, int i, kpstr_t *nm, int *cnt) + get_type_args(cline(f, i), &func_nm, &func_attr); + if(!kpstrcmpz(&func_attr, "@function")) { + if(func_nm.l > nm->l) +- remove_cold_hot_suffix(&func_nm); /* remove .cold. / .hot. */ ++ remove_cold_suffix(&func_nm); /* remove .cold */ + + if(!kpstrcmp(&func_nm, nm)) /* verify name matches */ +- ++(*cnt); ++ ++(*cnt); + } + } + } +diff --git a/src/include/kpatch_parse.h b/src/include/kpatch_parse.h +index c52a1e3..d2225c5 100644 +--- a/src/include/kpatch_parse.h ++++ b/src/include/kpatch_parse.h +@@ -106,7 +106,7 @@ struct cblock { + + void get_token(char **str, kpstr_t *x); + void __get_token(char **str, kpstr_t *x, const char *delim); +-void remove_cold_hot_suffix(kpstr_t *nm); ++void remove_cold_suffix(kpstr_t *nm); + + int is_function_start(struct kp_file *f, int l, kpstr_t *nm); + int is_function_end(struct kp_file *f, int l, kpstr_t *nm); +diff --git a/src/kpatch_parse.c b/src/kpatch_parse.c +index 0885cbe..43c885c 100644 +--- a/src/kpatch_parse.c ++++ b/src/kpatch_parse.c +@@ -78,17 +78,15 @@ void get_token(char **str, kpstr_t *x) + __get_token(str, x, delim); + } + +-/* remove .cold. / .hot. in function name */ +-void remove_cold_hot_suffix(kpstr_t *nm) ++/* remove .cold in function name */ ++void remove_cold_suffix(kpstr_t *nm) + { + if(!nm->s) + return; +- +- char *suffix_loc = strstr(nm->s, ".cold."); +- if(!suffix_loc) +- suffix_loc = strstr(nm->s, ".hot."); ++ ++ char *suffix_loc = strstr(nm->s, ".cold"); + if(suffix_loc) +- nm->l = suffix_loc - nm->s; /* remove .cold. / .hot. */ ++ nm->l = suffix_loc - nm->s; /* remove .cold */ + } + + /* ------------------------------ as directives parsing ---------------------------------- */ +@@ -790,7 +788,7 @@ int is_function_end(struct kp_file *f, int l, kpstr_t *nm) + get_token(&s, &nm2); + + if(nm2.l > nm->l) +- remove_cold_hot_suffix(&nm2); /* remove .cold. / .hot. */ ++ remove_cold_suffix(&nm2); /* remove .cold */ + + if (kpstrcmp(nm, &nm2)) /* verify name matches */ + return 0; +diff --git a/tests/gcc_ge8_gensrc/run_gcc_ge8_gensrc_test.sh b/tests/gcc_ge8_gensrc/run_gcc_ge8_gensrc_test.sh +index 4534038..b508e99 100755 +--- a/tests/gcc_ge8_gensrc/run_gcc_ge8_gensrc_test.sh ++++ b/tests/gcc_ge8_gensrc/run_gcc_ge8_gensrc_test.sh +@@ -22,12 +22,12 @@ for SOURCE in $SOURCE_SET; do + FILENAME=${SOURCE##*/} + CASENAME=${FILENAME%.orig.s} + if [ $CASENAME == "cold_func_suffix" ]; then +- KEY_WORD="\.cold." ++ KEY_WORD="\.cold" + else + KEY_WORD=$CASENAME + fi + +- KEY_WORD_LINE=$(grep -c $KEY_WORD $SOURCE) ++ KEY_WORD_LINE=$(grep -c "$KEY_WORD" $SOURCE) + if [ $KEY_WORD_LINE -lt "2" ]; then + echo "SKIP: $CASENAME, $KEY_WORD not found" + SKIP_CNT=$(($SKIP_CNT+1)) +@@ -37,7 +37,7 @@ for SOURCE in $SOURCE_SET; do + $KPATCH_GENSRC --os=rhel6 -i $SOURCE -i $SOURCE -o ${SOURCE/.orig/.o} + sed -i '/^#/d' ${SOURCE/.orig/.o} + +- DIFF_LINE=$(diff $SOURCE ${SOURCE/.orig/.o} | grep -c $KEY_WORD) ++ DIFF_LINE=$(diff $SOURCE ${SOURCE/.orig/.o} | grep -c "$KEY_WORD") + if [ $DIFF_LINE -gt "0" ]; then + echo "TEST $CASENAME IS FAIL" + FAIL_CNT=$(($FAIL_CNT+1)) +@@ -48,4 +48,7 @@ for SOURCE in $SOURCE_SET; do + done + + echo "OK $OK_CNT FAIL $FAIL_CNT SKIP $SKIP_CNT TOTAL $TOTAL_CASE" +-exit 0 +\ No newline at end of file ++if [ $FAIL_CNT -ne 0 ]; then ++ exit 1 ++fi ++exit 0 +-- +2.27.0 + diff --git a/0009-help-modify-some-help-information.patch b/0009-help-modify-some-help-information.patch new file mode 100644 index 0000000..2dde4ae --- /dev/null +++ b/0009-help-modify-some-help-information.patch @@ -0,0 +1,38 @@ +From b7bd30b1ff5408e52cb67cee6ef0f8df73e5f802 Mon Sep 17 00:00:00 2001 +From: jiang-dawei15 +Date: Wed, 9 Mar 2022 11:50:02 +0800 +Subject: [PATCH] help: modify some help information + +--- + src/kpatch_user.c | 1 - + src/libcare-patch-make | 2 +- + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/kpatch_user.c b/src/kpatch_user.c +index 0bcc219..add74ea 100644 +--- a/src/kpatch_user.c ++++ b/src/kpatch_user.c +@@ -376,7 +376,6 @@ static int usage(const char *err) + fprintf(stderr, " patch - apply patch to a user-space process\n"); + fprintf(stderr, " unpatch- unapply patch from a user-space process\n"); + fprintf(stderr, " info - show info on applied patches\n"); +- fprintf(stderr, " server - listen on a unix socket for commands\n"); + return -1; + } + +diff --git a/src/libcare-patch-make b/src/libcare-patch-make +index ad1b566..9a75e1f 100755 +--- a/src/libcare-patch-make ++++ b/src/libcare-patch-make +@@ -20,7 +20,7 @@ install with specified DESTDIR. + working on patch utils. + -d --destdir specify variable makefile system uses to specify destination + directory for the installation +- -i --id>-give this patch an unique id (less than 7 char) ++ -i --id give this patch an unique id (less than 7 char) + -b --buildid give this patch an unique build-id + -j --jobs specify variable makefile system jobs of compile, for example + `make -j 4` is startup `4` jobs to compile. +-- +2.27.0 + diff --git a/0010-libcare-patch-make-fix-some-bugs.patch b/0010-libcare-patch-make-fix-some-bugs.patch new file mode 100644 index 0000000..86d9a62 --- /dev/null +++ b/0010-libcare-patch-make-fix-some-bugs.patch @@ -0,0 +1,130 @@ +From 326fe36893de32fe8a8e95fcb5aee6df5c9a3fa7 Mon Sep 17 00:00:00 2001 +From: Bihong Yu +Date: Sat, 19 Mar 2022 15:20:27 +0800 +Subject: [PATCH] libcare-patch-make: fix some bugs + +This patch fix following bugs: +1. origin build should not add '-Wl,-q' flags +2. recover config-host.mak after make kpatch for next building + +Signed-off-by: Bihong Yu +Signed-off-by: yezengruan +--- + src/libcare-patch-make | 54 +++++++++++++++++++++++++----------------- + 1 file changed, 32 insertions(+), 22 deletions(-) + +diff --git a/src/libcare-patch-make b/src/libcare-patch-make +index 9a75e1f..03aa1d6 100755 +--- a/src/libcare-patch-make ++++ b/src/libcare-patch-make +@@ -53,9 +53,9 @@ prepare_env() { + LPMAKE_PATCHED_DIR="${LPMAKE_PATCHED_DIR-$PWD/.lpmaketmp/patched}" + LPMAKE_PATCHROOT="${LPMAKE_PATCHROOT-$PWD/patchroot}" + +- LIBCARE_CC=$CC +- SYMBOLINK_CC=$(which cc) +- REAL_CC=$(realpath $SYMBOLINK_CC) ++ LIBCARE_CC=$CC ++ SYMBOLINK_CC=$(which cc) ++ REAL_CC=$(realpath $SYMBOLINK_CC) + + export LPMAKE_ORIGINAL_DIR LPMAKE_PATCHED_DIR LPMAKE_PATCHROOT + mkdir -p "$LPMAKE_ORIGINAL_DIR" "$LPMAKE_PATCHED_DIR" "$LPMAKE_PATCHROOT" +@@ -83,24 +83,30 @@ restore_origs() { + + trap "restore_origs" 0 + +-change_qemu_ld_flags() { +- qemu_ld_flags=$(grep "^QEMU_LDFLAGS=" config-host.mak) +- ret=$(echo $qemu_ld_flags | grep "\-Wl,-q") +- if [[ "$ret" == "" ]];then +- qemu_ld_flags="${qemu_ld_flags} -Wl,-q" +- echo "change QEMU_LDFLAGS to '${qemu_ld_flags}'" +- sed -i "/^QEMU_LDFLAGS=/c\\${qemu_ld_flags}" config-host.mak +- fi ++replace_qemu_ld_flags() { ++ local qemu_ld_flags_old=$1 ++ ret=$(echo $qemu_ld_flags_old | grep "\-Wl,-q") ++ if [[ "$ret" == "" ]]; then ++ local qemu_ld_flags="${qemu_ld_flags_old} -Wl,-q" ++ echo "replace QEMU_LDFLAGS to '${qemu_ld_flags}'" ++ sed -i "/^QEMU_LDFLAGS=/c\\${qemu_ld_flags}" config-host.mak ++ fi ++} ++ ++recover_qemu_ld_flags() { ++ local qemu_ld_flags=$1 ++ echo "recover QEMU_LDFLAGS to '${qemu_ld_flags}'" ++ sed -i "/^QEMU_LDFLAGS=/c\\${qemu_ld_flags}" config-host.mak + } + + replace_cc_symbolink() { +- unlink $SYMBOLINK_CC +- ln -s $LIBCARE_CC $SYMBOLINK_CC ++ unlink $SYMBOLINK_CC ++ ln -s $LIBCARE_CC $SYMBOLINK_CC + } + + recover_cc_symbolink() { +- unlink $SYMBOLINK_CC +- ln -s $REAL_CC $SYMBOLINK_CC ++ unlink $SYMBOLINK_CC ++ ln -s $REAL_CC $SYMBOLINK_CC + } + + build_objects() { +@@ -117,9 +123,6 @@ build_objects() { + export KPATCH_STAGE=original + export KPCC_DBGFILTER_ARGS="" + +- #add '-Wl,-q' to LD_FLAGS +- change_qemu_ld_flags +- + echo "${green}BUILDING ORIGINAL CODE${reset}" + make $LPMAKEFILE $JOBS_MAKE >$MAKE_OUTPUT 2>&1 + +@@ -146,6 +149,10 @@ build_objects() { + export KPATCH_STAGE=patched + export KPCC_APPEND_ARGS="-Wl,-q" + ++ qemu_ld_flags_bak=$(grep "^QEMU_LDFLAGS=" config-host.mak) ++ #add '-Wl,-q' to LD_FLAGS ++ replace_qemu_ld_flags "$qemu_ld_flags_bak" ++ + echo "${green}BUILDING PATCHED CODE${reset}" + make $LPMAKEFILE $JOBS_MAKE >$MAKE_OUTPUT 2>&1 + +@@ -153,6 +160,9 @@ build_objects() { + make $LPMAKEFILE $JOBS_MAKE install \ + "$destdir=$LPMAKE_PATCHED_DIR" \ + >$MAKE_OUTPUT 2>&1 ++ ++ # recover LD_FLAGS ++ recover_qemu_ld_flags "$qemu_ld_flags_bak" + } + + build_kpatches() { +@@ -264,16 +274,16 @@ main() { + + prepare_env + +- # replace cc +- replace_cc_symbolink ++ # replace cc ++ replace_cc_symbolink + + if test -z "$only_update"; then + build_objects "$@" + fi + build_kpatches + +- # recover cc +- recover_cc_symbolink ++ # recover cc ++ recover_cc_symbolink + } + + main "$@" +-- +2.27.0 + diff --git a/0011-selinux-enable-libcare-ctl-to-mprotect-qemu-process.patch b/0011-selinux-enable-libcare-ctl-to-mprotect-qemu-process.patch new file mode 100644 index 0000000..02311c1 --- /dev/null +++ b/0011-selinux-enable-libcare-ctl-to-mprotect-qemu-process.patch @@ -0,0 +1,27 @@ +From 2724af94241663c9877e270c645dfcea124dc92c Mon Sep 17 00:00:00 2001 +From: jiang-dawei15 +Date: Tue, 29 Mar 2022 20:32:43 +0800 +Subject: [PATCH] selinux: enable libcare-ctl to mprotect qemu process + +Signed-off-by: Bihong Yu +--- + dist/selinux/libcare.te | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/dist/selinux/libcare.te b/dist/selinux/libcare.te +index c240875..670c026 100644 +--- a/dist/selinux/libcare.te ++++ b/dist/selinux/libcare.te +@@ -52,6 +52,9 @@ allow libcare_t libcare_file_t: lnk_file read_lnk_file_perms; + # to read patient's /proc entries and be able to attach to it + allow libcare_t self: capability { dac_override dac_read_search sys_ptrace }; + ++# need by remote mprotect ++allow svirt_t self : process execmem; ++ + allow libcare_t svirt_t : process ptrace; + allow libcare_t svirt_t : dir list_dir_perms; + allow libcare_t svirt_t : file rw_file_perms; +-- +2.27.0 + diff --git a/0012-libcare-dump-change-the-return-value.patch b/0012-libcare-dump-change-the-return-value.patch new file mode 100644 index 0000000..e0b452f --- /dev/null +++ b/0012-libcare-dump-change-the-return-value.patch @@ -0,0 +1,38 @@ +From 037c9ac7e9d3eaa072ae1edaad2bc22e18f4333a Mon Sep 17 00:00:00 2001 +From: jiang-dawei15 +Date: Thu, 5 May 2022 10:39:47 +0800 +Subject: [PATCH] libcare-dump:change the return value + +--- + src/libcare-dump.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/libcare-dump.c b/src/libcare-dump.c +index 8736452..b712709 100644 +--- a/src/libcare-dump.c ++++ b/src/libcare-dump.c +@@ -45,6 +45,7 @@ void usage() + + int kpatch_dump_kpatch_header(const char *input_file) + { ++ int rv; + int fdi = -1; + int ret = -1; + int elf_size; +@@ -67,7 +68,12 @@ int kpatch_dump_kpatch_header(const char *input_file) + goto cleanup; + } + +- ret = read(fdi, &kp, sizeof(struct kpatch_file)); ++ rv = read(fdi, &kp, sizeof(struct kpatch_file)); ++ if (rv <= 0) { ++ printf("Read kpatch file '%s' failed.\n", input_file); ++ goto cleanup; ++ } ++ ret = 0; + printf("%-25s %s\n", "Patch Name:", input_file); + printf("%-25s %s\n", "Magic:", kp.magic); + printf("%-25s %s\n", "Patch id:", kp.id); +-- +2.27.0 + diff --git a/0013-modify-pkgbuild-to-make-kpatch-for-RPM-based-packages.patch b/0013-modify-pkgbuild-to-make-kpatch-for-RPM-based-packages.patch new file mode 100644 index 0000000..9c5a7e7 --- /dev/null +++ b/0013-modify-pkgbuild-to-make-kpatch-for-RPM-based-packages.patch @@ -0,0 +1,459 @@ +From 0c414638168e0c1a006827daaae10c2ea4a8fc08 Mon Sep 17 00:00:00 2001 +From: wangcichen +Date: Mon, 9 May 2022 16:27:09 +0800 +Subject: [PATCH] modify scripts/pkgbuild to make kpatch'es for the RPM-based + packages + +1.support specify patch-id, build-id and sanity check +2.simplify script and put it into libcare devel package +--- + scripts/example_info | 59 ++++++++++++++ + scripts/pkgbuild | 179 ++++++++++++++++++++++++------------------- + 2 files changed, 161 insertions(+), 77 deletions(-) + create mode 100644 scripts/example_info + +diff --git a/scripts/example_info b/scripts/example_info +new file mode 100644 +index 0000000..d848e33 +--- /dev/null ++++ b/scripts/example_info +@@ -0,0 +1,59 @@ ++#!/bin/bash ++ ++KP_PROJECT=qemu ++KP_PROJECT_FORMAT=rpm ++KP_PROJECT_BUILD_ROOT=/var/libcareplus/qemu/rpmbuild ++KP_PROJECT_ORIG_RPMS=/var/libcareplus/qemu/qemu-6.2.0-29.oe2203 ++KP_PROJECT_SPEC=qemu.spec ++ ++# we choose plist filename as patch-id, eg: 220411 here ++KP_PROJECT_PLIST_FILE=/var/libcareplus/qemu/patch001/220506.plist ++KP_PROJECT_DIR=$KP_PROJECT_BUILD_ROOT/BUILD/qemu-6.2.0 ++KP_PROJECT_BUILD_DIR=$KP_PROJECT_DIR/build/x86_64-softmmu ++KP_PROJECT_BUILD_ID=61fcf129b23f05a623e0bf696a03d3348f366348 ++KP_SANITY_CHECK_STRICTLY=no ++KP_PROJECT_SOURCE_URL= ++KP_PROJECT_SOURCE=qemu-6.2.0-29.oe2203.src.rpm ++KP_PROJECT_BINARY=qemu-6.2.0-29.oe2203.x86_64.rpm ++ ++KP_PROJECT_PREBUILT=build.orig-$KP_PROJECT_BINARY.tgz ++KP_PROJECT_PATCH=kpatch-${KP_PROJECT_BINARY%.*}.tgz ++KP_RPMBUILD_FLAGS="'--define=dist .oe2203'" ++#KP_RPM_REPOS="--enablerepo=base" ++ ++ ++KP_INSTALL_FILES=" ++/qemu-system-x86_64 /usr/libexec/qemu-kvm ++" ++ ++KPATCH_ASM_DIR=$KP_PROJECT_BUILD_ROOT/asmdir ++export KPATCH_ASM_DIR ++ ++KPCC_PATCH_ARGS="--force-gotpcrel;--os=rhel6;--ignore-changes=banner,compilation" ++export KPCC_PATCH_ARGS ++ ++KPCC_DBGFILTER_ARGS="--dbg-filter;--dbg-filter-eh-frame;--dbg-filter-gcc-except-table;--os=rhel6" ++export KPCC_DBGFILTER_ARGS ++ ++kp_prebuild_hook() { ++ if test -z "$(command -v tar)"; then ++ echo "No tar command, Please install it first" ++ exit 1 ++ fi ++ if test -z "$(command -v rpmbuild)"; then ++ echo "No rpmbuild command, Please install it first" ++ exit 1 ++ fi ++} ++ ++kp_build_hook() { ++ : ++} ++ ++kp_prepare_test_binaries() { ++ : ++} ++ ++kp_patch_test() { ++ : ++} +diff --git a/scripts/pkgbuild b/scripts/pkgbuild +index f91af57..1185cd9 100755 +--- a/scripts/pkgbuild ++++ b/scripts/pkgbuild +@@ -1,4 +1,8 @@ + #!/bin/bash ++# make kpatch'es for the RPM-based packages using spec file. ++# Each package contains the config file: info in their project directory, ++# like /var/libcareplus/qemu/info ++# + + echo '+ set -x' + set -x +@@ -15,10 +19,10 @@ die() { + } + + usage() { +- echo "Usage: build [--prebuild] [--help] [--arch ARCH] DIR" ++ echo "Makes kpatch'es for the RPM-based packages using spec file." ++ echo "Usage: libcare-pkgbuild [--prebuild] [--test] [--help] DIR" + echo " -p|--prebuild prebuild project for further use" + echo " -t|--test run unit and stress tests" +- echo " -a|--arch ARCH target architecture(x86_64 by default)" + echo " -h|--help print this message" + echo " DIR directory with project's info file and other resources" + } +@@ -26,7 +30,6 @@ usage() { + prepare() { + # Parse cmdline args + ACTION=build +- ARCH=x86_64 + PDIR= + while [ "$1" != "" ]; do + case $1 in +@@ -36,10 +39,6 @@ prepare() { + -t|--test) + ACTION=test + ;; +- -a|--arch) +- shift +- ARCH=$1 +- ;; + -h|--help) + usage + exit 0 +@@ -56,11 +55,8 @@ prepare() { + shift + done + +- # Export env vars that are needed during the build +- SCRIPTS="$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)" +- LIBCARE_DIR="${LIBCARE_DIR:-$SCRIPTS/..}" +- KPATCH_PATH="${KPATCH_PATH:-$LIBCARE_DIR/src}" +- export LIBCARE_DIR KPATCH_PATH ++ KPATCH_PATH="$(dirname "$( which libcare-cc )" )" ++ export KPATCH_PATH + export OLDPATH=$PATH + export KPATCH_PASSTHROUGH_ASM=1 + CPUS=`cat /proc/cpuinfo | grep ^processor | wc -l` +@@ -70,12 +66,13 @@ prepare() { + # Obtain information about the project + source $PDIR/info + +- mkdir -p /kcdata ++ ROOT_ORIGINAL=$PDIR/root.original ++ ROOT_PATCHED=$PDIR/root.patched + } + + clean_dirs() { + echo " cleaning up" +- rm -rf $KP_PROJECT_BUILD_ROOT /root/root.original /root/root.patched ++ rm -rf $KP_PROJECT_BUILD_ROOT $ROOT_ORIGINAL $ROOT_PATCHED + } + + kp_prepare_env_hook() { +@@ -86,17 +83,15 @@ kp_prepare_env_hook() { + kp_pack_prebuilt() { + echo " packing prebuilt $KP_PROJECT into $KP_PROJECT_PREBUILT" + pushd $KP_PROJECT_BUILD_ROOT +- tar -zcf /kcdata/$KP_PROJECT_PREBUILT \ ++ tar -zcf $PDIR/$KP_PROJECT_PREBUILT \ + $KP_PROJECT_BUILD_ROOT \ +- /root/root.original ++ $ROOT_ORIGINAL + popd + } + + kp_unpack_prebuilt() { + echo " unpacking prebuilt $KP_PROJECT into $KP_PROJECT_PREBUILT" +- tar -xf /kcdata/$KP_PROJECT_PREBUILT -C / +- +- yum-builddep -d 1 -y $KP_PROJECT_BUILD_ROOT/SPECS/$KP_PROJECT_SPEC ++ tar -xf $PDIR/$KP_PROJECT_PREBUILT -C / + } + + kp_prepare_source_raw() { +@@ -108,38 +103,32 @@ kp_prepare_source_raw() { + } + + kp_download_source_rpm() { +- mkdir -p /kcdata + if test -n "$KP_PROJECT_SOURCE_URL"; then +- curl $KP_PROJECT_SOURCE_URL -o /kcdata/$KP_PROJECT_SOURCE ++ curl $KP_PROJECT_SOURCE_URL -o $KP_PROJECT_ORIG_RPMS/$KP_PROJECT_SOURCE + else +- yumdownloader --source --destdir /kcdata ${KP_PROJECT_SOURCE%.src.rpm} ++ yumdownloader --source --destdir $KP_PROJECT_ORIG_RPMS ${KP_PROJECT_SOURCE%.src.rpm} + fi + } + + kp_prepare_source_rpm() { +- rm -rf $HOME/deps ++ rm -rf $PDIR/deps + eval yum-builddep -d 1 -y $KP_RPM_REPOS \ +- --downloadonly --downloaddir=$HOME/deps \ +- /kcdata/$KP_PROJECT_SOURCE ++ --downloadonly --downloaddir=$PDIR/deps \ ++ $KP_PROJECT_ORIG_RPMS/$KP_PROJECT_SOURCE + mkdir -p $KP_PROJECT_BUILD_ROOT + rpm -qa > $KP_PROJECT_BUILD_ROOT/all-packages.txt +- ls $HOME/deps > $KP_PROJECT_BUILD_ROOT/dependencies.txt +- eval yum-builddep -d 1 -y $KP_RPM_REPOS \ +- /kcdata/$KP_PROJECT_SOURCE ++ ls $PDIR/deps > $KP_PROJECT_BUILD_ROOT/dependencies.txt ++ eval yum-builddep -d 1 -y $KP_RPM_REPOS \ ++ $KP_PROJECT_ORIG_RPMS/$KP_PROJECT_SOURCE + + sed -i 's/.rpm$//g' $KP_PROJECT_BUILD_ROOT/dependencies.txt + +- rpm -ivh /kcdata/$KP_PROJECT_SOURCE \ ++ rpm -ivh $KP_PROJECT_ORIG_RPMS/$KP_PROJECT_SOURCE \ + --define "_topdir $KP_PROJECT_BUILD_ROOT" + } + +-kp_prepare_source_deb() { +- echo "deb support is not implemented yet" +- exit 1 +-} +- + kp_prepare_source() { +- if ! test -f /kcdata/$KP_PROJECT_SOURCE; then ++ if ! test -f $KP_PROJECT_ORIG_RPMS/$KP_PROJECT_SOURCE; then + echo " downloading source for $KP_PROJECT" + kp_download_source_$KP_PROJECT_FORMAT + fi +@@ -147,12 +136,60 @@ kp_prepare_source() { + kp_prepare_source_$KP_PROJECT_FORMAT + } + ++patch_list_apply() { ++ SRC_DIR=$(cd "$(dirname "$1")" && pwd)/$(basename "$1") ++ PATCH_DIR=$(cd "$(dirname "$KP_PROJECT_PLIST_FILE")" && pwd) ++ PLIST=$PATCH_DIR/$(basename "$KP_PROJECT_PLIST_FILE") ++ PATCH_ID=$(echo $(basename "$KP_PROJECT_PLIST_FILE") | awk -F. '{print $1}') ++ if test -z "$PATCH_ID"; then ++ echo "Failed to get patch-id. Please check plist filename: $KP_PROJECT_PLIST_FILE" ++ exit 1 ++ fi ++ TEMP_PLIST=/tmp/build.kpatch/tmpplist ++ ++ if [ ! -f $PLIST ]; then ++ echo "File $PLIST not found" ++ exit 1; ++ fi ++ ++ echo "patching $PWD with patches from $PLIST" ++ ++ pushd $SRC_DIR # go to the directory with sources to be patched ++ ++ #in case we don't have a newline in plist ++ cat $PLIST > $TEMP_PLIST ++ echo -e "\n" >> $TEMP_PLIST ++ ++ # iterate through patches in PLIST ++ while read NAME ++ do ++ COMMENT=`echo $NAME | cut -c1` ++ if [ "$COMMENT" == "#" ]; then ++ continue; ++ fi ++ ++ if [ -z "${NAME}" ]; then ++ continue; ++ fi ++ ++ echo "Applying patch $NAME" ++ patch -p1 -u --fuzz=0 --batch < $PATCH_DIR/$NAME ++ if [ $? != 0 ]; then ++ echo "Failed applying patch $NAME"; popd; rm $TEMP_PLIST; exit 1 ++ else ++ echo "Successfully applied patch $NAME" ++ fi ++ done < $TEMP_PLIST ++ rm $TEMP_PLIST ++ ++ popd ++} ++ + kp_patch_source() { + echo " patching project" +- PATCH_DIR=$LIBCARE_DIR/patches + #patch_list_apply requires this dir + mkdir -p /tmp/build.kpatch +- $SCRIPTS/patch_list_apply $KP_PROJECT_DIR $PDIR/plist $PATCH_DIR ++ patch_list_apply $KP_PROJECT_DIR + } + + kp_prebuild_rpm() { +@@ -170,25 +207,17 @@ kp_prebuild_rpm() { + } + + _kp_install_orig_rpm() { +- for rpmfile in $KP_ORIG_RPMS; do +- pkgname="$(basename $rpmfile)" +- pkgname="${pkgname%%.rpm}" +- eval yumdownloader --enablerepo=base-debuginfo $KP_RPM_REPOS \ +- --destdir=$HOME/rpms.orig $pkgname +- done +- +- rpm --force -i $HOME/rpms.orig/*.rpm \ +- --root=$HOME/root.original \ ++ rpm --force -i $1 \ ++ --root=$ROOT_ORIGINAL \ + --nodeps --noscripts + } + + kp_install_orig_rpm() { +- _kp_install_orig_rpm ++ for orig_rpm in $(ls $KP_PROJECT_ORIG_RPMS | grep -v $KP_PROJECT_SOURCE); do ++ _kp_install_orig_rpm $KP_PROJECT_ORIG_RPMS/$orig_rpm ++ done + } + +-kp_prebuild_hook() { +- : +-} + + kp_prebuild() { + echo " prebuilding $KP_PROJECT" +@@ -200,25 +229,25 @@ de_offset_syms() { + local binary=$1 + + readelf -WSs $binary > $binary.symlist 2>/dev/null +- $SCRIPTS/de-offset-syms.awk $binary.symlist > $binary.symlist.tmp ++ de-offset-syms.awk $binary.symlist > $binary.symlist.tmp + sort $binary.symlist.tmp > $binary.symlist + rm -f $binary.symlist.tmp + } + + kp_sanity_check() { +- pushd $HOME/root.patched ++ pushd $ROOT_PATCHED + local targets="$(find . -perm /0111 -type f)" + popd + + local failed="" + for target in $targets; do +- local original="$HOME/root.original/usr/lib/debug/$target.debug" +- local patched="$HOME/root.patched/$target" ++ local original=`ls $ROOT_ORIGINAL/usr/lib/debug/${target}*.debug` ++ local patched="$ROOT_PATCHED/$target" + local alloweddiff="$PDIR/$(basename "$target").symlist.diff" + + de_offset_syms $original + if test ! -s $original.symlist; then +- original="$HOME/root.original/$target" ++ original="$ROOT_ORIGINAL/$target" + de_offset_syms $original + fi + +@@ -241,7 +270,11 @@ kp_sanity_check() { + done + + if test -n "$failed"; then +- die "Failed sanity check for $failed" ++ if test "$KP_SANITY_CHECK_STRICTLY" == "yes"; then ++ die "Failed sanity check for $failed" ++ else ++ echo "[Warning] Failed sanity check for $failed" ++ fi + fi + } + +@@ -308,7 +341,7 @@ kp_check_missing_files() { + } + + kp_install_generic() { +- local root_patched="$HOME/root.patched" ++ local root_patched="$ROOT_PATCHED" + + kp_install_files $KP_PROJECT_BUILD_DIR \ + $root_patched \ +@@ -318,13 +351,9 @@ kp_install_generic() { + } + + kp_install_rpm() { +- kp_install_orig_rpm + kp_install_generic + } + +-kp_build_hook() { +- : +-} + + kp_build() { + echo " building $KP_PROJECT" +@@ -340,19 +369,22 @@ kp_build() { + kp_gen_kpatch() { + echo " generating kpatches" + +- pushd $HOME/root.patched ++ pushd $ROOT_PATCHED + targets=$(find . -perm /0111 -type f) + popd + +- rm -rf $HOME/${KP_PROJECT_PATCH%.*} +- mkdir $HOME/${KP_PROJECT_PATCH%.*} ++ rm -rf $PDIR/${KP_PROJECT_PATCH%.*} ++ mkdir $PDIR/${KP_PROJECT_PATCH%.*} + + local no_patches=1 + + for t in $targets; do +- local debug="$HOME/root.original/usr/lib/debug/$t.debug" +- local patched="$HOME/root.patched/$t" ++ local debug=`ls $ROOT_ORIGINAL/usr/lib/debug/${t}*.debug` ++ local patched="$ROOT_PATCHED/$t" + local buildid=$(eu-readelf -n $debug | sed -n '/Build ID:/ { s/.* //; p }') ++ if test -n "$KP_PROJECT_BUILD_ID"; then ++ buildid=$KP_PROJECT_BUILD_ID ++ fi + if test -z "$buildid"; then + continue + fi +@@ -363,7 +395,7 @@ kp_gen_kpatch() { + + chmod u+w $debug $patched + +- eu-unstrip "$HOME/root.original/$t" "$debug" ++ eu-unstrip "$ROOT_ORIGINAL/$t" "$debug" + + $KPATCH_PATH/kpatch_strip --strip $patched $patched.kpstripped + cp $patched.kpstripped $patched.relfixup +@@ -372,8 +404,8 @@ kp_gen_kpatch() { + /usr/bin/strip --strip-unneeded $patched.stripped + cp $patched.stripped $patched.undolink + $KPATCH_PATH/kpatch_strip --undo-link $debug $patched.undolink +- $KPATCH_PATH/kpatch_make -b "$buildid" $patched.undolink -o $patched.kpatch +- cp $patched.kpatch $HOME/${KP_PROJECT_PATCH%.*}/$buildid.kpatch ++ $KPATCH_PATH/kpatch_make -b "$buildid" -i "$PATCH_ID" $patched.undolink -o $patched.kpatch ++ cp $patched.kpatch $PDIR/${KP_PROJECT_PATCH%.*}/$buildid.kpatch + no_patches=0 + done + +@@ -384,9 +416,7 @@ kp_gen_kpatch() { + + kp_pack_patch() { + echo " packing patch for $KP_PROJECT into $KP_PROJECT_PATCH" +- pushd $KP_PROJECT_BUILD_DIR +- tar -zcf /kcdata/$KP_PROJECT_PATCH $HOME/${KP_PROJECT_PATCH%.*} +- popd ++ tar -zcf $PDIR/$KP_PROJECT_PATCH $PDIR/${KP_PROJECT_PATCH%.*} + } + + kp_unpack_patch() { +@@ -411,11 +441,6 @@ kp_unpack_patch() { + + rm -fr $tmpdir + } +- +-kp_mark_tests_fail() { +- touch /kcdata/Tests-FAIL +-} +- + overwrite_utils() { + TMPBIN=$(mktemp -d --tmpdir) + +-- +2.24.1.windows.2 + diff --git a/0014-kpatch_process-fix-possible-double-free.patch b/0014-kpatch_process-fix-possible-double-free.patch new file mode 100644 index 0000000..07350ac --- /dev/null +++ b/0014-kpatch_process-fix-possible-double-free.patch @@ -0,0 +1,24 @@ +From fdf172f68f2270306effda39211a4be5ca7e437e Mon Sep 17 00:00:00 2001 +From: wangcichen +Date: Tue, 17 May 2022 16:40:26 +0800 +Subject: [PATCH 1/5] kpatch_process: fix possible double free. + +--- + src/kpatch_process.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/kpatch_process.c b/src/kpatch_process.c +index 9d6daa4..a31f70c 100644 +--- a/src/kpatch_process.c ++++ b/src/kpatch_process.c +@@ -682,7 +682,6 @@ process_list_threads(kpatch_process_t *proc, + t = realloc(pids, *alloc * sizeof(*pids)); + if (t == NULL) { + kplogerror("Failed to (re)allocate memory for pids\n"); +- closedir(dir); + goto dealloc; + } + +-- +2.27.0 + diff --git a/0015-ptrace-fix-NULL-pointer-access-problem.patch b/0015-ptrace-fix-NULL-pointer-access-problem.patch new file mode 100644 index 0000000..1038db5 --- /dev/null +++ b/0015-ptrace-fix-NULL-pointer-access-problem.patch @@ -0,0 +1,39 @@ +From a45b9424cb7258c00211115191f74fbaf8f74285 Mon Sep 17 00:00:00 2001 +From: wangcichen +Date: Mon, 23 May 2022 10:18:57 +0800 +Subject: [PATCH 2/5] ptrace: fix NULL pointer access problem + +--- + src/arch/aarch64/arch_ptrace.c | 2 -- + src/arch/x86/arch_ptrace.c | 2 -- + 2 files changed, 4 deletions(-) + +diff --git a/src/arch/aarch64/arch_ptrace.c b/src/arch/aarch64/arch_ptrace.c +index 774dc21..2227e95 100644 +--- a/src/arch/aarch64/arch_ptrace.c ++++ b/src/arch/aarch64/arch_ptrace.c +@@ -465,8 +465,6 @@ kpatch_arch_ptrace_waitpid(kpatch_process_t *proc, + + /* TODO: fix the latter by SINGLESTEPping such a thread with + * the original instruction in place */ +- kperr("the thread ran out: %d, pc= %llx, expected = %lx\n", pid, +- regs.pc, pctx->execute_until); + errno = ESRCH; + return -1; + } +diff --git a/src/arch/x86/arch_ptrace.c b/src/arch/x86/arch_ptrace.c +index 9069484..9dede71 100644 +--- a/src/arch/x86/arch_ptrace.c ++++ b/src/arch/x86/arch_ptrace.c +@@ -492,8 +492,6 @@ int kpatch_arch_ptrace_waitpid(kpatch_process_t *proc, + + /* TODO: fix the latter by SINGLESTEPping such a thread with + * the original instruction in place */ +- kperr("the thread ran out: %d, rip = %llx, expected = %lx\n", pid, +- regs.rip, pctx->execute_until); + errno = ESRCH; + return -1; + } +-- +2.27.0 + diff --git a/0016-fix-patched-process-crashing-when-acccess-the-global.patch b/0016-fix-patched-process-crashing-when-acccess-the-global.patch new file mode 100644 index 0000000..3834903 --- /dev/null +++ b/0016-fix-patched-process-crashing-when-acccess-the-global.patch @@ -0,0 +1,156 @@ +From add4a57f47eb89acf4a471253654cc806aedaaf8 Mon Sep 17 00:00:00 2001 +From: ctyunsystem +Date: Wed, 11 May 2022 10:20:26 +0800 +Subject: [PATCH 3/5] fix patched process crashing when acccess the global var + which newly added + +--- + src/kpatch_gensrc.c | 20 +++++++++++++++++--- + src/kpatch_patch.c | 6 +++--- + tests/new_var/Makefile | 2 ++ + tests/new_var/desc | 1 + + tests/new_var/new_var.c | 23 +++++++++++++++++++++++ + tests/new_var/new_var.diff | 15 +++++++++++++++ + 6 files changed, 61 insertions(+), 6 deletions(-) + create mode 100644 tests/new_var/Makefile + create mode 100644 tests/new_var/desc + create mode 100644 tests/new_var/new_var.c + create mode 100644 tests/new_var/new_var.diff + +diff --git a/src/kpatch_gensrc.c b/src/kpatch_gensrc.c +index bf1832a..67254d7 100644 +--- a/src/kpatch_gensrc.c ++++ b/src/kpatch_gensrc.c +@@ -432,6 +432,20 @@ out: + + /* ------------------------------------------ helpers -------------------------------------------- */ + ++static inline int page_shift(int n) { ++ int res = -1; ++ ++ while(n) { ++ res++; ++ n >>= 1; ++ } ++ ++ return res; ++} ++ ++#define PAGE_SIZE getpagesize() ++#define PAGE_SHIFT page_shift(PAGE_SIZE) ++ + static void change_section(struct kp_file *fout, struct section_desc *sect, int flags) + { + static int init_data_section = 0; +@@ -448,15 +462,15 @@ static void change_section(struct kp_file *fout, struct section_desc *sect, int + s = ".kpatch.text,\"ax\",@progbits"; + else { + s = ".kpatch.data,\"aw\",@progbits"; +- if (!init_data_section && (flags & FLAG_PUSH_SECTION)) { ++ if (!init_data_section) { + init_data_section = 1; +- align = ".p2align\t12"; ++ align = ".p2align"; + } + } + + fprintf(fout->f, "\t.%ssection %s\n", (flags & FLAG_PUSH_SECTION) ? "push" : "", s); + if (align) +- fprintf(fout->f, "\t%s\n", align); ++ fprintf(fout->f, "\t%s\t%d\n", align, PAGE_SHIFT); + } + + void get_comm_args(struct kp_file *f, int l, kpstr_t *xname, int *sz, int *align) +diff --git a/src/kpatch_patch.c b/src/kpatch_patch.c +index d74299d..3b53a5a 100644 +--- a/src/kpatch_patch.c ++++ b/src/kpatch_patch.c +@@ -372,9 +372,9 @@ object_apply_patch(struct object_file *o) + kp->jmp_offset = sz; + kpdebug("Jump table %d bytes for %d syms at offset 0x%x\n", + o->jmp_table->size, undef, kp->jmp_offset); +- sz = ROUND_UP(sz + o->jmp_table->size, 4096); ++ sz = ROUND_UP(sz + o->jmp_table->size, PAGE_SIZE); + } +- sz = ROUND_UP(sz, 4096); ++ sz = ROUND_UP(sz, PAGE_SIZE); + + /* kpatch elf */ + kp->elf_offset = sz; +@@ -386,7 +386,7 @@ object_apply_patch(struct object_file *o) + kp->user_undo = sz; + sz = ROUND_UP(sz + HUNK_SIZE * o->ninfo, 16); + +- sz = ROUND_UP(sz, 4096); ++ sz = ROUND_UP(sz, PAGE_SIZE); + kp->kpatch_total_mem_sz = sz; + + /* +diff --git a/tests/new_var/Makefile b/tests/new_var/Makefile +new file mode 100644 +index 0000000..6dd4b69 +--- /dev/null ++++ b/tests/new_var/Makefile +@@ -0,0 +1,2 @@ ++ ++include ../makefile.inc +diff --git a/tests/new_var/desc b/tests/new_var/desc +new file mode 100644 +index 0000000..4f8cd31 +--- /dev/null ++++ b/tests/new_var/desc +@@ -0,0 +1 @@ ++patch adds a new var +diff --git a/tests/new_var/new_var.c b/tests/new_var/new_var.c +new file mode 100644 +index 0000000..3ed116a +--- /dev/null ++++ b/tests/new_var/new_var.c +@@ -0,0 +1,23 @@ ++#include ++#include ++ ++void print_greetings_patched(int var) ++{ ++ printf("Hello. This is a PATCHED version\n"); ++ printf("Hello. \n", var); ++} ++ ++void print_greetings(void) ++{ ++ printf("Hello. This is an UNPATCHED version\n"); ++} ++ ++int main() ++{ ++ while (1) { ++ print_greetings(); ++ sleep(1); ++ } ++ ++ return 0; ++} +diff --git a/tests/new_var/new_var.diff b/tests/new_var/new_var.diff +new file mode 100644 +index 0000000..c617535 +--- /dev/null ++++ b/tests/new_var/new_var.diff +@@ -0,0 +1,15 @@ ++--- ./new_var.c 2022-02-10 19:40:17.948981115 +0800 +++++ ./new_var.c 2022-02-10 20:02:38.774536002 +0800 ++@@ -7,9 +7,11 @@ ++ printf("Hello. \n", var); ++ } ++ +++int newly_added_var = 0x20220210; ++ void print_greetings(void) ++ { ++- printf("Hello. This is an UNPATCHED version\n"); +++ newly_added_var = 0x2022 << 16 | 0x2202; +++ print_greetings_patched(newly_added_var); ++ } ++ ++ int main() +-- +2.27.0 + diff --git a/0017-fix-probably-restore-cc-symbol-link-fail-when-kill-p.patch b/0017-fix-probably-restore-cc-symbol-link-fail-when-kill-p.patch new file mode 100644 index 0000000..6147dfc --- /dev/null +++ b/0017-fix-probably-restore-cc-symbol-link-fail-when-kill-p.patch @@ -0,0 +1,100 @@ +From c4f9d59c62454d255af4a5c3933eebf6942dbd99 Mon Sep 17 00:00:00 2001 +From: ctyunsystem +Date: Wed, 11 May 2022 10:32:45 +0800 +Subject: [PATCH 4/5] fix probably restore cc symbol link fail when kill patch + building uncourteous + +--- + src/libcare-patch-make | 45 ++++-------------------------------------- + 1 file changed, 4 insertions(+), 41 deletions(-) + +diff --git a/src/libcare-patch-make b/src/libcare-patch-make +index 03aa1d6..41e5926 100755 +--- a/src/libcare-patch-make ++++ b/src/libcare-patch-make +@@ -83,32 +83,6 @@ restore_origs() { + + trap "restore_origs" 0 + +-replace_qemu_ld_flags() { +- local qemu_ld_flags_old=$1 +- ret=$(echo $qemu_ld_flags_old | grep "\-Wl,-q") +- if [[ "$ret" == "" ]]; then +- local qemu_ld_flags="${qemu_ld_flags_old} -Wl,-q" +- echo "replace QEMU_LDFLAGS to '${qemu_ld_flags}'" +- sed -i "/^QEMU_LDFLAGS=/c\\${qemu_ld_flags}" config-host.mak +- fi +-} +- +-recover_qemu_ld_flags() { +- local qemu_ld_flags=$1 +- echo "recover QEMU_LDFLAGS to '${qemu_ld_flags}'" +- sed -i "/^QEMU_LDFLAGS=/c\\${qemu_ld_flags}" config-host.mak +-} +- +-replace_cc_symbolink() { +- unlink $SYMBOLINK_CC +- ln -s $LIBCARE_CC $SYMBOLINK_CC +-} +- +-recover_cc_symbolink() { +- unlink $SYMBOLINK_CC +- ln -s $REAL_CC $SYMBOLINK_CC +-} +- + build_objects() { + restore_origs + +@@ -124,7 +98,8 @@ build_objects() { + export KPCC_DBGFILTER_ARGS="" + + echo "${green}BUILDING ORIGINAL CODE${reset}" +- make $LPMAKEFILE $JOBS_MAKE >$MAKE_OUTPUT 2>&1 ++ local lp_make_env_original="CC=${CC}" ++ make $LPMAKEFILE $JOBS_MAKE ${lp_make_env_original} >$MAKE_OUTPUT 2>&1 + + echo "${green}INSTALLING ORIGINAL OBJECTS INTO $LPMAKE_ORIGINAL_DIR${reset}" + make $LPMAKEFILE $JOBS_MAKE install \ +@@ -149,20 +124,14 @@ build_objects() { + export KPATCH_STAGE=patched + export KPCC_APPEND_ARGS="-Wl,-q" + +- qemu_ld_flags_bak=$(grep "^QEMU_LDFLAGS=" config-host.mak) +- #add '-Wl,-q' to LD_FLAGS +- replace_qemu_ld_flags "$qemu_ld_flags_bak" +- + echo "${green}BUILDING PATCHED CODE${reset}" +- make $LPMAKEFILE $JOBS_MAKE >$MAKE_OUTPUT 2>&1 ++ local lp_make_env_patched="CC=${CC}" ++ make $LPMAKEFILE $JOBS_MAKE ${lp_make_env_patched} >$MAKE_OUTPUT 2>&1 + + echo "${green}INSTALLING PATCHED OBJECTS INTO $LPMAKE_PATCHED_DIR${reset}" + make $LPMAKEFILE $JOBS_MAKE install \ + "$destdir=$LPMAKE_PATCHED_DIR" \ + >$MAKE_OUTPUT 2>&1 +- +- # recover LD_FLAGS +- recover_qemu_ld_flags "$qemu_ld_flags_bak" + } + + build_kpatches() { +@@ -274,16 +243,10 @@ main() { + + prepare_env + +- # replace cc +- replace_cc_symbolink +- + if test -z "$only_update"; then + build_objects "$@" + fi + build_kpatches +- +- # recover cc +- recover_cc_symbolink + } + + main "$@" +-- +2.27.0 + diff --git a/0018-optimize-Remove-unnecessary-comparison-code.patch b/0018-optimize-Remove-unnecessary-comparison-code.patch new file mode 100644 index 0000000..2747e11 --- /dev/null +++ b/0018-optimize-Remove-unnecessary-comparison-code.patch @@ -0,0 +1,39 @@ +From 5667441f87ef702ed537aba7c677eee1b36f1ead Mon Sep 17 00:00:00 2001 +From: wangcichen +Date: Fri, 27 May 2022 17:08:28 +0800 +Subject: [PATCH 5/5] optimize: Remove unnecessary comparison code + +--- + src/arch/aarch64/arch_elf.c | 2 +- + src/arch/x86/arch_elf.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/arch/aarch64/arch_elf.c b/src/arch/aarch64/arch_elf.c +index 9ce586d..10399ee 100644 +--- a/src/arch/aarch64/arch_elf.c ++++ b/src/arch/aarch64/arch_elf.c +@@ -202,7 +202,7 @@ int kpatch_arch_apply_relocate_add(struct object_file *o, GElf_Shdr *relsec) + unsigned long val; + void *loc, *loc2; + +- if (r->r_offset < 0 || r->r_offset >= tshdr->sh_size) { ++ if (r->r_offset >= tshdr->sh_size) { + kperr("Relocation offset for section '%s'" + " is at 0x%lx beyond the section size 0x%lx\n", + scnname, r->r_offset, tshdr->sh_size); +diff --git a/src/arch/x86/arch_elf.c b/src/arch/x86/arch_elf.c +index 265fd37..f79a996 100644 +--- a/src/arch/x86/arch_elf.c ++++ b/src/arch/x86/arch_elf.c +@@ -56,7 +56,7 @@ int kpatch_arch_apply_relocate_add(struct object_file *o, GElf_Shdr *relsec) + unsigned long val; + void *loc, *loc2; + +- if (r->r_offset < 0 || r->r_offset >= tshdr->sh_size) { ++ if (r->r_offset >= tshdr->sh_size) { + kperr("Relocation offset for section '%s'" + " is at 0x%lx beyond the section size 0x%lx\n", + scnname, r->r_offset, tshdr->sh_size); +-- +2.27.0 + diff --git a/0019-Revert-fix-probably-restore-cc-symbol-link-fail-when.patch b/0019-Revert-fix-probably-restore-cc-symbol-link-fail-when.patch new file mode 100644 index 0000000..4788049 --- /dev/null +++ b/0019-Revert-fix-probably-restore-cc-symbol-link-fail-when.patch @@ -0,0 +1,101 @@ +From d86044aa709617186fa4eeb2dff9540395f77c8e Mon Sep 17 00:00:00 2001 +From: ctyunsystem +Date: Tue, 5 Jul 2022 10:13:15 +0800 +Subject: [PATCH 1/2] Revert "fix probably restore cc symbol link fail when + kill patch building uncourteous" ==> Revert "libcare-patch-make: fix some + bugs" + +--- + src/libcare-patch-make | 45 ++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 41 insertions(+), 4 deletions(-) + +diff --git a/src/libcare-patch-make b/src/libcare-patch-make +index 41e5926..03aa1d6 100755 +--- a/src/libcare-patch-make ++++ b/src/libcare-patch-make +@@ -83,6 +83,32 @@ restore_origs() { + + trap "restore_origs" 0 + ++replace_qemu_ld_flags() { ++ local qemu_ld_flags_old=$1 ++ ret=$(echo $qemu_ld_flags_old | grep "\-Wl,-q") ++ if [[ "$ret" == "" ]]; then ++ local qemu_ld_flags="${qemu_ld_flags_old} -Wl,-q" ++ echo "replace QEMU_LDFLAGS to '${qemu_ld_flags}'" ++ sed -i "/^QEMU_LDFLAGS=/c\\${qemu_ld_flags}" config-host.mak ++ fi ++} ++ ++recover_qemu_ld_flags() { ++ local qemu_ld_flags=$1 ++ echo "recover QEMU_LDFLAGS to '${qemu_ld_flags}'" ++ sed -i "/^QEMU_LDFLAGS=/c\\${qemu_ld_flags}" config-host.mak ++} ++ ++replace_cc_symbolink() { ++ unlink $SYMBOLINK_CC ++ ln -s $LIBCARE_CC $SYMBOLINK_CC ++} ++ ++recover_cc_symbolink() { ++ unlink $SYMBOLINK_CC ++ ln -s $REAL_CC $SYMBOLINK_CC ++} ++ + build_objects() { + restore_origs + +@@ -98,8 +124,7 @@ build_objects() { + export KPCC_DBGFILTER_ARGS="" + + echo "${green}BUILDING ORIGINAL CODE${reset}" +- local lp_make_env_original="CC=${CC}" +- make $LPMAKEFILE $JOBS_MAKE ${lp_make_env_original} >$MAKE_OUTPUT 2>&1 ++ make $LPMAKEFILE $JOBS_MAKE >$MAKE_OUTPUT 2>&1 + + echo "${green}INSTALLING ORIGINAL OBJECTS INTO $LPMAKE_ORIGINAL_DIR${reset}" + make $LPMAKEFILE $JOBS_MAKE install \ +@@ -124,14 +149,20 @@ build_objects() { + export KPATCH_STAGE=patched + export KPCC_APPEND_ARGS="-Wl,-q" + ++ qemu_ld_flags_bak=$(grep "^QEMU_LDFLAGS=" config-host.mak) ++ #add '-Wl,-q' to LD_FLAGS ++ replace_qemu_ld_flags "$qemu_ld_flags_bak" ++ + echo "${green}BUILDING PATCHED CODE${reset}" +- local lp_make_env_patched="CC=${CC}" +- make $LPMAKEFILE $JOBS_MAKE ${lp_make_env_patched} >$MAKE_OUTPUT 2>&1 ++ make $LPMAKEFILE $JOBS_MAKE >$MAKE_OUTPUT 2>&1 + + echo "${green}INSTALLING PATCHED OBJECTS INTO $LPMAKE_PATCHED_DIR${reset}" + make $LPMAKEFILE $JOBS_MAKE install \ + "$destdir=$LPMAKE_PATCHED_DIR" \ + >$MAKE_OUTPUT 2>&1 ++ ++ # recover LD_FLAGS ++ recover_qemu_ld_flags "$qemu_ld_flags_bak" + } + + build_kpatches() { +@@ -243,10 +274,16 @@ main() { + + prepare_env + ++ # replace cc ++ replace_cc_symbolink ++ + if test -z "$only_update"; then + build_objects "$@" + fi + build_kpatches ++ ++ # recover cc ++ recover_cc_symbolink + } + + main "$@" +-- +2.27.0 + diff --git a/0020-fix-probably-restore-cc-symbol-link-fail-when-kill-p.patch b/0020-fix-probably-restore-cc-symbol-link-fail-when-kill-p.patch new file mode 100644 index 0000000..0465682 --- /dev/null +++ b/0020-fix-probably-restore-cc-symbol-link-fail-when-kill-p.patch @@ -0,0 +1,26 @@ +From 96362b54e9c2162fe10fd1cfe029bcc8e203b135 Mon Sep 17 00:00:00 2001 +From: ctyunsystem +Date: Tue, 5 Jul 2022 10:13:58 +0800 +Subject: [PATCH 2/2] fix probably restore cc symbol link fail when kill patch + building uncourteous + +--- + src/libcare-patch-make | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/libcare-patch-make b/src/libcare-patch-make +index 03aa1d6..3cd2fe9 100755 +--- a/src/libcare-patch-make ++++ b/src/libcare-patch-make +@@ -109,6 +109,8 @@ recover_cc_symbolink() { + ln -s $REAL_CC $SYMBOLINK_CC + } + ++trap "recover_cc_symbolink" SIGINT SIGTERM SIGQUIT ++ + build_objects() { + restore_origs + +-- +2.27.0 + diff --git a/0021-do-not-print-awk-warning-in-libcare-patch-make.patch b/0021-do-not-print-awk-warning-in-libcare-patch-make.patch new file mode 100644 index 0000000..7937c60 --- /dev/null +++ b/0021-do-not-print-awk-warning-in-libcare-patch-make.patch @@ -0,0 +1,25 @@ +From fce7fbc7ad2e830c5efc817e31da45f0e6a48a47 Mon Sep 17 00:00:00 2001 +From: jiang-dawei15 +Date: Fri, 16 Sep 2022 19:31:28 +0800 +Subject: [PATCH] do not print awk warning in libcare-patch-make + +--- + src/libcare-patch-make | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libcare-patch-make b/src/libcare-patch-make +index 3cd2fe9..9476063 100755 +--- a/src/libcare-patch-make ++++ b/src/libcare-patch-make +@@ -78,7 +78,7 @@ restore_origs() { + { vers[fname] = origfname; } + } + END { for (f in vers) system("mv " vers[f] " " f); } +-' ++' > /dev/null 2>&1 + } + + trap "restore_origs" 0 +-- +2.27.0 + diff --git a/README.en.md b/README.en.md index db9fc30..3077b91 100644 --- a/README.en.md +++ b/README.en.md @@ -1,40 +1,35 @@ -# libcareplus +# LibcarePlus #### Description -LibcarePlus delivers live patches to any of your Linux executables or libraries at the runtime, without the need for restart of your applications. +LibcarePlus‧is‧a‧general‧user-mode‧live‧patch‧framework.‧It delivers live patches to any of your Linux executables or libraries at the runtime, without the need for restart of your applications. -LibcarePlus is a self maintained branch derived from the LibCare project. It is released with the same LICENSE with LibCare and the original Copyright is kept. +LibcarePlus is a self-maintained branch derived from the LibCare project. It is released with the same license with LibCare and the original copyright is kept. More information about LibCare can be reached at: [https://github.com/cloudlinux/libcare](https://github.com/cloudlinux/libcare) -LibcarePlus aims at providing userspac livepatch ability -for popular architecture like x86_64 and aarch64. +LibcarePlus aims at providing user-mode live patches for popular architectures like x86_64 and AArch64. #### Software Architecture -For more information about the design of LibcarePlus, -please refer to the `LibcarePlus Design`. +For more information about the design of LibcarePlus, see the `LibcarePlus Design`. #### Installation -Please refer to the `LibcarePlus Intallation Guide` to -complete the installation of LibcarePlus. +Refer to the `LibcarePlus Intallation Guide` to install LibcarePlus. -### User Guide +#### User Guide -Please refer to: +Refer to: * LibcarePlus Patch Make Tutorial * LibcarePlus Patch Apply Tutorial -to help you to make the patch and apply it to the target process. +to help you make the patch and apply it to the target process. #### Contribution -Any contributors are wellcome to join this project, -we are glad to provide help and guide needed. -Developers can post an issue on this project and -make a pull request to join the development process. \ No newline at end of file +Any contributors are welcome to join this project, and we are glad to provide help and guidance needed. +Developers can post an issue on this project and submit a pull request to join the development process. \ No newline at end of file diff --git a/libcareplus-0.1.4.tar.gz b/libcareplus-0.1.4.tar.gz deleted file mode 100644 index b2dcc26..0000000 Binary files a/libcareplus-0.1.4.tar.gz and /dev/null differ diff --git a/libcareplus-1.0.0.tar.gz b/libcareplus-1.0.0.tar.gz new file mode 100644 index 0000000..02691fe Binary files /dev/null and b/libcareplus-1.0.0.tar.gz differ diff --git a/libcareplus.spec b/libcareplus.spec index 884aa95..e1d4ab6 100644 --- a/libcareplus.spec +++ b/libcareplus.spec @@ -1,27 +1,48 @@ -Version: 0.1.4 +%define with_selinux 1 + +Version: 1.0.0 Name: libcareplus Summary: LibcarePlus tools -Release: 2 +Release: 13 Group: Applications/System License: GPLv2 Url: https://gitee.com/openeuler/libcareplus Source0: %{name}-%{version}.tar.gz -Patch0001: src-Makefile-install-kpatch_gensrc-into-bindir.patch +Patch0000: 0000-gensrc-skip-vector-instruction-in-str_do_gotpcrel.patch +Patch0001: 0001-gensrc-we-should-add-align-while-FLAGS_PUSH_SECTION-.patch +Patch0002: 0002-fix-cblock-parse-for-LCOLD-LHOT-.cold.NUM-.init_arra.patch +Patch0003: 0003-elf-add-section-adderss-for-STT_NOTYPE-type-of-symbo.patch +Patch0004: 0004-elf-strip-adapt-to-new-gcc-version-10.3.1.patch +Patch0005: 0005-gitignore-ignore-some-tests-and-binary.patch +Patch0006: 0006-libcare-patch-make-adapt-libcare-patch-make-to-meson.patch +Patch0007: 0007-kpatch_elf-compatible-with-older-versions-of-the-so-.patch +Patch0008: 0008-kpatch_parse-fix-failed-to-recognize-.cold.patch +Patch0009: 0009-help-modify-some-help-information.patch +Patch0010: 0010-libcare-patch-make-fix-some-bugs.patch +Patch0011: 0011-selinux-enable-libcare-ctl-to-mprotect-qemu-process.patch +Patch0012: 0012-libcare-dump-change-the-return-value.patch +Patch0013: 0013-modify-pkgbuild-to-make-kpatch-for-RPM-based-packages.patch +Patch0014: 0014-kpatch_process-fix-possible-double-free.patch +Patch0015: 0015-ptrace-fix-NULL-pointer-access-problem.patch +Patch0016: 0016-fix-patched-process-crashing-when-acccess-the-global.patch +Patch0017: 0017-fix-probably-restore-cc-symbol-link-fail-when-kill-p.patch +Patch0018: 0018-optimize-Remove-unnecessary-comparison-code.patch +Patch0019: 0019-Revert-fix-probably-restore-cc-symbol-link-fail-when.patch +Patch0020: 0020-fix-probably-restore-cc-symbol-link-fail-when-kill-p.patch +Patch0021: 0021-do-not-print-awk-warning-in-libcare-patch-make.patch -ExclusiveArch: x86_64 -BuildRequires: elfutils-libelf-devel libunwind-devel +BuildRequires: elfutils-libelf-devel libunwind-devel gcc systemd %if 0%{with selinux} BuildRequires: checkpolicy BuildRequires: selinux-policy-devel -BuildRequires: /usr/share/selinux/devel/policyhelp %endif BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %if 0%{with selinux} -Requires: libcare-selinux = %{version}-%{release} +Requires: libcareplus-selinux = %{version}-%{release} %endif %description @@ -53,7 +74,9 @@ LibcarePlus devel files. %autopatch -p1 %build - +cd src +sh ./config +cd ../ make -C src %if 0%{with selinux} make -C dist/selinux @@ -73,54 +96,36 @@ make -C dist/selinux install \ %endif -install -m 0644 -D dist/libcare.service %{buildroot}%{_unitdir}/libcare.service -install -m 0644 -D dist/libcare.socket %{buildroot}%{_unitdir}/libcare.socket install -m 0644 -D dist/libcare.preset %{buildroot}%{_presetdir}/90-libcare.preset +install -m 0500 scripts/pkgbuild %{buildroot}%{_bindir}/libcare-pkgbuild +install -m 0500 scripts/de-offset-syms.awk %{buildroot}%{_bindir}/de-offset-syms.awk +install -m 0644 -D scripts/example_info %{buildroot}/usr/share/libcareplus/qemu_example_info %pre /usr/sbin/groupadd libcare -r 2>/dev/null || : /usr/sbin/usermod -a -G libcare qemu 2>/dev/null || : -%post -%systemd_post libcare.service -%systemd_post libcare.socket - -if [ $1 -eq 1 ]; then - # First install - systemctl start libcare.socket -fi -if [ $1 -eq 2 ]; then - # Upgrade. Just stop it, we will be reactivated - # by a connect to /run/libcare.sock - systemctl stop libcare.service -fi - -%preun -%systemd_preun libcare.service -%systemd_preun libcare.socket - -%postun -%systemd_postun libcare.service -%systemd_postun libcare.socket - %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %{_bindir}/libcare-ctl -%{_bindir}/libcare-client -%{_unitdir}/libcare.service -%{_unitdir}/libcare.socket %{_presetdir}/90-libcare.preset %files devel %defattr(-,root,root) %{_bindir}/libcare-cc %{_bindir}/libcare-patch-make +%{_bindir}/libcare-dump %{_bindir}/kpatch_gensrc %{_bindir}/kpatch_strip %{_bindir}/kpatch_make +%{_bindir}/libcare-server +%{_bindir}/libcare-client +%{_bindir}/libcare-pkgbuild +%{_bindir}/de-offset-syms.awk +/usr/share/libcareplus/qemu_example_info %if 0%{with selinux} @@ -163,8 +168,113 @@ exit 0 %endif %changelog +* Fri Sep 16 2022 yezengruan 1.0.0-13 +- do not print awk warning in libcare-patch-make + +* Wed Jun 15 2022 yezengruan 1.0.0-12 +- kpatch_process: fix possible double free. +- ptrace: fix NULL pointer access problem +- fix patched process crashing when acccess the global var +- fix probably restore cc symbol link fail when kill patch building uncourteous +- optimize: Remove unnecessary comparison code + +* Wed May 11 2022 Cichen Wang 1.0.0-11 +- modify scripts/pkgbuild to make kpatch'es for the RPM-based packages + +* Tue May 10 2022 yezengruan 1.0.0-10 +- libcare-dump: change the return value +- gensrc: skip vector instruction in str_do_gotpcrel + +* Wed Apr 27 2022 yezengruan 1.0.0-9 +- update the format of changelog + +* Tue Mar 29 2022 yezengruan 1.0.0-8 +- selinux: enable libcare-ctl to mprotect qemu process + +* Mon Mar 21 2022 yezengruan 1.0.0-7 +- libcare-patch-make: fix some bugs + +* Tue Mar 15 2022 yezengruan 1.0.0-6 +- help: modify some help information + +* Wed Mar 02 2022 imxcc - 1.0.0-5 +- kpatch_elf: compatible with older versions of the so naming rules +- kpatch_parse: fix failed to recognize .cold + +* Mon Feb 28 2022 imxcc - 1.0.0-4 +- libcare-patch-make: adapt libcare-patch-make to meson +- gitignore: ignore some tests and binary +- elf/strip: adapt to new gcc version(10.3.1) + +* Tue Feb 22 2022 imxcc - 1.0.0-3 +- libcareplus.spec:remove libcare.service and libcare.socket + +* Tue Feb 22 2022 imxcc - 1.0.0-2 +- gensrc: we should add align while FLAGS_PUSH_SECTION flag is set +- elf: add section adderss for STT_NOTYPE type of symbol + +* Tue Feb 22 2022 imxcc - 1.0.0-1 +- fix cblock parse for LCOLD/LHOT/.cold.NUM, .init_array and support gnu_unique_object + +* Mon Feb 07 2022 imxcc - 1.0.0-0 +- package init 1.0.0-0 + +* Mon Feb 07 2022 imxcc - 0.1.4-15 +- kpatch_user: init pid in cmd_info_user + +* Mon Feb 07 2022 imxcc - 0.1.4-14 +- some bugfix +- support aarch64 UT +- fix memory RWX problem + +* Mon Feb 07 2022 imxcc - 0.1.4-13 +- add libcare-dump tool +- support test sets running on x86 +- some bugfixs + +* Mon Feb 07 2022 imxcc - 0.1.4-12 +- src/Makefile: execute config scripts before building +- kpatch_gensrc.c: support ignoring functions which we don't need +- arch/aarch64/arch_parse: modify is_variable_start for arm asm +- libcare-ctl: implement applied patch list +- libcare-ctl: introduce patch-id +- arch/aarch64/arch_elf: Add LDR and B instruction relocation +- arch/aarch64/arch_parse: improve VAR_CBLOCK start indentify +- tls: add support for TLS symbol with IE model +- arch64/arch_elf: add R_AARCH64_LDST32_ABS_LO12_NC relocation type for aarch64 +- process: fix region start calculation +- aarch64/arch_elf: Add ldr and ldrb relocation for aarch6 + +* Mon Feb 07 2022 imxcc - 0.1.4-11 +- kpatch_cc: support gcc -MQ option +- libcare-cc: add gcc iquote option support + +* Mon Feb 07 2022 imxcc - 0.1.4-10 +- kpatch_user.c: fix gcc warning + +* Mon Feb 07 2022 imxcc - 0.1.4-9 +- libcare-patch-make: add `-j|--jobs` option + +* Mon Feb 07 2022 imxcc - 0.1.4-8 +- updated the README.en.md file + +* Wed Sep 08 2021 imxcc - 0.1.4-7 +- selinux: Allow init_t create lnk file + +* Thu Sep 02 2021 imxcc - 0.1.4-6 +- enable selinux + +* Sat Aug 21 2021 caodongxia - 0.1.4-5 +- fixes uninstall warning + +* Tue Jun 08 2021 wulei - 0.1.4-4 +- fixes failed: gcc: command not found + +* Tue Feb 09 2021 Jiajie Li - 0.1.4-3 +- Add basic support libcareplus on aarch64 + * Mon Dec 28 2020 sunguoshuai - 0.1.4-2 - Del the {dist} in release. -* Tue Dec 8 2020 Ying Fang +* Tue Dec 8 2020 Ying Fang - 0.1.4-1 - Init the libcareplus package spec diff --git a/src-Makefile-install-kpatch_gensrc-into-bindir.patch b/src-Makefile-install-kpatch_gensrc-into-bindir.patch deleted file mode 100644 index 6f31adb..0000000 --- a/src-Makefile-install-kpatch_gensrc-into-bindir.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 9221bb4ccd3f448fde2923df4598df17488978a9 Mon Sep 17 00:00:00 2001 -From: Ying Fang -Date: Tue, 8 Dec 2020 15:18:19 +0800 -Subject: [PATCH] src/Makefile: install kpatch_gensrc into bindir - -Signed-off-by: Ying Fang ---- - src/Makefile | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - -diff --git a/src/Makefile b/src/Makefile -index 72ec073..22eb623 100644 ---- a/src/Makefile -+++ b/src/Makefile -@@ -98,10 +98,8 @@ install: all - $(INSTALL) -m 0755 libcare-client $(DESTDIR)/$(bindir)/libcare-client - $(INSTALL) -m 0755 libcare-cc $(DESTDIR)/$(bindir)/libcare-cc - $(INSTALL) -m 0755 libcare-patch-make $(DESTDIR)/$(bindir)/libcare-patch-make -- -- $(INSTALL) -d $(DESTDIR)/$(libexecdir)/libcare -- $(INSTALL) -m 0755 kpatch_gensrc $(DESTDIR)/$(libexecdir)/libcare/kpatch_gensrc -- $(INSTALL) -m 0755 kpatch_make $(DESTDIR)/$(libexecdir)/libcare/kpatch_make -- $(INSTALL) -m 0755 kpatch_strip $(DESTDIR)/$(libexecdir)/libcare/kpatch_strip -+ $(INSTALL) -m 0755 kpatch_gensrc $(DESTDIR)/$(bindir)/kpatch_gensrc -+ $(INSTALL) -m 0755 kpatch_make $(DESTDIR)/$(bindir)/kpatch_make -+ $(INSTALL) -m 0755 kpatch_strip $(DESTDIR)/$(bindir)/kpatch_strip - - .PHONY: all clean test tests tests-gensrc tests-strip --- -2.25.4 -