代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/libcareplus 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
From c95f6cd656e9ccfd2e2b7169626cbc2f50b5e24b Mon Sep 17 00:00:00 2001
From: ctyunsystem <ctyuncommiter05@chinatelecom.cn>
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, <luoyi2@chinatelecom.cn>
+ *
+ * 2021.12.13 - support the type of C++ "gnu_unique_object" variable in is_variable_start()
+ * China Telecom, <luoyi2@chinatelecom.cn>
+ *
* 2021.10.08 - enhance kpatch_gensrc and kpatch_elf and kpatch_cc code
* Huawei Technologies Co., Ltd. <zhengchuan@huawei.com>
*
@@ -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, <luoyi2@chinatelecom.cn>
+ *
+ * 2021.12.13 - support the type of C++ "gnu_unique_object" variable in is_variable_start()
+ * China Telecom, <luoyi2@chinatelecom.cn>
+ *
+ * 2021.12.13 - support the appearance of ".LCOLD*" or ".LHOT*" label in is_function_start() and is_variable_start()
+ * China Telecom, <luoyi2@chinatelecom.cn>
+ *
* 2021.10.08 - enhance kpatch_gensrc and kpatch_elf and kpatch_cc code
* Huawei Technologies Co., Ltd. <zhengchuan@huawei.com>
******************************************************************************/
@@ -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, <luoyi2@chinatelecom.cn>
+ *
+ * 2021.12.13 - kpatch_parse: adjust the judgment for the end of function cblock in init_func_block()
+ * China Telecom, <luoyi2@chinatelecom.cn>
+ *
* 2021.10.11 - kpatch: fix code checker warning
* Huawei Technologies Co., Ltd. <zhengchuan@huawei.com>
*
@@ -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 <iostream>
+
+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 <iostream>
+
+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 <typename T>
+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 <iostream>
+
+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
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。