加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
0028-kpatch_parse-Split-function-is_variable_start.patch 7.23 KB
一键复制 编辑 原始数据 按行查看 历史
From a3fce6e82d24afe186a46461b9cf931f2f023f36 Mon Sep 17 00:00:00 2001
From: Jiajie Li <lijiajie11@huawei.com>
Date: Mon, 12 Oct 2020 13:48:18 +0800
Subject: [PATCH 28/89] kpatch_parse: Split function is_variable_start
The function is_variable_start is arch related, since different arch may
use different assembly directives to describe variables. So let's make
two definations in arch/x86/arch_parse.c and arch/aarch64/arch_parse.c
Signed-off-by: Jiajie Li <lijiajie11@huawei.com>
Signed-off-by: Ying Fang <fangying1@huawei.com>
---
src/arch/aarch64/arch_parse.c | 69 ++++++++++++++++++++++++++++++++++
src/arch/x86/arch_parse.c | 69 ++++++++++++++++++++++++++++++++++
src/include/kpatch_parse.h | 1 +
src/kpatch_parse.c | 71 +----------------------------------
4 files changed, 140 insertions(+), 70 deletions(-)
diff --git a/src/arch/aarch64/arch_parse.c b/src/arch/aarch64/arch_parse.c
index 1233e03..abbc38c 100644
--- a/src/arch/aarch64/arch_parse.c
+++ b/src/arch/aarch64/arch_parse.c
@@ -4,6 +4,75 @@
#include "include/kpatch_parse.h"
#include "include/kpatch_flags.h"
+int is_variable_start(struct kp_file *f, int l, int *e, int *pglobl, kpstr_t *nm)
+{
+ char *s;
+ int l0 = l, globl = 0;
+ kpstr_t nm2, attr;
+
+ kpstrset(nm, "", 0);
+ for ( ; cline(f, l); l++) {
+
+ /* first verify that all the commands we met has the same symbol name... just to be safe! */
+ s = cline(f, l);
+ if (*s == '\0' && l != l0)
+ continue;
+ switch (ctype(f, l)) {
+ case DIRECTIVE_TYPE:
+ case DIRECTIVE_GLOBL:
+ case DIRECTIVE_LOCAL:
+ get_token(&s, &nm2);
+ case DIRECTIVE_LABEL:
+ get_token(&s, &nm2);
+ if (nm->l && kpstrcmp(nm, &nm2)) /* some other symbol met... stop */
+ return 0;
+ *nm = nm2;
+ break;
+ }
+
+ switch (ctype(f, l)) {
+ case DIRECTIVE_TEXT:
+ case DIRECTIVE_DATA:
+ case DIRECTIVE_BSS:
+ case DIRECTIVE_SECTION:
+ case DIRECTIVE_PUSHSECTION:
+ case DIRECTIVE_POPSECTION:
+ case DIRECTIVE_PREVIOUS:
+ case DIRECTIVE_SUBSECTION:
+ break;
+ case DIRECTIVE_TYPE:
+ get_type_args(cline(f, l), &nm2, &attr);
+ if (kpstrcmpz(&attr, "%object") && kpstrcmpz(&attr, "%tls_object"))
+ return 0;
+ break;
+ case DIRECTIVE_GLOBL:
+ globl = 1;
+ break;
+ case DIRECTIVE_ALIGN:
+ break;
+ case DIRECTIVE_COMMENT:
+ case DIRECTIVE_SIZE:
+ /* can't start with .size */
+ if (l0 == l)
+ return 0;
+ break;
+ case DIRECTIVE_LABEL:
+ if (!is_data_sect(csect(f, l)))
+ return 0;
+ /* fall throught */
+ case DIRECTIVE_LOCAL:
+ if (e)
+ *e = l + 1;
+ if (pglobl)
+ *pglobl = globl;
+ return 1;
+ default:
+ return 0;
+ }
+ }
+ return 0;
+}
+
/* break manually crafted multiple statements separated by ; to separate lines */
void init_multilines(struct kp_file *f)
{
diff --git a/src/arch/x86/arch_parse.c b/src/arch/x86/arch_parse.c
index 92ff483..ca57507 100644
--- a/src/arch/x86/arch_parse.c
+++ b/src/arch/x86/arch_parse.c
@@ -4,6 +4,75 @@
#include "include/kpatch_parse.h"
#include "include/kpatch_flags.h"
+int is_variable_start(struct kp_file *f, int l, int *e, int *pglobl, kpstr_t *nm)
+{
+ char *s;
+ int l0 = l, globl = 0;
+ kpstr_t nm2, attr;
+
+ kpstrset(nm, "", 0);
+ for ( ; cline(f, l); l++) {
+
+ /* first verify that all the commands we met has the same symbol name... just to be safe! */
+ s = cline(f, l);
+ if (*s == '\0' && l != l0)
+ continue;
+ switch (ctype(f, l)) {
+ case DIRECTIVE_TYPE:
+ case DIRECTIVE_GLOBL:
+ case DIRECTIVE_LOCAL:
+ get_token(&s, &nm2);
+ case DIRECTIVE_LABEL:
+ get_token(&s, &nm2);
+ if (nm->l && kpstrcmp(nm, &nm2)) /* some other symbol met... stop */
+ return 0;
+ *nm = nm2;
+ break;
+ }
+
+ switch (ctype(f, l)) {
+ case DIRECTIVE_TEXT:
+ case DIRECTIVE_DATA:
+ case DIRECTIVE_BSS:
+ case DIRECTIVE_SECTION:
+ case DIRECTIVE_PUSHSECTION:
+ case DIRECTIVE_POPSECTION:
+ case DIRECTIVE_PREVIOUS:
+ case DIRECTIVE_SUBSECTION:
+ break;
+ case DIRECTIVE_TYPE:
+ get_type_args(cline(f, l), &nm2, &attr);
+ if (kpstrcmpz(&attr, "@object"))
+ return 0;
+ break;
+ case DIRECTIVE_GLOBL:
+ globl = 1;
+ break;
+ case DIRECTIVE_ALIGN:
+ break;
+ case DIRECTIVE_COMMENT:
+ case DIRECTIVE_SIZE:
+ /* can't start with .size */
+ if (l0 == l)
+ return 0;
+ break;
+ case DIRECTIVE_LABEL:
+ if (!is_data_sect(csect(f, l)))
+ return 0;
+ /* fall throught */
+ case DIRECTIVE_LOCAL:
+ if (e)
+ *e = l + 1;
+ if (pglobl)
+ *pglobl = globl;
+ return 1;
+ default:
+ return 0;
+ }
+ }
+ return 0;
+}
+
/* break manually crafted multiple statements separated by ; to separate lines */
void init_multilines(struct kp_file *f)
{
diff --git a/src/include/kpatch_parse.h b/src/include/kpatch_parse.h
index e1b7501..0f41509 100644
--- a/src/include/kpatch_parse.h
+++ b/src/include/kpatch_parse.h
@@ -109,6 +109,7 @@ void __get_token(char **str, kpstr_t *x, const char *delim);
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 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);
int is_data_def(char *s, int type);
diff --git a/src/kpatch_parse.c b/src/kpatch_parse.c
index 857dbf3..a3be7c0 100644
--- a/src/kpatch_parse.c
+++ b/src/kpatch_parse.c
@@ -93,7 +93,7 @@ static struct {
};
/* parse arguments of .type command */
-static void get_type_args(char *s, kpstr_t *nm, kpstr_t *attr)
+void get_type_args(char *s, kpstr_t *nm, kpstr_t *attr)
{
kpstr_t t, t2;
@@ -674,75 +674,6 @@ int is_function_end(struct kp_file *f, int l, kpstr_t *nm)
return 1;
}
-int is_variable_start(struct kp_file *f, int l, int *e, int *pglobl, kpstr_t *nm)
-{
- char *s;
- int l0 = l, globl = 0;
- kpstr_t nm2, attr;
-
- kpstrset(nm, "", 0);
- for ( ; cline(f, l); l++) {
-
- /* first verify that all the commands we met has the same symbol name... just to be safe! */
- s = cline(f, l);
- if (*s == '\0' && l != l0)
- continue;
- switch (ctype(f, l)) {
- case DIRECTIVE_TYPE:
- case DIRECTIVE_GLOBL:
- case DIRECTIVE_LOCAL:
- get_token(&s, &nm2);
- case DIRECTIVE_LABEL:
- get_token(&s, &nm2);
- if (nm->l && kpstrcmp(nm, &nm2)) /* some other symbol met... stop */
- return 0;
- *nm = nm2;
- break;
- }
-
- switch (ctype(f, l)) {
- case DIRECTIVE_TEXT:
- case DIRECTIVE_DATA:
- case DIRECTIVE_BSS:
- case DIRECTIVE_SECTION:
- case DIRECTIVE_PUSHSECTION:
- case DIRECTIVE_POPSECTION:
- case DIRECTIVE_PREVIOUS:
- case DIRECTIVE_SUBSECTION:
- break;
- case DIRECTIVE_TYPE:
- get_type_args(cline(f, l), &nm2, &attr);
- if (kpstrcmpz(&attr, "@object"))
- return 0;
- break;
- case DIRECTIVE_GLOBL:
- globl = 1;
- break;
- case DIRECTIVE_ALIGN:
- break;
- case DIRECTIVE_COMMENT:
- case DIRECTIVE_SIZE:
- /* can't start with .size */
- if (l0 == l)
- return 0;
- break;
- case DIRECTIVE_LABEL:
- if (!is_data_sect(csect(f, l)))
- return 0;
- /* fall throught */
- case DIRECTIVE_LOCAL:
- if (e)
- *e = l + 1;
- if (pglobl)
- *pglobl = globl;
- return 1;
- default:
- return 0;
- }
- }
- return 0;
-}
-
int is_data_def(char *s, int type)
{
kpstr_t t;
--
2.23.0
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化