From: @openeuler-sync-bot Reviewed-by: @Chuan-Zheng Signed-off-by: @Chuan-Zheng
This commit is contained in:
commit
4b9274afa0
30
elf-add-section-adderss-for-STT_NOTYPE-type-of-symbo.patch
Normal file
30
elf-add-section-adderss-for-STT_NOTYPE-type-of-symbo.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From 55b659c0b52a7c5f3fc493dd9c19ac76f09d0ccb Mon Sep 17 00:00:00 2001
|
||||
From: Bihong Yu <yubihong@huawei.com>
|
||||
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 <yubihong@huawei.com>
|
||||
---
|
||||
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
|
||||
|
||||
677
fix-cblock-parse-for-LCOLD-LHOT-.cold.NUM-.init_arra.patch
Normal file
677
fix-cblock-parse-for-LCOLD-LHOT-.cold.NUM-.init_arra.patch
Normal file
@ -0,0 +1,677 @@
|
||||
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
|
||||
|
||||
32
gensrc-we-should-add-align-while-FLAGS_PUSH_SECTION-.patch
Normal file
32
gensrc-we-should-add-align-while-FLAGS_PUSH_SECTION-.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From 9d601f4c697a9b2d926d92025bb43dd6ebf36033 Mon Sep 17 00:00:00 2001
|
||||
From: Bihong Yu <yubihong@huawei.com>
|
||||
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 <yubihong@huawei.com>
|
||||
---
|
||||
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
|
||||
|
||||
@ -3,12 +3,15 @@
|
||||
Version: 1.0.0
|
||||
Name: libcareplus
|
||||
Summary: LibcarePlus tools
|
||||
Release: 0
|
||||
Release: 2
|
||||
Group: Applications/System
|
||||
License: GPLv2
|
||||
Url: https://gitee.com/openeuler/libcareplus
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
|
||||
Patch0001: fix-cblock-parse-for-LCOLD-LHOT-.cold.NUM-.init_arra.patch
|
||||
Patch0002: gensrc-we-should-add-align-while-FLAGS_PUSH_SECTION-.patch
|
||||
Patch0003: elf-add-section-adderss-for-STT_NOTYPE-type-of-symbo.patch
|
||||
|
||||
BuildRequires: elfutils-libelf-devel libunwind-devel gcc systemd
|
||||
|
||||
@ -166,6 +169,13 @@ exit 0
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Tue Feb 22 2022 imxcc <xingchaochao@huawei.com> - 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 <xingchaochao@huawei.com> - 1.0.0.1
|
||||
- fix cblock parse for LCOLD/LHOT/.cold.NUM, .init_array and support gnu_unique_object
|
||||
|
||||
* Mon Feb 07 2022 imxcc <xingchaochao@huawei.com> - 1.0.0.0
|
||||
- package init 1.0.0
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user