1 Star 0 Fork 43

wangjunqiang / kpatch

forked from src-openEuler / kpatch 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0001-kpatch-add-aarch64-support.patch 6.10 KB
一键复制 编辑 原始数据 按行查看 历史
谢志鹏 提交于 2021-11-16 12:10 . rebase from upstream v0.9.5
From 821e6cb24778bd063d1e8ad097d4bd4c81973091 Mon Sep 17 00:00:00 2001
From: Zhipeng Xie <xiezhipeng1@huawei.com>
Date: Thu, 20 Dec 2018 04:55:38 +0000
Subject: [PATCH 01/24] kpatch: add aarch64 support
1.use R_AARCH64_ABS64 for aarch64
2.add find_special_section_data_arm64 for arm64:
arm64 kernel have no paravirt_patch_site or orc_entry structure
in vmlinux, we don't need to check these two struct for arm64.
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
---
kpatch-build/Makefile | 4 +++
kpatch-build/create-diff-object.c | 14 ++++++----
kpatch-build/kpatch-build | 46 +++++++++++++++++++++++++++++++
kpatch-build/kpatch-elf.c | 2 +-
4 files changed, 60 insertions(+), 6 deletions(-)
diff --git a/kpatch-build/Makefile b/kpatch-build/Makefile
index 50899b6..423c32a 100644
--- a/kpatch-build/Makefile
+++ b/kpatch-build/Makefile
@@ -14,6 +14,10 @@ ifeq ($(ARCH),x86_64)
SOURCES += insn/insn.c insn/inat.c
INSN = insn/insn.o insn/inat.o
insn/%.o: CFLAGS := $(filter-out -Wconversion, $(CFLAGS))
+else ifeq ($(ARCH),aarch64)
+SOURCES += insn/insn.c insn/inat.c
+INSN = insn/insn.o insn/inat.o
+insn/%.o: CFLAGS := $(filter-out -Wconversion, $(CFLAGS))
else ifeq ($(ARCH),ppc64le)
SOURCES += gcc-plugins/ppc64le-plugin.c
PLUGIN = gcc-plugins/ppc64le-plugin.so
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
index 6a4848a..ca55180 100644
--- a/kpatch-build/create-diff-object.c
+++ b/kpatch-build/create-diff-object.c
@@ -62,6 +62,8 @@
#ifdef __powerpc64__
#define ABSOLUTE_RELA_TYPE R_PPC64_ADDR64
+#elif __aarch64__
+#define ABSOLUTE_RELA_TYPE R_AARCH64_ABS64
#else
#define ABSOLUTE_RELA_TYPE R_X86_64_64
#endif
@@ -1536,7 +1538,7 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf)
continue;
}
-#ifdef __powerpc64__
+#if defined(__powerpc64__) || defined(__aarch64__)
add_off = 0;
#else
if (rela->type == R_X86_64_PC32 ||
@@ -2028,7 +2030,7 @@ static int printk_index_group_size(struct kpatch_elf *kelf, int offset)
return size;
}
-#ifdef __x86_64__
+#if defined(__x86_64__) || defined(__aarch64__)
static int parainstructions_group_size(struct kpatch_elf *kelf, int offset)
{
static int size = 0;
@@ -2177,7 +2179,7 @@ static struct special_section special_sections[] = {
.name = ".printk_index",
.group_size = printk_index_group_size,
},
-#ifdef __x86_64__
+#if defined(__x86_64__) || defined(__aarch64__)
{
.name = ".smp_locks",
.group_size = smp_locks_group_size,
@@ -2990,7 +2992,9 @@ static int function_ptr_rela(const struct rela *rela)
rela_toc->addend == (int)rela_toc->sym->sym.st_value &&
(rela->type == R_X86_64_32S ||
rela->type == R_PPC64_TOC16_HA ||
- rela->type == R_PPC64_TOC16_LO_DS));
+ rela->type == R_PPC64_TOC16_LO_DS ||
+ rela->type == R_AARCH64_ADR_PREL_PG_HI21 ||
+ rela->type == R_AARCH64_ADD_ABS_LO12_NC));
}
static bool need_dynrela(struct lookup_table *table, struct section *sec, const struct rela *rela)
@@ -3479,7 +3483,7 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf)
rela->type = R_X86_64_PC32;
}
-#else /* __powerpc64__ */
+#else /* __powerpc64__ || __aarch64__ */
{
bool found = false;
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
index eedf383..ad3a079 100755
--- a/kpatch-build/kpatch-build
+++ b/kpatch-build/kpatch-build
@@ -375,12 +375,58 @@ find_special_section_data_ppc64le() {
return
}
+find_special_section_data_aarch64() {
+
+ [[ "$CONFIG_JUMP_LABEL" -eq 0 ]] && AWK_OPTIONS="$AWK_OPTIONS -vskip_j=1"
+
+ # If $AWK_OPTIONS are blank gawk would treat "" as a blank script
+ # shellcheck disable=SC2086
+ SPECIAL_VARS="$(readelf -wi "$VMLINUX" |
+ gawk --non-decimal-data $AWK_OPTIONS '
+ BEGIN { a = b = e = j = 0 }
+
+ # Set state if name matches
+ a == 0 && /DW_AT_name.* alt_instr[[:space:]]*$/ {a = 1; next}
+ b == 0 && /DW_AT_name.* bug_entry[[:space:]]*$/ {b = 1; next}
+ e == 0 && /DW_AT_name.* exception_table_entry[[:space:]]*$/ {e = 1; next}
+ j == 0 && /DW_AT_name.* jump_entry[[:space:]]*$/ {j = 1; next}
+
+ # Reset state unless this abbrev describes the struct size
+ a == 1 && !/DW_AT_byte_size/ { a = 0; next }
+ b == 1 && !/DW_AT_byte_size/ { b = 0; next }
+ e == 1 && !/DW_AT_byte_size/ { e = 0; next }
+ j == 1 && !/DW_AT_byte_size/ { j = 0; next }
+
+ # Now that we know the size, stop parsing for it
+ a == 1 {printf("export ALT_STRUCT_SIZE=%d\n", $4); a = 2}
+ b == 1 {printf("export BUG_STRUCT_SIZE=%d\n", $4); b = 2}
+ e == 1 {printf("export EX_STRUCT_SIZE=%d\n", $4); e = 2}
+ j == 1 {printf("export JUMP_STRUCT_SIZE=%d\n", $4); j = 2}
+
+ # Bail out once we have everything
+ a == 2 && b == 2 && e == 2 && (j == 2 || skip_j) {exit}')"
+
+ [[ -n "$SPECIAL_VARS" ]] && eval "$SPECIAL_VARS"
+
+ [[ -z "$ALT_STRUCT_SIZE" ]] && die "can't find special struct alt_instr size"
+ [[ -z "$BUG_STRUCT_SIZE" ]] && die "can't find special struct bug_entry size"
+ [[ -z "$EX_STRUCT_SIZE" ]] && die "can't find special struct exception_table_entry size"
+ [[ -z "$JUMP_STRUCT_SIZE" && "$CONFIG_JUMP_LABEL" -ne 0 ]] && die "can't find special struct jump_entry size"
+
+ return
+}
+
find_special_section_data() {
if [[ "$ARCH" = "ppc64le" ]]; then
find_special_section_data_ppc64le
return
fi
+ if [[ "$ARCH" = "aarch64" ]]; then
+ find_special_section_data_aarch64
+ return
+ fi
+
[[ "$CONFIG_PARAVIRT" -eq 0 ]] && AWK_OPTIONS="-vskip_p=1"
[[ "$CONFIG_UNWINDER_ORC" -eq 0 ]] && AWK_OPTIONS="$AWK_OPTIONS -vskip_o=1"
[[ "$CONFIG_JUMP_LABEL" -eq 0 ]] && AWK_OPTIONS="$AWK_OPTIONS -vskip_j=1"
diff --git a/kpatch-build/kpatch-elf.c b/kpatch-build/kpatch-elf.c
index 7e272e2..68d5c86 100644
--- a/kpatch-build/kpatch-elf.c
+++ b/kpatch-build/kpatch-elf.c
@@ -325,7 +325,7 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf)
list_for_each_entry(sym, &kelf->symbols, list) {
if (sym->type != STT_FUNC || !sym->sec || !sym->sec->rela)
continue;
-#ifdef __powerpc64__
+#if defined(__powerpc64__) || defined(__aarch64__)
list_for_each_entry(rela, &sym->sec->rela->relas, list) {
if (!strcmp(rela->sym->name, "_mcount")) {
sym->has_func_profiling = 1;
--
2.23.0
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/geasscore/kpatch.git
git@gitee.com:geasscore/kpatch.git
geasscore
kpatch
kpatch
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891