From e9e0888ee64fbe3f0a25e6f1953503e34560ad1f Mon Sep 17 00:00:00 2001
From: Jiajie Li <lijiajie11@huawei.com>
Date: Tue, 24 Nov 2020 20:19:03 +0800
Subject: [PATCH build and enhance 6/8] kpatch_gensrc: modify ignore symbol
 function

Cancel is_func_need_ignore function. Because ignore attribute is
related to rename list. So we cann't just adjust ignore attribute
So modify in_syms_list function for function which need to be ignored.

Change-Id: I2085c702843f237de68aaab6243caa693c538616
Signed-off-by: imxcc <xingchaochao@huawei.com>
---
 libcare.spec        |  6 ++++-
 src/kpatch_gensrc.c | 60 ++++++++++++++++++++++++++++++++++++++++-----
 src/kpatch_parse.c  | 34 -------------------------
 3 files changed, 59 insertions(+), 41 deletions(-)

diff --git a/libcare.spec b/libcare.spec
index 0d75e90..6ba8d04 100644
--- a/libcare.spec
+++ b/libcare.spec
@@ -1,7 +1,7 @@
 Version: 0.1.4
 Name: libcare
 Summary: LibCare tools
-Release: 7%{?dist}
+Release: 8%{?dist}
 Group: Applications/System
 License: GPLv2
 Url: http://www.cloudlinux.com
@@ -158,6 +158,10 @@ exit 0
 %endif
 
 %changelog
+* Thu Sep 23 2021 Jiajie Li <lijiajie11@huawei.com> - 0.1.4-8
+- kpatch_parse: cancel is_func_need_ignore function
+- kpatch_gensrc: modify in_syms_list function for function ignore
+
 * Thu Sep 23 2021 Jiajie Li <lijiajie11@huawei.com> - 0.1.4-7
 - kpatch_parse: add is_func_need_ignore function
 
diff --git a/src/kpatch_gensrc.c b/src/kpatch_gensrc.c
index 4f978f8..f183a58 100644
--- a/src/kpatch_gensrc.c
+++ b/src/kpatch_gensrc.c
@@ -38,9 +38,57 @@ static int nr_must_adapt_syms;
 static int force_gotpcrel;
 static int force_global;
 
-static inline int in_syms_list(char *filename, kpstr_t *sym, const struct sym_desc *sym_arr, int nr_syms)
+static char* patch_func_file_name = "/etc/libcare/patch_func_names.conf";
+
+static int is_func_in_patch_func_file(FILE *fp, kpstr_t *sym)
+{
+	char buffer[1024];
+
+	/* 1024 should be enough for func_cblock name */
+	if (sym->l <= 0 || sym->l > sizeof(buffer))
+		return 0;
+
+	rewind(fp);
+	while (!feof(fp)) {
+		memset(buffer, 0, sizeof(buffer));
+		fgets(buffer, sizeof(buffer), fp);
+		if (strncmp(buffer, sym->s, sym->l) == 0) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static inline int in_syms_list(char *filename, kpstr_t *sym, const struct sym_desc *sym_arr, int nr_syms, int cblock_type)
 {
-	int i, len;
+	int i, len, rv;
+
+	/*
+	 * Since we need to ignore some unwanted function being patched,
+	 * so we will first check if there is a file called "patch_func_name".
+	 * If there isn't, we will continue as usual.
+	 * If there is, we will ignore those function which is not in the file.
+	 */
+	if (cblock_type == CBLOCK_FUNC && sym_arr == ignore_syms) {
+		FILE *fp = fopen(patch_func_file_name, "r");
+		if (fp == NULL) {
+			goto no_conf;
+		}
+
+		rv = is_func_in_patch_func_file(fp, sym);
+
+		if (fclose(fp) != 0) {
+			kpfatal("Error in closing file %s\n", patch_func_file_name);
+		}
+
+		/*
+		 * If rv is 1, which means symbol is in patch_func_file,
+		 * which means we cann't ignore it. So return 0, otherwise return 1.
+		 */
+		return rv == 1 ? 0 : 1;
+	}
+
+no_conf:
 	for (i = 0; i < nr_syms; i++) {
 		if (sym_arr[i].filename) {
 			len = strlen(sym_arr[i].filename);
@@ -811,7 +859,7 @@ static void cblock_var_check_content(struct cblock *b0)
 	cblock_print2(b0, b1);
 	kplog(LOG_DEBUG, "-------------------------------------------\n");
 
-	if (in_syms_list(b1->f->basename, &b0->human_name, ignore_syms, nr_ignore_syms))
+	if (in_syms_list(b1->f->basename, &b0->human_name, ignore_syms, nr_ignore_syms, b0->type))
 		return;
 
 	if (cblock_cmp(b0, b1, CBLOCK_CMP_SECT|CBLOCK_CMP_RENAME))
@@ -1114,12 +1162,12 @@ static void analyze_func_cblocks(struct kp_file *f0, struct kp_file *f1)
 		if (b1->type != CBLOCK_FUNC || !b1->pair)
 			continue;
 
-		if (in_syms_list(b1->f->basename, &b1->human_name, ignore_syms, nr_ignore_syms)) {
+		if (in_syms_list(b1->f->basename, &b1->human_name, ignore_syms, nr_ignore_syms, b1->type)) {
 			rename_del(b1->f, &b1->name);
 			rename_del(b1->pair->f, &b1->pair->name);
 			b1->ignore = 1;
 		}
-		if (in_syms_list(b1->f->basename, &b1->human_name, unlink_syms, nr_unlink_syms)) {
+		if (in_syms_list(b1->f->basename, &b1->human_name, unlink_syms, nr_unlink_syms, b1->type)) {
 			kplog(LOG_DEBUG, "unlinking %.*s\n", b1->name.l, b1->name.s);
 			b1->unlink = 1;
 		}
@@ -1141,7 +1189,7 @@ static void analyze_func_cblocks(struct kp_file *f0, struct kp_file *f1)
 			rename_add(b1->f, &b1->name, &b0->name);
 			b1->ignore = 1;
 		} else {
-			if (!b1->adapted && in_syms_list(b1->f->basename, &b1->human_name, must_adapt_syms, nr_must_adapt_syms)) {
+			if (!b1->adapted && in_syms_list(b1->f->basename, &b1->human_name, must_adapt_syms, nr_must_adapt_syms, b1->type)) {
 				not_adapted= 1;
 				kplog(LOG_ERR, "FATAL! not adapted function change %.*s\n", b1->name.l, b1->name.s);
 			}
diff --git a/src/kpatch_parse.c b/src/kpatch_parse.c
index 675e208..3df658d 100644
--- a/src/kpatch_parse.c
+++ b/src/kpatch_parse.c
@@ -4,27 +4,6 @@
 #include "include/kpatch_parse.h"
 #include "include/kpatch_flags.h"
 
-static char* patch_func_file_name = "/etc/libcare/patch_func_names.conf";
-
-bool is_func_need_ignore(FILE *fp, kpstr_t *nm)
-{
-	rewind(fp);
-	char buffer[1024];
-
-	/* 1024 should be enough for func_cblock name */
-	if (nm->l <= 0 || nm->l > 1024)
-		return true;
-
-	while (!feof(fp)) {
-		memset(buffer, 0, sizeof(char)*1024);
-		fgets(buffer, 1024, fp);
-		if (strncmp(buffer, nm->s, nm->l) == 0) {
-			return false;
-		}
-	}
-	return true;
-}
-
 char *cline(struct kp_file *f, int l)
 {
 	if (l < 0 || l >= f->nr_lines)
@@ -238,19 +217,6 @@ struct cblock * cblock_add(struct kp_file *f, int s, int e, kpstr_t *nm, int typ
 	blk->type = type;
 	blk->globl = globl;
 	blk->handled = blk->ignore = blk->unlink = 0;
-
-	/*
-	 * Since we need to ignore some unwanted function being patched,
-	 * so we will first check if there is a file called "patch_func_name".
-	 * If there isn't, we will continue as usual.
-	 * If there is, we will ignore those function which is not in the file.
-	 */
-	FILE *fp = fopen(patch_func_file_name, "r");
-	if (fp != NULL && type == CBLOCK_FUNC && is_func_need_ignore(fp,nm)) {
-		blk->ignore = 1;
-	}
-
-
 	blk->pair = NULL;
 	rb_insert_node(&f->cblocks_by_name, &blk->rbnm, cblock_name_cmp, (unsigned long)&blk->name);
 	rb_insert_node(&f->cblocks_by_human_name, &blk->rb_hnm, cblock_human_name_cmp, (unsigned long)&blk->human_name);
-- 
2.19.1

