rebase from upstream v0.9.0
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
This commit is contained in:
parent
f7ecdbaac7
commit
dc117ba0b6
@ -1,35 +0,0 @@
|
|||||||
From 722d27f6bdd4fa012e08db784bf9bb93bb75be2c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Artem Savkov <asavkov@redhat.com>
|
|
||||||
Date: Tue, 16 Oct 2018 16:05:01 +0200
|
|
||||||
Subject: [PATCH] Add "__addressable_" to maybe_discarded_sym().
|
|
||||||
|
|
||||||
Starting with 1b1eeca7e4c1 "init: allow initcall tables to be emitted using
|
|
||||||
relative references" [1] __init functions are generating an "__addressable_"
|
|
||||||
symbol in a ".discarded.addressable" section so it does not show up in final
|
|
||||||
vmlinux triggering find_local_syms failures. Add "_addressable_" to the list
|
|
||||||
in maybe_discarded_sym().
|
|
||||||
|
|
||||||
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1b1eeca7e4c19fa76d409d4c7b338dba21f2df45
|
|
||||||
|
|
||||||
Signed-off-by: Artem Savkov <asavkov@redhat.com>
|
|
||||||
---
|
|
||||||
kpatch-build/lookup.c | 3 ++-
|
|
||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c
|
|
||||||
index b88dc59..7c8e635 100644
|
|
||||||
--- a/kpatch-build/lookup.c
|
|
||||||
+++ b/kpatch-build/lookup.c
|
|
||||||
@@ -80,7 +80,8 @@ static int maybe_discarded_sym(const char *name)
|
|
||||||
*/
|
|
||||||
if (!strncmp(name, "__exitcall_", 11) ||
|
|
||||||
!strncmp(name, "__brk_reservation_fn_", 21) ||
|
|
||||||
- !strncmp(name, "__func_stack_frame_non_standard_", 32))
|
|
||||||
+ !strncmp(name, "__func_stack_frame_non_standard_", 32) ||
|
|
||||||
+ !strncmp(name, "__addressable_", 14))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
--
|
|
||||||
1.7.12.4
|
|
||||||
|
|
||||||
@ -1,15 +1,15 @@
|
|||||||
From 50782f658313574a530f80d2f4b78fe23488c6c2 Mon Sep 17 00:00:00 2001
|
From 33c4d7a2a31ca10ce943d7ab0603bd814f4ac530 Mon Sep 17 00:00:00 2001
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
Date: Thu, 20 Dec 2018 04:55:38 +0000
|
Date: Thu, 20 Dec 2018 04:55:38 +0000
|
||||||
Subject: [PATCH] support compile kpatch on aarch64
|
Subject: [PATCH 01/17] support compile kpatch on aarch64
|
||||||
|
|
||||||
delete __x86_64__ to support compile kpatch on aarch64.
|
delete __x86_64__ to support compile kpatch on aarch64.
|
||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
---
|
---
|
||||||
kpatch-build/Makefile | 3 +++
|
kpatch-build/Makefile | 3 +++
|
||||||
kpatch-build/create-diff-object.c | 16 +---------------
|
kpatch-build/create-diff-object.c | 14 +-------------
|
||||||
2 files changed, 4 insertions(+), 15 deletions(-)
|
2 files changed, 4 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
diff --git a/kpatch-build/Makefile b/kpatch-build/Makefile
|
diff --git a/kpatch-build/Makefile b/kpatch-build/Makefile
|
||||||
index 232b336..974e0f2 100644
|
index 232b336..974e0f2 100644
|
||||||
@ -26,10 +26,10 @@ index 232b336..974e0f2 100644
|
|||||||
SOURCES += gcc-plugins/ppc64le-plugin.c
|
SOURCES += gcc-plugins/ppc64le-plugin.c
|
||||||
PLUGIN = gcc-plugins/ppc64le-plugin.so
|
PLUGIN = gcc-plugins/ppc64le-plugin.so
|
||||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||||
index 97ae0d4..80a76a9 100644
|
index c9d2cc6..7b1deb0 100644
|
||||||
--- a/kpatch-build/create-diff-object.c
|
--- a/kpatch-build/create-diff-object.c
|
||||||
+++ b/kpatch-build/create-diff-object.c
|
+++ b/kpatch-build/create-diff-object.c
|
||||||
@@ -426,7 +426,6 @@ out:
|
@@ -470,7 +470,6 @@ out:
|
||||||
log_debug("section %s has changed\n", sec->name);
|
log_debug("section %s has changed\n", sec->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ index 97ae0d4..80a76a9 100644
|
|||||||
/*
|
/*
|
||||||
* Determine if a section has changed only due to a WARN* or might_sleep
|
* Determine if a section has changed only due to a WARN* or might_sleep
|
||||||
* macro call's embedding of the line number into an instruction operand.
|
* macro call's embedding of the line number into an instruction operand.
|
||||||
@@ -537,7 +536,7 @@ static int kpatch_line_macro_change_only(struct section *sec)
|
@@ -581,7 +580,7 @@ static int kpatch_line_macro_change_only(struct section *sec)
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -46,7 +46,7 @@ index 97ae0d4..80a76a9 100644
|
|||||||
#define PPC_INSTR_LEN 4
|
#define PPC_INSTR_LEN 4
|
||||||
#define PPC_RA_OFFSET 16
|
#define PPC_RA_OFFSET 16
|
||||||
|
|
||||||
@@ -603,11 +602,6 @@ static int kpatch_line_macro_change_only(struct section *sec)
|
@@ -647,11 +646,6 @@ static int kpatch_line_macro_change_only(struct section *sec)
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -56,25 +56,25 @@ index 97ae0d4..80a76a9 100644
|
|||||||
- return 0;
|
- return 0;
|
||||||
-}
|
-}
|
||||||
#endif
|
#endif
|
||||||
#define ARM64_INSTR_LEN 4
|
|
||||||
static int arm64_kpatch_line_macro_change_only(struct section *sec)
|
static void kpatch_compare_sections(struct list_head *seclist)
|
||||||
@@ -1248,7 +1242,6 @@ static void kpatch_compare_correlated_elements(struct kpatch_elf *kelf)
|
@@ -1202,7 +1196,6 @@ static void kpatch_compare_correlated_elements(struct kpatch_elf *kelf)
|
||||||
kpatch_compare_symbols(&kelf->symbols);
|
kpatch_compare_symbols(&kelf->symbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
-#ifdef __x86_64__
|
-#ifdef __x86_64__
|
||||||
static void rela_insn(struct section *sec, struct rela *rela, struct insn *insn)
|
static void rela_insn(const struct section *sec, const struct rela *rela,
|
||||||
|
struct insn *insn)
|
||||||
{
|
{
|
||||||
unsigned long insn_addr, start, end, rela_addr;
|
@@ -1226,7 +1219,6 @@ static void rela_insn(const struct section *sec, const struct rela *rela,
|
||||||
@@ -1267,7 +1260,6 @@ static void rela_insn(struct section *sec, struct rela *rela, struct insn *insn)
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
-#endif
|
-#endif
|
||||||
|
|
||||||
/*
|
static bool is_callback_section(struct section *sec) {
|
||||||
* Mangle the relas a little. The compiler will sometimes use section symbols
|
|
||||||
@@ -1810,7 +1802,6 @@ static int ex_table_group_size(struct kpatch_elf *kelf, int offset)
|
@@ -1771,7 +1763,6 @@ static int jump_table_group_size(struct kpatch_elf *kelf, int offset)
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ index 97ae0d4..80a76a9 100644
|
|||||||
static int parainstructions_group_size(struct kpatch_elf *kelf, int offset)
|
static int parainstructions_group_size(struct kpatch_elf *kelf, int offset)
|
||||||
{
|
{
|
||||||
static int size = 0;
|
static int size = 0;
|
||||||
@@ -1845,7 +1836,6 @@ static int smp_locks_group_size(struct kpatch_elf *kelf, int offset)
|
@@ -1806,7 +1797,6 @@ static int smp_locks_group_size(struct kpatch_elf *kelf, int offset)
|
||||||
{
|
{
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
@ -90,28 +90,15 @@ index 97ae0d4..80a76a9 100644
|
|||||||
#ifdef __powerpc64__
|
#ifdef __powerpc64__
|
||||||
static int fixup_entry_group_size(struct kpatch_elf *kelf, int offset)
|
static int fixup_entry_group_size(struct kpatch_elf *kelf, int offset)
|
||||||
{
|
{
|
||||||
@@ -1921,7 +1911,6 @@ static struct special_section special_sections[] = {
|
@@ -1901,7 +1891,6 @@ static struct special_section special_sections[] = {
|
||||||
.name = "__bug_table",
|
.name = "__jump_table",
|
||||||
.group_size = bug_table_group_size,
|
.group_size = jump_table_group_size,
|
||||||
},
|
},
|
||||||
-#ifdef __x86_64__
|
-#ifdef __x86_64__
|
||||||
{
|
{
|
||||||
.name = ".smp_locks",
|
.name = ".smp_locks",
|
||||||
.group_size = smp_locks_group_size,
|
.group_size = smp_locks_group_size,
|
||||||
@@ -1930,7 +1919,6 @@ static struct special_section special_sections[] = {
|
@@ -1914,7 +1903,6 @@ static struct special_section special_sections[] = {
|
||||||
.name = ".parainstructions",
|
|
||||||
.group_size = parainstructions_group_size,
|
|
||||||
},
|
|
||||||
-#endif
|
|
||||||
{
|
|
||||||
.name = ".fixup",
|
|
||||||
.group_size = fixup_group_size,
|
|
||||||
@@ -1939,12 +1927,10 @@ static struct special_section special_sections[] = {
|
|
||||||
.name = "__ex_table", /* must come after .fixup */
|
|
||||||
.group_size = ex_table_group_size,
|
|
||||||
},
|
|
||||||
-#ifdef __x86_64__
|
|
||||||
{
|
|
||||||
.name = ".altinstructions",
|
.name = ".altinstructions",
|
||||||
.group_size = altinstructions_group_size,
|
.group_size = altinstructions_group_size,
|
||||||
},
|
},
|
||||||
@ -120,5 +107,5 @@ index 97ae0d4..80a76a9 100644
|
|||||||
{
|
{
|
||||||
.name = "__ftr_fixup",
|
.name = "__ftr_fixup",
|
||||||
--
|
--
|
||||||
2.19.1
|
2.18.1
|
||||||
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
From 17a97b48bcf0d486007b746c48321bab6dedb2d8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Artem Savkov <asavkov@redhat.com>
|
|
||||||
Date: Wed, 14 Nov 2018 15:09:34 +0100
|
|
||||||
Subject: [PATCH] kmod/patch: fix patch linking with 4.20
|
|
||||||
|
|
||||||
4.20 includes commit 69ea912fda74 "kbuild: remove unneeded link_multi_deps"
|
|
||||||
which changes kbuild so that only '.o' files are given to ld as targets
|
|
||||||
for linking, leaving out our linker script. Even before this commit we
|
|
||||||
were still doing this wrong and were succeeding just because ld is smart
|
|
||||||
enough to detect the script, it even throws a warning:
|
|
||||||
|
|
||||||
ld: warning: kpatch.lds contains output sections; did you forget -T?
|
|
||||||
|
|
||||||
The right thing to do is to add the script to ldflags either through
|
|
||||||
kbuilds 'ldflags-y' or by adding it to LDFLAGS/KPATCH_LDFLAGS directly.
|
|
||||||
|
|
||||||
Signed-off-by: Artem Savkov <asavkov@redhat.com>
|
|
||||||
---
|
|
||||||
kmod/patch/Makefile | 1 +
|
|
||||||
1 file changed, 1 insertion(+)
|
|
||||||
|
|
||||||
diff --git a/kmod/patch/Makefile b/kmod/patch/Makefile
|
|
||||||
index 96d1fca..7ba0820 100644
|
|
||||||
--- a/kmod/patch/Makefile
|
|
||||||
+++ b/kmod/patch/Makefile
|
|
||||||
@@ -11,6 +11,7 @@ KBUILD_CFLAGS_MODULE += -mcmodel=large
|
|
||||||
endif
|
|
||||||
|
|
||||||
obj-m += $(KPATCH_NAME).o
|
|
||||||
+ldflags-y += -T $(src)/kpatch.lds
|
|
||||||
|
|
||||||
$(KPATCH_NAME)-objs += patch-hook.o kpatch.lds output.o
|
|
||||||
|
|
||||||
--
|
|
||||||
1.7.12.4
|
|
||||||
|
|
||||||
684
0002-kpatch-build-support-build-patch-for-aarch64.patch
Normal file
684
0002-kpatch-build-support-build-patch-for-aarch64.patch
Normal file
@ -0,0 +1,684 @@
|
|||||||
|
From 6dd77e9f5bc044a1f80ad89bb9d7f60756b39755 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
|
Date: Wed, 26 Feb 2020 07:09:50 -0500
|
||||||
|
Subject: [PATCH 02/17] kpatch-build: support build patch for aarch64
|
||||||
|
|
||||||
|
use R_AARCH64_ABS64 for aarch64
|
||||||
|
|
||||||
|
exclude line only change for arm64 by compare mov instruction
|
||||||
|
except immediate part.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
support cross compile for aarch64
|
||||||
|
|
||||||
|
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
|
---
|
||||||
|
kpatch-build/create-diff-object.c | 216 ++++++++++++++++++++++++----
|
||||||
|
kpatch-build/create-kpatch-module.c | 24 +++-
|
||||||
|
kpatch-build/kpatch-build | 116 ++++++++++++++-
|
||||||
|
kpatch-build/kpatch-gcc | 4 +-
|
||||||
|
4 files changed, 319 insertions(+), 41 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||||
|
index 7b1deb0..58789f1 100644
|
||||||
|
--- a/kpatch-build/create-diff-object.c
|
||||||
|
+++ b/kpatch-build/create-diff-object.c
|
||||||
|
@@ -76,6 +76,31 @@ enum subsection {
|
||||||
|
|
||||||
|
enum loglevel loglevel = NORMAL;
|
||||||
|
|
||||||
|
+#ifndef EM_X86_64
|
||||||
|
+#define EM_X86_64 62
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef EM_AARCH64
|
||||||
|
+#define EM_AARCH64 183
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef R_AARCH64_ABS64
|
||||||
|
+#define R_AARCH64_NONE 0
|
||||||
|
+#define R_AARCH64_ABS64 257
|
||||||
|
+#define R_AARCH64_CALL26 283
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+static unsigned int arch;
|
||||||
|
+static unsigned int absolute_rela_type;
|
||||||
|
+
|
||||||
|
+static unsigned int arch_of_elf(Elf *elf)
|
||||||
|
+{
|
||||||
|
+ GElf_Ehdr eh;
|
||||||
|
+ if (!gelf_getehdr(elf, &eh))
|
||||||
|
+ ERROR("gelf_getehdr");
|
||||||
|
+ return eh.e_machine;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*******************
|
||||||
|
* Data structures
|
||||||
|
* ****************/
|
||||||
|
@@ -647,6 +672,67 @@ static int kpatch_line_macro_change_only(struct section *sec)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
+#define ARM64_INSTR_LEN 4
|
||||||
|
+static int arm64_kpatch_line_macro_change_only(struct section *sec)
|
||||||
|
+{
|
||||||
|
+ unsigned long start1, start2, size, offset;
|
||||||
|
+ struct rela *rela;
|
||||||
|
+ int lineonly = 0, found;
|
||||||
|
+ unsigned int mov_imm_mask = ((1<<16) - 1)<<5;
|
||||||
|
+
|
||||||
|
+ if (sec->status != CHANGED ||
|
||||||
|
+ is_rela_section(sec) ||
|
||||||
|
+ !is_text_section(sec) ||
|
||||||
|
+ sec->sh.sh_size != sec->twin->sh.sh_size ||
|
||||||
|
+ !sec->rela ||
|
||||||
|
+ sec->rela->status != SAME)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ start1 = (unsigned long)sec->twin->data->d_buf;
|
||||||
|
+ start2 = (unsigned long)sec->data->d_buf;
|
||||||
|
+ size = sec->sh.sh_size;
|
||||||
|
+ for (offset = 0; offset < size; offset += ARM64_INSTR_LEN) {
|
||||||
|
+ if (!memcmp((void *)start1 + offset, (void *)start2 + offset,
|
||||||
|
+ ARM64_INSTR_LEN))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ /* verify it's a mov immediate to w1 */
|
||||||
|
+ if ((*(int *)(start1 + offset) & ~mov_imm_mask) !=
|
||||||
|
+ (*(int *)(start2 + offset) & ~mov_imm_mask))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ found = 0;
|
||||||
|
+ list_for_each_entry(rela, &sec->rela->relas, list) {
|
||||||
|
+ if (rela->offset < offset + ARM64_INSTR_LEN)
|
||||||
|
+ continue;
|
||||||
|
+ if (rela->string)
|
||||||
|
+ continue;
|
||||||
|
+ if (!strncmp(rela->sym->name, "__warned.", 9))
|
||||||
|
+ continue;
|
||||||
|
+ if (!strncmp(rela->sym->name, "warn_slowpath_", 14) ||
|
||||||
|
+ (!strcmp(rela->sym->name, "__warn_printk")) ||
|
||||||
|
+ (!strcmp(rela->sym->name, "__might_sleep")) ||
|
||||||
|
+ (!strcmp(rela->sym->name, "___might_sleep")) ||
|
||||||
|
+ (!strcmp(rela->sym->name, "__might_fault")) ||
|
||||||
|
+ (!strcmp(rela->sym->name, "printk")) ||
|
||||||
|
+ (!strcmp(rela->sym->name, "lockdep_rcu_suspicious"))) {
|
||||||
|
+ found = 1;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ if (!found)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ lineonly = 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!lineonly)
|
||||||
|
+ ERROR("no instruction changes detected for changed section %s",
|
||||||
|
+ sec->name);
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
|
||||||
|
static void kpatch_compare_sections(struct list_head *seclist)
|
||||||
|
{
|
||||||
|
@@ -662,7 +748,16 @@ static void kpatch_compare_sections(struct list_head *seclist)
|
||||||
|
|
||||||
|
/* exclude WARN-only, might_sleep changes */
|
||||||
|
list_for_each_entry(sec, seclist, list) {
|
||||||
|
- if (kpatch_line_macro_change_only(sec)) {
|
||||||
|
+ int line_only;
|
||||||
|
+
|
||||||
|
+ if (arch == EM_X86_64)
|
||||||
|
+ line_only = kpatch_line_macro_change_only(sec);
|
||||||
|
+ else if (arch == EM_AARCH64)
|
||||||
|
+ line_only = arm64_kpatch_line_macro_change_only(sec);
|
||||||
|
+ else
|
||||||
|
+ line_only = 0;
|
||||||
|
+
|
||||||
|
+ if (line_only) {
|
||||||
|
log_debug("reverting macro / line number section %s status to SAME\n",
|
||||||
|
sec->name);
|
||||||
|
sec->status = SAME;
|
||||||
|
@@ -722,6 +817,8 @@ static void kpatch_compare_correlated_symbol(struct symbol *sym)
|
||||||
|
if ((sym2->sec->twin && sym2->sec->twin->ignore) ||
|
||||||
|
kpatch_subsection_changed(sym1->sec, sym2->sec))
|
||||||
|
sym->status = CHANGED;
|
||||||
|
+ else if (sym1->name[0] == '$') /* reserved symbols in aarch64 */
|
||||||
|
+ log_debug("maping symbols: %s", sym1->name); /* do nothing just ignogre */
|
||||||
|
else
|
||||||
|
DIFF_FATAL("symbol changed sections: %s", sym1->name);
|
||||||
|
}
|
||||||
|
@@ -1289,22 +1386,22 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifdef __powerpc64__
|
||||||
|
add_off = 0;
|
||||||
|
-#else
|
||||||
|
- if (rela->type == R_X86_64_PC32 ||
|
||||||
|
- rela->type == R_X86_64_PLT32) {
|
||||||
|
- struct insn insn;
|
||||||
|
- rela_insn(sec, rela, &insn);
|
||||||
|
- add_off = (long)insn.next_byte -
|
||||||
|
- (long)sec->base->data->d_buf -
|
||||||
|
- rela->offset;
|
||||||
|
- } else if (rela->type == R_X86_64_64 ||
|
||||||
|
- rela->type == R_X86_64_32S)
|
||||||
|
- add_off = 0;
|
||||||
|
- else
|
||||||
|
- continue;
|
||||||
|
-#endif
|
||||||
|
+ if (arch == EM_X86_64) {
|
||||||
|
+ if (rela->type == R_X86_64_PC32 ||
|
||||||
|
+ rela->type == R_X86_64_PLT32) {
|
||||||
|
+ struct insn insn;
|
||||||
|
+ rela_insn(sec, rela, &insn);
|
||||||
|
+ add_off = (long)insn.next_byte -
|
||||||
|
+ (long)sec->base->data->d_buf -
|
||||||
|
+ rela->offset;
|
||||||
|
+ } else if (rela->type == R_X86_64_64 ||
|
||||||
|
+ rela->type == R_X86_64_32S)
|
||||||
|
+ add_off = 0;
|
||||||
|
+ else
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ /* add_off is always equal to 0 on arm64 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attempt to replace references to unbundled sections
|
||||||
|
@@ -2401,7 +2498,7 @@ static void kpatch_create_kpatch_arch_section(struct kpatch_elf *kelf, char *obj
|
||||||
|
/* entries[index].sec */
|
||||||
|
ALLOC_LINK(rela, &karch_sec->rela->relas);
|
||||||
|
rela->sym = sec->secsym;
|
||||||
|
- rela->type = ABSOLUTE_RELA_TYPE;
|
||||||
|
+ rela->type = absolute_rela_type;
|
||||||
|
rela->addend = 0;
|
||||||
|
rela->offset = index * sizeof(struct kpatch_arch) + \
|
||||||
|
offsetof(struct kpatch_arch, sec);
|
||||||
|
@@ -2409,7 +2506,7 @@ static void kpatch_create_kpatch_arch_section(struct kpatch_elf *kelf, char *obj
|
||||||
|
/* entries[index].objname */
|
||||||
|
ALLOC_LINK(rela, &karch_sec->rela->relas);
|
||||||
|
rela->sym = strsym;
|
||||||
|
- rela->type = ABSOLUTE_RELA_TYPE;
|
||||||
|
+ rela->type = absolute_rela_type;
|
||||||
|
rela->addend = offset_of_string(&kelf->strings, objname);
|
||||||
|
rela->offset = index * sizeof(struct kpatch_arch) + \
|
||||||
|
offsetof(struct kpatch_arch, objname);
|
||||||
|
@@ -2607,7 +2704,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
||||||
|
*/
|
||||||
|
ALLOC_LINK(rela, &relasec->relas);
|
||||||
|
rela->sym = sym;
|
||||||
|
- rela->type = ABSOLUTE_RELA_TYPE;
|
||||||
|
+ rela->type = absolute_rela_type;
|
||||||
|
rela->addend = 0;
|
||||||
|
rela->offset = index * sizeof(*funcs);
|
||||||
|
|
||||||
|
@@ -2617,7 +2714,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
||||||
|
*/
|
||||||
|
ALLOC_LINK(rela, &relasec->relas);
|
||||||
|
rela->sym = strsym;
|
||||||
|
- rela->type = ABSOLUTE_RELA_TYPE;
|
||||||
|
+ rela->type = absolute_rela_type;
|
||||||
|
rela->addend = offset_of_string(&kelf->strings, sym->name);
|
||||||
|
rela->offset = index * sizeof(*funcs) +
|
||||||
|
offsetof(struct kpatch_patch_func, name);
|
||||||
|
@@ -2628,7 +2725,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
||||||
|
*/
|
||||||
|
ALLOC_LINK(rela, &relasec->relas);
|
||||||
|
rela->sym = strsym;
|
||||||
|
- rela->type = ABSOLUTE_RELA_TYPE;
|
||||||
|
+ rela->type = absolute_rela_type;
|
||||||
|
rela->addend = objname_offset;
|
||||||
|
rela->offset = index * sizeof(*funcs) +
|
||||||
|
offsetof(struct kpatch_patch_func,objname);
|
||||||
|
@@ -2686,7 +2783,10 @@ 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 int may_need_dynrela(const struct rela *rela)
|
||||||
|
@@ -2940,7 +3040,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||||
|
/* add rela to fill in ksyms[index].name field */
|
||||||
|
ALLOC_LINK(rela2, &ksym_sec->rela->relas);
|
||||||
|
rela2->sym = strsym;
|
||||||
|
- rela2->type = ABSOLUTE_RELA_TYPE;
|
||||||
|
+ rela2->type = absolute_rela_type;
|
||||||
|
rela2->addend = offset_of_string(&kelf->strings, rela->sym->name);
|
||||||
|
rela2->offset = index * sizeof(*ksyms) + \
|
||||||
|
offsetof(struct kpatch_symbol, name);
|
||||||
|
@@ -2948,7 +3048,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||||
|
/* add rela to fill in ksyms[index].objname field */
|
||||||
|
ALLOC_LINK(rela2, &ksym_sec->rela->relas);
|
||||||
|
rela2->sym = strsym;
|
||||||
|
- rela2->type = ABSOLUTE_RELA_TYPE;
|
||||||
|
+ rela2->type = absolute_rela_type;
|
||||||
|
rela2->addend = offset_of_string(&kelf->strings, sym_objname);
|
||||||
|
rela2->offset = index * sizeof(*ksyms) + \
|
||||||
|
offsetof(struct kpatch_symbol, objname);
|
||||||
|
@@ -2969,7 +3069,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||||
|
ERROR("can't create dynrela for section %s (symbol %s): no bundled or section symbol",
|
||||||
|
sec->name, rela->sym->name);
|
||||||
|
|
||||||
|
- rela2->type = ABSOLUTE_RELA_TYPE;
|
||||||
|
+ rela2->type = absolute_rela_type;
|
||||||
|
rela2->addend = rela->offset;
|
||||||
|
rela2->offset = index * sizeof(*krelas) + \
|
||||||
|
offsetof(struct kpatch_relocation, dest);
|
||||||
|
@@ -2977,7 +3077,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||||
|
/* add rela to fill in krelas[index].objname field */
|
||||||
|
ALLOC_LINK(rela2, &krela_sec->rela->relas);
|
||||||
|
rela2->sym = strsym;
|
||||||
|
- rela2->type = ABSOLUTE_RELA_TYPE;
|
||||||
|
+ rela2->type = absolute_rela_type;
|
||||||
|
rela2->addend = offset_of_string(&kelf->strings, objname);
|
||||||
|
rela2->offset = index * sizeof(*krelas) + \
|
||||||
|
offsetof(struct kpatch_relocation, objname);
|
||||||
|
@@ -2985,7 +3085,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||||
|
/* add rela to fill in krelas[index].ksym field */
|
||||||
|
ALLOC_LINK(rela2, &krela_sec->rela->relas);
|
||||||
|
rela2->sym = ksym_sec_sym;
|
||||||
|
- rela2->type = ABSOLUTE_RELA_TYPE;
|
||||||
|
+ rela2->type = absolute_rela_type;
|
||||||
|
rela2->addend = index * sizeof(*ksyms);
|
||||||
|
rela2->offset = index * sizeof(*krelas) + \
|
||||||
|
offsetof(struct kpatch_relocation, ksym);
|
||||||
|
@@ -3048,7 +3148,7 @@ static void kpatch_create_callbacks_objname_rela(struct kpatch_elf *kelf, char *
|
||||||
|
if (!strcmp(callbackp->name, sec->name)) {
|
||||||
|
ALLOC_LINK(rela, &sec->relas);
|
||||||
|
rela->sym = strsym;
|
||||||
|
- rela->type = ABSOLUTE_RELA_TYPE;
|
||||||
|
+ rela->type = absolute_rela_type;
|
||||||
|
rela->addend = objname_offset;
|
||||||
|
rela->offset = callbackp->offset;
|
||||||
|
break;
|
||||||
|
@@ -3101,6 +3201,7 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf)
|
||||||
|
/* add rela in .rela__mcount_loc to fill in function pointer */
|
||||||
|
ALLOC_LINK(rela, &relasec->relas);
|
||||||
|
rela->sym = sym;
|
||||||
|
+ if (arch == EM_X86_64) {
|
||||||
|
rela->type = R_X86_64_64;
|
||||||
|
rela->addend = 0;
|
||||||
|
rela->offset = index * sizeof(void*);
|
||||||
|
@@ -3136,6 +3237,40 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf)
|
||||||
|
|
||||||
|
rela->type = R_X86_64_PC32;
|
||||||
|
}
|
||||||
|
+ } else if (arch == EM_AARCH64) {
|
||||||
|
+ unsigned int *insnp;
|
||||||
|
+ rela->type = R_AARCH64_ABS64;
|
||||||
|
+ /* bl <__fentry__> is the second insn */
|
||||||
|
+ rela->addend = 4;
|
||||||
|
+ rela->offset = index * sizeof(void*);
|
||||||
|
+
|
||||||
|
+ newdata = malloc(sym->sec->data->d_size);
|
||||||
|
+ if (!newdata)
|
||||||
|
+ ERROR("malloc");
|
||||||
|
+
|
||||||
|
+ memcpy(newdata, sym->sec->data->d_buf, sym->sec->data->d_size);
|
||||||
|
+ sym->sec->data->d_buf = newdata;
|
||||||
|
+ insnp = newdata;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * mov x9, x30
|
||||||
|
+ * nop //function in .text.<func>, so it be replaced with nop by recordmcount
|
||||||
|
+ * mov x30, x9
|
||||||
|
+ */
|
||||||
|
+ if (insnp[0] != 0xaa1e03e9 || insnp[1] != 0xd503201f || insnp[2] != 0xaa0903fe)
|
||||||
|
+ ERROR("%s: unexpected instruction at the start of the function",
|
||||||
|
+ sym->name);
|
||||||
|
+
|
||||||
|
+ /* change the nop to bl __fentry__ */
|
||||||
|
+ insnp[1] = 0x94000000;
|
||||||
|
+ rela = list_first_entry(&sym->sec->rela->relas, struct rela,
|
||||||
|
+ list);
|
||||||
|
+ rela->type = R_AARCH64_CALL26;
|
||||||
|
+ rela->offset = 4;
|
||||||
|
+
|
||||||
|
+ } else {
|
||||||
|
+ ERROR("unsupport arch %d\n", arch);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
@@ -3334,6 +3469,8 @@ int main(int argc, char *argv[])
|
||||||
|
char *hint = NULL, *orig_obj, *patched_obj, *parent_name;
|
||||||
|
char *parent_symtab, *mod_symvers, *patch_name, *output_obj;
|
||||||
|
struct sym_compare_type *base_locals, *sym_comp;
|
||||||
|
+ char *no_profiling_calls = NULL;
|
||||||
|
+ char *gcc_add_option = NULL, *mlongcall = NULL;
|
||||||
|
|
||||||
|
arguments.debug = 0;
|
||||||
|
argp_parse (&argp, argc, argv, 0, NULL, &arguments);
|
||||||
|
@@ -3354,6 +3491,13 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
|
kelf_base = kpatch_elf_open(orig_obj);
|
||||||
|
kelf_patched = kpatch_elf_open(patched_obj);
|
||||||
|
+ arch = arch_of_elf(kelf_base->elf);
|
||||||
|
+ if (arch == EM_X86_64)
|
||||||
|
+ absolute_rela_type = R_X86_64_64;
|
||||||
|
+ else if (arch == EM_AARCH64)
|
||||||
|
+ absolute_rela_type = R_AARCH64_ABS64;
|
||||||
|
+ else
|
||||||
|
+ ERROR("only arch x86_64 and arm64 be supported\n");
|
||||||
|
|
||||||
|
kpatch_compare_elf_headers(kelf_base->elf, kelf_patched->elf);
|
||||||
|
kpatch_check_program_headers(kelf_base->elf);
|
||||||
|
@@ -3392,7 +3536,12 @@ int main(int argc, char *argv[])
|
||||||
|
*/
|
||||||
|
kpatch_mark_ignored_sections(kelf_patched);
|
||||||
|
kpatch_compare_correlated_elements(kelf_patched);
|
||||||
|
- kpatch_check_func_profiling_calls(kelf_patched);
|
||||||
|
+ no_profiling_calls = getenv("NO_PROFILING_CALLS");
|
||||||
|
+ if (!no_profiling_calls)
|
||||||
|
+ kpatch_check_func_profiling_calls(kelf_patched);
|
||||||
|
+ else
|
||||||
|
+ log_debug("NO_PROFILING_CALLS set\n");
|
||||||
|
+
|
||||||
|
kpatch_elf_teardown(kelf_base);
|
||||||
|
kpatch_elf_free(kelf_base);
|
||||||
|
|
||||||
|
@@ -3452,7 +3601,14 @@ int main(int argc, char *argv[])
|
||||||
|
kpatch_create_callbacks_objname_rela(kelf_out, parent_name);
|
||||||
|
kpatch_build_strings_section_data(kelf_out);
|
||||||
|
|
||||||
|
- kpatch_create_mcount_sections(kelf_out);
|
||||||
|
+ gcc_add_option = getenv("GCC_ADD_OPTION");
|
||||||
|
+ if (gcc_add_option)
|
||||||
|
+ mlongcall = strstr(gcc_add_option, "-mlong-calls");
|
||||||
|
+ if (arch == EM_AARCH64 && mlongcall) {
|
||||||
|
+ printf("-mlong-calls found, no need to create mcount section\n");
|
||||||
|
+ } else {
|
||||||
|
+ kpatch_create_mcount_sections(kelf_out);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* At this point, the set of output sections and symbols is
|
||||||
|
diff --git a/kpatch-build/create-kpatch-module.c b/kpatch-build/create-kpatch-module.c
|
||||||
|
index 43d6809..6f80831 100644
|
||||||
|
--- a/kpatch-build/create-kpatch-module.c
|
||||||
|
+++ b/kpatch-build/create-kpatch-module.c
|
||||||
|
@@ -31,6 +31,17 @@
|
||||||
|
char *childobj;
|
||||||
|
enum loglevel loglevel = NORMAL;
|
||||||
|
|
||||||
|
+static unsigned int arch;
|
||||||
|
+static unsigned int absolute_rela_type;
|
||||||
|
+
|
||||||
|
+static unsigned int arch_of_elf(Elf *elf)
|
||||||
|
+{
|
||||||
|
+ GElf_Ehdr eh;
|
||||||
|
+ if (!gelf_getehdr(elf, &eh))
|
||||||
|
+ ERROR("gelf_getehdr");
|
||||||
|
+ return eh.e_machine;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Create .kpatch.dynrelas from .kpatch.relocations and .kpatch.symbols sections
|
||||||
|
*
|
||||||
|
@@ -102,14 +113,14 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section
|
||||||
|
/* dest */
|
||||||
|
ALLOC_LINK(rela, &dynsec->rela->relas);
|
||||||
|
rela->sym = sym;
|
||||||
|
- rela->type = R_X86_64_64;
|
||||||
|
+ rela->type = absolute_rela_type;
|
||||||
|
rela->addend = dest_offset;
|
||||||
|
rela->offset = index * sizeof(*dynrelas);
|
||||||
|
|
||||||
|
/* name */
|
||||||
|
ALLOC_LINK(rela, &dynsec->rela->relas);
|
||||||
|
rela->sym = strsec->secsym;
|
||||||
|
- rela->type = R_X86_64_64;
|
||||||
|
+ rela->type = absolute_rela_type;
|
||||||
|
rela->addend = name_offset;
|
||||||
|
rela->offset = index * sizeof(*dynrelas) + \
|
||||||
|
offsetof(struct kpatch_patch_dynrela, name);
|
||||||
|
@@ -117,7 +128,7 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section
|
||||||
|
/* objname */
|
||||||
|
ALLOC_LINK(rela, &dynsec->rela->relas);
|
||||||
|
rela->sym = strsec->secsym;
|
||||||
|
- rela->type = R_X86_64_64;
|
||||||
|
+ rela->type = absolute_rela_type;
|
||||||
|
rela->addend = objname_offset;
|
||||||
|
rela->offset = index * sizeof(*dynrelas) + \
|
||||||
|
offsetof(struct kpatch_patch_dynrela, objname);
|
||||||
|
@@ -200,6 +211,13 @@ int main(int argc, char *argv[])
|
||||||
|
childobj = basename(arguments.args[0]);
|
||||||
|
|
||||||
|
kelf = kpatch_elf_open(arguments.args[0]);
|
||||||
|
+ arch = arch_of_elf(kelf->elf);
|
||||||
|
+ if (arch == EM_X86_64)
|
||||||
|
+ absolute_rela_type = R_X86_64_64;
|
||||||
|
+ else if (arch == EM_AARCH64)
|
||||||
|
+ absolute_rela_type = R_AARCH64_ABS64;
|
||||||
|
+ else
|
||||||
|
+ ERROR("only arch x86_64 and arm64 be supported\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sanity checks:
|
||||||
|
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||||
|
index ae0733c..17a5e11 100755
|
||||||
|
--- a/kpatch-build/kpatch-build
|
||||||
|
+++ b/kpatch-build/kpatch-build
|
||||||
|
@@ -299,12 +299,72 @@ find_special_section_data_ppc64le() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
+find_special_section_data_arm64() {
|
||||||
|
+
|
||||||
|
+ [[ "$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 = c = f = s = i = r = t = h = 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}
|
||||||
|
+ c == 0 && /DW_AT_name.* klp_func[[:space:]]*$/ {c = 1; next}
|
||||||
|
+ t == 0 && /DW_AT_name.* klp_object[[:space:]]*$/ {t = 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 }
|
||||||
|
+ c == 1 && /DW_TAG_structure_type/ { c = 3; next }
|
||||||
|
+ t == 1 && /DW_TAG_structure_type/ { t = 3; next }
|
||||||
|
+ c == 1 && /DW_AT_name.* force[[:space:]]*$/ {f = 2; next}
|
||||||
|
+ c == 1 && /DW_AT_name.* old_sympos[[:space:]]*$/ {s = 2; next}
|
||||||
|
+ i == 1 && /DW_AT_name.* immediate[[:space:]]*$/ {i = 2; next}
|
||||||
|
+ t == 1 && /DW_AT_name.* relocs[[:space:]]*$/ {r = 2; next}
|
||||||
|
+ t == 1 && /DW_AT_name.* hooks_load[[:space:]]*$/ {h = 2; 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}
|
||||||
|
+ f == 2 {printf("export KLP_SUPPORT_FORCE=y\n"); f = 3}
|
||||||
|
+ s == 2 {printf("export KLP_SUPPORT_OLD_SYMPOS=y\n"); s = 3}
|
||||||
|
+ i == 2 {printf("export KLP_SUPPORT_IMMEDIATE=y\n"); i = 3}
|
||||||
|
+ r == 2 {printf("export KLP_SUPPORT_RELOCS=y\n"); r = 3}
|
||||||
|
+ h == 2 {printf("export KLP_SUPPORT_LOADHOOKS=y\n"); h = 3}
|
||||||
|
+
|
||||||
|
+ # Bail out once we have everything
|
||||||
|
+ a == 2 && b == 2 && e == 2 && (j == 2 || skip_j) && c == 3 && t == 3 {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" = "arm64" ]]; then
|
||||||
|
+ find_special_section_data_arm64
|
||||||
|
+ 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"
|
||||||
|
@@ -428,6 +488,29 @@ find_kobj() {
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
+arch_export() {
|
||||||
|
+ E_MACHINE=$(od -An -j18 -N2 -d $VMLINUX)
|
||||||
|
+ if [[ $E_MACHINE -eq 62 ]]; then
|
||||||
|
+ export ARCH=x86_64
|
||||||
|
+ export ARCH_COMPILE=
|
||||||
|
+ export ENDIAN=little
|
||||||
|
+ export GCC_ADD_OPTION=
|
||||||
|
+ elif [[ $E_MACHINE -eq 183 ]]; then
|
||||||
|
+ export ARCH=arm64
|
||||||
|
+ if [ $(arch) != "aarch64" ]; then
|
||||||
|
+ export ARCH_COMPILE=aarch64-linux-gnu-
|
||||||
|
+ fi
|
||||||
|
+ export ENDIAN=little
|
||||||
|
+ if grep "\-mlong-calls" /lib/modules/$ARCHVERSION/build//Makefile > /dev/null; then
|
||||||
|
+ export GCC_ADD_OPTION="-fno-section-anchors -mlong-calls"
|
||||||
|
+ else
|
||||||
|
+ export GCC_ADD_OPTION="-fno-section-anchors"
|
||||||
|
+ fi
|
||||||
|
+ else
|
||||||
|
+ die "only support arm64 or x86_64 architecture"
|
||||||
|
+ fi
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
# Only allow alphanumerics and '_' and '-' in the module name. Everything else
|
||||||
|
# is replaced with '-'. Also truncate to 48 chars so the full name fits in the
|
||||||
|
# kernel's 56-byte module name array.
|
||||||
|
@@ -786,13 +869,13 @@ apply_patches
|
||||||
|
remove_patches
|
||||||
|
|
||||||
|
cp -LR "$DATADIR/patch" "$TEMPDIR" || die
|
||||||
|
-
|
||||||
|
+arch_export
|
||||||
|
if [[ "$ARCH" = "ppc64le" ]]; then
|
||||||
|
ARCH_KCFLAGS="-mcmodel=large -fplugin=$PLUGINDIR/ppc64le-plugin.so"
|
||||||
|
fi
|
||||||
|
|
||||||
|
export KCFLAGS="-I$DATADIR/patch -ffunction-sections -fdata-sections \
|
||||||
|
- $ARCH_KCFLAGS $DEBUG_KCFLAGS"
|
||||||
|
+ $ARCH_KCFLAGS $DEBUG_KCFLAGS ${GCC_ADD_OPTION}"
|
||||||
|
|
||||||
|
echo "Reading special section data"
|
||||||
|
find_special_section_data
|
||||||
|
@@ -806,7 +889,7 @@ echo "Building original source"
|
||||||
|
unset KPATCH_GCC_TEMPDIR
|
||||||
|
# $TARGETS used as list, no quotes.
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
-CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
||||||
|
+CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
||||||
|
|
||||||
|
echo "Building patched source"
|
||||||
|
apply_patches
|
||||||
|
@@ -817,7 +900,7 @@ KPATCH_GCC_SRCDIR="$SRCDIR"
|
||||||
|
export KPATCH_GCC_SRCDIR
|
||||||
|
# $TARGETS used as list, no quotes.
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
-CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " \
|
||||||
|
+CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" \
|
||||||
|
KBUILD_MODPOST_WARN=1 \
|
||||||
|
make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
||||||
|
|
||||||
|
@@ -950,6 +1033,26 @@ if "$KPATCH_MODULE"; then
|
||||||
|
export KCPPFLAGS="-D__KPATCH_MODULE__"
|
||||||
|
fi
|
||||||
|
|
||||||
|
+if [[ -n "$KLP_SUPPORT_FORCE" ]];then
|
||||||
|
+ export KCPPFLAGS="-D__KLP_SUPPORT_FORCE__ $KCPPFLAGS"
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if [[ -n "$KLP_SUPPORT_OLD_SYMPOS" ]];then
|
||||||
|
+ export KCPPFLAGS="-DHAVE_SYMPOS $KCPPFLAGS"
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if [[ -n "$KLP_SUPPORT_IMMEDIATE" ]];then
|
||||||
|
+ export KCPPFLAGS="-DHAVE_IMMEDIATE $KCPPFLAGS"
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if [[ -n "$KLP_SUPPORT_RELOCS" ]];then
|
||||||
|
+ export KCPPFLAGS="-DHAVE_ELF_RELOCS $KCPPFLAGS"
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+if [[ -n "$KLP_SUPPORT_LOADHOOKS" ]];then
|
||||||
|
+ export KCPPFLAGS="-DHAVE_LOADHOOKS $KCPPFLAGS"
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
echo "Building patch module: $MODNAME.ko"
|
||||||
|
|
||||||
|
if [[ -z "$USERSRCDIR" ]] && [[ "$DISTRO" = ubuntu ]]; then
|
||||||
|
@@ -962,12 +1065,12 @@ fi
|
||||||
|
cd "$TEMPDIR/output" || die
|
||||||
|
# $KPATCH_LDFLAGS and result of find used as list, no quotes.
|
||||||
|
# shellcheck disable=SC2086,SC2046
|
||||||
|
-ld -r $KPATCH_LDFLAGS -o ../patch/tmp_output.o $(find . -name "*.o") 2>&1 | logger || die
|
||||||
|
+${ARCH_COMPILE}ld -r $KPATCH_LDFLAGS -o ../patch/tmp_output.o $(find . -name "*.o") 2>&1 | logger || die
|
||||||
|
|
||||||
|
if "$KPATCH_MODULE"; then
|
||||||
|
# Add .kpatch.checksum for kpatch script
|
||||||
|
md5sum ../patch/tmp_output.o | awk '{printf "%s\0", $1}' > checksum.tmp || die
|
||||||
|
- objcopy --add-section .kpatch.checksum=checksum.tmp --set-section-flags .kpatch.checksum=alloc,load,contents,readonly ../patch/tmp_output.o || die
|
||||||
|
+ ${ARCH_COMPILE}objcopy --add-section .kpatch.checksum=checksum.tmp --set-section-flags .kpatch.checksum=alloc,load,contents,readonly ../patch/tmp_output.o || die
|
||||||
|
rm -f checksum.tmp
|
||||||
|
"$TOOLSDIR"/create-kpatch-module "$TEMPDIR"/patch/tmp_output.o "$TEMPDIR"/patch/output.o 2>&1 | logger 1
|
||||||
|
check_pipe_status create-kpatch-module
|
||||||
|
@@ -984,6 +1087,7 @@ fi
|
||||||
|
KPATCH_BUILD="$KPATCH_BUILD" KPATCH_NAME="$MODNAME" \
|
||||||
|
KBUILD_EXTRA_SYMBOLS="$KBUILD_EXTRA_SYMBOLS" \
|
||||||
|
KPATCH_LDFLAGS="$KPATCH_LDFLAGS" \
|
||||||
|
+CROSS_COMPILE="$ARCH_COMPILE" \
|
||||||
|
make 2>&1 | logger || die
|
||||||
|
|
||||||
|
if ! "$KPATCH_MODULE"; then
|
||||||
|
diff --git a/kpatch-build/kpatch-gcc b/kpatch-build/kpatch-gcc
|
||||||
|
index 9663290..35d7c1c 100755
|
||||||
|
--- a/kpatch-build/kpatch-gcc
|
||||||
|
+++ b/kpatch-build/kpatch-gcc
|
||||||
|
@@ -13,7 +13,7 @@ fi
|
||||||
|
|
||||||
|
declare -a args=("$@")
|
||||||
|
|
||||||
|
-if [[ "$TOOLCHAINCMD" =~ "gcc" ]] ; then
|
||||||
|
+if [[ "$TOOLCHAINCMD" =~ "${ARCH_COMPILE}gcc" ]] ; then
|
||||||
|
while [ "$#" -gt 0 ]; do
|
||||||
|
if [ "$1" = "-o" ]; then
|
||||||
|
obj="$2"
|
||||||
|
@@ -60,7 +60,7 @@ if [[ "$TOOLCHAINCMD" =~ "gcc" ]] ; then
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
-elif [[ "$TOOLCHAINCMD" = "ld" ]] ; then
|
||||||
|
+elif [[ "$TOOLCHAINCMD" = "${ARCH_COMPILE}ld" ]] ; then
|
||||||
|
while [ "$#" -gt 0 ]; do
|
||||||
|
if [ "$1" = "-o" ]; then
|
||||||
|
obj="$2"
|
||||||
|
--
|
||||||
|
2.18.1
|
||||||
|
|
||||||
@ -1,8 +1,7 @@
|
|||||||
From fc6b9c5b1b3eb5d59186fe35cc90d3c06b07c537 Mon Sep 17 00:00:00 2001
|
From 3af07fd0f178a4c6e2ae68207c3fedfd10672e65 Mon Sep 17 00:00:00 2001
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
Date: Fri, 2 Nov 2018 17:24:36 +0000
|
Date: Tue, 25 Feb 2020 22:44:50 -0500
|
||||||
Subject: [PATCH 1004/1015] create-diff-object: new static var should be
|
Subject: [PATCH 03/17] create-diff-object: new static var should be included
|
||||||
included
|
|
||||||
|
|
||||||
Before this patch, only global variables(no referenced) will be
|
Before this patch, only global variables(no referenced) will be
|
||||||
included by kpatch-build. But some macros put some static varibles
|
included by kpatch-build. But some macros put some static varibles
|
||||||
@ -15,14 +14,14 @@ cause a problem even the new static variables are in unbundled section.
|
|||||||
Signed-off-by: Zhou Chengming <zhouchengming1@huawei.com>
|
Signed-off-by: Zhou Chengming <zhouchengming1@huawei.com>
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
---
|
---
|
||||||
kpatch-build/create-diff-object.c | 15 +++++++++++++++
|
kpatch-build/create-diff-object.c | 15 +++++++++++++++
|
||||||
1 files changed, 15 insertions(+), 0 deletions(-)
|
1 file changed, 15 insertions(+)
|
||||||
|
|
||||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||||
index d242d01..6e23295 100644
|
index 58789f1..93570df 100644
|
||||||
--- a/kpatch-build/create-diff-object.c
|
--- a/kpatch-build/create-diff-object.c
|
||||||
+++ b/kpatch-build/create-diff-object.c
|
+++ b/kpatch-build/create-diff-object.c
|
||||||
@@ -1536,6 +1536,20 @@ static void kpatch_include_force_elements(struct kpatch_elf *kelf)
|
@@ -1689,6 +1689,20 @@ static void kpatch_include_force_elements(struct kpatch_elf *kelf)
|
||||||
sym->include = 0;
|
sym->include = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,8 +31,8 @@ index d242d01..6e23295 100644
|
|||||||
+
|
+
|
||||||
+ list_for_each_entry(sym, &kelf->symbols, list) {
|
+ list_for_each_entry(sym, &kelf->symbols, list) {
|
||||||
+ if (sym->status == NEW &&
|
+ if (sym->status == NEW &&
|
||||||
+ sym->type == STT_OBJECT &&
|
+ sym->bind == STB_LOCAL &&
|
||||||
+ sym->bind == STB_LOCAL)
|
+ (sym->type == STT_OBJECT || (sym->type == STT_NOTYPE && sym->name[0] != '$')))
|
||||||
+ kpatch_include_symbol(sym);
|
+ kpatch_include_symbol(sym);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
@ -43,14 +42,14 @@ index d242d01..6e23295 100644
|
|||||||
static int kpatch_include_new_globals(struct kpatch_elf *kelf)
|
static int kpatch_include_new_globals(struct kpatch_elf *kelf)
|
||||||
{
|
{
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
@@ -3211,6 +3225,7 @@ int main(int argc, char *argv[])
|
@@ -3554,6 +3568,7 @@ int main(int argc, char *argv[])
|
||||||
callbacks_exist = kpatch_include_callback_elements(kelf_patched);
|
callbacks_exist = kpatch_include_callback_elements(kelf_patched);
|
||||||
kpatch_include_force_elements(kelf_patched);
|
kpatch_include_force_elements(kelf_patched);
|
||||||
new_globals_exist = kpatch_include_new_globals(kelf_patched);
|
new_globals_exist = kpatch_include_new_globals(kelf_patched);
|
||||||
+ kpatch_include_new_static_var(kelf_patched);
|
+ kpatch_include_new_static_var(kelf_patched);
|
||||||
|
|
||||||
|
kpatch_process_special_sections(kelf_patched);
|
||||||
|
|
||||||
kpatch_print_changes(kelf_patched);
|
|
||||||
kpatch_dump_kelf(kelf_patched);
|
|
||||||
--
|
--
|
||||||
1.7.5.4
|
2.18.1
|
||||||
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
From b2f40b03ce1778c7e97586e4111d22d3b28b3330 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Artem Savkov <asavkov@redhat.com>
|
|
||||||
Date: Fri, 7 Dec 2018 16:46:08 +0100
|
|
||||||
Subject: [PATCH] kmod/patch: more linking fixes
|
|
||||||
|
|
||||||
While adding proper linker script option my previous patch left the
|
|
||||||
linker script in the list of source files (on pre-4.20 kernels) for
|
|
||||||
ld somehow breaking kpatch callback sections. For this to work
|
|
||||||
properly kpatch.lds needs to be added to 'extra-y' instead of objs. And
|
|
||||||
for kbuild to process this option properly we need to call make without
|
|
||||||
the .ko target, i.e. let kbuild decide what to build.
|
|
||||||
|
|
||||||
Fixes: 17a97b4 ("kmod/patch: fix patch linking with 4.20")
|
|
||||||
Signed-off-by: Artem Savkov <asavkov@redhat.com>
|
|
||||||
---
|
|
||||||
kmod/patch/Makefile | 5 +++--
|
|
||||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kmod/patch/Makefile b/kmod/patch/Makefile
|
|
||||||
index 7ba0820..e017b17 100644
|
|
||||||
--- a/kmod/patch/Makefile
|
|
||||||
+++ b/kmod/patch/Makefile
|
|
||||||
@@ -12,13 +12,14 @@ endif
|
|
||||||
|
|
||||||
obj-m += $(KPATCH_NAME).o
|
|
||||||
ldflags-y += -T $(src)/kpatch.lds
|
|
||||||
+extra-y := kpatch.lds
|
|
||||||
|
|
||||||
-$(KPATCH_NAME)-objs += patch-hook.o kpatch.lds output.o
|
|
||||||
+$(KPATCH_NAME)-objs += patch-hook.o output.o
|
|
||||||
|
|
||||||
all: $(KPATCH_NAME).ko
|
|
||||||
|
|
||||||
$(KPATCH_NAME).ko:
|
|
||||||
- $(KPATCH_MAKE) $(KPATCH_NAME).ko
|
|
||||||
+ $(KPATCH_MAKE)
|
|
||||||
|
|
||||||
patch-hook.o: patch-hook.c kpatch-patch-hook.c livepatch-patch-hook.c
|
|
||||||
$(KPATCH_MAKE) patch-hook.o
|
|
||||||
--
|
|
||||||
1.7.12.4
|
|
||||||
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
From 942cc3ace7edb7c15f40f931dd6f47a934b9fc77 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Artem Savkov <asavkov@redhat.com>
|
|
||||||
Date: Tue, 12 Jun 2018 17:33:17 +0200
|
|
||||||
Subject: [PATCH] create-diff-object: allow changing subsections
|
|
||||||
|
|
||||||
gcc8 can place functions to .text.unlikely and .text.hot subsections
|
|
||||||
during optimizations. Allow symbols to change subsections instead of
|
|
||||||
failing.
|
|
||||||
|
|
||||||
Signed-off-by: Artem Savkov <asavkov@redhat.com>
|
|
||||||
|
|
||||||
backport from:
|
|
||||||
https://github.com/jpoimboe/kpatch/commit/35cc6ff0162fc8008c4c639fdfcabd61b38a982f
|
|
||||||
---
|
|
||||||
kpatch-build/create-diff-object.c | 28 ++++++++++++++++++++++++++--
|
|
||||||
1 file changed, 26 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
|
||||||
index 2ddd00d..61ce74f 100644
|
|
||||||
--- a/kpatch-build/create-diff-object.c
|
|
||||||
+++ b/kpatch-build/create-diff-object.c
|
|
||||||
@@ -68,6 +68,12 @@
|
|
||||||
|
|
||||||
char *childobj;
|
|
||||||
|
|
||||||
+enum subsection {
|
|
||||||
+ SUBSECTION_NORMAL,
|
|
||||||
+ SUBSECTION_HOT,
|
|
||||||
+ SUBSECTION_UNLIKELY
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
enum loglevel loglevel = NORMAL;
|
|
||||||
|
|
||||||
#ifndef EM_X86_64
|
|
||||||
@@ -708,6 +714,22 @@ static void kpatch_compare_sections(struct list_head *seclist)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+static enum subsection kpatch_subsection_type(struct section *sec)
|
|
||||||
+{
|
|
||||||
+ if (!strncmp(sec->name, ".text.unlikely.", 15))
|
|
||||||
+ return SUBSECTION_UNLIKELY;
|
|
||||||
+
|
|
||||||
+ if (!strncmp(sec->name, ".text.hot.", 10))
|
|
||||||
+ return SUBSECTION_HOT;
|
|
||||||
+
|
|
||||||
+ return SUBSECTION_NORMAL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int kpatch_subsection_changed(struct section *sec1, struct section *sec2)
|
|
||||||
+{
|
|
||||||
+ return kpatch_subsection_type(sec1) != kpatch_subsection_type(sec2);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void kpatch_compare_correlated_symbol(struct symbol *sym)
|
|
||||||
{
|
|
||||||
struct symbol *sym1 = sym, *sym2 = sym->twin;
|
|
||||||
@@ -720,10 +742,12 @@ static void kpatch_compare_correlated_symbol(struct symbol *sym)
|
|
||||||
/*
|
|
||||||
* If two symbols are correlated but their sections are not, then the
|
|
||||||
* symbol has changed sections. This is only allowed if the symbol is
|
|
||||||
- * moving out of an ignored section.
|
|
||||||
++ * moving out of an ignored section, or moving between normal/hot/unlikely
|
|
||||||
++ * subsections.
|
|
||||||
*/
|
|
||||||
if (sym1->sec && sym2->sec && sym1->sec->twin != sym2->sec) {
|
|
||||||
- if (sym2->sec->twin && sym2->sec->twin->ignore)
|
|
||||||
+ if ((sym2->sec->twin && sym2->sec->twin->ignore) ||
|
|
||||||
+ kpatch_subsection_changed(sym1->sec, sym2->sec))
|
|
||||||
sym->status = CHANGED;
|
|
||||||
else if (sym1->name[0] == '$') /* reserved symbols in aarch64 */
|
|
||||||
log_debug("maping symbols: %s", sym1->name); /* do nothing just ignogre */
|
|
||||||
--
|
|
||||||
2.19.1
|
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
From 858cc1f1ef2565d6ffa539550fc13af7e62863e4 Mon Sep 17 00:00:00 2001
|
From c03772c4e29473eae68009c12efc182238d103c7 Mon Sep 17 00:00:00 2001
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
Date: Fri, 2 Nov 2018 17:24:42 +0000
|
Date: Fri, 2 Nov 2018 17:24:42 +0000
|
||||||
Subject: [PATCH 1005/1015] livepatch, fix: use THIS modname as the name of
|
Subject: [PATCH 04/17] livepatch, fix: use THIS modname as the name of
|
||||||
ddebug_table
|
ddebug_table
|
||||||
|
|
||||||
We just want a unique name for every module, so put a _ddebug in
|
We just want a unique name for every module, so put a _ddebug in
|
||||||
@ -12,21 +12,21 @@ Suggested-by: Li Bin <huawei.libin@huawei.com>
|
|||||||
Signed-off-by: Zhou Chengming <zhouchengming1@huawei.com>
|
Signed-off-by: Zhou Chengming <zhouchengming1@huawei.com>
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
---
|
---
|
||||||
kmod/patch/livepatch-patch-hook.c | 1 +
|
kmod/patch/livepatch-patch-hook.c | 1 +
|
||||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
||||||
index e59a377..2c0cadd 100644
|
index e12fd50..613d037 100644
|
||||||
--- a/kmod/patch/livepatch-patch-hook.c
|
--- a/kmod/patch/livepatch-patch-hook.c
|
||||||
+++ b/kmod/patch/livepatch-patch-hook.c
|
+++ b/kmod/patch/livepatch-patch-hook.c
|
||||||
@@ -452,6 +452,7 @@ out:
|
@@ -473,6 +473,7 @@ out:
|
||||||
|
|
||||||
static void __exit patch_exit(void)
|
static void __exit patch_exit(void)
|
||||||
{
|
{
|
||||||
+ pr_debug("make THIS modname first\n");
|
+ pr_debug("make THIS modname first\n");
|
||||||
|
#ifndef HAVE_SIMPLE_ENABLE
|
||||||
WARN_ON(klp_unregister_patch(lpatch));
|
WARN_ON(klp_unregister_patch(lpatch));
|
||||||
}
|
#endif
|
||||||
|
|
||||||
--
|
--
|
||||||
1.7.5.4
|
2.18.1
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
From 2f95a0fa6214a97f60a0d5ba4dc0cda152d5c7d4 Mon Sep 17 00:00:00 2001
|
From 5504f36c6de3abae8a4f7ba11f7a2838ddbc5b58 Mon Sep 17 00:00:00 2001
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
Date: Fri, 2 Nov 2018 17:24:51 +0000
|
Date: Fri, 2 Nov 2018 17:24:51 +0000
|
||||||
Subject: [PATCH 1006/1015] create-diff-object: fix correlate static local
|
Subject: [PATCH 05/17] create-diff-object: fix correlate static local
|
||||||
variables for __param section
|
variables for __param section
|
||||||
|
|
||||||
kpatch-build correlate fail when no sections reference
|
kpatch-build correlate fail when no sections reference
|
||||||
@ -27,14 +27,14 @@ copy_module_from_fd.isra.43+0x53/0x150
|
|||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
---
|
---
|
||||||
kpatch-build/create-diff-object.c | 4 ++++
|
kpatch-build/create-diff-object.c | 4 ++++
|
||||||
1 files changed, 4 insertions(+), 0 deletions(-)
|
1 file changed, 4 insertions(+)
|
||||||
|
|
||||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||||
index 6e23295..bd7dd37 100644
|
index 93570df..9f1abc0 100644
|
||||||
--- a/kpatch-build/create-diff-object.c
|
--- a/kpatch-build/create-diff-object.c
|
||||||
+++ b/kpatch-build/create-diff-object.c
|
+++ b/kpatch-build/create-diff-object.c
|
||||||
@@ -925,6 +925,10 @@ static int kpatch_is_normal_static_local(struct symbol *sym)
|
@@ -1094,6 +1094,10 @@ static int kpatch_is_normal_static_local(struct symbol *sym)
|
||||||
if (is_special_static(sym))
|
if (is_special_static(sym))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -46,5 +46,5 @@ index 6e23295..bd7dd37 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
--
|
--
|
||||||
1.7.5.4
|
2.18.1
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
From 0a92ec9f158340501151bf350050597414affece Mon Sep 17 00:00:00 2001
|
From 16aa1e59851c29ce63b18f8ef5c570052c6a95af Mon Sep 17 00:00:00 2001
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
Date: Fri, 2 Nov 2018 17:24:58 +0000
|
Date: Fri, 2 Nov 2018 17:24:58 +0000
|
||||||
Subject: [PATCH 1007/1015] create-diff-object: don't create dynamic reloc for
|
Subject: [PATCH 06/17] create-diff-object: don't create dynamic reloc for
|
||||||
symbol exported by patch itself
|
symbol exported by patch itself
|
||||||
|
|
||||||
when a patch export a new function, ___kcrctab+xxx has a reloc,
|
when a patch export a new function, ___kcrctab+xxx has a reloc,
|
||||||
@ -9,23 +9,23 @@ use origin reloc to get right symbol version.
|
|||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
---
|
---
|
||||||
kpatch-build/create-diff-object.c | 3 +++
|
kpatch-build/create-diff-object.c | 3 +++
|
||||||
1 files changed, 3 insertions(+), 0 deletions(-)
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||||
index bd7dd37..349e483 100644
|
index 9f1abc0..18ed1f7 100644
|
||||||
--- a/kpatch-build/create-diff-object.c
|
--- a/kpatch-build/create-diff-object.c
|
||||||
+++ b/kpatch-build/create-diff-object.c
|
+++ b/kpatch-build/create-diff-object.c
|
||||||
@@ -2808,6 +2808,9 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
@@ -3039,6 +3039,9 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||||
if (!strcmp(sym_objname, "vmlinux"))
|
if (!strcmp(sym_objname, "vmlinux"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
+ if (!strcmp(sym_objname, pmod_name))
|
+ if (!strcmp(sym_objname, objname))
|
||||||
+ continue;
|
+ continue;
|
||||||
+
|
+
|
||||||
external = 1;
|
external = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
--
|
--
|
||||||
1.7.5.4
|
2.18.1
|
||||||
|
|
||||||
@ -1,8 +1,8 @@
|
|||||||
From 78a13a6091a0d4b1a45fe8f378892a64dece7202 Mon Sep 17 00:00:00 2001
|
From a743990bb6d871fb8cd5ffe6f78ffaa8d5ee7c0a Mon Sep 17 00:00:00 2001
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
Date: Fri, 2 Nov 2018 17:25:38 +0000
|
Date: Fri, 2 Nov 2018 17:25:38 +0000
|
||||||
Subject: [PATCH 1012/1015] create-diff-object: create dynamic relocs for
|
Subject: [PATCH 07/17] create-diff-object: create dynamic relocs for changed
|
||||||
changed functions in this object
|
functions in this object
|
||||||
|
|
||||||
Currently, we only create dynamic relocs for changed functions of
|
Currently, we only create dynamic relocs for changed functions of
|
||||||
other objects, but not this object. It will cause a problem like:
|
other objects, but not this object. It will cause a problem like:
|
||||||
@ -22,14 +22,14 @@ Signed-off-by: Zhou Chengming <zhouchengming1@huawei.com>
|
|||||||
Signed-off-by: Li Bin <huawei.libin@huawei.com>
|
Signed-off-by: Li Bin <huawei.libin@huawei.com>
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
---
|
---
|
||||||
kpatch-build/create-diff-object.c | 20 ++++++++++++++++----
|
kpatch-build/create-diff-object.c | 20 ++++++++++++++++----
|
||||||
1 files changed, 16 insertions(+), 4 deletions(-)
|
1 file changed, 16 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||||
index b8d3bb4..4fb27da 100644
|
index 18ed1f7..5cdb97b 100644
|
||||||
--- a/kpatch-build/create-diff-object.c
|
--- a/kpatch-build/create-diff-object.c
|
||||||
+++ b/kpatch-build/create-diff-object.c
|
+++ b/kpatch-build/create-diff-object.c
|
||||||
@@ -2684,6 +2684,14 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
@@ -2883,6 +2883,14 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||||
*/
|
*/
|
||||||
if (may_need_dynrela(rela))
|
if (may_need_dynrela(rela))
|
||||||
toc_rela(rela)->need_dynrela = 1;
|
toc_rela(rela)->need_dynrela = 1;
|
||||||
@ -44,7 +44,7 @@ index b8d3bb4..4fb27da 100644
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2765,10 +2773,14 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
@@ -2965,10 +2973,14 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||||
/* An unchanged local symbol */
|
/* An unchanged local symbol */
|
||||||
ret = lookup_local_symbol(table,
|
ret = lookup_local_symbol(table,
|
||||||
rela->sym->name, &result);
|
rela->sym->name, &result);
|
||||||
@ -64,5 +64,5 @@ index b8d3bb4..4fb27da 100644
|
|||||||
else if (vmlinux) {
|
else if (vmlinux) {
|
||||||
/*
|
/*
|
||||||
--
|
--
|
||||||
1.7.5.4
|
2.18.1
|
||||||
|
|
||||||
@ -1,20 +1,20 @@
|
|||||||
From e617351fafaf7504a531fd00a49994653e59a737 Mon Sep 17 00:00:00 2001
|
From b356b59eb0f4c21ae927b036a45e573899a59378 Mon Sep 17 00:00:00 2001
|
||||||
From: Zhiyu Hu <huzhiyu1@huawei.com>
|
From: Zhiyu Hu <huzhiyu1@huawei.com>
|
||||||
Date: Fri, 28 Dec 2018 07:06:38 +0000
|
Date: Fri, 28 Dec 2018 07:06:38 +0000
|
||||||
Subject: [PATCH] fix rodata.str problem
|
Subject: [PATCH 08/17] fix rodata.str problem
|
||||||
|
|
||||||
fix some rodata.str problem
|
fix some rodata.str problem
|
||||||
|
|
||||||
Signed-off-by: Zhiyu Hu <huzhiyu1@huawei.com>
|
Signed-off-by: Zhiyu Hu <huzhiyu1@huawei.com>
|
||||||
---
|
---
|
||||||
kpatch-build/create-diff-object.c | 2 +-
|
kpatch-build/create-diff-object.c | 2 +-
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||||
index d2e6aee..f075671 100644
|
index 5cdb97b..643ae3e 100644
|
||||||
--- a/kpatch-build/create-diff-object.c
|
--- a/kpatch-build/create-diff-object.c
|
||||||
+++ b/kpatch-build/create-diff-object.c
|
+++ b/kpatch-build/create-diff-object.c
|
||||||
@@ -1552,7 +1552,7 @@ static void kpatch_include_standard_elements(struct kpatch_elf *kelf)
|
@@ -1620,7 +1620,7 @@ static void kpatch_include_standard_elements(struct kpatch_elf *kelf)
|
||||||
!strcmp(sec->name, ".toc") ||
|
!strcmp(sec->name, ".toc") ||
|
||||||
!strcmp(sec->name, ".rodata") ||
|
!strcmp(sec->name, ".rodata") ||
|
||||||
(!strncmp(sec->name, ".rodata.", 8) &&
|
(!strncmp(sec->name, ".rodata.", 8) &&
|
||||||
@ -24,5 +24,5 @@ index d2e6aee..f075671 100644
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
--
|
--
|
||||||
1.8.3.1
|
2.18.1
|
||||||
|
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
From c14444fc4049048abd445462676576cd8b043ea3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
|
Date: Tue, 25 Feb 2020 23:40:37 -0500
|
||||||
|
Subject: [PATCH 09/17] livepatch-patch-hook: don't active patch when insmod
|
||||||
|
|
||||||
|
Don't active patch after loading the patch when
|
||||||
|
DISABLE_AFTER_LOAD is set.
|
||||||
|
|
||||||
|
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
|
---
|
||||||
|
kmod/patch/livepatch-patch-hook.c | 2 ++
|
||||||
|
kpatch-build/kpatch-build | 4 ++++
|
||||||
|
2 files changed, 6 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
||||||
|
index 613d037..163ae1d 100644
|
||||||
|
--- a/kmod/patch/livepatch-patch-hook.c
|
||||||
|
+++ b/kmod/patch/livepatch-patch-hook.c
|
||||||
|
@@ -455,6 +455,7 @@ static int __init patch_init(void)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#if !defined(DISABLE_AFTER_LOAD)
|
||||||
|
ret = klp_enable_patch(lpatch);
|
||||||
|
if (ret) {
|
||||||
|
#ifndef HAVE_SIMPLE_ENABLE
|
||||||
|
@@ -463,6 +464,7 @@ static int __init patch_init(void)
|
||||||
|
patch_free_livepatch(lpatch);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
out:
|
||||||
|
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||||
|
index 17a5e11..894f0ab 100755
|
||||||
|
--- a/kpatch-build/kpatch-build
|
||||||
|
+++ b/kpatch-build/kpatch-build
|
||||||
|
@@ -1053,6 +1053,10 @@ if [[ -n "$KLP_SUPPORT_LOADHOOKS" ]];then
|
||||||
|
export KCPPFLAGS="-DHAVE_LOADHOOKS $KCPPFLAGS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
+if [[ -n "$DISABLE_AFTER_LOAD" ]];then
|
||||||
|
+ export KCPPFLAGS="-DDISABLE_AFTER_LOAD $KCPPFLAGS"
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
echo "Building patch module: $MODNAME.ko"
|
||||||
|
|
||||||
|
if [[ -z "$USERSRCDIR" ]] && [[ "$DISTRO" = ubuntu ]]; then
|
||||||
|
--
|
||||||
|
2.18.1
|
||||||
|
|
||||||
133
0010-kpatch-build-enhance-for-out-of-tree-module.patch
Normal file
133
0010-kpatch-build-enhance-for-out-of-tree-module.patch
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
From a8cf8f9bd90e0e7fde437a59715aa21622fad7b6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
|
Date: Wed, 26 Feb 2020 06:44:06 -0500
|
||||||
|
Subject: [PATCH 10/17] kpatch-build: enhance for out of tree module
|
||||||
|
|
||||||
|
support set USERMODBUILDDIR to build patch for out
|
||||||
|
of tree module.
|
||||||
|
|
||||||
|
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
|
---
|
||||||
|
kpatch-build/kpatch-build | 50 ++++++++++++++++++++++++++++++++-------
|
||||||
|
1 file changed, 42 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||||
|
index 894f0ab..4e38412 100755
|
||||||
|
--- a/kpatch-build/kpatch-build
|
||||||
|
+++ b/kpatch-build/kpatch-build
|
||||||
|
@@ -419,7 +419,11 @@ filter_parent_obj()
|
||||||
|
local dir="${1}"
|
||||||
|
local file="${2}"
|
||||||
|
|
||||||
|
- grep -v "\.mod\.cmd$" | grep -Fv "${dir}/.${file}.cmd"
|
||||||
|
+ grep -v "\.mod\.cmd$" | grep -Fv "${dir}/.${file}.cmd" | while read input; do
|
||||||
|
+ if [ "$(readlink -f $input)" != "$(readlink -f ${dir}/.${file}.cmd)" ];then
|
||||||
|
+ echo $input;
|
||||||
|
+ fi
|
||||||
|
+ done
|
||||||
|
}
|
||||||
|
|
||||||
|
find_parent_obj() {
|
||||||
|
@@ -441,6 +445,11 @@ find_parent_obj() {
|
||||||
|
num="$(find . -name ".*.cmd" -print0 | xargs -0 grep -lw "$grepname" | filter_parent_obj "${pdir}" "${file}" | wc -l)"
|
||||||
|
[[ "$num" -eq 1 ]] && last_deep_find="$(dirname "$parent")"
|
||||||
|
fi
|
||||||
|
+ if [[ "$num" -eq 0 ]]; then
|
||||||
|
+ parent="$(find $USERMODBUILDDIR -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fv "$pdir/.${file}.cmd" | head -n1)"
|
||||||
|
+ num="$(find $USERMODBUILDDIR -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fvc "$pdir/.${file}.cmd")"
|
||||||
|
+ [[ "$num" -eq 1 ]] && last_deep_find="$(dirname "$parent")"
|
||||||
|
+ fi
|
||||||
|
else
|
||||||
|
parent="$(grep -lw "$grepname" "$dir"/.*.cmd | filter_parent_obj "${dir}" "${file}" | head -n1)"
|
||||||
|
num="$(grep -lw "$grepname" "$dir"/.*.cmd | filter_parent_obj "${dir}" "${file}" | wc -l)"
|
||||||
|
@@ -646,6 +655,10 @@ if [[ -n "$SRCRPM" ]]; then
|
||||||
|
ARCHVERSION="${ARCHVERSION#alt-}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
+if [[ -n "$USERMODBUILDDIR" ]]; then
|
||||||
|
+ OOT_MODULE="yes"
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
if [[ -n "$OOT_MODULE" ]] && [[ -z "$USERSRCDIR" ]]; then
|
||||||
|
warn "--oot-module requires --sourcedir"
|
||||||
|
exit 1
|
||||||
|
@@ -663,7 +676,7 @@ if [[ -n "$USERSRCDIR" ]]; then
|
||||||
|
fi
|
||||||
|
SRCDIR="$USERSRCDIR"
|
||||||
|
|
||||||
|
- if [[ -z "$OOT_MODULE" ]]; then
|
||||||
|
+ if [[ -z "$OOT_MODULE" || "$OOT_MODULE" == "yes" ]]; then
|
||||||
|
[[ -z "$VMLINUX" ]] && VMLINUX="$SRCDIR"/vmlinux
|
||||||
|
[[ ! -e "$VMLINUX" ]] && die "can't find vmlinux"
|
||||||
|
|
||||||
|
@@ -685,7 +698,7 @@ if [[ "$ARCHVERSION" =~ - ]]; then
|
||||||
|
fi
|
||||||
|
[[ "$ARCHVERSION" =~ .el7a. ]] && ALT="-alt"
|
||||||
|
|
||||||
|
-[[ -z "$TARGETS" ]] && TARGETS="vmlinux modules"
|
||||||
|
+[[ -z "$OOT_MODULE" ]] && [[ -z "$TARGETS" ]] && TARGETS="vmlinux modules"
|
||||||
|
|
||||||
|
# Don't check external file.
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
@@ -889,7 +902,11 @@ echo "Building original source"
|
||||||
|
unset KPATCH_GCC_TEMPDIR
|
||||||
|
# $TARGETS used as list, no quotes.
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
-CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
||||||
|
+if [[ -z "$USERMODBUILDDIR" ]]; then
|
||||||
|
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
||||||
|
+else
|
||||||
|
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" "-j$CPUS" $USERMODFLAGS $TARGETS 2>&1 | logger || die
|
||||||
|
+fi
|
||||||
|
|
||||||
|
echo "Building patched source"
|
||||||
|
apply_patches
|
||||||
|
@@ -900,9 +917,15 @@ KPATCH_GCC_SRCDIR="$SRCDIR"
|
||||||
|
export KPATCH_GCC_SRCDIR
|
||||||
|
# $TARGETS used as list, no quotes.
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
-CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" \
|
||||||
|
- KBUILD_MODPOST_WARN=1 \
|
||||||
|
- make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
||||||
|
+if [[ -z "$USERMODBUILDDIR" ]]; then
|
||||||
|
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" \
|
||||||
|
+ KBUILD_MODPOST_WARN=1 \
|
||||||
|
+ make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
||||||
|
+else
|
||||||
|
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" \
|
||||||
|
+ KBUILD_MODPOST_WARN=1 \
|
||||||
|
+ make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" "-j$CPUS" $USERMODFLAGS $TARGETS 2>&1 | logger || die
|
||||||
|
+fi
|
||||||
|
|
||||||
|
# source.c:(.section+0xFF): undefined reference to `symbol'
|
||||||
|
grep "undefined reference" "$LOGFILE" | sed -r "s/^.*\`(.*)'$/\\1/" \
|
||||||
|
@@ -922,7 +945,11 @@ fi
|
||||||
|
for i in $(cat "$TEMPDIR/changed_objs")
|
||||||
|
do
|
||||||
|
mkdir -p "$TEMPDIR/patched/$(dirname "$i")" || die
|
||||||
|
- cp -f "$SRCDIR/$i" "$TEMPDIR/patched/$i" || die
|
||||||
|
+ if [ -z "$USERMODBUILDDIR" ];then
|
||||||
|
+ cp -f "$SRCDIR/$i" "$TEMPDIR/patched/$i" || die
|
||||||
|
+ else
|
||||||
|
+ cp -f "$i" "$TEMPDIR/patched/$i" || die
|
||||||
|
+ fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Extracting new and modified ELF sections"
|
||||||
|
@@ -987,6 +1014,13 @@ for i in $FILES; do
|
||||||
|
KOBJFILE_PATH="${TEMPDIR}/module/$KOBJFILE"
|
||||||
|
SYMTAB="${KOBJFILE_PATH}.symtab"
|
||||||
|
SYMVERS_FILE="$SRCDIR/Module.symvers"
|
||||||
|
+
|
||||||
|
+ if [ "$OOT_MODULE" == "yes" ];then
|
||||||
|
+ BUILDDIR="/lib/modules/$ARCHVERSION/build/"
|
||||||
|
+ SYMVERS_FILE="$TEMPDIR/Module.symvers"
|
||||||
|
+ [[ -e $SRCDIR/Module.symvers ]] && cp "$SRCDIR/Module.symvers" "$SYMVERS_FILE"
|
||||||
|
+ awk '{ print $1 "\t" $2 "\t" $3 "\t" $4}' "${BUILDDIR}/Module.symvers" >> "$SYMVERS_FILE"
|
||||||
|
+ fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
readelf -s --wide "$KOBJFILE_PATH" > "$SYMTAB"
|
||||||
|
--
|
||||||
|
2.18.1
|
||||||
|
|
||||||
193
0011-support-c-plus-kernel-module.patch
Normal file
193
0011-support-c-plus-kernel-module.patch
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
From 20de56a8393e6be3b556156124aa4b2139b10733 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
|
Date: Wed, 26 Feb 2020 07:36:59 -0500
|
||||||
|
Subject: [PATCH 11/17] support c plus kernel module
|
||||||
|
|
||||||
|
support GNU_UNIQUE type symbols.
|
||||||
|
support .group section corelation.
|
||||||
|
ignore compile warning for third party modules.
|
||||||
|
|
||||||
|
Signed-off-by: Zhipeng Xie <root@localhost.localdomain>
|
||||||
|
---
|
||||||
|
kpatch-build/create-diff-object.c | 62 ++++++++++++++++++++-----------
|
||||||
|
kpatch-build/kpatch-build | 2 +-
|
||||||
|
kpatch-build/kpatch-elf.c | 8 +++-
|
||||||
|
kpatch-build/kpatch-gcc | 3 +-
|
||||||
|
kpatch-build/lookup.c | 5 ++-
|
||||||
|
5 files changed, 55 insertions(+), 25 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||||
|
index 643ae3e..190753a 100644
|
||||||
|
--- a/kpatch-build/create-diff-object.c
|
||||||
|
+++ b/kpatch-build/create-diff-object.c
|
||||||
|
@@ -454,7 +454,7 @@ static void kpatch_compare_correlated_nonrela_section(struct section *sec)
|
||||||
|
{
|
||||||
|
struct section *sec1 = sec, *sec2 = sec->twin;
|
||||||
|
|
||||||
|
- if (sec1->sh.sh_type != SHT_NOBITS &&
|
||||||
|
+ if (sec1->sh.sh_type != SHT_NOBITS && sec1->sh.sh_type != SHT_GROUP &&
|
||||||
|
memcmp(sec1->data->d_buf, sec2->data->d_buf, sec1->data->d_size))
|
||||||
|
sec->status = CHANGED;
|
||||||
|
else
|
||||||
|
@@ -470,7 +470,7 @@ static void kpatch_compare_correlated_section(struct section *sec)
|
||||||
|
sec1->sh.sh_flags != sec2->sh.sh_flags ||
|
||||||
|
sec1->sh.sh_entsize != sec2->sh.sh_entsize ||
|
||||||
|
(sec1->sh.sh_addralign != sec2->sh.sh_addralign &&
|
||||||
|
- !is_text_section(sec1)))
|
||||||
|
+ !is_text_section(sec1) && strcmp(sec1->name, ".rodata")))
|
||||||
|
DIFF_FATAL("%s section header details differ from %s", sec1->name, sec2->name);
|
||||||
|
|
||||||
|
/* Short circuit for mcount sections, we rebuild regardless */
|
||||||
|
@@ -907,6 +907,33 @@ static void kpatch_correlate_section(struct section *sec1, struct section *sec2)
|
||||||
|
kpatch_correlate_symbol(sec1->sym, sec2->sym);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int kpatch_correlate_group_section(struct list_head *seclist1, struct list_head *seclist2, struct section *sec1, struct section *sec2)
|
||||||
|
+{
|
||||||
|
+ unsigned int *data1, *end1, *data2;
|
||||||
|
+ struct section *isec1, *isec2;
|
||||||
|
+
|
||||||
|
+ if (sec1->data->d_size != sec2->data->d_size)
|
||||||
|
+ return 1;
|
||||||
|
+ data1 = sec1->data->d_buf;
|
||||||
|
+ data2 = sec2->data->d_buf;
|
||||||
|
+ end1 = sec1->data->d_buf + sec1->data->d_size;
|
||||||
|
+ data1++;
|
||||||
|
+ data2++;
|
||||||
|
+ while (data1 < end1) {
|
||||||
|
+ isec1 = find_section_by_index(seclist1, *data1);
|
||||||
|
+ if (!isec1)
|
||||||
|
+ ERROR("group section not found");
|
||||||
|
+ isec2 = find_section_by_index(seclist2, *data2);
|
||||||
|
+ if (!isec2)
|
||||||
|
+ ERROR("group section not found");
|
||||||
|
+ if (strcmp(isec1->name, isec2->name))
|
||||||
|
+ return 1;
|
||||||
|
+ data1++;
|
||||||
|
+ data2++;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void kpatch_correlate_sections(struct list_head *seclist1, struct list_head *seclist2)
|
||||||
|
{
|
||||||
|
struct section *sec1, *sec2;
|
||||||
|
@@ -924,15 +951,19 @@ static void kpatch_correlate_sections(struct list_head *seclist1, struct list_he
|
||||||
|
sec1->secsym))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- /*
|
||||||
|
- * Group sections must match exactly to be correlated.
|
||||||
|
- * Changed group sections are currently not supported.
|
||||||
|
- */
|
||||||
|
+ /* Group section的格式为:
|
||||||
|
+ * flag
|
||||||
|
+ * section index
|
||||||
|
+ * section index
|
||||||
|
+ * ...
|
||||||
|
+ *
|
||||||
|
+ * 当C++代码发生修改时,section index可能会发生变化
|
||||||
|
+ * 这时候我们就比对一下section index所对应的section的
|
||||||
|
+ * name,如果相同,我们就认为这两个group是SAME
|
||||||
|
+ * */
|
||||||
|
+
|
||||||
|
if (sec1->sh.sh_type == SHT_GROUP) {
|
||||||
|
- if (sec1->data->d_size != sec2->data->d_size)
|
||||||
|
- continue;
|
||||||
|
- if (memcmp(sec1->data->d_buf, sec2->data->d_buf,
|
||||||
|
- sec1->data->d_size))
|
||||||
|
+ if(kpatch_correlate_group_section(seclist1, seclist2, sec1, sec2))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1507,17 +1538,6 @@ static void kpatch_verify_patchability(struct kpatch_elf *kelf)
|
||||||
|
errs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (sec->status != SAME && sec->grouped) {
|
||||||
|
- log_normal("changed section %s is part of a section group\n",
|
||||||
|
- sec->name);
|
||||||
|
- errs++;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (sec->sh.sh_type == SHT_GROUP && sec->status == NEW) {
|
||||||
|
- log_normal("new/changed group sections are not supported\n");
|
||||||
|
- errs++;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* ensure we aren't including .data.* or .bss.*
|
||||||
|
* (.data.unlikely and .data.once is ok b/c it only has __warned vars)
|
||||||
|
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||||
|
index 4e38412..4896136 100755
|
||||||
|
--- a/kpatch-build/kpatch-build
|
||||||
|
+++ b/kpatch-build/kpatch-build
|
||||||
|
@@ -1157,7 +1157,7 @@ fi
|
||||||
|
# column containing lines unique to first file.
|
||||||
|
UNDEFINED=$(comm -23 <(sort -u "${TEMPDIR}"/undefined_references) \
|
||||||
|
<(sort -u "${TEMPDIR}"/new_symbols) | tr '\n' ' ')
|
||||||
|
-[[ -n "$UNDEFINED" ]] && die "Undefined symbols: $UNDEFINED"
|
||||||
|
+[[ -z "$USERMODBUILDDIR" ]] && [[ -n "$UNDEFINED" ]] && die "Undefined symbols: $UNDEFINED"
|
||||||
|
|
||||||
|
cp -f "$TEMPDIR/patch/$MODNAME.ko" "$BASE" || die
|
||||||
|
|
||||||
|
diff --git a/kpatch-build/kpatch-elf.c b/kpatch-build/kpatch-elf.c
|
||||||
|
index 1c0e099..debf028 100644
|
||||||
|
--- a/kpatch-build/kpatch-elf.c
|
||||||
|
+++ b/kpatch-build/kpatch-elf.c
|
||||||
|
@@ -708,8 +708,14 @@ void kpatch_reindex_elements(struct kpatch_elf *kelf)
|
||||||
|
unsigned int index;
|
||||||
|
|
||||||
|
index = 1; /* elf write function handles NULL section 0 */
|
||||||
|
- list_for_each_entry(sec, &kelf->sections, list)
|
||||||
|
+ list_for_each_entry(sec, &kelf->sections, list) {
|
||||||
|
sec->index = index++;
|
||||||
|
+ /*
|
||||||
|
+ * since we exclude .group section, we clear SHF_GROUP
|
||||||
|
+ * for every section in case of link error.
|
||||||
|
+ * */
|
||||||
|
+ sec->sh.sh_flags &= (~SHF_GROUP);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
list_for_each_entry(sym, &kelf->symbols, list) {
|
||||||
|
diff --git a/kpatch-build/kpatch-gcc b/kpatch-build/kpatch-gcc
|
||||||
|
index 35d7c1c..6ad6ebc 100755
|
||||||
|
--- a/kpatch-build/kpatch-gcc
|
||||||
|
+++ b/kpatch-build/kpatch-gcc
|
||||||
|
@@ -13,7 +13,8 @@ fi
|
||||||
|
|
||||||
|
declare -a args=("$@")
|
||||||
|
|
||||||
|
-if [[ "$TOOLCHAINCMD" =~ "${ARCH_COMPILE}gcc" ]] ; then
|
||||||
|
+if [[ "$TOOLCHAINCMD" =~ "${ARCH_COMPILE}gcc" ||
|
||||||
|
+ "$TOOLCHAINCMD" =~ "${ARCH_COMPILE}g++" ]] ; then
|
||||||
|
while [ "$#" -gt 0 ]; do
|
||||||
|
if [ "$1" = "-o" ]; then
|
||||||
|
obj="$2"
|
||||||
|
diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c
|
||||||
|
index 8387e8b..4e2fcb9 100644
|
||||||
|
--- a/kpatch-build/lookup.c
|
||||||
|
+++ b/kpatch-build/lookup.c
|
||||||
|
@@ -255,6 +255,8 @@ static void symtab_read(struct lookup_table *table, char *path)
|
||||||
|
table->obj_syms[i].bind = STB_GLOBAL;
|
||||||
|
} else if (!strcmp(bind, "WEAK")) {
|
||||||
|
table->obj_syms[i].bind = STB_WEAK;
|
||||||
|
+ } else if (!strcmp(bind, "UNIQUE")) {
|
||||||
|
+ table->obj_syms[i].bind = STB_GNU_UNIQUE;
|
||||||
|
} else {
|
||||||
|
ERROR("unknown symbol bind %s", bind);
|
||||||
|
}
|
||||||
|
@@ -431,7 +433,8 @@ int lookup_global_symbol(struct lookup_table *table, char *name,
|
||||||
|
|
||||||
|
memset(result, 0, sizeof(*result));
|
||||||
|
for_each_obj_symbol(i, sym, table) {
|
||||||
|
- if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK) &&
|
||||||
|
+ if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK
|
||||||
|
+ || sym->bind == STB_GNU_UNIQUE) &&
|
||||||
|
!strcmp(sym->name, name)) {
|
||||||
|
result->value = sym->value;
|
||||||
|
result->size = sym->size;
|
||||||
|
--
|
||||||
|
2.18.1
|
||||||
|
|
||||||
454
0012-symbol-lookup-enhancement.patch
Normal file
454
0012-symbol-lookup-enhancement.patch
Normal file
@ -0,0 +1,454 @@
|
|||||||
|
From 56ec8b76667fb6c7fbc018a8fe7a77f144232f3f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
|
Date: Wed, 26 Feb 2020 22:03:55 -0500
|
||||||
|
Subject: [PATCH 12/17] symbol lookup enhancement
|
||||||
|
|
||||||
|
For symbols which have same name in one module or have
|
||||||
|
length longger than KSYM_NAME_LEN(128 bytes). we add
|
||||||
|
some work around to lookup another unique symbol and add
|
||||||
|
relative offset to get the actual symbol. This patch
|
||||||
|
depend on a kernel patch to deal with new relocation
|
||||||
|
style.
|
||||||
|
|
||||||
|
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
|
---
|
||||||
|
kmod/patch/kpatch-patch.h | 4 +
|
||||||
|
kpatch-build/create-diff-object.c | 46 ++++++++++-
|
||||||
|
kpatch-build/create-klp-module.c | 25 +++++-
|
||||||
|
kpatch-build/kpatch-build | 12 +++
|
||||||
|
kpatch-build/kpatch-intermediate.h | 2 +
|
||||||
|
kpatch-build/lookup.c | 123 ++++++++++++++++++++++++++++-
|
||||||
|
kpatch-build/lookup.h | 13 +++
|
||||||
|
7 files changed, 217 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/kmod/patch/kpatch-patch.h b/kmod/patch/kpatch-patch.h
|
||||||
|
index 917ea32..7cd6dae 100644
|
||||||
|
--- a/kmod/patch/kpatch-patch.h
|
||||||
|
+++ b/kmod/patch/kpatch-patch.h
|
||||||
|
@@ -30,6 +30,8 @@ struct kpatch_patch_func {
|
||||||
|
unsigned long sympos;
|
||||||
|
char *name;
|
||||||
|
char *objname;
|
||||||
|
+ char *ref_name;
|
||||||
|
+ long ref_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct kpatch_patch_dynrela {
|
||||||
|
@@ -41,6 +43,8 @@ struct kpatch_patch_dynrela {
|
||||||
|
char *objname;
|
||||||
|
int external;
|
||||||
|
int addend;
|
||||||
|
+ char *ref_name;
|
||||||
|
+ long ref_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct kpatch_pre_patch_callback {
|
||||||
|
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||||
|
index 190753a..55db18c 100644
|
||||||
|
--- a/kpatch-build/create-diff-object.c
|
||||||
|
+++ b/kpatch-build/create-diff-object.c
|
||||||
|
@@ -2734,6 +2734,28 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
||||||
|
funcs[index].old_size = result.size;
|
||||||
|
funcs[index].new_size = sym->sym.st_size;
|
||||||
|
funcs[index].sympos = result.pos;
|
||||||
|
+ if (lookup_is_duplicate_symbol(table, sym->name, objname, result.pos)) {
|
||||||
|
+ struct lookup_refsym refsym;
|
||||||
|
+ long offset;
|
||||||
|
+
|
||||||
|
+ if (lookup_ref_symbol_offset(table, sym->name, &refsym, objname, &offset))
|
||||||
|
+ ERROR("unresolvable ambiguity on symbol %s\n", sym->name);
|
||||||
|
+
|
||||||
|
+ funcs[index].ref_offset = offset;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Add a relocation that will populate
|
||||||
|
+ * the funcs[index].ref_name field.
|
||||||
|
+ */
|
||||||
|
+ ALLOC_LINK(rela, &relasec->relas);
|
||||||
|
+ rela->sym = strsym;
|
||||||
|
+ rela->type = absolute_rela_type;
|
||||||
|
+ rela->addend = offset_of_string(&kelf->strings, refsym.name);
|
||||||
|
+ rela->offset = index * sizeof(*funcs) +
|
||||||
|
+ offsetof(struct kpatch_patch_func, ref_name);
|
||||||
|
+
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a relocation that will populate
|
||||||
|
@@ -2753,7 +2775,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
||||||
|
ALLOC_LINK(rela, &relasec->relas);
|
||||||
|
rela->sym = strsym;
|
||||||
|
rela->type = absolute_rela_type;
|
||||||
|
- rela->addend = offset_of_string(&kelf->strings, sym->name);
|
||||||
|
+ rela->addend = offset_of_string(&kelf->strings, strndup(sym->name, KSYM_NAME_LEN-1));
|
||||||
|
rela->offset = index * sizeof(*funcs) +
|
||||||
|
offsetof(struct kpatch_patch_func, name);
|
||||||
|
|
||||||
|
@@ -2872,6 +2894,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||||
|
struct lookup_result result;
|
||||||
|
char *sym_objname;
|
||||||
|
int ret, vmlinux, external;
|
||||||
|
+ long ref_offset;
|
||||||
|
|
||||||
|
vmlinux = !strcmp(objname, "vmlinux");
|
||||||
|
|
||||||
|
@@ -3080,12 +3103,28 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||||
|
log_debug("lookup for %s @ 0x%016lx len %lu\n",
|
||||||
|
rela->sym->name, result.value, result.size);
|
||||||
|
|
||||||
|
+ ref_offset = 0;
|
||||||
|
/* Fill in ksyms[index] */
|
||||||
|
if (vmlinux)
|
||||||
|
ksyms[index].src = result.value;
|
||||||
|
- else
|
||||||
|
+ else {
|
||||||
|
/* for modules, src is discovered at runtime */
|
||||||
|
ksyms[index].src = 0;
|
||||||
|
+ if (lookup_is_duplicate_symbol(table, rela->sym->name, objname, result.pos)) {
|
||||||
|
+ struct lookup_refsym refsym;
|
||||||
|
+
|
||||||
|
+ if (lookup_ref_symbol_offset(table, rela->sym->name, &refsym, objname, &ref_offset))
|
||||||
|
+ ERROR("unresolvable ambiguity on symbol %s\n", rela->sym->name);
|
||||||
|
+
|
||||||
|
+ /* add rela to fill in ref_name field */
|
||||||
|
+ ALLOC_LINK(rela2, &krela_sec->rela->relas);
|
||||||
|
+ rela2->sym = strsym;
|
||||||
|
+ rela2->type = absolute_rela_type;
|
||||||
|
+ rela2->addend = offset_of_string(&kelf->strings, refsym.name);
|
||||||
|
+ rela2->offset = index * sizeof(*krelas) +
|
||||||
|
+ offsetof(struct kpatch_relocation, ref_name);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
ksyms[index].pos = result.pos;
|
||||||
|
ksyms[index].type = rela->sym->type;
|
||||||
|
ksyms[index].bind = rela->sym->bind;
|
||||||
|
@@ -3094,7 +3133,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||||
|
ALLOC_LINK(rela2, &ksym_sec->rela->relas);
|
||||||
|
rela2->sym = strsym;
|
||||||
|
rela2->type = absolute_rela_type;
|
||||||
|
- rela2->addend = offset_of_string(&kelf->strings, rela->sym->name);
|
||||||
|
+ rela2->addend = offset_of_string(&kelf->strings, strndup(rela->sym->name, KSYM_NAME_LEN-1));
|
||||||
|
rela2->offset = index * sizeof(*ksyms) + \
|
||||||
|
offsetof(struct kpatch_symbol, name);
|
||||||
|
|
||||||
|
@@ -3113,6 +3152,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
||||||
|
krelas[index].addend = rela->addend;
|
||||||
|
krelas[index].type = rela->type;
|
||||||
|
krelas[index].external = external;
|
||||||
|
+ krelas[index].ref_offset = ref_offset;
|
||||||
|
|
||||||
|
/* add rela to fill in krelas[index].dest field */
|
||||||
|
ALLOC_LINK(rela2, &krela_sec->rela->relas);
|
||||||
|
diff --git a/kpatch-build/create-klp-module.c b/kpatch-build/create-klp-module.c
|
||||||
|
index d995525..5073a04 100644
|
||||||
|
--- a/kpatch-build/create-klp-module.c
|
||||||
|
+++ b/kpatch-build/create-klp-module.c
|
||||||
|
@@ -38,7 +38,9 @@ enum loglevel loglevel = NORMAL;
|
||||||
|
*/
|
||||||
|
static struct symbol *find_or_add_ksym_to_symbols(struct kpatch_elf *kelf,
|
||||||
|
struct section *ksymsec,
|
||||||
|
- char *strings, int offset)
|
||||||
|
+ char *strings, int offset,
|
||||||
|
+ char *ref_name,
|
||||||
|
+ long ref_offset)
|
||||||
|
{
|
||||||
|
struct kpatch_symbol *ksyms, *ksym;
|
||||||
|
struct symbol *sym;
|
||||||
|
@@ -67,9 +69,14 @@ static struct symbol *find_or_add_ksym_to_symbols(struct kpatch_elf *kelf,
|
||||||
|
|
||||||
|
objname = strings + rela->addend;
|
||||||
|
|
||||||
|
- snprintf(pos, 32, "%lu", ksym->pos);
|
||||||
|
/* .klp.sym.objname.name,pos */
|
||||||
|
- snprintf(buf, 256, KLP_SYM_PREFIX "%s.%s,%s", objname, name, pos);
|
||||||
|
+ if (!ref_name) {
|
||||||
|
+ snprintf(pos, 32, "%lu", ksym->pos);
|
||||||
|
+ snprintf(buf, 256, KLP_SYM_PREFIX "%s.%s,%s", objname, name, pos);
|
||||||
|
+ } else {
|
||||||
|
+ snprintf(pos, 32, "%ld", ref_offset);
|
||||||
|
+ snprintf(buf, 256, KLP_SYM_PREFIX "%s-%s,%s", objname, ref_name, pos);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* Look for an already allocated symbol */
|
||||||
|
list_for_each_entry(sym, &kelf->symbols, list) {
|
||||||
|
@@ -176,6 +183,7 @@ static void create_klp_relasecs_and_syms(struct kpatch_elf *kelf, struct section
|
||||||
|
struct rela *rela;
|
||||||
|
char *objname;
|
||||||
|
int nr, index, offset, dest_off;
|
||||||
|
+ char *ref_name;
|
||||||
|
|
||||||
|
krelas = krelasec->data->d_buf;
|
||||||
|
nr = krelasec->data->d_size / sizeof(*krelas);
|
||||||
|
@@ -200,6 +208,15 @@ static void create_klp_relasecs_and_syms(struct kpatch_elf *kelf, struct section
|
||||||
|
|
||||||
|
objname = strings + rela->addend;
|
||||||
|
|
||||||
|
+ /* Get the unique ref_name */
|
||||||
|
+ rela = find_rela_by_offset(krelasec->rela,
|
||||||
|
+ offset + offsetof(struct kpatch_relocation, ref_name));
|
||||||
|
+ if (!rela)
|
||||||
|
+ ref_name = NULL;
|
||||||
|
+ else {
|
||||||
|
+ ref_name = strings + rela->addend;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Get the .kpatch.symbol entry for the rela src */
|
||||||
|
rela = find_rela_by_offset(krelasec->rela,
|
||||||
|
offset + offsetof(struct kpatch_relocation, ksym));
|
||||||
|
@@ -207,7 +224,7 @@ static void create_klp_relasecs_and_syms(struct kpatch_elf *kelf, struct section
|
||||||
|
ERROR("find_rela_by_offset");
|
||||||
|
|
||||||
|
/* Create (or find) a klp symbol from the rela src entry */
|
||||||
|
- sym = find_or_add_ksym_to_symbols(kelf, ksymsec, strings, rela->addend);
|
||||||
|
+ sym = find_or_add_ksym_to_symbols(kelf, ksymsec, strings, rela->addend, ref_name, krelas[index].ref_offset);
|
||||||
|
if (!sym)
|
||||||
|
ERROR("error finding or adding ksym to symtab");
|
||||||
|
|
||||||
|
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||||
|
index 4896136..8bef7fb 100755
|
||||||
|
--- a/kpatch-build/kpatch-build
|
||||||
|
+++ b/kpatch-build/kpatch-build
|
||||||
|
@@ -1015,6 +1015,18 @@ for i in $FILES; do
|
||||||
|
SYMTAB="${KOBJFILE_PATH}.symtab"
|
||||||
|
SYMVERS_FILE="$SRCDIR/Module.symvers"
|
||||||
|
|
||||||
|
+ unset KCFLAGS
|
||||||
|
+ remove_patches
|
||||||
|
+ cd "$SRCDIR" || die
|
||||||
|
+ if [ -z "$USERMODBUILDDIR" ];then
|
||||||
|
+ CROSS_COMPILE="$ARCH_COMPILE" make "-j$CPUS" ${KOBJFILE} 2>&1 | logger || die
|
||||||
|
+ else
|
||||||
|
+ CROSS_COMPILE="$ARCH_COMPILE" make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" "-j$CPUS" $USERMODFLAGS $TARGETS 2>&1 | logger || die
|
||||||
|
+ fi
|
||||||
|
+ cp ${KOBJFILE} ${KOBJFILE_PATH}
|
||||||
|
+ apply_patches
|
||||||
|
+ cd "$TEMPDIR" || die
|
||||||
|
+
|
||||||
|
if [ "$OOT_MODULE" == "yes" ];then
|
||||||
|
BUILDDIR="/lib/modules/$ARCHVERSION/build/"
|
||||||
|
SYMVERS_FILE="$TEMPDIR/Module.symvers"
|
||||||
|
diff --git a/kpatch-build/kpatch-intermediate.h b/kpatch-build/kpatch-intermediate.h
|
||||||
|
index 3dea775..59deed0 100644
|
||||||
|
--- a/kpatch-build/kpatch-intermediate.h
|
||||||
|
+++ b/kpatch-build/kpatch-intermediate.h
|
||||||
|
@@ -39,6 +39,8 @@ struct kpatch_relocation {
|
||||||
|
int external;
|
||||||
|
char *objname; /* object to which this rela applies to */
|
||||||
|
struct kpatch_symbol *ksym;
|
||||||
|
+ char *ref_name;
|
||||||
|
+ long ref_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct kpatch_arch {
|
||||||
|
diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c
|
||||||
|
index 4e2fcb9..190a7d8 100644
|
||||||
|
--- a/kpatch-build/lookup.c
|
||||||
|
+++ b/kpatch-build/lookup.c
|
||||||
|
@@ -44,6 +44,7 @@ struct object_symbol {
|
||||||
|
unsigned long size;
|
||||||
|
char *name;
|
||||||
|
int type, bind;
|
||||||
|
+ int sec_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct export_symbol {
|
||||||
|
@@ -248,6 +249,7 @@ static void symtab_read(struct lookup_table *table, char *path)
|
||||||
|
|
||||||
|
table->obj_syms[i].value = value;
|
||||||
|
table->obj_syms[i].size = strtoul(size, NULL, 0);
|
||||||
|
+ table->obj_syms[i].sec_index = atoi(ndx);
|
||||||
|
|
||||||
|
if (!strcmp(bind, "LOCAL")) {
|
||||||
|
table->obj_syms[i].bind = STB_LOCAL;
|
||||||
|
@@ -398,6 +400,15 @@ int lookup_local_symbol(struct lookup_table *table, char *name,
|
||||||
|
for_each_obj_symbol(i, sym, table) {
|
||||||
|
if (sym->bind == STB_LOCAL && !strcmp(sym->name, name))
|
||||||
|
pos++;
|
||||||
|
+ else {
|
||||||
|
+ /* symbol name longer than KSYM_NAME_LEN will be truncated
|
||||||
|
+ * by kernel, so we can not find it using its original
|
||||||
|
+ * name. we need to add pos for symbols which have same
|
||||||
|
+ * KSYM_NAME_LEN-1 long prefix.*/
|
||||||
|
+ if (strlen(name) >= KSYM_NAME_LEN-1 &&
|
||||||
|
+ !strncmp(sym->name, name, KSYM_NAME_LEN-1))
|
||||||
|
+ pos++;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (table->local_syms == sym) {
|
||||||
|
in_file = 1;
|
||||||
|
@@ -429,16 +440,25 @@ int lookup_global_symbol(struct lookup_table *table, char *name,
|
||||||
|
struct lookup_result *result)
|
||||||
|
{
|
||||||
|
struct object_symbol *sym;
|
||||||
|
+ unsigned long pos = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset(result, 0, sizeof(*result));
|
||||||
|
for_each_obj_symbol(i, sym, table) {
|
||||||
|
+ /* symbol name longer than KSYM_NAME_LEN will be truncated
|
||||||
|
+ * by kernel, so we can not find it using its original
|
||||||
|
+ * name. we need to add pos for symbols which have same
|
||||||
|
+ * KSYM_NAME_LEN-1 long prefix.*/
|
||||||
|
+ if (strlen(name) >= KSYM_NAME_LEN-1 &&
|
||||||
|
+ !strncmp(sym->name, name, KSYM_NAME_LEN-1))
|
||||||
|
+ pos++;
|
||||||
|
+
|
||||||
|
if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK
|
||||||
|
|| sym->bind == STB_GNU_UNIQUE) &&
|
||||||
|
!strcmp(sym->name, name)) {
|
||||||
|
result->value = sym->value;
|
||||||
|
result->size = sym->size;
|
||||||
|
- result->pos = 0; /* always 0 for global symbols */
|
||||||
|
+ result->pos = pos;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -485,6 +505,107 @@ char *lookup_exported_symbol_objname(struct lookup_table *table, char *name)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int lookup_is_duplicate_symbol(struct lookup_table *table, char *name,
|
||||||
|
+ char *objname, unsigned long pos)
|
||||||
|
+{
|
||||||
|
+ struct object_symbol *sym;
|
||||||
|
+ int i, count = 0;
|
||||||
|
+ char posstr[32], buf[256];
|
||||||
|
+
|
||||||
|
+ for_each_obj_symbol(i, sym, table)
|
||||||
|
+ if (!strcmp(sym->name, name)) {
|
||||||
|
+ count++;
|
||||||
|
+ if (count > 1)
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* symbol name longer than KSYM_NAME_LEN will be truncated
|
||||||
|
+ * by kernel, so we can not find it using its original
|
||||||
|
+ * name. Here, we consider these long name symbol as duplicated
|
||||||
|
+ * symbols. since create_klp_module will create symbol name
|
||||||
|
+ * format like .klp.sym.objname.symbol,pos, so we consider name
|
||||||
|
+ * length longer than KSYM_NAME_LEN-1 bytes as duplicated symbol*/
|
||||||
|
+ snprintf(posstr, 32, "%lu", pos);
|
||||||
|
+ snprintf(buf, 256, KLP_SYM_PREFIX "%s.%s,%s", objname, name, posstr);
|
||||||
|
+ if (strlen(buf) >= KSYM_NAME_LEN-1)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct object_symbol *lookup_find_symbol_by_name(struct lookup_table *table, char *name)
|
||||||
|
+{
|
||||||
|
+ struct object_symbol *sym;
|
||||||
|
+ unsigned long pos = 0;
|
||||||
|
+ int i, match = 0, in_file = 0;
|
||||||
|
+
|
||||||
|
+ if (!table->local_syms)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ for_each_obj_symbol(i, sym, table) {
|
||||||
|
+ if (sym->bind == STB_LOCAL && !strcmp(sym->name, name))
|
||||||
|
+ pos++;
|
||||||
|
+
|
||||||
|
+ if (table->local_syms == sym) {
|
||||||
|
+ in_file = 1;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!in_file)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (sym->type == STT_FILE)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ if (sym->bind == STB_LOCAL && !strcmp(sym->name, name)) {
|
||||||
|
+ match = 1;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!match) {
|
||||||
|
+ for_each_obj_symbol(i, sym, table) {
|
||||||
|
+ if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK) &&
|
||||||
|
+ !strcmp(sym->name, name)) {
|
||||||
|
+ return sym;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return sym;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int lookup_ref_symbol_offset(struct lookup_table *table, char *name,
|
||||||
|
+ struct lookup_refsym *refsym,
|
||||||
|
+ char *objname, long *offset)
|
||||||
|
+{
|
||||||
|
+ struct object_symbol *orig_sym, *sym;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ orig_sym = lookup_find_symbol_by_name(table, name);
|
||||||
|
+ if (!orig_sym)
|
||||||
|
+ ERROR("lookup_ref_symbol_offset");
|
||||||
|
+ memset(refsym, 0, sizeof(*refsym));
|
||||||
|
+
|
||||||
|
+ /*find a unique symbol in the same section first*/
|
||||||
|
+ for_each_obj_symbol(i, sym, table) {
|
||||||
|
+ if (!strcmp(sym->name, name) || sym->type == STT_FILE ||
|
||||||
|
+ sym->sec_index != orig_sym->sec_index ||
|
||||||
|
+ strchr(sym->name, '.'))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (!lookup_is_duplicate_symbol(table, sym->name, objname, 1)) {
|
||||||
|
+ refsym->name = sym->name;
|
||||||
|
+ refsym->value = sym->value;
|
||||||
|
+ *offset = (long)orig_sym->value - (long)sym->value;
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#if 0 /* for local testing */
|
||||||
|
static void find_this(struct lookup_table *table, char *sym, char *hint)
|
||||||
|
{
|
||||||
|
diff --git a/kpatch-build/lookup.h b/kpatch-build/lookup.h
|
||||||
|
index 420d0f0..fed3fe9 100644
|
||||||
|
--- a/kpatch-build/lookup.h
|
||||||
|
+++ b/kpatch-build/lookup.h
|
||||||
|
@@ -1,6 +1,9 @@
|
||||||
|
#ifndef _LOOKUP_H_
|
||||||
|
#define _LOOKUP_H_
|
||||||
|
|
||||||
|
+#include "kpatch-elf.h"
|
||||||
|
+#define KSYM_NAME_LEN 128
|
||||||
|
+
|
||||||
|
struct lookup_table;
|
||||||
|
|
||||||
|
struct lookup_result {
|
||||||
|
@@ -14,6 +17,11 @@ struct sym_compare_type {
|
||||||
|
int type;
|
||||||
|
};
|
||||||
|
|
||||||
|
+struct lookup_refsym {
|
||||||
|
+ char *name;
|
||||||
|
+ unsigned long value;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct lookup_table *lookup_open(char *symtab_path, char *symvers_path,
|
||||||
|
char *hint, struct sym_compare_type *locals);
|
||||||
|
void lookup_close(struct lookup_table *table);
|
||||||
|
@@ -23,5 +31,10 @@ int lookup_global_symbol(struct lookup_table *table, char *name,
|
||||||
|
struct lookup_result *result);
|
||||||
|
int lookup_is_exported_symbol(struct lookup_table *table, char *name);
|
||||||
|
char *lookup_exported_symbol_objname(struct lookup_table *table, char *name);
|
||||||
|
+int lookup_is_duplicate_symbol(struct lookup_table *table, char *name,
|
||||||
|
+ char *objname, unsigned long pos);
|
||||||
|
+int lookup_ref_symbol_offset(struct lookup_table *table, char *name,
|
||||||
|
+ struct lookup_refsym *refsym, char *objname,
|
||||||
|
+ long *offset);
|
||||||
|
|
||||||
|
#endif /* _LOOKUP_H_ */
|
||||||
|
--
|
||||||
|
2.18.1
|
||||||
|
|
||||||
171
0013-Add-running-kernel-symbol-table-to-help-symbol-looku.patch
Normal file
171
0013-Add-running-kernel-symbol-table-to-help-symbol-looku.patch
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
From 05051ffc7abcb953fb1ec51b0826b41f160ce191 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
|
Date: Wed, 26 Feb 2020 20:28:13 -0500
|
||||||
|
Subject: [PATCH 13/17] Add running kernel symbol table to help symbol lookup
|
||||||
|
|
||||||
|
For some duplicate symbols whose section have no other
|
||||||
|
symbols, we need running kernel symbol table to help
|
||||||
|
symbol lookup.
|
||||||
|
|
||||||
|
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
|
---
|
||||||
|
kpatch-build/create-diff-object.c | 7 ++-
|
||||||
|
kpatch-build/lookup.c | 73 ++++++++++++++++++++++++++++++-
|
||||||
|
kpatch-build/lookup.h | 3 +-
|
||||||
|
3 files changed, 80 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||||
|
index 55db18c..4589ba4 100644
|
||||||
|
--- a/kpatch-build/create-diff-object.c
|
||||||
|
+++ b/kpatch-build/create-diff-object.c
|
||||||
|
@@ -3564,6 +3564,7 @@ int main(int argc, char *argv[])
|
||||||
|
struct sym_compare_type *base_locals, *sym_comp;
|
||||||
|
char *no_profiling_calls = NULL;
|
||||||
|
char *gcc_add_option = NULL, *mlongcall = NULL;
|
||||||
|
+ char *kallsyms;
|
||||||
|
|
||||||
|
arguments.debug = 0;
|
||||||
|
argp_parse (&argp, argc, argv, 0, NULL, &arguments);
|
||||||
|
@@ -3677,8 +3678,12 @@ int main(int argc, char *argv[])
|
||||||
|
*/
|
||||||
|
kpatch_elf_teardown(kelf_patched);
|
||||||
|
|
||||||
|
+ kallsyms = getenv("KALLSYMS");
|
||||||
|
+ if (kallsyms)
|
||||||
|
+ log_debug("kallsyms file:%s\n", kallsyms);
|
||||||
|
+
|
||||||
|
/* create symbol lookup table */
|
||||||
|
- lookup = lookup_open(parent_symtab, mod_symvers, hint, base_locals);
|
||||||
|
+ lookup = lookup_open(parent_symtab, mod_symvers, hint, base_locals, kallsyms);
|
||||||
|
for (sym_comp = base_locals; sym_comp && sym_comp->name; sym_comp++) {
|
||||||
|
free(sym_comp->name);
|
||||||
|
}
|
||||||
|
diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c
|
||||||
|
index 190a7d8..8f53567 100644
|
||||||
|
--- a/kpatch-build/lookup.c
|
||||||
|
+++ b/kpatch-build/lookup.c
|
||||||
|
@@ -45,6 +45,7 @@ struct object_symbol {
|
||||||
|
char *name;
|
||||||
|
int type, bind;
|
||||||
|
int sec_index;
|
||||||
|
+ unsigned long kaddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct export_symbol {
|
||||||
|
@@ -284,6 +285,56 @@ static void symtab_read(struct lookup_table *table, char *path)
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void ksymtab_read(struct lookup_table *table, char *path)
|
||||||
|
+{
|
||||||
|
+ FILE *file;
|
||||||
|
+ struct object_symbol *sym, *sym1, *sym2;
|
||||||
|
+ unsigned long value;
|
||||||
|
+ int i, j, idx;
|
||||||
|
+ char line[256], name[256], type[256], mod[256];
|
||||||
|
+ idx = 0;
|
||||||
|
+
|
||||||
|
+ if ((file = fopen(path, "r")) == NULL)
|
||||||
|
+ ERROR("fopen");
|
||||||
|
+
|
||||||
|
+ while (fgets(line, 256, file)) {
|
||||||
|
+ if (sscanf(line, "%lx %s %s [%s]\n",
|
||||||
|
+ &value, type, name, mod) != 4)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (name[0] == '$')
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ i = idx;
|
||||||
|
+ for_each_obj_symbol_continue(i, sym, table) {
|
||||||
|
+ if (!strncmp(sym->name, name, KSYM_NAME_LEN-1)) {
|
||||||
|
+ sym->kaddr = value;
|
||||||
|
+ idx = i + 1;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for_each_obj_symbol(i, sym1, table) {
|
||||||
|
+ if (sym1->kaddr == 0)
|
||||||
|
+ continue;
|
||||||
|
+ for_each_obj_symbol(j, sym2, table) {
|
||||||
|
+ if (sym2->kaddr == 0)
|
||||||
|
+ continue;
|
||||||
|
+ if (sym1 == sym2)
|
||||||
|
+ continue;
|
||||||
|
+ if (sym1->sec_index != sym2->sec_index)
|
||||||
|
+ continue;
|
||||||
|
+ if ((long)sym1->value - (long)sym2->value ==
|
||||||
|
+ (long)sym1->kaddr - (long)sym2->kaddr)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ ERROR("base mismatch(symbol offset)");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ fclose(file);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Symvers file format is the following for kernels v5.3 and newer:
|
||||||
|
* <CRC> <Symbol> <Namespace> <Module> <Export Type>
|
||||||
|
@@ -352,7 +403,8 @@ static void symvers_read(struct lookup_table *table, char *path)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct lookup_table *lookup_open(char *symtab_path, char *symvers_path,
|
||||||
|
- char *hint, struct sym_compare_type *locals)
|
||||||
|
+ char *hint, struct sym_compare_type *locals,
|
||||||
|
+ char *kallsyms)
|
||||||
|
{
|
||||||
|
struct lookup_table *table;
|
||||||
|
|
||||||
|
@@ -363,6 +415,8 @@ struct lookup_table *lookup_open(char *symtab_path, char *symvers_path,
|
||||||
|
|
||||||
|
symtab_read(table, symtab_path);
|
||||||
|
symvers_read(table, symvers_path);
|
||||||
|
+ if (kallsyms)
|
||||||
|
+ ksymtab_read(table, kallsyms);
|
||||||
|
find_local_syms(table, hint, locals);
|
||||||
|
|
||||||
|
return table;
|
||||||
|
@@ -603,6 +657,23 @@ int lookup_ref_symbol_offset(struct lookup_table *table, char *name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (orig_sym->kaddr == 0)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ /*find a unique symbol has kaddr*/
|
||||||
|
+ for_each_obj_symbol(i, sym, table) {
|
||||||
|
+ if (!strcmp(sym->name, name) || sym->type == STT_FILE ||
|
||||||
|
+ sym->kaddr == 0 || strchr(sym->name, '.'))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (!lookup_is_duplicate_symbol(table, sym->name, objname, 1)) {
|
||||||
|
+ refsym->name = sym->name;
|
||||||
|
+ refsym->value = 0;
|
||||||
|
+ *offset = (long)orig_sym->kaddr - (long)sym->kaddr;
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/kpatch-build/lookup.h b/kpatch-build/lookup.h
|
||||||
|
index fed3fe9..00b6ccc 100644
|
||||||
|
--- a/kpatch-build/lookup.h
|
||||||
|
+++ b/kpatch-build/lookup.h
|
||||||
|
@@ -23,7 +23,8 @@ struct lookup_refsym {
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lookup_table *lookup_open(char *symtab_path, char *symvers_path,
|
||||||
|
- char *hint, struct sym_compare_type *locals);
|
||||||
|
+ char *hint, struct sym_compare_type *locals,
|
||||||
|
+ char *kallsyms);
|
||||||
|
void lookup_close(struct lookup_table *table);
|
||||||
|
int lookup_local_symbol(struct lookup_table *table, char *name,
|
||||||
|
struct lookup_result *result);
|
||||||
|
--
|
||||||
|
2.18.1
|
||||||
|
|
||||||
@ -1,21 +1,21 @@
|
|||||||
From aaaec2d292b7e1d07c35e07ba92917ee05a4a141 Mon Sep 17 00:00:00 2001
|
From b63c72375420cb098a81167c48d822d596e770a9 Mon Sep 17 00:00:00 2001
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
Date: Fri, 2 Nov 2018 17:25:03 +0000
|
Date: Wed, 26 Feb 2020 20:43:34 -0500
|
||||||
Subject: [PATCH 1008/1015] livepatch-patch-hook: support force enable/disable
|
Subject: [PATCH 14/17] livepatch-patch-hook: support force enable/disable
|
||||||
function
|
|
||||||
|
|
||||||
we use immediate to indicate patch which bypass stack check.
|
we use force to indicate function which bypass stack check
|
||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
---
|
---
|
||||||
kmod/patch/livepatch-patch-hook.c | 11 +++++++++++
|
kmod/patch/livepatch-patch-hook.c | 18 ++++++++++++++++++
|
||||||
1 files changed, 11 insertions(+), 0 deletions(-)
|
kpatch-build/kpatch-build | 4 ++++
|
||||||
|
2 files changed, 22 insertions(+)
|
||||||
|
|
||||||
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
||||||
index 2c0cadd..625ffbd 100644
|
index 163ae1d..7e848a7 100644
|
||||||
--- a/kmod/patch/livepatch-patch-hook.c
|
--- a/kmod/patch/livepatch-patch-hook.c
|
||||||
+++ b/kmod/patch/livepatch-patch-hook.c
|
+++ b/kmod/patch/livepatch-patch-hook.c
|
||||||
@@ -228,6 +228,16 @@ extern struct kpatch_pre_patch_callback __kpatch_callbacks_pre_patch[], __kpatch
|
@@ -238,6 +238,17 @@ extern struct kpatch_pre_patch_callback __kpatch_callbacks_pre_patch[], __kpatch
|
||||||
extern struct kpatch_post_patch_callback __kpatch_callbacks_post_patch[], __kpatch_callbacks_post_patch_end[];
|
extern struct kpatch_post_patch_callback __kpatch_callbacks_post_patch[], __kpatch_callbacks_post_patch_end[];
|
||||||
extern struct kpatch_pre_unpatch_callback __kpatch_callbacks_pre_unpatch[], __kpatch_callbacks_pre_unpatch_end[];
|
extern struct kpatch_pre_unpatch_callback __kpatch_callbacks_pre_unpatch[], __kpatch_callbacks_pre_unpatch_end[];
|
||||||
extern struct kpatch_post_unpatch_callback __kpatch_callbacks_post_unpatch[], __kpatch_callbacks_post_unpatch_end[];
|
extern struct kpatch_post_unpatch_callback __kpatch_callbacks_post_unpatch[], __kpatch_callbacks_post_unpatch_end[];
|
||||||
@ -29,17 +29,39 @@ index 2c0cadd..625ffbd 100644
|
|||||||
+ return 1;
|
+ return 1;
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
|
+
|
||||||
|
|
||||||
#ifdef HAVE_CALLBACKS
|
#ifdef HAVE_CALLBACKS
|
||||||
static int add_callbacks_to_patch_objects(void)
|
static int add_callbacks_to_patch_objects(void)
|
||||||
@@ -393,6 +403,7 @@ static int __init patch_init(void)
|
@@ -403,6 +414,13 @@ static int __init patch_init(void)
|
||||||
lfunc = &lfuncs[j];
|
lfunc = &lfuncs[j];
|
||||||
lfunc->old_name = func->kfunc->name;
|
lfunc->old_name = func->kfunc->name;
|
||||||
lfunc->new_func = (void *)func->kfunc->new_addr;
|
lfunc->new_func = (void *)func->kfunc->new_addr;
|
||||||
+ lfunc->immediate = patch_is_func_forced(lfunc->new_func);
|
+#if defined(__KLP_SUPPORT_FORCE__)
|
||||||
|
+#ifdef __ALL_FORCE__
|
||||||
|
+ lfunc->force = 1;
|
||||||
|
+#else
|
||||||
|
+ lfunc->force = patch_is_func_forced(func->kfunc->new_addr);
|
||||||
|
+#endif
|
||||||
|
+#endif
|
||||||
#ifdef HAVE_SYMPOS
|
#ifdef HAVE_SYMPOS
|
||||||
lfunc->old_sympos = func->kfunc->sympos;
|
lfunc->old_sympos = func->kfunc->sympos;
|
||||||
#else
|
#else
|
||||||
|
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||||
|
index 8bef7fb..57487b1 100755
|
||||||
|
--- a/kpatch-build/kpatch-build
|
||||||
|
+++ b/kpatch-build/kpatch-build
|
||||||
|
@@ -1079,6 +1079,10 @@ if "$KPATCH_MODULE"; then
|
||||||
|
export KCPPFLAGS="-D__KPATCH_MODULE__"
|
||||||
|
fi
|
||||||
|
|
||||||
|
+if [[ -n "$NO_STACK_CHECK" ]];then
|
||||||
|
+ export KCPPFLAGS="-D__ALL_FORCE__ $KCPPFLAGS"
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
if [[ -n "$KLP_SUPPORT_FORCE" ]];then
|
||||||
|
export KCPPFLAGS="-D__KLP_SUPPORT_FORCE__ $KCPPFLAGS"
|
||||||
|
fi
|
||||||
--
|
--
|
||||||
1.7.5.4
|
2.18.1
|
||||||
|
|
||||||
64
0015-kpatch-build-ignore-debuginfo-in-patch.patch
Normal file
64
0015-kpatch-build-ignore-debuginfo-in-patch.patch
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
From 720769ca54d446baf9cbc986fd2a8832da45ce71 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
|
Date: Wed, 26 Feb 2020 21:01:02 -0500
|
||||||
|
Subject: [PATCH 15/17] kpatch-build: ignore debuginfo in patch
|
||||||
|
|
||||||
|
Just ignore all .debug_* sections
|
||||||
|
|
||||||
|
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
|
---
|
||||||
|
kpatch-build/create-diff-object.c | 18 ++++++++++++++++++
|
||||||
|
kpatch-build/kpatch-build | 1 +
|
||||||
|
2 files changed, 19 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||||
|
index 4589ba4..c466eb0 100644
|
||||||
|
--- a/kpatch-build/create-diff-object.c
|
||||||
|
+++ b/kpatch-build/create-diff-object.c
|
||||||
|
@@ -2396,6 +2396,23 @@ static void kpatch_include_debug_sections(struct kpatch_elf *kelf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void kpatch_ignore_debug_sections(struct kpatch_elf *kelf)
|
||||||
|
+{
|
||||||
|
+ struct section *sec;
|
||||||
|
+
|
||||||
|
+ /* include all .debug_* sections */
|
||||||
|
+ list_for_each_entry(sec, &kelf->sections, list) {
|
||||||
|
+ if (is_debug_section(sec)) {
|
||||||
|
+ sec->include = 0;
|
||||||
|
+ sec->status = SAME;
|
||||||
|
+ if (!is_rela_section(sec)) {
|
||||||
|
+ sec->secsym->include = 0;
|
||||||
|
+ sec->secsym->status = SAME;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void kpatch_mark_ignored_sections(struct kpatch_elf *kelf)
|
||||||
|
{
|
||||||
|
struct section *sec, *strsec, *ignoresec;
|
||||||
|
@@ -3645,6 +3662,7 @@ int main(int argc, char *argv[])
|
||||||
|
kpatch_include_standard_elements(kelf_patched);
|
||||||
|
num_changed = kpatch_include_changed_functions(kelf_patched);
|
||||||
|
kpatch_include_debug_sections(kelf_patched);
|
||||||
|
+ kpatch_ignore_debug_sections(kelf_patched);
|
||||||
|
callbacks_exist = kpatch_include_callback_elements(kelf_patched);
|
||||||
|
kpatch_include_force_elements(kelf_patched);
|
||||||
|
new_globals_exist = kpatch_include_new_globals(kelf_patched);
|
||||||
|
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||||
|
index 57487b1..c109ee3 100755
|
||||||
|
--- a/kpatch-build/kpatch-build
|
||||||
|
+++ b/kpatch-build/kpatch-build
|
||||||
|
@@ -1143,6 +1143,7 @@ KBUILD_EXTRA_SYMBOLS="$KBUILD_EXTRA_SYMBOLS" \
|
||||||
|
KPATCH_LDFLAGS="$KPATCH_LDFLAGS" \
|
||||||
|
CROSS_COMPILE="$ARCH_COMPILE" \
|
||||||
|
make 2>&1 | logger || die
|
||||||
|
+${ARCH_COMPILE}strip -g "$TEMPDIR/patch/$MODNAME.ko"
|
||||||
|
|
||||||
|
if ! "$KPATCH_MODULE"; then
|
||||||
|
if [[ -z "$KPATCH_LDFLAGS" ]]; then
|
||||||
|
--
|
||||||
|
2.18.1
|
||||||
|
|
||||||
@ -1,17 +1,17 @@
|
|||||||
From d6304fcd36edd4e9df48687517f30965d9a790e9 Mon Sep 17 00:00:00 2001
|
From dd03a70462783a9e8426ff76e42c41a7eaab644f Mon Sep 17 00:00:00 2001
|
||||||
From: Bin Yang <robin.yb@huawei.com>
|
From: Bin Yang <robin.yb@huawei.com>
|
||||||
Date: Tue, 16 Jul 2019 14:39:27 +0800
|
Date: Tue, 16 Jul 2019 14:39:27 +0800
|
||||||
Subject: [PATCH] add object in kpatch
|
Subject: [PATCH 16/17] add object in kpatch
|
||||||
|
|
||||||
---
|
---
|
||||||
kpatch-build/kpatch-build | 3 +++
|
kpatch-build/kpatch-build | 3 +++
|
||||||
1 file changed, 3 insertions(+)
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
||||||
index 59af250..f685654 100644
|
index c109ee3..de448dc 100755
|
||||||
--- a/kpatch-build/kpatch-build
|
--- a/kpatch-build/kpatch-build
|
||||||
+++ b/kpatch-build/kpatch-build
|
+++ b/kpatch-build/kpatch-build
|
||||||
@@ -1011,6 +1011,8 @@ echo -n "Patched objects:"
|
@@ -1071,6 +1071,8 @@ echo -n "Patched objects:"
|
||||||
for i in $(echo "${objnames[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')
|
for i in $(echo "${objnames[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')
|
||||||
do
|
do
|
||||||
echo -n " $i"
|
echo -n " $i"
|
||||||
@ -20,8 +20,8 @@ index 59af250..f685654 100644
|
|||||||
done
|
done
|
||||||
echo
|
echo
|
||||||
|
|
||||||
@@ -1113,6 +1115,7 @@ UNDEFINED=$(comm -23 <(sort -u "${TEMPDIR}"/undefined_references) \
|
@@ -1177,6 +1179,7 @@ UNDEFINED=$(comm -23 <(sort -u "${TEMPDIR}"/undefined_references) \
|
||||||
[[ -z "$USERMODDIR" ]] && [[ ! -z "$UNDEFINED" ]] && die "Undefined symbols: $UNDEFINED"
|
[[ -z "$USERMODBUILDDIR" ]] && [[ -n "$UNDEFINED" ]] && die "Undefined symbols: $UNDEFINED"
|
||||||
|
|
||||||
cp -f "$TEMPDIR/patch/$MODNAME.ko" "$BASE" || die
|
cp -f "$TEMPDIR/patch/$MODNAME.ko" "$BASE" || die
|
||||||
+cp -f "$TEMPDIR/patch/object" "$BASE" || die
|
+cp -f "$TEMPDIR/patch/object" "$BASE" || die
|
||||||
@ -29,5 +29,5 @@ index 59af250..f685654 100644
|
|||||||
[[ "$DEBUG" -eq 0 ]] && rm -f "$LOGFILE"
|
[[ "$DEBUG" -eq 0 ]] && rm -f "$LOGFILE"
|
||||||
|
|
||||||
--
|
--
|
||||||
2.17.1
|
2.18.1
|
||||||
|
|
||||||
42
0017-create-diff-object-fix-.orc_unwind_ip-error.patch
Normal file
42
0017-create-diff-object-fix-.orc_unwind_ip-error.patch
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
From 96e3ca2fbed32589510c800e9efe31bab2f5e58a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||||
|
Date: Thu, 27 Feb 2020 15:36:55 -0500
|
||||||
|
Subject: [PATCH 17/17] create-diff-object: fix .orc_unwind_ip error
|
||||||
|
|
||||||
|
error: .orc_unwind_ip section header details
|
||||||
|
differ from .orc_unwind_ip
|
||||||
|
|
||||||
|
Don't correlate .orc_unwind sections and symbols
|
||||||
|
|
||||||
|
Signed-off-by: root <root@localhost.localdomain>
|
||||||
|
---
|
||||||
|
kpatch-build/create-diff-object.c | 6 ++++++
|
||||||
|
1 file changed, 6 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
||||||
|
index c466eb0..320b239 100644
|
||||||
|
--- a/kpatch-build/create-diff-object.c
|
||||||
|
+++ b/kpatch-build/create-diff-object.c
|
||||||
|
@@ -967,6 +967,9 @@ static void kpatch_correlate_sections(struct list_head *seclist1, struct list_he
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (strstr(sec1->name, ".orc_unwind"))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
kpatch_correlate_section(sec1, sec2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -1012,6 +1015,9 @@ static void kpatch_correlate_symbols(struct list_head *symlist1, struct list_hea
|
||||||
|
sym1->sec->twin != sym2->sec)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
+ if (strstr(sym1->name, ".orc_unwind"))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
kpatch_correlate_symbol(sym1, sym2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.18.1
|
||||||
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
From ee167e43252bdb9e84cbefcd8b6fe767c9dc768f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
Date: Fri, 2 Nov 2018 17:24:15 +0000
|
|
||||||
Subject: [PATCH 1001/1015] livepatch-patch-hook: don't active patch when
|
|
||||||
insmod
|
|
||||||
|
|
||||||
we want to active patch after loading the patch.
|
|
||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
---
|
|
||||||
kmod/patch/livepatch-patch-hook.c | 7 -------
|
|
||||||
1 files changed, 0 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
|
||||||
index 7a587a3..e59a377 100644
|
|
||||||
--- a/kmod/patch/livepatch-patch-hook.c
|
|
||||||
+++ b/kmod/patch/livepatch-patch-hook.c
|
|
||||||
@@ -443,13 +443,6 @@ static int __init patch_init(void)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
- ret = klp_enable_patch(lpatch);
|
|
||||||
- if (ret) {
|
|
||||||
- WARN_ON(klp_unregister_patch(lpatch));
|
|
||||||
- patch_free_livepatch(lpatch);
|
|
||||||
- return ret;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
return 0;
|
|
||||||
out:
|
|
||||||
patch_free_livepatch(lpatch);
|
|
||||||
--
|
|
||||||
1.7.5.4
|
|
||||||
|
|
||||||
@ -1,208 +0,0 @@
|
|||||||
From c27f1093cd47c48e2f403c4ffb29bf066ce0bea5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
Date: Fri, 2 Nov 2018 17:24:24 +0000
|
|
||||||
Subject: [PATCH 1002/1015] kpatch-build: support third party module make
|
|
||||||
hotpatch
|
|
||||||
|
|
||||||
support out of tree module to make hotpatch.
|
|
||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
---
|
|
||||||
kpatch-build/kpatch-build | 76 ++++++++++++++++++++++++++++++++++++---------
|
|
||||||
kpatch-build/kpatch-gcc | 5 +++
|
|
||||||
2 files changed, 66 insertions(+), 15 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
|
||||||
index a76913f..ccef86d 100755
|
|
||||||
--- a/kpatch-build/kpatch-build
|
|
||||||
+++ b/kpatch-build/kpatch-build
|
|
||||||
@@ -102,7 +102,11 @@ remove_patches() {
|
|
||||||
for (( ; APPLIED_PATCHES>0; APPLIED_PATCHES-- )); do
|
|
||||||
idx=$(( APPLIED_PATCHES - 1))
|
|
||||||
patch="${PATCH_LIST[$idx]}"
|
|
||||||
- patch -p1 -R -d "$SRCDIR" < "$patch" &> /dev/null
|
|
||||||
+ if [ -n "$USERMODDIR" ];then
|
|
||||||
+ patch -p1 -R -d "$USERMODDIR" < "$patch" &> /dev/null
|
|
||||||
+ else
|
|
||||||
+ patch -p1 -R -d "$SRCDIR" < "$patch" &> /dev/null
|
|
||||||
+ fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# If $SRCDIR was a git repo, make sure git actually sees that
|
|
||||||
@@ -318,8 +322,8 @@ find_parent_obj() {
|
|
||||||
num="$(grep -l "$grepname" "$last_deep_find"/.*.cmd | grep -Fvc "$pdir/.${file}.cmd")"
|
|
||||||
fi
|
|
||||||
if [[ "$num" -eq 0 ]]; then
|
|
||||||
- parent="$(find ./* -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fv "$pdir/.${file}.cmd" | cut -c3- | head -n1)"
|
|
||||||
- num="$(find ./* -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fvc "$pdir/.${file}.cmd")"
|
|
||||||
+ parent="$(find . -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fv "$pdir/.${file}.cmd" | cut -c3- | head -n1)"
|
|
||||||
+ num="$(find . -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fvc "$pdir/.${file}.cmd")"
|
|
||||||
[[ "$num" -eq 1 ]] && last_deep_find="$(dirname "$parent")"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
@@ -335,6 +339,9 @@ find_parent_obj() {
|
|
||||||
PARENT="${PARENT#.}"
|
|
||||||
PARENT="${PARENT%.cmd}"
|
|
||||||
PARENT="$dir/$PARENT"
|
|
||||||
+ if [ -n "$USERMODDIR" ];then
|
|
||||||
+ PARENT="$(readlink -f "$PARENT")"
|
|
||||||
+ fi
|
|
||||||
[[ ! -e "$PARENT" ]] && die "ERROR: can't find parent $PARENT for $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -397,7 +404,7 @@ usage() {
|
|
||||||
echo " (not recommended)" >&2
|
|
||||||
}
|
|
||||||
|
|
||||||
-options="$(getopt -o ha:r:s:c:v:j:t:n:o:d -l "help,archversion:,sourcerpm:,sourcedir:,config:,vmlinux:,jobs:,target:,name:,output:,debug,skip-gcc-check,skip-cleanup" -- "$@")" || die "getopt failed"
|
|
||||||
+options="$(getopt -o ha:r:s:c:v:j:t:n:o:dm:b: -l "help,archversion:,sourcerpm:,sourcedir:,config:,vmlinux:,jobs:,target:,name:,output:,debug,skip-gcc-check,skip-cleanup,moduledir,builddir" -- "$@")" || die "getopt failed"
|
|
||||||
|
|
||||||
eval set -- "$options"
|
|
||||||
|
|
||||||
@@ -463,6 +470,16 @@ while [[ $# -gt 0 ]]; do
|
|
||||||
echo "WARNING: Skipping gcc version matching check (not recommended)"
|
|
||||||
SKIPGCCCHECK=1
|
|
||||||
;;
|
|
||||||
+ -m|--moduledir)
|
|
||||||
+ USERMODDIR=$(readlink -f "$2")
|
|
||||||
+ shift
|
|
||||||
+ [[ ! -d "$USERMODDIR" ]] && die "module dir $USERMODDIR not found"
|
|
||||||
+ ;;
|
|
||||||
+ -b|--builddir)
|
|
||||||
+ BUILDDIR=$(readlink -f "$2")
|
|
||||||
+ shift
|
|
||||||
+ [[ ! -d "$BUILDDIR" ]] && die "kernel develop dir $BUILDDIR not found"
|
|
||||||
+ ;;
|
|
||||||
*)
|
|
||||||
[[ "$1" = "--" ]] && shift && continue
|
|
||||||
[[ ! -f "$1" ]] && die "patch file '$1' not found"
|
|
||||||
@@ -528,7 +545,7 @@ if [[ "$ARCHVERSION" =~ - ]]; then
|
|
||||||
fi
|
|
||||||
[[ "$ARCHVERSION" =~ .el7a. ]] && ALT="-alt"
|
|
||||||
|
|
||||||
-[[ -z "$TARGETS" ]] && TARGETS="vmlinux modules"
|
|
||||||
+[[ -z "$USERMODDIR" ]] && [[ -z "$TARGETS" ]] && TARGETS="vmlinux modules"
|
|
||||||
|
|
||||||
# Don't check external file.
|
|
||||||
# shellcheck disable=SC1091
|
|
||||||
@@ -691,7 +708,11 @@ fi
|
|
||||||
grep -q "CONFIG_DEBUG_INFO_SPLIT=y" "$CONFIGFILE" && die "kernel option 'CONFIG_DEBUG_INFO_SPLIT' not supported"
|
|
||||||
|
|
||||||
echo "Testing patch file(s)"
|
|
||||||
-cd "$SRCDIR" || die
|
|
||||||
+if [ -z "$USERMODDIR" ];then
|
|
||||||
+ cd "$SRCDIR" || die
|
|
||||||
+else
|
|
||||||
+ cd $USERMODDIR || die
|
|
||||||
+fi
|
|
||||||
apply_patches
|
|
||||||
remove_patches
|
|
||||||
|
|
||||||
@@ -709,15 +730,23 @@ find_special_section_data
|
|
||||||
if [[ $DEBUG -ge 4 ]]; then
|
|
||||||
export KPATCH_GCC_DEBUG=1
|
|
||||||
fi
|
|
||||||
-
|
|
||||||
-echo "Building original kernel"
|
|
||||||
-./scripts/setlocalversion --save-scmversion || die
|
|
||||||
+if [ -z "$USERMODDIR" ];then
|
|
||||||
+ echo "Building original kernel"
|
|
||||||
+ ./scripts/setlocalversion --save-scmversion || die
|
|
||||||
+else
|
|
||||||
+ echo "Building original module"
|
|
||||||
+fi
|
|
||||||
unset KPATCH_GCC_TEMPDIR
|
|
||||||
# $TARGETS used as list, no quotes.
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
|
||||||
|
|
||||||
-echo "Building patched kernel"
|
|
||||||
+sleep 1
|
|
||||||
+if [ -z "$USERMODDIR" ];then
|
|
||||||
+ echo "Building patched kernel"
|
|
||||||
+else
|
|
||||||
+ echo "Building patched module"
|
|
||||||
+fi
|
|
||||||
apply_patches
|
|
||||||
mkdir -p "$TEMPDIR/orig" "$TEMPDIR/patched"
|
|
||||||
KPATCH_GCC_TEMPDIR="$TEMPDIR"
|
|
||||||
@@ -739,14 +768,22 @@ if [[ ! -e "$TEMPDIR/changed_objs" ]]; then
|
|
||||||
die "no changed objects found"
|
|
||||||
fi
|
|
||||||
|
|
||||||
-grep -q vmlinux "$SRCDIR/Module.symvers" || die "truncated $SRCDIR/Module.symvers file"
|
|
||||||
+SYMVERS="$SRCDIR/Module.symvers"
|
|
||||||
+if [ ! -f "$SYMVERS" -a -n "$BUILDDIR" ];then
|
|
||||||
+ SYMVERS="$BUILDDIR/Module.symvers"
|
|
||||||
+fi
|
|
||||||
+grep -q vmlinux "$SYMVERS" || die "truncated $SYMVERS file"
|
|
||||||
|
|
||||||
# Read as words, no quotes.
|
|
||||||
# shellcheck disable=SC2013
|
|
||||||
for i in $(cat "$TEMPDIR/changed_objs")
|
|
||||||
do
|
|
||||||
mkdir -p "$TEMPDIR/patched/$(dirname "$i")" || die
|
|
||||||
- cp -f "$SRCDIR/$i" "$TEMPDIR/patched/$i" || die
|
|
||||||
+ if [ -z "$USERMODDIR" ];then
|
|
||||||
+ cp -f "$SRCDIR/$i" "$TEMPDIR/patched/$i" || die
|
|
||||||
+ else
|
|
||||||
+ cp -f "$i" "$TEMPDIR/patched/$i" || die
|
|
||||||
+ fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Extracting new and modified ELF sections"
|
|
||||||
@@ -788,7 +825,11 @@ for i in $FILES; do
|
|
||||||
[[ "$i" = usr/initramfs_data.o ]] && continue
|
|
||||||
|
|
||||||
mkdir -p "output/$(dirname "$i")"
|
|
||||||
- cd "$SRCDIR" || die
|
|
||||||
+ if [ -z "$USERMODDIR" ];then
|
|
||||||
+ cd "$SRCDIR" || die
|
|
||||||
+ else
|
|
||||||
+ cd $USERMODDIR || die
|
|
||||||
+ fi
|
|
||||||
find_kobj "$i"
|
|
||||||
cd "$TEMPDIR" || die
|
|
||||||
if [[ -e "orig/$i" ]]; then
|
|
||||||
@@ -808,7 +849,7 @@ for i in $FILES; do
|
|
||||||
# create-diff-object orig.o patched.o parent-name parent-symtab
|
|
||||||
# Module.symvers patch-mod-name output.o
|
|
||||||
"$TOOLSDIR"/create-diff-object "orig/$i" "patched/$i" "$KOBJFILE_NAME" \
|
|
||||||
- "$SYMTAB" "$SRCDIR/Module.symvers" "${MODNAME//-/_}" \
|
|
||||||
+ "$SYMTAB" "$SYMVERS" "${MODNAME//-/_}" \
|
|
||||||
"output/$i" 2>&1 | logger 1
|
|
||||||
check_pipe_status create-diff-object
|
|
||||||
# create-diff-object returns 3 if no functional change is found
|
|
||||||
@@ -871,7 +912,12 @@ fi
|
|
||||||
|
|
||||||
cd "$TEMPDIR/patch" || die
|
|
||||||
|
|
||||||
-KPATCH_BUILD="$SRCDIR" KPATCH_NAME="$MODNAME" \
|
|
||||||
+if [ -z "$BUILDDIR" ];then
|
|
||||||
+ KPATCH_BUILDIR="$SRCDIR"
|
|
||||||
+else
|
|
||||||
+ KPATCH_BUILDIR="$BUILDDIR"
|
|
||||||
+fi
|
|
||||||
+KPATCH_BUILD="$KPATCH_BUILDIR" KPATCH_NAME="$MODNAME" \
|
|
||||||
KBUILD_EXTRA_SYMBOLS="$KBUILD_EXTRA_SYMBOLS" \
|
|
||||||
KPATCH_LDFLAGS="$KPATCH_LDFLAGS" \
|
|
||||||
make 2>&1 | logger || die
|
|
||||||
diff --git a/kpatch-build/kpatch-gcc b/kpatch-build/kpatch-gcc
|
|
||||||
index 2d56da1..21f7e2e 100755
|
|
||||||
--- a/kpatch-build/kpatch-gcc
|
|
||||||
+++ b/kpatch-build/kpatch-gcc
|
|
||||||
@@ -23,6 +23,11 @@ if [[ "$TOOLCHAINCMD" = "gcc" ]] ; then
|
|
||||||
[[ "$obj" = */.tmp_mc_*.o ]] && break;
|
|
||||||
|
|
||||||
[[ "$obj" = */.tmp_*.o ]] && obj="${obj/.tmp_/}"
|
|
||||||
+
|
|
||||||
+ if [[ $obj =~ \/\.[0-9]+\.o ]]; then
|
|
||||||
+ break;
|
|
||||||
+ fi
|
|
||||||
+
|
|
||||||
case "$obj" in
|
|
||||||
*.mod.o|\
|
|
||||||
*built-in.o|\
|
|
||||||
--
|
|
||||||
1.7.5.4
|
|
||||||
|
|
||||||
@ -1,92 +0,0 @@
|
|||||||
From 214de7459555f3f0461cf4127c55f727ccf473d1 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
Date: Fri, 2 Nov 2018 17:24:30 +0000
|
|
||||||
Subject: [PATCH 1003/1015] kpatch-build: support makefile not in third party
|
|
||||||
module source directory
|
|
||||||
|
|
||||||
support makefile not in third party module source directory.
|
|
||||||
for example:
|
|
||||||
testmod/build/Makefile
|
|
||||||
testmod/src/test.c
|
|
||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
---
|
|
||||||
kpatch-build/kpatch-build | 32 +++++++++++++++++++++++++++-----
|
|
||||||
1 files changed, 27 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
|
||||||
index ccef86d..93a0589 100755
|
|
||||||
--- a/kpatch-build/kpatch-build
|
|
||||||
+++ b/kpatch-build/kpatch-build
|
|
||||||
@@ -311,7 +311,10 @@ find_parent_obj() {
|
|
||||||
dir="$(dirname "$1")"
|
|
||||||
absdir="$(readlink -f "$dir")"
|
|
||||||
pwddir="$(readlink -f .)"
|
|
||||||
- pdir="${absdir#$pwddir/}"
|
|
||||||
+ pdir="."
|
|
||||||
+ if [ "$absdir" != "$pwddir" ];then
|
|
||||||
+ pdir="${absdir#$pwddir/}"
|
|
||||||
+ fi
|
|
||||||
file="$(basename "$1")"
|
|
||||||
grepname="${1%.o}"
|
|
||||||
grepname="$grepname\\.o"
|
|
||||||
@@ -326,6 +329,11 @@ find_parent_obj() {
|
|
||||||
num="$(find . -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fvc "$pdir/.${file}.cmd")"
|
|
||||||
[[ "$num" -eq 1 ]] && last_deep_find="$(dirname "$parent")"
|
|
||||||
fi
|
|
||||||
+ if [[ "$num" -eq 0 ]]; then
|
|
||||||
+ parent="$(find $USERMODBUILDDIR -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fv "$pdir/.${file}.cmd" | head -n1)"
|
|
||||||
+ num="$(find $USERMODBUILDDIR -name ".*.cmd" -print0 | xargs -0 grep -l "$grepname" | grep -Fvc "$pdir/.${file}.cmd")"
|
|
||||||
+ [[ "$num" -eq 1 ]] && last_deep_find="$(dirname "$parent")"
|
|
||||||
+ fi
|
|
||||||
else
|
|
||||||
parent="$(grep -l "$grepname" "$dir"/.*.cmd | grep -Fv "$dir/.${file}.cmd" | head -n1)"
|
|
||||||
num="$(grep -l "$grepname" "$dir"/.*.cmd | grep -Fvc "$dir/.${file}.cmd")"
|
|
||||||
@@ -730,16 +738,24 @@ find_special_section_data
|
|
||||||
if [[ $DEBUG -ge 4 ]]; then
|
|
||||||
export KPATCH_GCC_DEBUG=1
|
|
||||||
fi
|
|
||||||
+if [ -z "$USERMODBUILDDIR" ];then
|
|
||||||
+ USERMODBUILDDIR=$USERMODDIR;
|
|
||||||
+fi
|
|
||||||
if [ -z "$USERMODDIR" ];then
|
|
||||||
echo "Building original kernel"
|
|
||||||
./scripts/setlocalversion --save-scmversion || die
|
|
||||||
else
|
|
||||||
echo "Building original module"
|
|
||||||
+ [[ -e $USERMODDIR/Module.symvers ]] && cp -f $USERMODDIR/Module.symvers $TEMPDIR/patch/
|
|
||||||
fi
|
|
||||||
unset KPATCH_GCC_TEMPDIR
|
|
||||||
# $TARGETS used as list, no quotes.
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
-CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
|
||||||
+if [ -z "$USERMODDIR" ];then
|
|
||||||
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
|
||||||
+else
|
|
||||||
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" "-j$CPUS" $USERMODFLAGS $TARGETS 2>&1 | logger || die
|
|
||||||
+fi
|
|
||||||
|
|
||||||
sleep 1
|
|
||||||
if [ -z "$USERMODDIR" ];then
|
|
||||||
@@ -753,9 +769,15 @@ KPATCH_GCC_TEMPDIR="$TEMPDIR"
|
|
||||||
export KPATCH_GCC_TEMPDIR
|
|
||||||
# $TARGETS used as list, no quotes.
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
-CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " \
|
|
||||||
- KBUILD_MODPOST_WARN=1 \
|
|
||||||
- make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
|
||||||
+if [ -z "$USERMODDIR" ];then
|
|
||||||
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " \
|
|
||||||
+ KBUILD_MODPOST_WARN=1 \
|
|
||||||
+ make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
|
||||||
+else
|
|
||||||
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " \
|
|
||||||
+ KBUILD_MODPOST_WARN=1 \
|
|
||||||
+ make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" "-j$CPUS" $USERMODFLAGS $TARGETS 2>&1 | logger || die
|
|
||||||
+fi
|
|
||||||
|
|
||||||
# source.c:(.section+0xFF): undefined reference to `symbol'
|
|
||||||
grep "undefined reference" "$LOGFILE" | sed -r "s/^.*\`(.*)'$/\\1/" \
|
|
||||||
--
|
|
||||||
1.7.5.4
|
|
||||||
|
|
||||||
@ -1,349 +0,0 @@
|
|||||||
From e91d2d2c6778275b16249f7e9d7439018fed70fe Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
Date: Fri, 2 Nov 2018 17:25:08 +0000
|
|
||||||
Subject: [PATCH 1009/1015] kmod/kpatch-build: support build patch for
|
|
||||||
old kernels
|
|
||||||
|
|
||||||
Forward compatible for old kernels
|
|
||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
---
|
|
||||||
kmod/patch/kpatch-macros.h | 48 ++++++++++++++
|
|
||||||
kmod/patch/kpatch-patch.h | 4 +
|
|
||||||
kmod/patch/kpatch.lds.S | 12 ++++
|
|
||||||
kmod/patch/livepatch-patch-hook.c | 124 +++++++++++++++++++++++++++++++++++++
|
|
||||||
kpatch-build/create-diff-object.c | 8 +++
|
|
||||||
5 files changed, 196 insertions(+), 0 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kmod/patch/kpatch-macros.h b/kmod/patch/kpatch-macros.h
|
|
||||||
index a60a267..569a18d 100644
|
|
||||||
--- a/kmod/patch/kpatch-macros.h
|
|
||||||
+++ b/kmod/patch/kpatch-macros.h
|
|
||||||
@@ -133,4 +133,52 @@ struct kpatch_post_unpatch_callback {
|
|
||||||
printk(_fmt, ## __VA_ARGS__); \
|
|
||||||
})
|
|
||||||
|
|
||||||
+typedef void (*kpatch_loadcall_t)(void);
|
|
||||||
+typedef void (*kpatch_unloadcall_t)(void);
|
|
||||||
+
|
|
||||||
+struct kpatch_load {
|
|
||||||
+ kpatch_loadcall_t fn;
|
|
||||||
+ char *objname; /* filled in by create-diff-object */
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+struct kpatch_unload {
|
|
||||||
+ kpatch_unloadcall_t fn;
|
|
||||||
+ char *objname; /* filled in by create-diff-object */
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * KPATCH_LOAD_HOOK macro
|
|
||||||
+ *
|
|
||||||
+ * The first line only ensures that the hook being registered has the required
|
|
||||||
+ * function signature. If not, there is compile error on this line.
|
|
||||||
+ *
|
|
||||||
+ * The section line declares a struct kpatch_load to be allocated in a new
|
|
||||||
+ * .kpatch.hook.load section. This kpatch_load_data symbol is later stripped
|
|
||||||
+ * by create-diff-object so that it can be declared in multiple objects that
|
|
||||||
+ * are later linked together, avoiding global symbol collision. Since multiple
|
|
||||||
+ * hooks can be registered, the .kpatch.hook.load section is a table of struct
|
|
||||||
+ * kpatch_load elements that will be executed in series by the kpatch core
|
|
||||||
+ * module at load time, assuming the kernel object (module) is currently
|
|
||||||
+ * loaded; otherwise, the hook is called when module to be patched is loaded
|
|
||||||
+ * via the module load notifier.
|
|
||||||
+ */
|
|
||||||
+#define KPATCH_LOAD_HOOK(_fn) \
|
|
||||||
+ static inline kpatch_loadcall_t __loadtest(void) { return _fn; } \
|
|
||||||
+ struct kpatch_load kpatch_load_data __section(.kpatch.hooks.load) = { \
|
|
||||||
+ .fn = _fn, \
|
|
||||||
+ .objname = NULL \
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * KPATCH_UNLOAD_HOOK macro
|
|
||||||
+ *
|
|
||||||
+ * Same as LOAD hook with s/load/unload/
|
|
||||||
+ */
|
|
||||||
+#define KPATCH_UNLOAD_HOOK(_fn) \
|
|
||||||
+ static inline kpatch_unloadcall_t __unloadtest(void) { return _fn; } \
|
|
||||||
+ struct kpatch_unload kpatch_unload_data __section(.kpatch.hooks.unload) = { \
|
|
||||||
+ .fn = _fn, \
|
|
||||||
+ .objname = NULL \
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
#endif /* __KPATCH_MACROS_H_ */
|
|
||||||
diff --git a/kmod/patch/kpatch-patch.h b/kmod/patch/kpatch-patch.h
|
|
||||||
index 917ea32..4d47d30 100644
|
|
||||||
--- a/kmod/patch/kpatch-patch.h
|
|
||||||
+++ b/kmod/patch/kpatch-patch.h
|
|
||||||
@@ -59,5 +59,9 @@ struct kpatch_post_unpatch_callback {
|
|
||||||
void (*callback)(void *obj);
|
|
||||||
char *objname;
|
|
||||||
};
|
|
||||||
+struct kpatch_patch_hook {
|
|
||||||
+ void (*hook)(void);
|
|
||||||
+ char *objname;
|
|
||||||
+};
|
|
||||||
|
|
||||||
#endif /* _KPATCH_PATCH_H_ */
|
|
||||||
diff --git a/kmod/patch/kpatch.lds.S b/kmod/patch/kpatch.lds.S
|
|
||||||
index bc5de82..e3c4e97 100644
|
|
||||||
--- a/kmod/patch/kpatch.lds.S
|
|
||||||
+++ b/kmod/patch/kpatch.lds.S
|
|
||||||
@@ -47,4 +47,16 @@ SECTIONS
|
|
||||||
__kpatch_force_funcs_end = . ;
|
|
||||||
QUAD(0);
|
|
||||||
}
|
|
||||||
+ .kpatch.hooks.load : {
|
|
||||||
+ __kpatch_hooks_load = . ;
|
|
||||||
+ *(.kpatch.hooks.load)
|
|
||||||
+ __kpatch_hooks_load_end = . ;
|
|
||||||
+ QUAD(0);
|
|
||||||
+ }
|
|
||||||
+ .kpatch.hooks.unload : {
|
|
||||||
+ __kpatch_hooks_unload = . ;
|
|
||||||
+ *(.kpatch.hooks.unload)
|
|
||||||
+ __kpatch_hooks_unload_end = . ;
|
|
||||||
+ QUAD(0);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
|
||||||
index 625ffbd..8f7d044 100644
|
|
||||||
--- a/kmod/patch/livepatch-patch-hook.c
|
|
||||||
+++ b/kmod/patch/livepatch-patch-hook.c
|
|
||||||
@@ -64,6 +64,15 @@
|
|
||||||
# define HAVE_CALLBACKS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+#ifdef EULER_RELEASE_CODE
|
|
||||||
+# if EULER_RELEASE_CODE <= EULER_RELEASE_VERSION(2, 3)
|
|
||||||
+# undef HAVE_SYMPOS
|
|
||||||
+# undef HAVE_IMMEDIATE
|
|
||||||
+# undef HAVE_ELF_RELOCS
|
|
||||||
+# define HAVE_LOADHOOKS
|
|
||||||
+# endif
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* There are quite a few similar structures at play in this file:
|
|
||||||
* - livepatch.h structs prefixed with klp_*
|
|
||||||
@@ -95,6 +104,11 @@ struct patch_object {
|
|
||||||
#endif
|
|
||||||
const char *name;
|
|
||||||
int funcs_nr, relocs_nr;
|
|
||||||
+#ifdef HAVE_LOADHOOKS
|
|
||||||
+ struct list_head hooks_load;
|
|
||||||
+ struct list_head hooks_unload;
|
|
||||||
+ int hooks_load_nr, hooks_unload_nr;
|
|
||||||
+#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
struct patch_func {
|
|
||||||
@@ -107,6 +121,13 @@ struct patch_reloc {
|
|
||||||
struct kpatch_patch_dynrela *kdynrela;
|
|
||||||
};
|
|
||||||
|
|
||||||
+#ifdef HAVE_LOADHOOKS
|
|
||||||
+struct patch_hook {
|
|
||||||
+ struct list_head list;
|
|
||||||
+ struct kpatch_patch_hook *khook;
|
|
||||||
+};
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
static struct patch_object *patch_alloc_new_object(const char *name)
|
|
||||||
{
|
|
||||||
struct patch_object *object;
|
|
||||||
@@ -118,6 +139,10 @@ static struct patch_object *patch_alloc_new_object(const char *name)
|
|
||||||
#ifndef HAVE_ELF_RELOCS
|
|
||||||
INIT_LIST_HEAD(&object->relocs);
|
|
||||||
#endif
|
|
||||||
+#ifdef HAVE_LOADHOOKS
|
|
||||||
+ INIT_LIST_HEAD(&object->hooks_load);
|
|
||||||
+ INIT_LIST_HEAD(&object->hooks_unload);
|
|
||||||
+#endif
|
|
||||||
if (strcmp(name, "vmlinux"))
|
|
||||||
object->name = name;
|
|
||||||
list_add(&object->list, &patch_objects);
|
|
||||||
@@ -180,6 +205,37 @@ static int patch_add_reloc_to_object(struct kpatch_patch_dynrela *kdynrela)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+#ifdef HAVE_LOADHOOKS
|
|
||||||
+static int patch_add_hook_to_object(struct kpatch_patch_hook *khook, bool load)
|
|
||||||
+{
|
|
||||||
+ struct patch_hook *hook;
|
|
||||||
+ struct patch_object *object;
|
|
||||||
+
|
|
||||||
+ hook = kzalloc(sizeof(*hook), GFP_KERNEL);
|
|
||||||
+ if (!hook)
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+ INIT_LIST_HEAD(&hook->list);
|
|
||||||
+ hook->khook = khook;
|
|
||||||
+
|
|
||||||
+ object = patch_find_object_by_name(khook->objname);
|
|
||||||
+ if (!object) {
|
|
||||||
+ kfree(hook);
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (load) {
|
|
||||||
+ list_add(&hook->list, &object->hooks_load);
|
|
||||||
+ object->hooks_load_nr++;
|
|
||||||
+ }
|
|
||||||
+ else {
|
|
||||||
+ list_add(&hook->list, &object->hooks_unload);
|
|
||||||
+ object->hooks_unload_nr++;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
static void patch_free_scaffold(void) {
|
|
||||||
struct patch_func *func, *safefunc;
|
|
||||||
struct patch_object *object, *safeobject;
|
|
||||||
@@ -217,6 +273,12 @@ static void patch_free_livepatch(struct klp_patch *patch)
|
|
||||||
if (object->relocs)
|
|
||||||
kfree(object->relocs);
|
|
||||||
#endif
|
|
||||||
+#ifdef HAVE_LOADHOOKS
|
|
||||||
+ if (object->hooks_load)
|
|
||||||
+ kfree(object->hooks_load);
|
|
||||||
+ if (object->hooks_unload)
|
|
||||||
+ kfree(object->hooks_unload);
|
|
||||||
+#endif
|
|
||||||
}
|
|
||||||
if (patch->objs)
|
|
||||||
kfree(patch->objs);
|
|
||||||
@@ -228,6 +290,10 @@ extern struct kpatch_pre_patch_callback __kpatch_callbacks_pre_patch[], __kpatch
|
|
||||||
extern struct kpatch_post_patch_callback __kpatch_callbacks_post_patch[], __kpatch_callbacks_post_patch_end[];
|
|
||||||
extern struct kpatch_pre_unpatch_callback __kpatch_callbacks_pre_unpatch[], __kpatch_callbacks_pre_unpatch_end[];
|
|
||||||
extern struct kpatch_post_unpatch_callback __kpatch_callbacks_post_unpatch[], __kpatch_callbacks_post_unpatch_end[];
|
|
||||||
+#ifdef HAVE_LOADHOOKS
|
|
||||||
+extern struct kpatch_patch_hook __kpatch_hooks_load[], __kpatch_hooks_load_end[];
|
|
||||||
+extern struct kpatch_patch_hook __kpatch_hooks_unload[], __kpatch_hooks_unload_end[];
|
|
||||||
+#endif
|
|
||||||
extern unsigned long __kpatch_force_funcs[], __kpatch_force_funcs_end[];
|
|
||||||
|
|
||||||
static int patch_is_func_forced(unsigned long addr)
|
|
||||||
@@ -347,6 +413,11 @@ static int __init patch_init(void)
|
|
||||||
struct patch_reloc *reloc;
|
|
||||||
struct klp_reloc *lrelocs, *lreloc;
|
|
||||||
#endif
|
|
||||||
+#ifdef HAVE_LOADHOOKS
|
|
||||||
+ struct patch_hook *hook;
|
|
||||||
+ struct kpatch_patch_hook *khook_load, *khook_unload;
|
|
||||||
+ struct klp_hook *lhooks_load, *lhooks_unload, *lhook;
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
/* organize functions and relocs by object in scaffold */
|
|
||||||
for (kfunc = __kpatch_funcs;
|
|
||||||
@@ -371,6 +442,24 @@ static int __init patch_init(void)
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
+#ifdef HAVE_LOADHOOKS
|
|
||||||
+ for (khook_load = __kpatch_hooks_load;
|
|
||||||
+ khook_load != __kpatch_hooks_load_end;
|
|
||||||
+ khook_load++) {
|
|
||||||
+ ret = patch_add_hook_to_object(khook_load, true);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for (khook_unload = __kpatch_hooks_unload;
|
|
||||||
+ khook_unload != __kpatch_hooks_unload_end;
|
|
||||||
+ khook_unload++) {
|
|
||||||
+ ret = patch_add_hook_to_object(khook_unload, false);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
/* past this point, only possible return code is -ENOMEM */
|
|
||||||
ret = -ENOMEM;
|
|
||||||
|
|
||||||
@@ -403,12 +492,21 @@ static int __init patch_init(void)
|
|
||||||
lfunc = &lfuncs[j];
|
|
||||||
lfunc->old_name = func->kfunc->name;
|
|
||||||
lfunc->new_func = (void *)func->kfunc->new_addr;
|
|
||||||
+#if defined(HAVE_IMMEDIATE)
|
|
||||||
lfunc->immediate = patch_is_func_forced(lfunc->new_func);
|
|
||||||
+#endif
|
|
||||||
#ifdef HAVE_SYMPOS
|
|
||||||
lfunc->old_sympos = func->kfunc->sympos;
|
|
||||||
#else
|
|
||||||
lfunc->old_addr = func->kfunc->old_addr;
|
|
||||||
#endif
|
|
||||||
+#ifdef EULER_RELEASE_CODE
|
|
||||||
+# if EULER_RELEASE_CODE <= EULER_RELEASE_VERSION(2, 3)
|
|
||||||
+ lfunc->old_size = func->kfunc->old_size;
|
|
||||||
+ lfunc->new_size = func->kfunc->new_size;
|
|
||||||
+ lfunc->force = patch_is_func_forced(func->kfunc->new_addr);
|
|
||||||
+# endif
|
|
||||||
+#endif
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -439,6 +537,32 @@ static int __init patch_init(void)
|
|
||||||
lobject->callbacks = object->callbacks;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+#ifdef HAVE_LOADHOOKS
|
|
||||||
+ lhooks_load = kzalloc(sizeof(struct klp_hook) *
|
|
||||||
+ (object->hooks_load_nr+1), GFP_KERNEL);
|
|
||||||
+ if (!lhooks_load)
|
|
||||||
+ goto out;
|
|
||||||
+ lobject->hooks_load = lhooks_load;
|
|
||||||
+ j = 0;
|
|
||||||
+ list_for_each_entry(hook, &object->hooks_load, list) {
|
|
||||||
+ lhook = &lhooks_load[j];
|
|
||||||
+ lhook->hook = hook->khook->hook;
|
|
||||||
+ j++;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ lhooks_unload = kzalloc(sizeof(struct klp_hook) *
|
|
||||||
+ (object->hooks_unload_nr+1), GFP_KERNEL);
|
|
||||||
+ if (!lhooks_unload)
|
|
||||||
+ goto out;
|
|
||||||
+ lobject->hooks_unload = lhooks_unload;
|
|
||||||
+ j = 0;
|
|
||||||
+ list_for_each_entry(hook, &object->hooks_unload, list) {
|
|
||||||
+ lhook = &lhooks_unload[j];
|
|
||||||
+ lhook->hook = hook->khook->hook;
|
|
||||||
+ j++;
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
|
||||||
index 349e483..ed96758 100644
|
|
||||||
--- a/kpatch-build/create-diff-object.c
|
|
||||||
+++ b/kpatch-build/create-diff-object.c
|
|
||||||
@@ -1463,6 +1463,10 @@ static int kpatch_include_callback_elements(struct kpatch_elf *kelf)
|
|
||||||
".rela.kpatch.callbacks.post_patch",
|
|
||||||
".rela.kpatch.callbacks.pre_unpatch",
|
|
||||||
".rela.kpatch.callbacks.post_unpatch",
|
|
||||||
+ ".kpatch.hooks.load",
|
|
||||||
+ ".kpatch.hooks.unload",
|
|
||||||
+ ".rela.kpatch.hooks.load",
|
|
||||||
+ ".rela.kpatch.hooks.unload",
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
char **callback_section;
|
|
||||||
@@ -2921,6 +2925,10 @@ static void kpatch_create_callbacks_objname_rela(struct kpatch_elf *kelf, char *
|
|
||||||
.offset = offsetof(struct kpatch_pre_unpatch_callback, objname) },
|
|
||||||
{ .name = ".rela.kpatch.callbacks.post_unpatch",
|
|
||||||
.offset = offsetof(struct kpatch_post_patch_callback, objname) },
|
|
||||||
+ { .name = ".rela.kpatch.hooks.load",
|
|
||||||
+ .offset = offsetof(struct kpatch_patch_hook, objname) },
|
|
||||||
+ { .name = ".rela.kpatch.hooks.unload",
|
|
||||||
+ .offset = offsetof(struct kpatch_patch_hook, objname) },
|
|
||||||
{ .name = NULL, .offset = 0 },
|
|
||||||
};
|
|
||||||
struct callback *callbackp;
|
|
||||||
--
|
|
||||||
1.7.5.4
|
|
||||||
|
|
||||||
@ -1,480 +0,0 @@
|
|||||||
From be8e5ce9541fc230131be230bd0646c473427895 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
Date: Fri, 2 Nov 2018 17:25:20 +0000
|
|
||||||
Subject: [PATCH 1010/1015] kmod/kpatch-build: support cross compile hotpatch
|
|
||||||
for aarch64
|
|
||||||
|
|
||||||
use R_AARCH64_ABS64 for aarch64, function_ptr_rela and
|
|
||||||
kpatch_line_macro_change_only are left to implement later.
|
|
||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
---
|
|
||||||
kmod/patch/livepatch-patch-hook.c | 16 +++---
|
|
||||||
kpatch-build/create-diff-object.c | 98 ++++++++++++++++++++++++++++++----
|
|
||||||
kpatch-build/create-kpatch-module.c | 24 ++++++++-
|
|
||||||
kpatch-build/kpatch-build | 42 ++++++++++++---
|
|
||||||
kpatch-build/kpatch-gcc | 4 +-
|
|
||||||
5 files changed, 152 insertions(+), 32 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
|
||||||
index 8f7d044..ee3b2b9 100644
|
|
||||||
--- a/kmod/patch/livepatch-patch-hook.c
|
|
||||||
+++ b/kmod/patch/livepatch-patch-hook.c
|
|
||||||
@@ -66,13 +66,17 @@
|
|
||||||
|
|
||||||
#ifdef EULER_RELEASE_CODE
|
|
||||||
# if EULER_RELEASE_CODE <= EULER_RELEASE_VERSION(2, 3)
|
|
||||||
-# undef HAVE_SYMPOS
|
|
||||||
-# undef HAVE_IMMEDIATE
|
|
||||||
-# undef HAVE_ELF_RELOCS
|
|
||||||
-# define HAVE_LOADHOOKS
|
|
||||||
+# define __HULK__
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+#ifdef __HULK__
|
|
||||||
+# undef HAVE_SYMPOS
|
|
||||||
+# undef HAVE_IMMEDIATE
|
|
||||||
+# undef HAVE_ELF_RELOCS
|
|
||||||
+# define HAVE_LOADHOOKS
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* There are quite a few similar structures at play in this file:
|
|
||||||
* - livepatch.h structs prefixed with klp_*
|
|
||||||
@@ -500,12 +504,10 @@ static int __init patch_init(void)
|
|
||||||
#else
|
|
||||||
lfunc->old_addr = func->kfunc->old_addr;
|
|
||||||
#endif
|
|
||||||
-#ifdef EULER_RELEASE_CODE
|
|
||||||
-# if EULER_RELEASE_CODE <= EULER_RELEASE_VERSION(2, 3)
|
|
||||||
+#ifdef __HULK__
|
|
||||||
lfunc->old_size = func->kfunc->old_size;
|
|
||||||
lfunc->new_size = func->kfunc->new_size;
|
|
||||||
lfunc->force = patch_is_func_forced(func->kfunc->new_addr);
|
|
||||||
-# endif
|
|
||||||
#endif
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
|
||||||
index ed96758..b8d3bb4 100644
|
|
||||||
--- a/kpatch-build/create-diff-object.c
|
|
||||||
+++ b/kpatch-build/create-diff-object.c
|
|
||||||
@@ -70,6 +70,31 @@ char *childobj;
|
|
||||||
|
|
||||||
enum loglevel loglevel = NORMAL;
|
|
||||||
|
|
||||||
+#ifndef EM_X86_64
|
|
||||||
+#define EM_X86_64 62
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+#ifndef EM_AARCH64
|
|
||||||
+#define EM_AARCH64 183
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+#ifndef R_AARCH64_ABS64
|
|
||||||
+#define R_AARCH64_NONE 0
|
|
||||||
+#define R_AARCH64_ABS64 257
|
|
||||||
+#define R_AARCH64_CALL26 283
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+static unsigned int arch;
|
|
||||||
+static unsigned int absolute_rela_type;
|
|
||||||
+
|
|
||||||
+static unsigned int arch_of_elf(Elf *elf)
|
|
||||||
+{
|
|
||||||
+ GElf_Ehdr eh;
|
|
||||||
+ if (!gelf_getehdr(elf, &eh))
|
|
||||||
+ ERROR("gelf_getehdr");
|
|
||||||
+ return eh.e_machine;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/*******************
|
|
||||||
* Data structures
|
|
||||||
* ****************/
|
|
||||||
@@ -635,6 +660,8 @@ static void kpatch_compare_correlated_symbol(struct symbol *sym)
|
|
||||||
if (sym1->sec && sym2->sec && sym1->sec->twin != sym2->sec) {
|
|
||||||
if (sym2->sec->twin && sym2->sec->twin->ignore)
|
|
||||||
sym->status = CHANGED;
|
|
||||||
+ else if (sym1->name[0] == '$') /* reserved symbols in aarch64 */
|
|
||||||
+ log_debug("maping symbols: %s", sym1->name); /* do nothing just ignogre */
|
|
||||||
else
|
|
||||||
DIFF_FATAL("symbol changed sections: %s", sym1->name);
|
|
||||||
}
|
|
||||||
@@ -2294,7 +2321,7 @@ static void kpatch_create_kpatch_arch_section(struct kpatch_elf *kelf, char *obj
|
|
||||||
/* entries[index].sec */
|
|
||||||
ALLOC_LINK(rela, &karch_sec->rela->relas);
|
|
||||||
rela->sym = sec->secsym;
|
|
||||||
- rela->type = ABSOLUTE_RELA_TYPE;
|
|
||||||
+ rela->type = absolute_rela_type;
|
|
||||||
rela->addend = 0;
|
|
||||||
rela->offset = index * sizeof(*entries) + \
|
|
||||||
offsetof(struct kpatch_arch, sec);
|
|
||||||
@@ -2302,7 +2329,7 @@ static void kpatch_create_kpatch_arch_section(struct kpatch_elf *kelf, char *obj
|
|
||||||
/* entries[index].objname */
|
|
||||||
ALLOC_LINK(rela, &karch_sec->rela->relas);
|
|
||||||
rela->sym = strsym;
|
|
||||||
- rela->type = ABSOLUTE_RELA_TYPE;
|
|
||||||
+ rela->type = absolute_rela_type;
|
|
||||||
rela->addend = offset_of_string(&kelf->strings, objname);
|
|
||||||
rela->offset = index * sizeof(*entries) + \
|
|
||||||
offsetof(struct kpatch_arch, objname);
|
|
||||||
@@ -2500,7 +2527,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
|
||||||
*/
|
|
||||||
ALLOC_LINK(rela, &relasec->relas);
|
|
||||||
rela->sym = sym;
|
|
||||||
- rela->type = ABSOLUTE_RELA_TYPE;
|
|
||||||
+ rela->type = absolute_rela_type;
|
|
||||||
rela->addend = 0;
|
|
||||||
rela->offset = index * sizeof(*funcs);
|
|
||||||
|
|
||||||
@@ -2510,7 +2537,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
|
||||||
*/
|
|
||||||
ALLOC_LINK(rela, &relasec->relas);
|
|
||||||
rela->sym = strsym;
|
|
||||||
- rela->type = ABSOLUTE_RELA_TYPE;
|
|
||||||
+ rela->type = absolute_rela_type;
|
|
||||||
rela->addend = offset_of_string(&kelf->strings, sym->name);
|
|
||||||
rela->offset = index * sizeof(*funcs) +
|
|
||||||
offsetof(struct kpatch_patch_func, name);
|
|
||||||
@@ -2521,7 +2548,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
|
||||||
*/
|
|
||||||
ALLOC_LINK(rela, &relasec->relas);
|
|
||||||
rela->sym = strsym;
|
|
||||||
- rela->type = ABSOLUTE_RELA_TYPE;
|
|
||||||
+ rela->type = absolute_rela_type;
|
|
||||||
rela->addend = objname_offset;
|
|
||||||
rela->offset = index * sizeof(*funcs) +
|
|
||||||
offsetof(struct kpatch_patch_func,objname);
|
|
||||||
@@ -2834,7 +2861,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
|
||||||
/* add rela to fill in ksyms[index].name field */
|
|
||||||
ALLOC_LINK(rela2, &ksym_sec->rela->relas);
|
|
||||||
rela2->sym = strsym;
|
|
||||||
- rela2->type = ABSOLUTE_RELA_TYPE;
|
|
||||||
+ rela2->type = absolute_rela_type;
|
|
||||||
rela2->addend = offset_of_string(&kelf->strings, rela->sym->name);
|
|
||||||
rela2->offset = index * sizeof(*ksyms) + \
|
|
||||||
offsetof(struct kpatch_symbol, name);
|
|
||||||
@@ -2842,7 +2869,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
|
||||||
/* add rela to fill in ksyms[index].objname field */
|
|
||||||
ALLOC_LINK(rela2, &ksym_sec->rela->relas);
|
|
||||||
rela2->sym = strsym;
|
|
||||||
- rela2->type = ABSOLUTE_RELA_TYPE;
|
|
||||||
+ rela2->type = absolute_rela_type;
|
|
||||||
rela2->addend = offset_of_string(&kelf->strings, sym_objname);
|
|
||||||
rela2->offset = index * sizeof(*ksyms) + \
|
|
||||||
offsetof(struct kpatch_symbol, objname);
|
|
||||||
@@ -2863,7 +2890,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
|
||||||
ERROR("can't create dynrela for section %s (symbol %s): no bundled or section symbol",
|
|
||||||
sec->name, rela->sym->name);
|
|
||||||
|
|
||||||
- rela2->type = ABSOLUTE_RELA_TYPE;
|
|
||||||
+ rela2->type = absolute_rela_type;
|
|
||||||
rela2->addend = rela->offset;
|
|
||||||
rela2->offset = index * sizeof(*krelas) + \
|
|
||||||
offsetof(struct kpatch_relocation, dest);
|
|
||||||
@@ -2871,7 +2898,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
|
||||||
/* add rela to fill in krelas[index].objname field */
|
|
||||||
ALLOC_LINK(rela2, &krela_sec->rela->relas);
|
|
||||||
rela2->sym = strsym;
|
|
||||||
- rela2->type = ABSOLUTE_RELA_TYPE;
|
|
||||||
+ rela2->type = absolute_rela_type;
|
|
||||||
rela2->addend = offset_of_string(&kelf->strings, objname);
|
|
||||||
rela2->offset = index * sizeof(*krelas) + \
|
|
||||||
offsetof(struct kpatch_relocation, objname);
|
|
||||||
@@ -2879,7 +2906,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
|
||||||
/* add rela to fill in krelas[index].ksym field */
|
|
||||||
ALLOC_LINK(rela2, &krela_sec->rela->relas);
|
|
||||||
rela2->sym = ksym_sec_sym;
|
|
||||||
- rela2->type = ABSOLUTE_RELA_TYPE;
|
|
||||||
+ rela2->type = absolute_rela_type;
|
|
||||||
rela2->addend = index * sizeof(*ksyms);
|
|
||||||
rela2->offset = index * sizeof(*krelas) + \
|
|
||||||
offsetof(struct kpatch_relocation, ksym);
|
|
||||||
@@ -2946,7 +2973,7 @@ static void kpatch_create_callbacks_objname_rela(struct kpatch_elf *kelf, char *
|
|
||||||
if (!strcmp(callbackp->name, sec->name)) {
|
|
||||||
ALLOC_LINK(rela, &sec->relas);
|
|
||||||
rela->sym = strsym;
|
|
||||||
- rela->type = ABSOLUTE_RELA_TYPE;
|
|
||||||
+ rela->type = absolute_rela_type;
|
|
||||||
rela->addend = objname_offset;
|
|
||||||
rela->offset = callbackp->offset;
|
|
||||||
break;
|
|
||||||
@@ -3000,6 +3027,7 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf)
|
|
||||||
/* add rela in .rela__mcount_loc to fill in function pointer */
|
|
||||||
ALLOC_LINK(rela, &relasec->relas);
|
|
||||||
rela->sym = sym;
|
|
||||||
+ if (arch == EM_X86_64) {
|
|
||||||
rela->type = R_X86_64_64;
|
|
||||||
rela->addend = 0;
|
|
||||||
rela->offset = index * sizeof(*funcs);
|
|
||||||
@@ -3024,6 +3052,37 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf)
|
|
||||||
rela = list_first_entry(&sym->sec->rela->relas, struct rela,
|
|
||||||
list);
|
|
||||||
rela->type = R_X86_64_PC32;
|
|
||||||
+ } else if (arch == EM_AARCH64) {
|
|
||||||
+ unsigned int *insnp;
|
|
||||||
+ rela->type = R_AARCH64_ABS64;
|
|
||||||
+ /* bl <__fentry__> is the second insn */
|
|
||||||
+ rela->addend = 4;
|
|
||||||
+ rela->offset = index * sizeof(*funcs);
|
|
||||||
+
|
|
||||||
+ newdata = malloc(sym->sec->data->d_size);
|
|
||||||
+ memcpy(newdata, sym->sec->data->d_buf, sym->sec->data->d_size);
|
|
||||||
+ sym->sec->data->d_buf = newdata;
|
|
||||||
+ insnp = newdata;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * mov x9, x30
|
|
||||||
+ * nop //function in .text.<func>, so it be replaced with nop by recordmcount
|
|
||||||
+ * mov x30, x9
|
|
||||||
+ */
|
|
||||||
+ if (insnp[0] != 0xaa1e03e9 || insnp[1] != 0xd503201f || insnp[2] != 0xaa0903fe)
|
|
||||||
+ ERROR("%s: unexpected instruction at the start of the function",
|
|
||||||
+ sym->name);
|
|
||||||
+
|
|
||||||
+ /* change the nop to bl __fentry__ */
|
|
||||||
+ insnp[1] = 0x94000000;
|
|
||||||
+ rela = list_first_entry(&sym->sec->rela->relas, struct rela,
|
|
||||||
+ list);
|
|
||||||
+ rela->type = R_AARCH64_CALL26;
|
|
||||||
+ rela->offset = 4;
|
|
||||||
+
|
|
||||||
+ } else {
|
|
||||||
+ ERROR("unsupport arch %d\n", arch);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
@@ -3168,6 +3227,7 @@ int main(int argc, char *argv[])
|
|
||||||
char *hint = NULL, *orig_obj, *patched_obj, *parent_name;
|
|
||||||
char *parent_symtab, *mod_symvers, *patch_name, *output_obj;
|
|
||||||
struct sym_compare_type *base_locals;
|
|
||||||
+ char *gcc_add_option, *mlongcall;
|
|
||||||
|
|
||||||
arguments.debug = 0;
|
|
||||||
argp_parse (&argp, argc, argv, 0, NULL, &arguments);
|
|
||||||
@@ -3188,6 +3248,13 @@ int main(int argc, char *argv[])
|
|
||||||
|
|
||||||
kelf_base = kpatch_elf_open(orig_obj);
|
|
||||||
kelf_patched = kpatch_elf_open(patched_obj);
|
|
||||||
+ arch = arch_of_elf(kelf_base->elf);
|
|
||||||
+ if (arch == EM_X86_64)
|
|
||||||
+ absolute_rela_type = R_X86_64_64;
|
|
||||||
+ else if (arch == EM_AARCH64)
|
|
||||||
+ absolute_rela_type = R_AARCH64_ABS64;
|
|
||||||
+ else
|
|
||||||
+ ERROR("only arch x86_64 and arm64 be supported\n");
|
|
||||||
|
|
||||||
kpatch_bundle_symbols(kelf_base);
|
|
||||||
kpatch_bundle_symbols(kelf_patched);
|
|
||||||
@@ -3276,7 +3343,14 @@ int main(int argc, char *argv[])
|
|
||||||
kpatch_create_callbacks_objname_rela(kelf_out, parent_name);
|
|
||||||
kpatch_build_strings_section_data(kelf_out);
|
|
||||||
|
|
||||||
- kpatch_create_mcount_sections(kelf_out);
|
|
||||||
+ gcc_add_option = getenv("GCC_ADD_OPTION");
|
|
||||||
+ printf("gcc add option :%s\n", gcc_add_option);
|
|
||||||
+ mlongcall = strstr(gcc_add_option, "-mlong-calls");
|
|
||||||
+ if (arch == EM_AARCH64 && mlongcall) {
|
|
||||||
+ printf("-mlong-calls found, no need to create mcount section\n");
|
|
||||||
+ } else {
|
|
||||||
+ kpatch_create_mcount_sections(kelf_out);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/*
|
|
||||||
* At this point, the set of output sections and symbols is
|
|
||||||
diff --git a/kpatch-build/create-kpatch-module.c b/kpatch-build/create-kpatch-module.c
|
|
||||||
index 67b16b0..9f1c3b9 100644
|
|
||||||
--- a/kpatch-build/create-kpatch-module.c
|
|
||||||
+++ b/kpatch-build/create-kpatch-module.c
|
|
||||||
@@ -31,6 +31,17 @@
|
|
||||||
char *childobj;
|
|
||||||
enum loglevel loglevel = NORMAL;
|
|
||||||
|
|
||||||
+static unsigned int arch;
|
|
||||||
+static unsigned int absolute_rela_type;
|
|
||||||
+
|
|
||||||
+static unsigned int arch_of_elf(Elf *elf)
|
|
||||||
+{
|
|
||||||
+ GElf_Ehdr eh;
|
|
||||||
+ if (!gelf_getehdr(elf, &eh))
|
|
||||||
+ ERROR("gelf_getehdr");
|
|
||||||
+ return eh.e_machine;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Create .kpatch.dynrelas from .kpatch.relocations and .kpatch.symbols sections
|
|
||||||
*
|
|
||||||
@@ -102,14 +113,14 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section
|
|
||||||
/* dest */
|
|
||||||
ALLOC_LINK(rela, &dynsec->rela->relas);
|
|
||||||
rela->sym = sym;
|
|
||||||
- rela->type = R_X86_64_64;
|
|
||||||
+ rela->type = absolute_rela_type;
|
|
||||||
rela->addend = dest_offset;
|
|
||||||
rela->offset = index * sizeof(*dynrelas);
|
|
||||||
|
|
||||||
/* name */
|
|
||||||
ALLOC_LINK(rela, &dynsec->rela->relas);
|
|
||||||
rela->sym = strsec->secsym;
|
|
||||||
- rela->type = R_X86_64_64;
|
|
||||||
+ rela->type = absolute_rela_type;
|
|
||||||
rela->addend = name_offset;
|
|
||||||
rela->offset = index * sizeof(*dynrelas) + \
|
|
||||||
offsetof(struct kpatch_patch_dynrela, name);
|
|
||||||
@@ -117,7 +128,7 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section
|
|
||||||
/* objname */
|
|
||||||
ALLOC_LINK(rela, &dynsec->rela->relas);
|
|
||||||
rela->sym = strsec->secsym;
|
|
||||||
- rela->type = R_X86_64_64;
|
|
||||||
+ rela->type = absolute_rela_type;
|
|
||||||
rela->addend = objname_offset;
|
|
||||||
rela->offset = index * sizeof(*dynrelas) + \
|
|
||||||
offsetof(struct kpatch_patch_dynrela, objname);
|
|
||||||
@@ -200,6 +211,13 @@ int main(int argc, char *argv[])
|
|
||||||
childobj = basename(arguments.args[0]);
|
|
||||||
|
|
||||||
kelf = kpatch_elf_open(arguments.args[0]);
|
|
||||||
+ arch = arch_of_elf(kelf->elf);
|
|
||||||
+ if (arch == EM_X86_64)
|
|
||||||
+ absolute_rela_type = R_X86_64_64;
|
|
||||||
+ else if (arch == EM_AARCH64)
|
|
||||||
+ absolute_rela_type = R_AARCH64_ABS64;
|
|
||||||
+ else
|
|
||||||
+ ERROR("only arch x86_64 and arm64 be supported\n");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sanity checks:
|
|
||||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
|
||||||
index 93a0589..017604c 100755
|
|
||||||
--- a/kpatch-build/kpatch-build
|
|
||||||
+++ b/kpatch-build/kpatch-build
|
|
||||||
@@ -384,6 +384,27 @@ find_kobj() {
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
+arch_export() {
|
|
||||||
+ E_MACHINE=$(od -An -j18 -N2 -d $VMLINUX)
|
|
||||||
+ if [[ $E_MACHINE -eq 62 ]]; then
|
|
||||||
+ export ARCH=x86_64
|
|
||||||
+ export ARCH_COMPILE=
|
|
||||||
+ export ENDIAN=little
|
|
||||||
+ export GCC_ADD_OPTION=
|
|
||||||
+ elif [[ $E_MACHINE -eq 183 ]]; then
|
|
||||||
+ export ARCH=arm64
|
|
||||||
+ export ARCH_COMPILE=aarch64-linux-gnu-
|
|
||||||
+ export ENDIAN=little
|
|
||||||
+ if grep "\-mlong-calls" $SRCDIR/Makefile > /dev/null; then
|
|
||||||
+ export GCC_ADD_OPTION="-fno-section-anchors -mlong-calls"
|
|
||||||
+ else
|
|
||||||
+ export GCC_ADD_OPTION="-fno-section-anchors"
|
|
||||||
+ fi
|
|
||||||
+ else
|
|
||||||
+ die "only support arm64 or x86_64 architecture"
|
|
||||||
+ fi
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
# Only allow alphanumerics and '_' and '-' in the module name. Everything else
|
|
||||||
# is replaced with '-'. Also truncate to 48 chars so the full name fits in the
|
|
||||||
# kernel's 56-byte module name array.
|
|
||||||
@@ -725,12 +746,12 @@ apply_patches
|
|
||||||
remove_patches
|
|
||||||
|
|
||||||
cp -LR "$DATADIR/patch" "$TEMPDIR" || die
|
|
||||||
-
|
|
||||||
+arch_export
|
|
||||||
if [[ "$ARCH" = "ppc64le" ]]; then
|
|
||||||
ARCH_KCFLAGS="-mcmodel=large -fplugin=$PLUGINDIR/ppc64le-plugin.so"
|
|
||||||
fi
|
|
||||||
|
|
||||||
-export KCFLAGS="-I$DATADIR/patch -ffunction-sections -fdata-sections $ARCH_KCFLAGS"
|
|
||||||
+export KCFLAGS="-I$DATADIR/patch -ffunction-sections -fdata-sections $ARCH_KCFLAGS ${GCC_ADD_OPTION}"
|
|
||||||
|
|
||||||
echo "Reading special section data"
|
|
||||||
find_special_section_data
|
|
||||||
@@ -752,9 +773,9 @@ unset KPATCH_GCC_TEMPDIR
|
|
||||||
# $TARGETS used as list, no quotes.
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
if [ -z "$USERMODDIR" ];then
|
|
||||||
- CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
|
||||||
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
|
||||||
else
|
|
||||||
- CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" "-j$CPUS" $USERMODFLAGS $TARGETS 2>&1 | logger || die
|
|
||||||
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" "-j$CPUS" $USERMODFLAGS $TARGETS 2>&1 | logger || die
|
|
||||||
fi
|
|
||||||
|
|
||||||
sleep 1
|
|
||||||
@@ -770,11 +791,11 @@ export KPATCH_GCC_TEMPDIR
|
|
||||||
# $TARGETS used as list, no quotes.
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
if [ -z "$USERMODDIR" ];then
|
|
||||||
- CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " \
|
|
||||||
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" \
|
|
||||||
KBUILD_MODPOST_WARN=1 \
|
|
||||||
make "-j$CPUS" $TARGETS 2>&1 | logger || die
|
|
||||||
else
|
|
||||||
- CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " \
|
|
||||||
+ CROSS_COMPILE="$TOOLSDIR/kpatch-gcc $ARCH_COMPILE" \
|
|
||||||
KBUILD_MODPOST_WARN=1 \
|
|
||||||
make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" "-j$CPUS" $USERMODFLAGS $TARGETS 2>&1 | logger || die
|
|
||||||
fi
|
|
||||||
@@ -907,6 +928,10 @@ if "$KPATCH_MODULE"; then
|
|
||||||
export KCPPFLAGS="-D__KPATCH_MODULE__"
|
|
||||||
fi
|
|
||||||
|
|
||||||
+if grep "hulk" $SRCDIR/Makefile > /dev/null; then
|
|
||||||
+ export KCPPFLAGS="-D__HULK__ $KCPPFLAGS"
|
|
||||||
+fi
|
|
||||||
+
|
|
||||||
echo "Building patch module: $MODNAME.ko"
|
|
||||||
|
|
||||||
if [[ -z "$USERSRCDIR" ]] && [[ "$DISTRO" = ubuntu ]]; then
|
|
||||||
@@ -919,12 +944,12 @@ fi
|
|
||||||
cd "$TEMPDIR/output" || die
|
|
||||||
# $KPATCH_LDFLAGS and result of find used as list, no quotes.
|
|
||||||
# shellcheck disable=SC2086,SC2046
|
|
||||||
-ld -r $KPATCH_LDFLAGS -o ../patch/tmp_output.o $(find . -name "*.o") 2>&1 | logger || die
|
|
||||||
+${ARCH_COMPILE}ld -r $KPATCH_LDFLAGS -o ../patch/tmp_output.o $(find . -name "*.o") 2>&1 | logger || die
|
|
||||||
|
|
||||||
if "$KPATCH_MODULE"; then
|
|
||||||
# Add .kpatch.checksum for kpatch script
|
|
||||||
md5sum ../patch/tmp_output.o | awk '{printf "%s\0", $1}' > checksum.tmp || die
|
|
||||||
- objcopy --add-section .kpatch.checksum=checksum.tmp --set-section-flags .kpatch.checksum=alloc,load,contents,readonly ../patch/tmp_output.o || die
|
|
||||||
+ ${ARCH_COMPILE}objcopy --add-section .kpatch.checksum=checksum.tmp --set-section-flags .kpatch.checksum=alloc,load,contents,readonly ../patch/tmp_output.o || die
|
|
||||||
rm -f checksum.tmp
|
|
||||||
"$TOOLSDIR"/create-kpatch-module "$TEMPDIR"/patch/tmp_output.o "$TEMPDIR"/patch/output.o 2>&1 | logger 1
|
|
||||||
check_pipe_status create-kpatch-module
|
|
||||||
@@ -942,6 +967,7 @@ fi
|
|
||||||
KPATCH_BUILD="$KPATCH_BUILDIR" KPATCH_NAME="$MODNAME" \
|
|
||||||
KBUILD_EXTRA_SYMBOLS="$KBUILD_EXTRA_SYMBOLS" \
|
|
||||||
KPATCH_LDFLAGS="$KPATCH_LDFLAGS" \
|
|
||||||
+CROSS_COMPILE="$ARCH_COMPILE" \
|
|
||||||
make 2>&1 | logger || die
|
|
||||||
|
|
||||||
if ! "$KPATCH_MODULE"; then
|
|
||||||
diff --git a/kpatch-build/kpatch-gcc b/kpatch-build/kpatch-gcc
|
|
||||||
index 21f7e2e..be18847 100755
|
|
||||||
--- a/kpatch-build/kpatch-gcc
|
|
||||||
+++ b/kpatch-build/kpatch-gcc
|
|
||||||
@@ -13,7 +13,7 @@ fi
|
|
||||||
|
|
||||||
declare -a args=("$@")
|
|
||||||
|
|
||||||
-if [[ "$TOOLCHAINCMD" = "gcc" ]] ; then
|
|
||||||
+if [[ "$TOOLCHAINCMD" = ${ARCH_COMPILE}gcc ]] ; then
|
|
||||||
while [ "$#" -gt 0 ]; do
|
|
||||||
if [ "$1" = "-o" ]; then
|
|
||||||
obj="$2"
|
|
||||||
@@ -64,7 +64,7 @@ if [[ "$TOOLCHAINCMD" = "gcc" ]] ; then
|
|
||||||
fi
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
-elif [[ "$TOOLCHAINCMD" = "ld" ]] ; then
|
|
||||||
+elif [[ "$TOOLCHAINCMD" = ${ARCH_COMPILE}ld ]] ; then
|
|
||||||
while [ "$#" -gt 0 ]; do
|
|
||||||
if [ "$1" = "-o" ]; then
|
|
||||||
obj="$2"
|
|
||||||
--
|
|
||||||
1.7.5.4
|
|
||||||
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
From 868a6e4462bebcffa4bf6beea02262823e7dc3a3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
Date: Fri, 2 Nov 2018 17:25:33 +0000
|
|
||||||
Subject: [PATCH] kpatch-build: use .klp.rela in euleros 7.5 kernel
|
|
||||||
|
|
||||||
use .klp.rela in euleros 7.5 kernel
|
|
||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
---
|
|
||||||
kpatch-build/kpatch-build | 13 +++++++++++--
|
|
||||||
1 files changed, 11 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
|
||||||
index fb14850..5a70a44 100755
|
|
||||||
--- a/kpatch-build/kpatch-build
|
|
||||||
+++ b/kpatch-build/kpatch-build
|
|
||||||
@@ -157,6 +157,15 @@ is_rhel() {
|
|
||||||
[[ $1 =~ \.el[78]\. ]]
|
|
||||||
}
|
|
||||||
|
|
||||||
+is_euleros_klp() {
|
|
||||||
+ if [[ "$1" =~ ^3.10.0-862 ]] ;then
|
|
||||||
+ if [ $ID == "euleros" ];then
|
|
||||||
+ return 0;
|
|
||||||
+ fi
|
|
||||||
+ fi
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
find_dirs() {
|
|
||||||
if [[ -e "$SCRIPTDIR/create-diff-object" ]]; then
|
|
||||||
# git repo
|
|
||||||
@@ -708,10 +717,10 @@ KPATCH_MODULE=true
|
|
||||||
grep -q "CONFIG_DEBUG_INFO=y" "$CONFIGFILE" || die "kernel doesn't have 'CONFIG_DEBUG_INFO' enabled"
|
|
||||||
if grep -q "CONFIG_LIVEPATCH=y" "$CONFIGFILE"; then
|
|
||||||
# The kernel supports livepatch.
|
|
||||||
- if version_gte "${ARCHVERSION//-*/}" 4.7.0 || is_rhel "$ARCHVERSION"; then
|
|
||||||
+ if version_gte "${ARCHVERSION//-*/}" 4.7.0 || is_rhel "$ARCHVERSION" || is_euleros_klp "$ARCHVERSION"; then
|
|
||||||
# Use new .klp.rela. sections
|
|
||||||
KPATCH_MODULE=false
|
|
||||||
- if version_gte "${ARCHVERSION//-*/}" 4.9.0 || is_rhel "$ARCHVERSION"; then
|
|
||||||
+ if version_gte "${ARCHVERSION//-*/}" 4.9.0 || is_rhel "$ARCHVERSION" || is_euleros_klp "$ARCHVERSION"; then
|
|
||||||
KPATCH_LDFLAGS="--unique=.parainstructions --unique=.altinstructions"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
--
|
|
||||||
1.7.5.4
|
|
||||||
|
|
||||||
@ -1,365 +0,0 @@
|
|||||||
From 1eaabfe01cfae870abd45bfa470caa144f34e74c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
Date: Fri, 2 Nov 2018 17:25:45 +0000
|
|
||||||
Subject: [PATCH 1013/1015] kmod/kpatch-build: fix duplicate symbol relocation
|
|
||||||
for hulk kernel
|
|
||||||
|
|
||||||
hulk kernel fix it by find a uniq symbol(ref_name) and
|
|
||||||
use ref_offset to find the duplicate symbol
|
|
||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
---
|
|
||||||
kmod/patch/kpatch-patch.h | 4 ++
|
|
||||||
kmod/patch/livepatch-patch-hook.c | 6 ++
|
|
||||||
kpatch-build/create-diff-object.c | 44 +++++++++++++++++-
|
|
||||||
kpatch-build/create-kpatch-module.c | 23 +++++++++-
|
|
||||||
kpatch-build/kpatch-build | 12 +++++
|
|
||||||
kpatch-build/kpatch-intermediate.h | 2 +
|
|
||||||
kpatch-build/lookup.c | 87 ++++++++++++++++++++++++++++++++++-
|
|
||||||
kpatch-build/lookup.h | 8 +++
|
|
||||||
8 files changed, 183 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kmod/patch/kpatch-patch.h b/kmod/patch/kpatch-patch.h
|
|
||||||
index 4d47d30..2eacb37 100644
|
|
||||||
--- a/kmod/patch/kpatch-patch.h
|
|
||||||
+++ b/kmod/patch/kpatch-patch.h
|
|
||||||
@@ -30,6 +30,8 @@ struct kpatch_patch_func {
|
|
||||||
unsigned long sympos;
|
|
||||||
char *name;
|
|
||||||
char *objname;
|
|
||||||
+ char *ref_name;
|
|
||||||
+ long ref_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct kpatch_patch_dynrela {
|
|
||||||
@@ -41,6 +43,8 @@ struct kpatch_patch_dynrela {
|
|
||||||
char *objname;
|
|
||||||
int external;
|
|
||||||
int addend;
|
|
||||||
+ char *ref_name;
|
|
||||||
+ long ref_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct kpatch_pre_patch_callback {
|
|
||||||
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
|
||||||
index ee3b2b9..fefc068 100644
|
|
||||||
--- a/kmod/patch/livepatch-patch-hook.c
|
|
||||||
+++ b/kmod/patch/livepatch-patch-hook.c
|
|
||||||
@@ -508,6 +508,8 @@ static int __init patch_init(void)
|
|
||||||
lfunc->old_size = func->kfunc->old_size;
|
|
||||||
lfunc->new_size = func->kfunc->new_size;
|
|
||||||
lfunc->force = patch_is_func_forced(func->kfunc->new_addr);
|
|
||||||
+ lfunc->ref_name= func->kfunc->ref_name;
|
|
||||||
+ lfunc->ref_offset = func->kfunc->ref_offset;
|
|
||||||
#endif
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
@@ -531,6 +533,10 @@ static int __init patch_init(void)
|
|
||||||
lreloc->name = reloc->kdynrela->name;
|
|
||||||
lreloc->addend = reloc->kdynrela->addend;
|
|
||||||
lreloc->external = reloc->kdynrela->external;
|
|
||||||
+#ifdef __HULK__
|
|
||||||
+ lreloc->ref_name = reloc->kdynrela->ref_name;
|
|
||||||
+ lreloc->ref_offset = reloc->kdynrela->ref_offset;
|
|
||||||
+#endif
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
#endif /* HAVE_ELF_RELOCS */
|
|
||||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
|
||||||
index 4fb27da..e72f6dd 100644
|
|
||||||
--- a/kpatch-build/create-diff-object.c
|
|
||||||
+++ b/kpatch-build/create-diff-object.c
|
|
||||||
@@ -2519,6 +2519,29 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
|
||||||
funcs[index].old_size = result.size;
|
|
||||||
funcs[index].new_size = sym->sym.st_size;
|
|
||||||
funcs[index].sympos = result.pos;
|
|
||||||
+ if (lookup_is_duplicate_symbol(table, sym->name)) {
|
|
||||||
+ struct lookup_refsym refsym;
|
|
||||||
+ long offset;
|
|
||||||
+
|
|
||||||
+ if (lookup_ref_symbol(table, sym->name, &refsym))
|
|
||||||
+ ERROR("unresolvable ambiguity on symbol %s\n", sym->name);
|
|
||||||
+
|
|
||||||
+ offset = (long)result.value - (long)refsym.value;
|
|
||||||
+ funcs[index].ref_offset = offset;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Add a relocation that will populate
|
|
||||||
+ * the funcs[index].ref_name field.
|
|
||||||
+ */
|
|
||||||
+ ALLOC_LINK(rela, &relasec->relas);
|
|
||||||
+ rela->sym = strsym;
|
|
||||||
+ rela->type = absolute_rela_type;
|
|
||||||
+ rela->addend = offset_of_string(&kelf->strings, refsym.name);
|
|
||||||
+ rela->offset = index * sizeof(*funcs) +
|
|
||||||
+ offsetof(struct kpatch_patch_func, ref_name);
|
|
||||||
+
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Add a relocation that will populate
|
|
||||||
@@ -2653,6 +2676,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
|
||||||
struct lookup_result result;
|
|
||||||
char *sym_objname;
|
|
||||||
int ret, vmlinux, external;
|
|
||||||
+ long ref_offset;
|
|
||||||
|
|
||||||
vmlinux = !strcmp(objname, "vmlinux");
|
|
||||||
|
|
||||||
@@ -2860,12 +2884,29 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
|
||||||
log_debug("lookup for %s @ 0x%016lx len %lu\n",
|
|
||||||
rela->sym->name, result.value, result.size);
|
|
||||||
|
|
||||||
+ ref_offset = 0;
|
|
||||||
/* Fill in ksyms[index] */
|
|
||||||
if (vmlinux)
|
|
||||||
ksyms[index].src = result.value;
|
|
||||||
- else
|
|
||||||
+ else {
|
|
||||||
/* for modules, src is discovered at runtime */
|
|
||||||
ksyms[index].src = 0;
|
|
||||||
+ if (lookup_is_duplicate_symbol(table, rela->sym->name)) {
|
|
||||||
+ struct lookup_refsym refsym;
|
|
||||||
+
|
|
||||||
+ if (lookup_ref_symbol(table, rela->sym->name, &refsym))
|
|
||||||
+ ERROR("unresolvable ambiguity on symbol %s\n", rela->sym->name);
|
|
||||||
+
|
|
||||||
+ ref_offset = (long)result.value - (long)refsym.value;
|
|
||||||
+ /* add rela to fill in ref_name field */
|
|
||||||
+ ALLOC_LINK(rela2, &krela_sec->rela->relas);
|
|
||||||
+ rela2->sym = strsym;
|
|
||||||
+ rela2->type = absolute_rela_type;
|
|
||||||
+ rela2->addend = offset_of_string(&kelf->strings, refsym.name);
|
|
||||||
+ rela2->offset = index * sizeof(*krelas) +
|
|
||||||
+ offsetof(struct kpatch_relocation, ref_name);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
ksyms[index].pos = result.pos;
|
|
||||||
ksyms[index].type = rela->sym->type;
|
|
||||||
ksyms[index].bind = rela->sym->bind;
|
|
||||||
@@ -2893,6 +2934,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
|
||||||
krelas[index].addend = rela->addend;
|
|
||||||
krelas[index].type = rela->type;
|
|
||||||
krelas[index].external = external;
|
|
||||||
+ krelas[index].ref_offset = ref_offset;
|
|
||||||
|
|
||||||
/* add rela to fill in krelas[index].dest field */
|
|
||||||
ALLOC_LINK(rela2, &krela_sec->rela->relas);
|
|
||||||
diff --git a/kpatch-build/create-kpatch-module.c b/kpatch-build/create-kpatch-module.c
|
|
||||||
index 9f1c3b9..8292dc8 100644
|
|
||||||
--- a/kpatch-build/create-kpatch-module.c
|
|
||||||
+++ b/kpatch-build/create-kpatch-module.c
|
|
||||||
@@ -57,7 +57,7 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section
|
|
||||||
struct section *dynsec;
|
|
||||||
struct symbol *sym;
|
|
||||||
struct rela *rela;
|
|
||||||
- int index, nr, offset, dest_offset, objname_offset, name_offset;
|
|
||||||
+ int index, nr, offset, dest_offset, objname_offset, name_offset, ref_name_offset;
|
|
||||||
|
|
||||||
ksyms = ksymsec->data->d_buf;
|
|
||||||
krelas = krelasec->data->d_buf;
|
|
||||||
@@ -109,6 +109,27 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section
|
|
||||||
dynrelas[index].type = krelas[index].type;
|
|
||||||
dynrelas[index].external = krelas[index].external;
|
|
||||||
dynrelas[index].sympos = ksym->pos;
|
|
||||||
+ dynrelas[index].ref_name = krelas[index].ref_name;
|
|
||||||
+ dynrelas[index].ref_offset = krelas[index].ref_offset;
|
|
||||||
+
|
|
||||||
+ if (dynrelas[index].ref_offset)
|
|
||||||
+ {
|
|
||||||
+ /* Get objname offset */
|
|
||||||
+ rela = find_rela_by_offset(krelasec->rela,
|
|
||||||
+ index * sizeof(*krelas) + offsetof(struct kpatch_relocation, ref_name));
|
|
||||||
+ if (!rela) {
|
|
||||||
+ ERROR("find_rela_by_offset");
|
|
||||||
+ }
|
|
||||||
+ ref_name_offset = rela->addend;
|
|
||||||
+ /* ref_name */
|
|
||||||
+ ALLOC_LINK(rela, &dynsec->rela->relas);
|
|
||||||
+ rela->sym = strsec->secsym;
|
|
||||||
+ rela->type = absolute_rela_type;
|
|
||||||
+ rela->addend = ref_name_offset;
|
|
||||||
+ rela->offset = index * sizeof(*dynrelas) + \
|
|
||||||
+ offsetof(struct kpatch_patch_dynrela, ref_name);
|
|
||||||
+
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/* dest */
|
|
||||||
ALLOC_LINK(rela, &dynsec->rela->relas);
|
|
||||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
|
||||||
index 9c40612..80b9607 100755
|
|
||||||
--- a/kpatch-build/kpatch-build
|
|
||||||
+++ b/kpatch-build/kpatch-build
|
|
||||||
@@ -894,6 +894,18 @@ for i in $FILES; do
|
|
||||||
KOBJFILE_NAME="${KOBJFILE_NAME/-/_}"
|
|
||||||
KOBJFILE_PATH="${TEMPDIR}/module/$KOBJFILE"
|
|
||||||
SYMTAB="${KOBJFILE_PATH}.symtab"
|
|
||||||
+ unset KCFLAGS
|
|
||||||
+ remove_patches
|
|
||||||
+ if [ -z "$USERMODDIR" ];then
|
|
||||||
+ cd "$SRCDIR" || die
|
|
||||||
+ CROSS_COMPILE="$ARCH_COMPILE" make "-j$CPUS" ${KOBJFILE} 2>&1 | logger || die
|
|
||||||
+ else
|
|
||||||
+ cd "$USERMODDIR"
|
|
||||||
+ CROSS_COMPILE="$ARCH_COMPILE" make -C "$USERMODBUILDDIR" M="$USERMODBUILDDIR" "-j$CPUS" $USERMODFLAGS $TARGETS 2>&1 | logger || die
|
|
||||||
+ fi
|
|
||||||
+ cp ${KOBJFILE} ${KOBJFILE_PATH}
|
|
||||||
+ apply_patches
|
|
||||||
+ cd "$TEMPDIR" || die
|
|
||||||
fi
|
|
||||||
|
|
||||||
eu-readelf -s "$KOBJFILE_PATH" > "$SYMTAB"
|
|
||||||
diff --git a/kpatch-build/kpatch-intermediate.h b/kpatch-build/kpatch-intermediate.h
|
|
||||||
index 3dea775..59deed0 100644
|
|
||||||
--- a/kpatch-build/kpatch-intermediate.h
|
|
||||||
+++ b/kpatch-build/kpatch-intermediate.h
|
|
||||||
@@ -39,6 +39,8 @@ struct kpatch_relocation {
|
|
||||||
int external;
|
|
||||||
char *objname; /* object to which this rela applies to */
|
|
||||||
struct kpatch_symbol *ksym;
|
|
||||||
+ char *ref_name;
|
|
||||||
+ long ref_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct kpatch_arch {
|
|
||||||
diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c
|
|
||||||
index d08c10b..e4677db 100644
|
|
||||||
--- a/kpatch-build/lookup.c
|
|
||||||
+++ b/kpatch-build/lookup.c
|
|
||||||
@@ -44,6 +44,7 @@ struct object_symbol {
|
|
||||||
unsigned long size;
|
|
||||||
char *name;
|
|
||||||
int type, bind;
|
|
||||||
+ int sec_index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct export_symbol {
|
|
||||||
@@ -229,6 +230,7 @@ static void symtab_read(struct lookup_table *table, char *path)
|
|
||||||
table->obj_syms[i].value = value;
|
|
||||||
table->obj_syms[i].size = size;
|
|
||||||
table->obj_syms[i].name = strdup(name);
|
|
||||||
+ table->obj_syms[i].sec_index = atoi(ndx);
|
|
||||||
|
|
||||||
if (!strcmp(bind, "LOCAL")) {
|
|
||||||
table->obj_syms[i].bind = STB_LOCAL;
|
|
||||||
@@ -425,7 +427,90 @@ char *lookup_exported_symbol_objname(struct lookup_table *table, char *name)
|
|
||||||
return match->objname;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
- }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int lookup_is_duplicate_symbol(struct lookup_table *table, char *name)
|
|
||||||
+{
|
|
||||||
+ struct object_symbol *sym;
|
|
||||||
+ int i, count = 0;
|
|
||||||
+
|
|
||||||
+ for_each_obj_symbol(i, sym, table)
|
|
||||||
+ if (!strcmp(sym->name, name)) {
|
|
||||||
+ count++;
|
|
||||||
+ if (count > 1)
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+struct object_symbol *lookup_find_symbol_by_name(struct lookup_table *table, char *name)
|
|
||||||
+{
|
|
||||||
+ struct object_symbol *sym;
|
|
||||||
+ unsigned long pos = 0;
|
|
||||||
+ int i, match = 0, in_file = 0;
|
|
||||||
+
|
|
||||||
+ if (!table->local_syms)
|
|
||||||
+ return NULL;
|
|
||||||
+
|
|
||||||
+ for_each_obj_symbol(i, sym, table) {
|
|
||||||
+ if (sym->bind == STB_LOCAL && !strcmp(sym->name, name))
|
|
||||||
+ pos++;
|
|
||||||
+
|
|
||||||
+ if (table->local_syms == sym) {
|
|
||||||
+ in_file = 1;
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (!in_file)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ if (sym->type == STT_FILE)
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ if (sym->bind == STB_LOCAL && !strcmp(sym->name, name)) {
|
|
||||||
+ match = 1;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (!match) {
|
|
||||||
+ for_each_obj_symbol(i, sym, table) {
|
|
||||||
+ if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK) &&
|
|
||||||
+ !strcmp(sym->name, name)) {
|
|
||||||
+ return sym;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return sym;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int lookup_ref_symbol(struct lookup_table *table, char *name,
|
|
||||||
+ struct lookup_refsym *refsym)
|
|
||||||
+{
|
|
||||||
+ struct object_symbol *orig_sym, *sym;
|
|
||||||
+ int i;
|
|
||||||
+
|
|
||||||
+ orig_sym = lookup_find_symbol_by_name(table, name);
|
|
||||||
+ if (!orig_sym)
|
|
||||||
+ ERROR("lookup_ref_symbol");
|
|
||||||
+ memset(refsym, 0, sizeof(*refsym));
|
|
||||||
+ for_each_obj_symbol(i, sym, table) {
|
|
||||||
+ if (!strcmp(sym->name, name) || sym->type == STT_FILE ||
|
|
||||||
+ sym->sec_index != orig_sym->sec_index)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ if (!lookup_is_duplicate_symbol(table, sym->name)) {
|
|
||||||
+ refsym->name = sym->name;
|
|
||||||
+ refsym->value = sym->value;
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
|
|
||||||
#if 0 /* for local testing */
|
|
||||||
static void find_this(struct lookup_table *table, char *sym, char *hint)
|
|
||||||
diff --git a/kpatch-build/lookup.h b/kpatch-build/lookup.h
|
|
||||||
index 420d0f0..5ad9241 100644
|
|
||||||
--- a/kpatch-build/lookup.h
|
|
||||||
+++ b/kpatch-build/lookup.h
|
|
||||||
@@ -14,6 +14,11 @@ struct sym_compare_type {
|
|
||||||
int type;
|
|
||||||
};
|
|
||||||
|
|
||||||
+struct lookup_refsym {
|
|
||||||
+ char *name;
|
|
||||||
+ unsigned long value;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
struct lookup_table *lookup_open(char *symtab_path, char *symvers_path,
|
|
||||||
char *hint, struct sym_compare_type *locals);
|
|
||||||
void lookup_close(struct lookup_table *table);
|
|
||||||
@@ -23,5 +28,8 @@ int lookup_global_symbol(struct lookup_table *table, char *name,
|
|
||||||
struct lookup_result *result);
|
|
||||||
int lookup_is_exported_symbol(struct lookup_table *table, char *name);
|
|
||||||
char *lookup_exported_symbol_objname(struct lookup_table *table, char *name);
|
|
||||||
+int lookup_is_duplicate_symbol(struct lookup_table *table, char *name);
|
|
||||||
+int lookup_ref_symbol(struct lookup_table *table, char *name,
|
|
||||||
+ struct lookup_refsym *refsym);
|
|
||||||
|
|
||||||
#endif /* _LOOKUP_H_ */
|
|
||||||
--
|
|
||||||
1.7.5.4
|
|
||||||
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
From 83ecafcda5326baceeb68fba90dc13083ff48fe6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
Date: Fri, 2 Nov 2018 17:25:50 +0000
|
|
||||||
Subject: [PATCH 1014/1015] create-diff-object: add dynamic reloction for
|
|
||||||
function pointer on aarch64
|
|
||||||
|
|
||||||
implement function_ptr_rela for aarch64.
|
|
||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
---
|
|
||||||
kpatch-build/create-diff-object.c | 4 +++-
|
|
||||||
1 files changed, 3 insertions(+), 1 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
|
||||||
index e72f6dd..f8f3e15 100644
|
|
||||||
--- a/kpatch-build/create-diff-object.c
|
|
||||||
+++ b/kpatch-build/create-diff-object.c
|
|
||||||
@@ -2628,7 +2628,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 int may_need_dynrela(const struct rela *rela)
|
|
||||||
--
|
|
||||||
1.7.5.4
|
|
||||||
|
|
||||||
@ -1,106 +0,0 @@
|
|||||||
From d1bbff5da464148e5d277b601a31d7872b4e376b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
Date: Fri, 2 Nov 2018 17:26:00 +0000
|
|
||||||
Subject: [PATCH 1015/1015] create-diff-object: exclude line only change for
|
|
||||||
arm64
|
|
||||||
|
|
||||||
exclude line only change for arm64 by compare mov instruction
|
|
||||||
except immediate part.
|
|
||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
---
|
|
||||||
kpatch-build/create-diff-object.c | 71 ++++++++++++++++++++++++++++++++++++-
|
|
||||||
1 files changed, 70 insertions(+), 1 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
|
||||||
index f8f3e15..12d8bd6 100644
|
|
||||||
--- a/kpatch-build/create-diff-object.c
|
|
||||||
+++ b/kpatch-build/create-diff-object.c
|
|
||||||
@@ -609,6 +609,68 @@ static int kpatch_line_macro_change_only(struct section *sec)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
+#define ARM64_INSTR_LEN 4
|
|
||||||
+static int arm64_kpatch_line_macro_change_only(struct section *sec)
|
|
||||||
+{
|
|
||||||
+ unsigned long start1, start2, size, offset;
|
|
||||||
+ struct rela *rela;
|
|
||||||
+ int lineonly = 0, found;
|
|
||||||
+ unsigned int mov_imm_mask = ((1<<16) - 1)<<5;
|
|
||||||
+
|
|
||||||
+ if (sec->status != CHANGED ||
|
|
||||||
+ is_rela_section(sec) ||
|
|
||||||
+ !is_text_section(sec) ||
|
|
||||||
+ sec->sh.sh_size != sec->twin->sh.sh_size ||
|
|
||||||
+ !sec->rela ||
|
|
||||||
+ sec->rela->status != SAME)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ start1 = (unsigned long)sec->twin->data->d_buf;
|
|
||||||
+ start2 = (unsigned long)sec->data->d_buf;
|
|
||||||
+ size = sec->sh.sh_size;
|
|
||||||
+ for (offset = 0; offset < size; offset += ARM64_INSTR_LEN) {
|
|
||||||
+ if (!memcmp((void *)start1 + offset, (void *)start2 + offset,
|
|
||||||
+ ARM64_INSTR_LEN))
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ /* verify it's a mov immediate to w1 */
|
|
||||||
+ if ((*(int *)(start1 + offset) & ~mov_imm_mask) !=
|
|
||||||
+ (*(int *)(start2 + offset) & ~mov_imm_mask))
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ found = 0;
|
|
||||||
+ list_for_each_entry(rela, &sec->rela->relas, list) {
|
|
||||||
+ if (rela->offset < offset + ARM64_INSTR_LEN)
|
|
||||||
+ continue;
|
|
||||||
+ if (rela->string)
|
|
||||||
+ continue;
|
|
||||||
+ if (!strncmp(rela->sym->name, "__warned.", 9))
|
|
||||||
+ continue;
|
|
||||||
+ if (!strncmp(rela->sym->name, "warn_slowpath_", 14) ||
|
|
||||||
+ (!strcmp(rela->sym->name, "__warn_printk")) ||
|
|
||||||
+ (!strcmp(rela->sym->name, "__might_sleep")) ||
|
|
||||||
+ (!strcmp(rela->sym->name, "___might_sleep")) ||
|
|
||||||
+ (!strcmp(rela->sym->name, "__might_fault")) ||
|
|
||||||
+ (!strcmp(rela->sym->name, "printk")) ||
|
|
||||||
+ (!strcmp(rela->sym->name, "lockdep_rcu_suspicious"))) {
|
|
||||||
+ found = 1;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ if (!found)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ lineonly = 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (!lineonly)
|
|
||||||
+ ERROR("no instruction changes detected for changed section %s",
|
|
||||||
+ sec->name);
|
|
||||||
+
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
|
|
||||||
static void kpatch_compare_sections(struct list_head *seclist)
|
|
||||||
{
|
|
||||||
@@ -624,7 +686,14 @@ static void kpatch_compare_sections(struct list_head *seclist)
|
|
||||||
|
|
||||||
/* exclude WARN-only, might_sleep changes */
|
|
||||||
list_for_each_entry(sec, seclist, list) {
|
|
||||||
- if (kpatch_line_macro_change_only(sec)) {
|
|
||||||
+ int line_only;
|
|
||||||
+ if (arch == EM_X86_64)
|
|
||||||
+ line_only = kpatch_line_macro_change_only(sec);
|
|
||||||
+ else if (arch == EM_AARCH64)
|
|
||||||
+ line_only = arm64_kpatch_line_macro_change_only(sec);
|
|
||||||
+ else
|
|
||||||
+ line_only = 0;
|
|
||||||
+ if (line_only) {
|
|
||||||
log_debug("reverting macro / line number section %s status to SAME\n",
|
|
||||||
sec->name);
|
|
||||||
sec->status = SAME;
|
|
||||||
--
|
|
||||||
1.7.5.4
|
|
||||||
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
From dc771a1789ea3769777228f792f0902f8b0566ba Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
Date: Thu, 22 Nov 2018 21:06:32 +0000
|
|
||||||
Subject: [PATCH] kpatch-build: include secsym in kpatch_mark_ignored_sections
|
|
||||||
|
|
||||||
kpatch_mark_ignored_sections include .rodata.str1.1 section but does
|
|
||||||
not include its section symbol, causing its section symbol can not be
|
|
||||||
included any more in kpatch_include_standard_elements. After the
|
|
||||||
section symbol is freed in kpatch_elf_teardown, we got a segmentation
|
|
||||||
fault in kpatch_create_intermediate_sections.
|
|
||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
---
|
|
||||||
kpatch-build/create-diff-object.c | 1 +
|
|
||||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
|
||||||
index 2e54960..97ae0d4 100644
|
|
||||||
--- a/kpatch-build/create-diff-object.c
|
|
||||||
+++ b/kpatch-build/create-diff-object.c
|
|
||||||
@@ -2285,6 +2285,7 @@ static void kpatch_mark_ignored_sections(struct kpatch_elf *kelf)
|
|
||||||
* from the section data comparison, but this is a simpler way.
|
|
||||||
*/
|
|
||||||
strsec->include = 1;
|
|
||||||
+ strsec->secsym->include = 1;
|
|
||||||
name = strsec->data->d_buf + rela->addend;
|
|
||||||
ignoresec = find_section_by_name(&kelf->sections, name);
|
|
||||||
if (!ignoresec)
|
|
||||||
--
|
|
||||||
1.7.5.4
|
|
||||||
|
|
||||||
@ -1,828 +0,0 @@
|
|||||||
From 9d590b5b9fb59c1cd52221feeef2794eb3333571 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
Date: Thu, 8 Nov 2018 15:12:06 +0000
|
|
||||||
Subject: [PATCH] support c plus kernel module
|
|
||||||
|
|
||||||
support GNU_UNIQUE type symbols.
|
|
||||||
support .group section corelation.
|
|
||||||
support symbol name longger than 128 bytes.
|
|
||||||
fix object size changed error for __FUNCTION__.xxx.
|
|
||||||
ignore compile warning for third party modules.
|
|
||||||
support functions have no fentry call.
|
|
||||||
support all function force enable/disable
|
|
||||||
fix sym replacing error for aarch64
|
|
||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
---
|
|
||||||
kmod/patch/livepatch-patch-hook.c | 8 ++
|
|
||||||
kpatch-build/create-diff-object.c | 161 ++++++++++++++++++++++++-----------
|
|
||||||
kpatch-build/create-klp-module.c | 27 +++++-
|
|
||||||
kpatch-build/create-kpatch-module.c | 15 +--
|
|
||||||
kpatch-build/kpatch-build | 7 ++-
|
|
||||||
kpatch-build/kpatch-elf.c | 8 ++-
|
|
||||||
kpatch-build/kpatch-gcc | 2 +-
|
|
||||||
kpatch-build/lookup.c | 125 +++++++++++++++++++++++++--
|
|
||||||
kpatch-build/lookup.h | 14 ++-
|
|
||||||
9 files changed, 287 insertions(+), 80 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
|
||||||
index fefc068..ce1c955 100644
|
|
||||||
--- a/kmod/patch/livepatch-patch-hook.c
|
|
||||||
+++ b/kmod/patch/livepatch-patch-hook.c
|
|
||||||
@@ -497,8 +497,12 @@ static int __init patch_init(void)
|
|
||||||
lfunc->old_name = func->kfunc->name;
|
|
||||||
lfunc->new_func = (void *)func->kfunc->new_addr;
|
|
||||||
#if defined(HAVE_IMMEDIATE)
|
|
||||||
+#ifdef __ALL_FORCE__
|
|
||||||
+ lfunc->immediate = 1;
|
|
||||||
+#else
|
|
||||||
lfunc->immediate = patch_is_func_forced(lfunc->new_func);
|
|
||||||
#endif
|
|
||||||
+#endif
|
|
||||||
#ifdef HAVE_SYMPOS
|
|
||||||
lfunc->old_sympos = func->kfunc->sympos;
|
|
||||||
#else
|
|
||||||
@@ -507,7 +511,11 @@ static int __init patch_init(void)
|
|
||||||
#ifdef __HULK__
|
|
||||||
lfunc->old_size = func->kfunc->old_size;
|
|
||||||
lfunc->new_size = func->kfunc->new_size;
|
|
||||||
+#ifdef __ALL_FORCE__
|
|
||||||
+ lfunc->force = 1;
|
|
||||||
+#else
|
|
||||||
lfunc->force = patch_is_func_forced(func->kfunc->new_addr);
|
|
||||||
+#endif
|
|
||||||
lfunc->ref_name= func->kfunc->ref_name;
|
|
||||||
lfunc->ref_offset = func->kfunc->ref_offset;
|
|
||||||
#endif
|
|
||||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
|
||||||
index 97ae0d4..8bb650d 100644
|
|
||||||
--- a/kpatch-build/create-diff-object.c
|
|
||||||
+++ b/kpatch-build/create-diff-object.c
|
|
||||||
@@ -224,6 +224,7 @@ static int is_special_static(struct symbol *sym)
|
|
||||||
"__func__.",
|
|
||||||
"_rs.",
|
|
||||||
"CSWTCH.",
|
|
||||||
+ "__FUNCTION__.",
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
char **prefix;
|
|
||||||
@@ -386,7 +387,7 @@ static void kpatch_compare_correlated_nonrela_section(struct section *sec)
|
|
||||||
{
|
|
||||||
struct section *sec1 = sec, *sec2 = sec->twin;
|
|
||||||
|
|
||||||
- if (sec1->sh.sh_type != SHT_NOBITS &&
|
|
||||||
+ if (sec1->sh.sh_type != SHT_NOBITS && sec1->sh.sh_type != SHT_GROUP &&
|
|
||||||
memcmp(sec1->data->d_buf, sec2->data->d_buf, sec1->data->d_size))
|
|
||||||
sec->status = CHANGED;
|
|
||||||
else
|
|
||||||
@@ -400,8 +401,9 @@ static void kpatch_compare_correlated_section(struct section *sec)
|
|
||||||
/* Compare section headers (must match or fatal) */
|
|
||||||
if (sec1->sh.sh_type != sec2->sh.sh_type ||
|
|
||||||
sec1->sh.sh_flags != sec2->sh.sh_flags ||
|
|
||||||
- sec1->sh.sh_addralign != sec2->sh.sh_addralign ||
|
|
||||||
- sec1->sh.sh_entsize != sec2->sh.sh_entsize)
|
|
||||||
+ sec1->sh.sh_entsize != sec2->sh.sh_entsize ||
|
|
||||||
+ (sec1->sh.sh_addralign != sec2->sh.sh_addralign &&
|
|
||||||
+ strcmp(sec1->name, ".rodata")))
|
|
||||||
DIFF_FATAL("%s section header details differ", sec1->name);
|
|
||||||
|
|
||||||
/* Short circuit for mcount sections, we rebuild regardless */
|
|
||||||
@@ -763,6 +765,33 @@ static void kpatch_compare_symbols(struct list_head *symlist)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int kpatch_correlate_group_section(struct list_head *seclist1, struct list_head *seclist2, struct section *sec1, struct section *sec2)
|
|
||||||
+{
|
|
||||||
+ unsigned int *data1, *end1, *data2;
|
|
||||||
+ struct section *isec1, *isec2;
|
|
||||||
+
|
|
||||||
+ if (sec1->data->d_size != sec2->data->d_size)
|
|
||||||
+ return 1;
|
|
||||||
+ data1 = sec1->data->d_buf;
|
|
||||||
+ data2 = sec2->data->d_buf;
|
|
||||||
+ end1 = sec1->data->d_buf + sec1->data->d_size;
|
|
||||||
+ data1++;
|
|
||||||
+ data2++;
|
|
||||||
+ while (data1 < end1) {
|
|
||||||
+ isec1 = find_section_by_index(seclist1, *data1);
|
|
||||||
+ if (!isec1)
|
|
||||||
+ ERROR("group section not found");
|
|
||||||
+ isec2 = find_section_by_index(seclist2, *data2);
|
|
||||||
+ if (!isec2)
|
|
||||||
+ ERROR("group section not found");
|
|
||||||
+ if (strcmp(isec1->name, isec2->name))
|
|
||||||
+ return 1;
|
|
||||||
+ data1++;
|
|
||||||
+ data2++;
|
|
||||||
+ }
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void kpatch_correlate_sections(struct list_head *seclist1, struct list_head *seclist2)
|
|
||||||
{
|
|
||||||
struct section *sec1, *sec2;
|
|
||||||
@@ -777,15 +806,18 @@ static void kpatch_correlate_sections(struct list_head *seclist1, struct list_he
|
|
||||||
sec1->secsym))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
- /*
|
|
||||||
- * Group sections must match exactly to be correlated.
|
|
||||||
- * Changed group sections are currently not supported.
|
|
||||||
- */
|
|
||||||
+ /* Group section的格式为:
|
|
||||||
+ * flag
|
|
||||||
+ * section index
|
|
||||||
+ * section index
|
|
||||||
+ * ...
|
|
||||||
+ *
|
|
||||||
+ * 当C++代码发生修改时,section index可能会发生变化
|
|
||||||
+ * 这时候我们就比对一下section index所对应的section的
|
|
||||||
+ * name,如果相同,我们就认为这两个group是SAME
|
|
||||||
+ * */
|
|
||||||
if (sec1->sh.sh_type == SHT_GROUP) {
|
|
||||||
- if (sec1->data->d_size != sec2->data->d_size)
|
|
||||||
- continue;
|
|
||||||
- if (memcmp(sec1->data->d_buf, sec2->data->d_buf,
|
|
||||||
- sec1->data->d_size))
|
|
||||||
+ if(kpatch_correlate_group_section(seclist1, seclist2, sec1, sec2))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
sec1->twin = sec2;
|
|
||||||
@@ -1308,17 +1340,21 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf)
|
|
||||||
#ifdef __powerpc64__
|
|
||||||
add_off = 0;
|
|
||||||
#else
|
|
||||||
- if (rela->type == R_X86_64_PC32) {
|
|
||||||
- struct insn insn;
|
|
||||||
- rela_insn(sec, rela, &insn);
|
|
||||||
- add_off = (long)insn.next_byte -
|
|
||||||
- (long)sec->base->data->d_buf -
|
|
||||||
- rela->offset;
|
|
||||||
- } else if (rela->type == R_X86_64_64 ||
|
|
||||||
- rela->type == R_X86_64_32S)
|
|
||||||
- add_off = 0;
|
|
||||||
- else
|
|
||||||
- continue;
|
|
||||||
+ add_off = 0;
|
|
||||||
+ if (arch == EM_X86_64) {
|
|
||||||
+ if (rela->type == R_X86_64_PC32) {
|
|
||||||
+ struct insn insn;
|
|
||||||
+ rela_insn(sec, rela, &insn);
|
|
||||||
+ add_off = (long)insn.next_byte -
|
|
||||||
+ (long)sec->base->data->d_buf -
|
|
||||||
+ rela->offset;
|
|
||||||
+ } else if (rela->type == R_X86_64_64 ||
|
|
||||||
+ rela->type == R_X86_64_32S)
|
|
||||||
+ add_off = 0;
|
|
||||||
+ else
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+ /* add_off is always equal to 0 on arm64 */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -1421,17 +1457,6 @@ static void kpatch_verify_patchability(struct kpatch_elf *kelf)
|
|
||||||
errs++;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (sec->status != SAME && sec->grouped) {
|
|
||||||
- log_normal("changed section %s is part of a section group\n",
|
|
||||||
- sec->name);
|
|
||||||
- errs++;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (sec->sh.sh_type == SHT_GROUP && sec->status == NEW) {
|
|
||||||
- log_normal("new/changed group sections are not supported\n");
|
|
||||||
- errs++;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
* ensure we aren't including .data.* or .bss.*
|
|
||||||
* (.data.unlikely and .data.once is ok b/c it only has __warned vars)
|
|
||||||
@@ -1458,6 +1483,7 @@ static void kpatch_include_section(struct section *sec)
|
|
||||||
/* Include the section and its section symbol */
|
|
||||||
if (sec->include)
|
|
||||||
return;
|
|
||||||
+
|
|
||||||
sec->include = 1;
|
|
||||||
if (sec->secsym)
|
|
||||||
sec->secsym->include = 1;
|
|
||||||
@@ -1640,7 +1666,7 @@ static void kpatch_include_force_elements(struct kpatch_elf *kelf)
|
|
||||||
sym->include = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-int kpatch_include_new_static_var(struct kpatch_elf *kelf)
|
|
||||||
+static int kpatch_include_new_static_var(struct kpatch_elf *kelf)
|
|
||||||
{
|
|
||||||
struct symbol *sym;
|
|
||||||
|
|
||||||
@@ -2253,6 +2279,23 @@ static void kpatch_include_debug_sections(struct kpatch_elf *kelf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void kpatch_ignore_debug_sections(struct kpatch_elf *kelf)
|
|
||||||
+{
|
|
||||||
+ struct section *sec;
|
|
||||||
+
|
|
||||||
+ /* include all .debug_* sections */
|
|
||||||
+ list_for_each_entry(sec, &kelf->sections, list) {
|
|
||||||
+ if (is_debug_section(sec)) {
|
|
||||||
+ sec->include = 0;
|
|
||||||
+ sec->status = SAME;
|
|
||||||
+ if (!is_rela_section(sec)) {
|
|
||||||
+ sec->secsym->include = 0;
|
|
||||||
+ sec->secsym->status = SAME;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void kpatch_mark_ignored_sections(struct kpatch_elf *kelf)
|
|
||||||
{
|
|
||||||
struct section *sec, *strsec, *ignoresec;
|
|
||||||
@@ -2589,14 +2632,13 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
|
||||||
funcs[index].old_size = result.size;
|
|
||||||
funcs[index].new_size = sym->sym.st_size;
|
|
||||||
funcs[index].sympos = result.pos;
|
|
||||||
- if (lookup_is_duplicate_symbol(table, sym->name)) {
|
|
||||||
+ if (lookup_is_duplicate_symbol(table, sym->name, objname, result.pos)) {
|
|
||||||
struct lookup_refsym refsym;
|
|
||||||
long offset;
|
|
||||||
|
|
||||||
- if (lookup_ref_symbol(table, sym->name, &refsym))
|
|
||||||
+ if (lookup_ref_symbol_offset(table, sym->name, &refsym, objname, &offset))
|
|
||||||
ERROR("unresolvable ambiguity on symbol %s\n", sym->name);
|
|
||||||
|
|
||||||
- offset = (long)result.value - (long)refsym.value;
|
|
||||||
funcs[index].ref_offset = offset;
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -2631,7 +2673,7 @@ static void kpatch_create_patches_sections(struct kpatch_elf *kelf,
|
|
||||||
ALLOC_LINK(rela, &relasec->relas);
|
|
||||||
rela->sym = strsym;
|
|
||||||
rela->type = absolute_rela_type;
|
|
||||||
- rela->addend = offset_of_string(&kelf->strings, sym->name);
|
|
||||||
+ rela->addend = offset_of_string(&kelf->strings, strndup(sym->name, KSYM_NAME_LEN-1));
|
|
||||||
rela->offset = index * sizeof(*funcs) +
|
|
||||||
offsetof(struct kpatch_patch_func, name);
|
|
||||||
|
|
||||||
@@ -2780,13 +2822,14 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
|
||||||
*/
|
|
||||||
if (may_need_dynrela(rela))
|
|
||||||
toc_rela(rela)->need_dynrela = 1;
|
|
||||||
+
|
|
||||||
if (rela->sym->sec) {
|
|
||||||
if (rela->sym->type == STT_FUNC &&
|
|
||||||
- rela->sym->status == CHANGED &&
|
|
||||||
- rela->sym->sec != sec->base &&
|
|
||||||
- sec->base->sym &&
|
|
||||||
- sec->base->sym->type == STT_FUNC)
|
|
||||||
- toc_rela(rela)->need_dynrela = 1;
|
|
||||||
+ rela->sym->status == CHANGED &&
|
|
||||||
+ rela->sym->sec != sec->base &&
|
|
||||||
+ sec->base->sym &&
|
|
||||||
+ sec->base->sym->type == STT_FUNC)
|
|
||||||
+ toc_rela(rela)->need_dynrela = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2820,6 +2863,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
|
||||||
if (!strcmp(sec->name, ".rela.kpatch.funcs") ||
|
|
||||||
!strcmp(sec->name, ".rela.kpatch.dynrelas"))
|
|
||||||
continue;
|
|
||||||
+
|
|
||||||
list_for_each_entry_safe(rela, safe, &sec->relas, list) {
|
|
||||||
if (!rela->need_dynrela)
|
|
||||||
continue;
|
|
||||||
@@ -2963,13 +3007,12 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
|
||||||
else {
|
|
||||||
/* for modules, src is discovered at runtime */
|
|
||||||
ksyms[index].src = 0;
|
|
||||||
- if (lookup_is_duplicate_symbol(table, rela->sym->name)) {
|
|
||||||
+ if (lookup_is_duplicate_symbol(table, rela->sym->name, objname, result.pos)) {
|
|
||||||
struct lookup_refsym refsym;
|
|
||||||
|
|
||||||
- if (lookup_ref_symbol(table, rela->sym->name, &refsym))
|
|
||||||
+ if (lookup_ref_symbol_offset(table, rela->sym->name, &refsym, objname, &ref_offset))
|
|
||||||
ERROR("unresolvable ambiguity on symbol %s\n", rela->sym->name);
|
|
||||||
|
|
||||||
- ref_offset = (long)result.value - (long)refsym.value;
|
|
||||||
/* add rela to fill in ref_name field */
|
|
||||||
ALLOC_LINK(rela2, &krela_sec->rela->relas);
|
|
||||||
rela2->sym = strsym;
|
|
||||||
@@ -2987,7 +3030,7 @@ static void kpatch_create_intermediate_sections(struct kpatch_elf *kelf,
|
|
||||||
ALLOC_LINK(rela2, &ksym_sec->rela->relas);
|
|
||||||
rela2->sym = strsym;
|
|
||||||
rela2->type = absolute_rela_type;
|
|
||||||
- rela2->addend = offset_of_string(&kelf->strings, rela->sym->name);
|
|
||||||
+ rela2->addend = offset_of_string(&kelf->strings, strndup(rela->sym->name, KSYM_NAME_LEN-1));
|
|
||||||
rela2->offset = index * sizeof(*ksyms) + \
|
|
||||||
offsetof(struct kpatch_symbol, name);
|
|
||||||
|
|
||||||
@@ -3163,6 +3206,9 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf)
|
|
||||||
* __fentry__" so that ftrace will be happy.
|
|
||||||
*/
|
|
||||||
newdata = malloc(sym->sec->data->d_size);
|
|
||||||
+ if (!newdata)
|
|
||||||
+ ERROR("malloc");
|
|
||||||
+
|
|
||||||
memcpy(newdata, sym->sec->data->d_buf, sym->sec->data->d_size);
|
|
||||||
sym->sec->data->d_buf = newdata;
|
|
||||||
insn = newdata;
|
|
||||||
@@ -3186,6 +3232,8 @@ static void kpatch_create_mcount_sections(struct kpatch_elf *kelf)
|
|
||||||
rela->offset = index * sizeof(*funcs);
|
|
||||||
|
|
||||||
newdata = malloc(sym->sec->data->d_size);
|
|
||||||
+ if (!newdata)
|
|
||||||
+ ERROR("malloc");
|
|
||||||
memcpy(newdata, sym->sec->data->d_buf, sym->sec->data->d_size);
|
|
||||||
sym->sec->data->d_buf = newdata;
|
|
||||||
insnp = newdata;
|
|
||||||
@@ -3354,6 +3402,8 @@ int main(int argc, char *argv[])
|
|
||||||
char *parent_symtab, *mod_symvers, *patch_name, *output_obj;
|
|
||||||
struct sym_compare_type *base_locals;
|
|
||||||
char *gcc_add_option, *mlongcall;
|
|
||||||
+ char *no_profiling_calls;
|
|
||||||
+ char *kallsyms;
|
|
||||||
|
|
||||||
arguments.debug = 0;
|
|
||||||
argp_parse (&argp, argc, argv, 0, NULL, &arguments);
|
|
||||||
@@ -3400,9 +3450,12 @@ int main(int argc, char *argv[])
|
|
||||||
return EXIT_STATUS_NO_CHANGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ kallsyms = getenv("KALLSYMS");
|
|
||||||
+ if (kallsyms)
|
|
||||||
+ log_debug("kallsyms file:%s\n", kallsyms);
|
|
||||||
/* create symbol lookup table */
|
|
||||||
base_locals = kpatch_elf_locals(kelf_base);
|
|
||||||
- lookup = lookup_open(parent_symtab, mod_symvers, hint, base_locals);
|
|
||||||
+ lookup = lookup_open(parent_symtab, mod_symvers, hint, base_locals, kallsyms);
|
|
||||||
free(base_locals);
|
|
||||||
|
|
||||||
kpatch_mark_grouped_sections(kelf_patched);
|
|
||||||
@@ -3420,7 +3473,12 @@ int main(int argc, char *argv[])
|
|
||||||
*/
|
|
||||||
kpatch_mark_ignored_sections(kelf_patched);
|
|
||||||
kpatch_compare_correlated_elements(kelf_patched);
|
|
||||||
- kpatch_check_func_profiling_calls(kelf_patched);
|
|
||||||
+
|
|
||||||
+ no_profiling_calls = getenv("NO_PROFILING_CALLS");
|
|
||||||
+ if (!no_profiling_calls)
|
|
||||||
+ kpatch_check_func_profiling_calls(kelf_patched);
|
|
||||||
+ else
|
|
||||||
+ log_debug("NO_PROFILING_CALLS set\n");
|
|
||||||
kpatch_elf_teardown(kelf_base);
|
|
||||||
kpatch_elf_free(kelf_base);
|
|
||||||
|
|
||||||
@@ -3430,6 +3488,7 @@ int main(int argc, char *argv[])
|
|
||||||
kpatch_include_standard_elements(kelf_patched);
|
|
||||||
num_changed = kpatch_include_changed_functions(kelf_patched);
|
|
||||||
kpatch_include_debug_sections(kelf_patched);
|
|
||||||
+ kpatch_ignore_debug_sections(kelf_patched);
|
|
||||||
callbacks_exist = kpatch_include_callback_elements(kelf_patched);
|
|
||||||
kpatch_include_force_elements(kelf_patched);
|
|
||||||
new_globals_exist = kpatch_include_new_globals(kelf_patched);
|
|
||||||
@@ -3470,10 +3529,10 @@ int main(int argc, char *argv[])
|
|
||||||
kpatch_build_strings_section_data(kelf_out);
|
|
||||||
|
|
||||||
gcc_add_option = getenv("GCC_ADD_OPTION");
|
|
||||||
- printf("gcc add option :%s\n", gcc_add_option);
|
|
||||||
+ log_debug("gcc add option :%s\n", gcc_add_option);
|
|
||||||
mlongcall = strstr(gcc_add_option, "-mlong-calls");
|
|
||||||
if (arch == EM_AARCH64 && mlongcall) {
|
|
||||||
- printf("-mlong-calls found, no need to create mcount section\n");
|
|
||||||
+ log_debug("-mlong-calls found, no need to create mcount section\n");
|
|
||||||
} else {
|
|
||||||
kpatch_create_mcount_sections(kelf_out);
|
|
||||||
}
|
|
||||||
diff --git a/kpatch-build/create-klp-module.c b/kpatch-build/create-klp-module.c
|
|
||||||
index 253704b..7a72afd 100644
|
|
||||||
--- a/kpatch-build/create-klp-module.c
|
|
||||||
+++ b/kpatch-build/create-klp-module.c
|
|
||||||
@@ -38,7 +38,9 @@ enum loglevel loglevel = NORMAL;
|
|
||||||
*/
|
|
||||||
static struct symbol *find_or_add_ksym_to_symbols(struct kpatch_elf *kelf,
|
|
||||||
struct section *ksymsec,
|
|
||||||
- char *strings, int offset)
|
|
||||||
+ char *strings, int offset,
|
|
||||||
+ char *ref_name,
|
|
||||||
+ long ref_offset)
|
|
||||||
{
|
|
||||||
struct kpatch_symbol *ksyms, *ksym;
|
|
||||||
struct symbol *sym;
|
|
||||||
@@ -71,9 +73,14 @@ static struct symbol *find_or_add_ksym_to_symbols(struct kpatch_elf *kelf,
|
|
||||||
if (!objname)
|
|
||||||
ERROR("strdup");
|
|
||||||
|
|
||||||
- snprintf(pos, 32, "%lu", ksym->pos);
|
|
||||||
/* .klp.sym.objname.name,pos */
|
|
||||||
- snprintf(buf, 256, KLP_SYM_PREFIX "%s.%s,%s", objname, name, pos);
|
|
||||||
+ if (!ref_name) {
|
|
||||||
+ snprintf(pos, 32, "%lu", ksym->pos);
|
|
||||||
+ snprintf(buf, 256, KLP_SYM_PREFIX "%s.%s,%s", objname, name, pos);
|
|
||||||
+ } else {
|
|
||||||
+ snprintf(pos, 32, "%ld", ref_offset);
|
|
||||||
+ snprintf(buf, 256, KLP_SYM_PREFIX "%s-%s,%s", objname, ref_name, pos);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/* Look for an already allocated symbol */
|
|
||||||
list_for_each_entry(sym, &kelf->symbols, list) {
|
|
||||||
@@ -180,6 +187,7 @@ static void create_klp_relasecs_and_syms(struct kpatch_elf *kelf, struct section
|
|
||||||
struct rela *rela;
|
|
||||||
char *objname;
|
|
||||||
int nr, index, offset, dest_off;
|
|
||||||
+ char *ref_name;
|
|
||||||
|
|
||||||
krelas = krelasec->data->d_buf;
|
|
||||||
nr = krelasec->data->d_size / sizeof(*krelas);
|
|
||||||
@@ -206,6 +214,17 @@ static void create_klp_relasecs_and_syms(struct kpatch_elf *kelf, struct section
|
|
||||||
if (!objname)
|
|
||||||
ERROR("strdup");
|
|
||||||
|
|
||||||
+ /* Get the unique ref_name */
|
|
||||||
+ rela = find_rela_by_offset(krelasec->rela,
|
|
||||||
+ offset + offsetof(struct kpatch_relocation, ref_name));
|
|
||||||
+ if (!rela)
|
|
||||||
+ ref_name = NULL;
|
|
||||||
+ else {
|
|
||||||
+ ref_name = strdup(strings + rela->addend);
|
|
||||||
+ if (!ref_name)
|
|
||||||
+ ERROR("strdup");
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* Get the .kpatch.symbol entry for the rela src */
|
|
||||||
rela = find_rela_by_offset(krelasec->rela,
|
|
||||||
offset + offsetof(struct kpatch_relocation, ksym));
|
|
||||||
@@ -213,7 +232,7 @@ static void create_klp_relasecs_and_syms(struct kpatch_elf *kelf, struct section
|
|
||||||
ERROR("find_rela_by_offset");
|
|
||||||
|
|
||||||
/* Create (or find) a klp symbol from the rela src entry */
|
|
||||||
- sym = find_or_add_ksym_to_symbols(kelf, ksymsec, strings, rela->addend);
|
|
||||||
+ sym = find_or_add_ksym_to_symbols(kelf, ksymsec, strings, rela->addend, ref_name, krelas[index].ref_offset);
|
|
||||||
if (!sym)
|
|
||||||
ERROR("error finding or adding ksym to symtab");
|
|
||||||
|
|
||||||
diff --git a/kpatch-build/create-kpatch-module.c b/kpatch-build/create-kpatch-module.c
|
|
||||||
index 8292dc8..3e24b3a 100644
|
|
||||||
--- a/kpatch-build/create-kpatch-module.c
|
|
||||||
+++ b/kpatch-build/create-kpatch-module.c
|
|
||||||
@@ -112,14 +112,10 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section
|
|
||||||
dynrelas[index].ref_name = krelas[index].ref_name;
|
|
||||||
dynrelas[index].ref_offset = krelas[index].ref_offset;
|
|
||||||
|
|
||||||
- if (dynrelas[index].ref_offset)
|
|
||||||
- {
|
|
||||||
- /* Get objname offset */
|
|
||||||
- rela = find_rela_by_offset(krelasec->rela,
|
|
||||||
- index * sizeof(*krelas) + offsetof(struct kpatch_relocation, ref_name));
|
|
||||||
- if (!rela) {
|
|
||||||
- ERROR("find_rela_by_offset");
|
|
||||||
- }
|
|
||||||
+ /* Get ref_name offset */
|
|
||||||
+ rela = find_rela_by_offset(krelasec->rela,
|
|
||||||
+ index * sizeof(*krelas) + offsetof(struct kpatch_relocation, ref_name));
|
|
||||||
+ if (rela) {
|
|
||||||
ref_name_offset = rela->addend;
|
|
||||||
/* ref_name */
|
|
||||||
ALLOC_LINK(rela, &dynsec->rela->relas);
|
|
||||||
@@ -128,9 +124,8 @@ static void create_dynamic_rela_sections(struct kpatch_elf *kelf, struct section
|
|
||||||
rela->addend = ref_name_offset;
|
|
||||||
rela->offset = index * sizeof(*dynrelas) + \
|
|
||||||
offsetof(struct kpatch_patch_dynrela, ref_name);
|
|
||||||
-
|
|
||||||
}
|
|
||||||
-
|
|
||||||
+
|
|
||||||
/* dest */
|
|
||||||
ALLOC_LINK(rela, &dynsec->rela->relas);
|
|
||||||
rela->sym = sym;
|
|
||||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
|
||||||
index 81a6a44..a860f12 100755
|
|
||||||
--- a/kpatch-build/kpatch-build
|
|
||||||
+++ b/kpatch-build/kpatch-build
|
|
||||||
@@ -953,6 +953,10 @@ if grep "hulk" $SRCDIR/Makefile > /dev/null; then
|
|
||||||
export KCPPFLAGS="-D__HULK__ $KCPPFLAGS"
|
|
||||||
fi
|
|
||||||
|
|
||||||
+if [[ -n "$NO_STACK_CHECK" ]];then
|
|
||||||
+ export KCPPFLAGS="-D__ALL_FORCE__ $KCPPFLAGS"
|
|
||||||
+fi
|
|
||||||
+
|
|
||||||
echo "Building patch module: $MODNAME.ko"
|
|
||||||
|
|
||||||
if [[ -z "$USERSRCDIR" ]] && [[ "$DISTRO" = ubuntu ]]; then
|
|
||||||
@@ -990,6 +994,7 @@ KBUILD_EXTRA_SYMBOLS="$KBUILD_EXTRA_SYMBOLS" \
|
|
||||||
KPATCH_LDFLAGS="$KPATCH_LDFLAGS" \
|
|
||||||
CROSS_COMPILE="$ARCH_COMPILE" \
|
|
||||||
make 2>&1 | logger || die
|
|
||||||
+${ARCH_COMPILE}strip -g "$TEMPDIR/patch/$MODNAME.ko"
|
|
||||||
|
|
||||||
if ! "$KPATCH_MODULE"; then
|
|
||||||
if [[ -z "$KPATCH_LDFLAGS" ]]; then
|
|
||||||
@@ -1019,7 +1024,7 @@ fi
|
|
||||||
# column containing lines unique to first file.
|
|
||||||
UNDEFINED=$(comm -23 <(sort -u "${TEMPDIR}"/undefined_references) \
|
|
||||||
<(sort -u "${TEMPDIR}"/new_symbols) | tr '\n' ' ')
|
|
||||||
-[[ ! -z "$UNDEFINED" ]] && die "Undefined symbols: $UNDEFINED"
|
|
||||||
+[[ -z "$USERMODDIR" ]] && [[ ! -z "$UNDEFINED" ]] && die "Undefined symbols: $UNDEFINED"
|
|
||||||
|
|
||||||
cp -f "$TEMPDIR/patch/$MODNAME.ko" "$BASE" || die
|
|
||||||
|
|
||||||
diff --git a/kpatch-build/kpatch-elf.c b/kpatch-build/kpatch-elf.c
|
|
||||||
index fcb7161..0794031 100644
|
|
||||||
--- a/kpatch-build/kpatch-elf.c
|
|
||||||
+++ b/kpatch-build/kpatch-elf.c
|
|
||||||
@@ -700,8 +700,14 @@ void kpatch_reindex_elements(struct kpatch_elf *kelf)
|
|
||||||
unsigned int index;
|
|
||||||
|
|
||||||
index = 1; /* elf write function handles NULL section 0 */
|
|
||||||
- list_for_each_entry(sec, &kelf->sections, list)
|
|
||||||
+ list_for_each_entry(sec, &kelf->sections, list) {
|
|
||||||
sec->index = index++;
|
|
||||||
+ /*
|
|
||||||
+ * since we exclude .group section, we clear SHF_GROUP
|
|
||||||
+ * for every section in case of link error.
|
|
||||||
+ * */
|
|
||||||
+ sec->sh.sh_flags &= (~SHF_GROUP);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
index = 0;
|
|
||||||
list_for_each_entry(sym, &kelf->symbols, list) {
|
|
||||||
diff --git a/kpatch-build/kpatch-gcc b/kpatch-build/kpatch-gcc
|
|
||||||
index be18847..d36e67b 100755
|
|
||||||
--- a/kpatch-build/kpatch-gcc
|
|
||||||
+++ b/kpatch-build/kpatch-gcc
|
|
||||||
@@ -13,7 +13,7 @@ fi
|
|
||||||
|
|
||||||
declare -a args=("$@")
|
|
||||||
|
|
||||||
-if [[ "$TOOLCHAINCMD" = ${ARCH_COMPILE}gcc ]] ; then
|
|
||||||
+if [[ "$TOOLCHAINCMD" = ${ARCH_COMPILE}gcc || "$TOOLCHAINCMD" = ${ARCH_COMPILE}g++ ]] ; then
|
|
||||||
while [ "$#" -gt 0 ]; do
|
|
||||||
if [ "$1" = "-o" ]; then
|
|
||||||
obj="$2"
|
|
||||||
diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c
|
|
||||||
index e4677db..2a728f6 100644
|
|
||||||
--- a/kpatch-build/lookup.c
|
|
||||||
+++ b/kpatch-build/lookup.c
|
|
||||||
@@ -45,6 +45,7 @@ struct object_symbol {
|
|
||||||
char *name;
|
|
||||||
int type, bind;
|
|
||||||
int sec_index;
|
|
||||||
+ unsigned long kaddr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct export_symbol {
|
|
||||||
@@ -238,6 +239,8 @@ static void symtab_read(struct lookup_table *table, char *path)
|
|
||||||
table->obj_syms[i].bind = STB_GLOBAL;
|
|
||||||
} else if (!strcmp(bind, "WEAK")) {
|
|
||||||
table->obj_syms[i].bind = STB_WEAK;
|
|
||||||
+ } else if (!strcmp(bind, "GNU_UNIQUE")) {
|
|
||||||
+ table->obj_syms[i].bind = STB_GNU_UNIQUE;
|
|
||||||
} else {
|
|
||||||
ERROR("unknown symbol bind %s", bind);
|
|
||||||
}
|
|
||||||
@@ -263,6 +266,56 @@ static void symtab_read(struct lookup_table *table, char *path)
|
|
||||||
fclose(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void ksymtab_read(struct lookup_table *table, char *path)
|
|
||||||
+{
|
|
||||||
+ FILE *file;
|
|
||||||
+ struct object_symbol *sym, *sym1, *sym2;
|
|
||||||
+ unsigned long value;
|
|
||||||
+ int i, j, idx;
|
|
||||||
+ char line[256], name[256], type[256], mod[256];
|
|
||||||
+ idx = 0;
|
|
||||||
+
|
|
||||||
+ if ((file = fopen(path, "r")) == NULL)
|
|
||||||
+ ERROR("fopen");
|
|
||||||
+
|
|
||||||
+ while (fgets(line, 256, file)) {
|
|
||||||
+ if (sscanf(line, "%lx %s %s [%s]\n",
|
|
||||||
+ &value, type, name, mod) != 4)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ if (name[0] == '$')
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ i = idx;
|
|
||||||
+ for_each_obj_symbol_continue(i, sym, table) {
|
|
||||||
+ if (!strncmp(sym->name, name, KSYM_NAME_LEN-1)) {
|
|
||||||
+ sym->kaddr = value;
|
|
||||||
+ idx = i + 1;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for_each_obj_symbol(i, sym1, table) {
|
|
||||||
+ if (sym1->kaddr == 0)
|
|
||||||
+ continue;
|
|
||||||
+ for_each_obj_symbol(j, sym2, table) {
|
|
||||||
+ if (sym2->kaddr == 0)
|
|
||||||
+ continue;
|
|
||||||
+ if (sym1 == sym2)
|
|
||||||
+ continue;
|
|
||||||
+ if (sym1->sec_index != sym2->sec_index)
|
|
||||||
+ continue;
|
|
||||||
+ if ((long)sym1->value - (long)sym2->value ==
|
|
||||||
+ (long)sym1->kaddr - (long)sym2->kaddr)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ ERROR("base mismatch(symbol offset)");
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ fclose(file);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void symvers_read(struct lookup_table *table, char *path)
|
|
||||||
{
|
|
||||||
FILE *file;
|
|
||||||
@@ -306,7 +359,8 @@ static void symvers_read(struct lookup_table *table, char *path)
|
|
||||||
}
|
|
||||||
|
|
||||||
struct lookup_table *lookup_open(char *symtab_path, char *symvers_path,
|
|
||||||
- char *hint, struct sym_compare_type *locals)
|
|
||||||
+ char *hint, struct sym_compare_type *locals,
|
|
||||||
+ char *kallsyms)
|
|
||||||
{
|
|
||||||
struct lookup_table *table;
|
|
||||||
|
|
||||||
@@ -317,6 +371,8 @@ struct lookup_table *lookup_open(char *symtab_path, char *symvers_path,
|
|
||||||
|
|
||||||
symtab_read(table, symtab_path);
|
|
||||||
symvers_read(table, symvers_path);
|
|
||||||
+ if (kallsyms)
|
|
||||||
+ ksymtab_read(table, kallsyms);
|
|
||||||
find_local_syms(table, hint, locals);
|
|
||||||
|
|
||||||
return table;
|
|
||||||
@@ -343,6 +399,15 @@ int lookup_local_symbol(struct lookup_table *table, char *name,
|
|
||||||
for_each_obj_symbol(i, sym, table) {
|
|
||||||
if (sym->bind == STB_LOCAL && !strcmp(sym->name, name))
|
|
||||||
pos++;
|
|
||||||
+ else {
|
|
||||||
+ /* symbol name longer than KSYM_NAME_LEN will be truncated
|
|
||||||
+ * by kernel, so we can not find it using its original
|
|
||||||
+ * name. we need to add pos for symbols which have same
|
|
||||||
+ * KSYM_NAME_LEN-1 long prefix.*/
|
|
||||||
+ if (strlen(name) >= KSYM_NAME_LEN-1 &&
|
|
||||||
+ !strncmp(sym->name, name, KSYM_NAME_LEN-1))
|
|
||||||
+ pos++;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if (table->local_syms == sym) {
|
|
||||||
in_file = 1;
|
|
||||||
@@ -374,15 +439,25 @@ int lookup_global_symbol(struct lookup_table *table, char *name,
|
|
||||||
struct lookup_result *result)
|
|
||||||
{
|
|
||||||
struct object_symbol *sym;
|
|
||||||
+ unsigned long pos = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
memset(result, 0, sizeof(*result));
|
|
||||||
for_each_obj_symbol(i, sym, table) {
|
|
||||||
- if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK) &&
|
|
||||||
+ /* symbol name longer than KSYM_NAME_LEN will be truncated
|
|
||||||
+ * by kernel, so we can not find it using its original
|
|
||||||
+ * name. we need to add pos for symbols which have same
|
|
||||||
+ * KSYM_NAME_LEN-1 long prefix.*/
|
|
||||||
+ if (strlen(name) >= KSYM_NAME_LEN-1 &&
|
|
||||||
+ !strncmp(sym->name, name, KSYM_NAME_LEN-1))
|
|
||||||
+ pos++;
|
|
||||||
+
|
|
||||||
+ if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK
|
|
||||||
+ || sym->bind == STB_GNU_UNIQUE) &&
|
|
||||||
!strcmp(sym->name, name)) {
|
|
||||||
result->value = sym->value;
|
|
||||||
result->size = sym->size;
|
|
||||||
- result->pos = 0; /* always 0 for global symbols */
|
|
||||||
+ result->pos = pos;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -429,10 +504,12 @@ char *lookup_exported_symbol_objname(struct lookup_table *table, char *name)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
-int lookup_is_duplicate_symbol(struct lookup_table *table, char *name)
|
|
||||||
+int lookup_is_duplicate_symbol(struct lookup_table *table, char *name,
|
|
||||||
+ char *objname, unsigned long pos)
|
|
||||||
{
|
|
||||||
struct object_symbol *sym;
|
|
||||||
int i, count = 0;
|
|
||||||
+ char posstr[32], buf[256];
|
|
||||||
|
|
||||||
for_each_obj_symbol(i, sym, table)
|
|
||||||
if (!strcmp(sym->name, name)) {
|
|
||||||
@@ -441,6 +518,17 @@ int lookup_is_duplicate_symbol(struct lookup_table *table, char *name)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* symbol name longer than KSYM_NAME_LEN will be truncated
|
|
||||||
+ * by kernel, so we can not find it using its original
|
|
||||||
+ * name. Here, we consider these long name symbol as duplicated
|
|
||||||
+ * symbols. since create_klp_module will create symbol name
|
|
||||||
+ * format like .klp.sym.objname.symbol,pos, so we consider name
|
|
||||||
+ * length longer than KSYM_NAME_LEN-1 bytes as duplicated symbol*/
|
|
||||||
+ snprintf(posstr, 32, "%lu", pos);
|
|
||||||
+ snprintf(buf, 256, KLP_SYM_PREFIX "%s.%s,%s", objname, name, posstr);
|
|
||||||
+ if (strlen(buf) >= KSYM_NAME_LEN-1)
|
|
||||||
+ return 1;
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -487,24 +575,45 @@ struct object_symbol *lookup_find_symbol_by_name(struct lookup_table *table, cha
|
|
||||||
return sym;
|
|
||||||
}
|
|
||||||
|
|
||||||
-int lookup_ref_symbol(struct lookup_table *table, char *name,
|
|
||||||
- struct lookup_refsym *refsym)
|
|
||||||
+int lookup_ref_symbol_offset(struct lookup_table *table, char *name,
|
|
||||||
+ struct lookup_refsym *refsym,
|
|
||||||
+ char *objname, long *offset)
|
|
||||||
{
|
|
||||||
struct object_symbol *orig_sym, *sym;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
orig_sym = lookup_find_symbol_by_name(table, name);
|
|
||||||
if (!orig_sym)
|
|
||||||
- ERROR("lookup_ref_symbol");
|
|
||||||
+ ERROR("lookup_ref_symbol_offset");
|
|
||||||
memset(refsym, 0, sizeof(*refsym));
|
|
||||||
+
|
|
||||||
+ /*find a unique symbol in the same section first*/
|
|
||||||
for_each_obj_symbol(i, sym, table) {
|
|
||||||
if (!strcmp(sym->name, name) || sym->type == STT_FILE ||
|
|
||||||
sym->sec_index != orig_sym->sec_index)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
- if (!lookup_is_duplicate_symbol(table, sym->name)) {
|
|
||||||
+ if (!lookup_is_duplicate_symbol(table, sym->name, objname, 1)) {
|
|
||||||
refsym->name = sym->name;
|
|
||||||
refsym->value = sym->value;
|
|
||||||
+ *offset = (long)orig_sym->value - (long)sym->value;
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (orig_sym->kaddr == 0)
|
|
||||||
+ return 1;
|
|
||||||
+
|
|
||||||
+ /*find a unique symbol has kaddr*/
|
|
||||||
+ for_each_obj_symbol(i, sym, table) {
|
|
||||||
+ if (!strcmp(sym->name, name) || sym->type == STT_FILE ||
|
|
||||||
+ sym->kaddr == 0)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ if (!lookup_is_duplicate_symbol(table, sym->name, objname, 1)) {
|
|
||||||
+ refsym->name = sym->name;
|
|
||||||
+ refsym->value = 0;
|
|
||||||
+ *offset = (long)orig_sym->kaddr - (long)sym->kaddr;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diff --git a/kpatch-build/lookup.h b/kpatch-build/lookup.h
|
|
||||||
index 5ad9241..00b6ccc 100644
|
|
||||||
--- a/kpatch-build/lookup.h
|
|
||||||
+++ b/kpatch-build/lookup.h
|
|
||||||
@@ -1,6 +1,9 @@
|
|
||||||
#ifndef _LOOKUP_H_
|
|
||||||
#define _LOOKUP_H_
|
|
||||||
|
|
||||||
+#include "kpatch-elf.h"
|
|
||||||
+#define KSYM_NAME_LEN 128
|
|
||||||
+
|
|
||||||
struct lookup_table;
|
|
||||||
|
|
||||||
struct lookup_result {
|
|
||||||
@@ -20,7 +23,8 @@ struct lookup_refsym {
|
|
||||||
};
|
|
||||||
|
|
||||||
struct lookup_table *lookup_open(char *symtab_path, char *symvers_path,
|
|
||||||
- char *hint, struct sym_compare_type *locals);
|
|
||||||
+ char *hint, struct sym_compare_type *locals,
|
|
||||||
+ char *kallsyms);
|
|
||||||
void lookup_close(struct lookup_table *table);
|
|
||||||
int lookup_local_symbol(struct lookup_table *table, char *name,
|
|
||||||
struct lookup_result *result);
|
|
||||||
@@ -28,8 +32,10 @@ int lookup_global_symbol(struct lookup_table *table, char *name,
|
|
||||||
struct lookup_result *result);
|
|
||||||
int lookup_is_exported_symbol(struct lookup_table *table, char *name);
|
|
||||||
char *lookup_exported_symbol_objname(struct lookup_table *table, char *name);
|
|
||||||
-int lookup_is_duplicate_symbol(struct lookup_table *table, char *name);
|
|
||||||
-int lookup_ref_symbol(struct lookup_table *table, char *name,
|
|
||||||
- struct lookup_refsym *refsym);
|
|
||||||
+int lookup_is_duplicate_symbol(struct lookup_table *table, char *name,
|
|
||||||
+ char *objname, unsigned long pos);
|
|
||||||
+int lookup_ref_symbol_offset(struct lookup_table *table, char *name,
|
|
||||||
+ struct lookup_refsym *refsym, char *objname,
|
|
||||||
+ long *offset);
|
|
||||||
|
|
||||||
#endif /* _LOOKUP_H_ */
|
|
||||||
--
|
|
||||||
1.7.5.4
|
|
||||||
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
From f221fbe8ff0c22b61aaf42687f5ece04f10ec403 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
Date: Thu, 17 Jan 2019 20:50:25 +0000
|
|
||||||
Subject: [PATCH] kpatch-build: adapt for ksymtab in 4.19 kernel
|
|
||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
---
|
|
||||||
kpatch-build/create-diff-object.c | 4 ++--
|
|
||||||
1 files changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
|
||||||
index f075671..2ddd00d 100644
|
|
||||||
--- a/kpatch-build/create-diff-object.c
|
|
||||||
+++ b/kpatch-build/create-diff-object.c
|
|
||||||
@@ -1664,8 +1664,8 @@ static int kpatch_include_new_static_var(struct kpatch_elf *kelf)
|
|
||||||
|
|
||||||
list_for_each_entry(sym, &kelf->symbols, list) {
|
|
||||||
if (sym->status == NEW &&
|
|
||||||
- sym->type == STT_OBJECT &&
|
|
||||||
- sym->bind == STB_LOCAL)
|
|
||||||
+ sym->bind == STB_LOCAL &&
|
|
||||||
+ (sym->type == STT_OBJECT || (sym->type == STT_NOTYPE && sym->name[0] != '$')))
|
|
||||||
kpatch_include_symbol(sym);
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
1.7.5.4
|
|
||||||
|
|
||||||
@ -1,91 +0,0 @@
|
|||||||
From 6b7ff79bb40a7dbb28e6aba320e4ac075e4c182d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
Date: Fri, 18 Jan 2019 00:07:02 +0000
|
|
||||||
Subject: [PATCH] support force enable/disable for kernel 4.19
|
|
||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
---
|
|
||||||
kmod/patch/livepatch-patch-hook.c | 7 +++++--
|
|
||||||
kpatch-build/kpatch-build | 12 ++++++++++--
|
|
||||||
2 files changed, 15 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kmod/patch/livepatch-patch-hook.c b/kmod/patch/livepatch-patch-hook.c
|
|
||||||
index ce1c955..919dfc7 100644
|
|
||||||
--- a/kmod/patch/livepatch-patch-hook.c
|
|
||||||
+++ b/kmod/patch/livepatch-patch-hook.c
|
|
||||||
@@ -511,14 +511,17 @@ static int __init patch_init(void)
|
|
||||||
#ifdef __HULK__
|
|
||||||
lfunc->old_size = func->kfunc->old_size;
|
|
||||||
lfunc->new_size = func->kfunc->new_size;
|
|
||||||
+ lfunc->ref_name= func->kfunc->ref_name;
|
|
||||||
+ lfunc->ref_offset = func->kfunc->ref_offset;
|
|
||||||
+#endif
|
|
||||||
+#if defined(__HULK__) || defined(__KLP_SUPPORT_FORCE__)
|
|
||||||
#ifdef __ALL_FORCE__
|
|
||||||
lfunc->force = 1;
|
|
||||||
#else
|
|
||||||
lfunc->force = patch_is_func_forced(func->kfunc->new_addr);
|
|
||||||
#endif
|
|
||||||
- lfunc->ref_name= func->kfunc->ref_name;
|
|
||||||
- lfunc->ref_offset = func->kfunc->ref_offset;
|
|
||||||
#endif
|
|
||||||
+
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
|
||||||
index a860f12..c227b44 100755
|
|
||||||
--- a/kpatch-build/kpatch-build
|
|
||||||
+++ b/kpatch-build/kpatch-build
|
|
||||||
@@ -279,7 +279,7 @@ find_special_section_data() {
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
SPECIAL_VARS="$(readelf -wi "$VMLINUX" |
|
|
||||||
gawk --non-decimal-data $AWK_OPTIONS '
|
|
||||||
- BEGIN { a = b = p = e = o = 0 }
|
|
||||||
+ BEGIN { a = b = p = e = o = f = 0 }
|
|
||||||
|
|
||||||
# Set state if name matches
|
|
||||||
a == 0 && /DW_AT_name.* alt_instr[[:space:]]*$/ {a = 1; next}
|
|
||||||
@@ -287,6 +287,7 @@ find_special_section_data() {
|
|
||||||
p == 0 && /DW_AT_name.* paravirt_patch_site[[:space:]]*$/ {p = 1; next}
|
|
||||||
e == 0 && /DW_AT_name.* exception_table_entry[[:space:]]*$/ {e = 1; next}
|
|
||||||
o == 0 && /DW_AT_name.* orc_entry[[:space:]]*$/ {o = 1; next}
|
|
||||||
+ f == 0 && /DW_AT_name.* klp_func[[:space:]]*$/ {f = 1; next}
|
|
||||||
|
|
||||||
# Reset state unless this abbrev describes the struct size
|
|
||||||
a == 1 && !/DW_AT_byte_size/ { a = 0; next }
|
|
||||||
@@ -294,6 +295,8 @@ find_special_section_data() {
|
|
||||||
p == 1 && !/DW_AT_byte_size/ { p = 0; next }
|
|
||||||
e == 1 && !/DW_AT_byte_size/ { e = 0; next }
|
|
||||||
o == 1 && !/DW_AT_byte_size/ { o = 0; next }
|
|
||||||
+ f == 1 && /DW_TAG_structure_type/ { f = 3; next }
|
|
||||||
+ f == 1 && /DW_AT_name.* force[[:space:]]*$/ {f = 2; next}
|
|
||||||
|
|
||||||
# Now that we know the size, stop parsing for it
|
|
||||||
a == 1 {printf("export ALT_STRUCT_SIZE=%d\n", $4); a = 2}
|
|
||||||
@@ -301,9 +304,10 @@ find_special_section_data() {
|
|
||||||
p == 1 {printf("export PARA_STRUCT_SIZE=%d\n", $4); p = 2}
|
|
||||||
e == 1 {printf("export EX_STRUCT_SIZE=%d\n", $4); e = 2}
|
|
||||||
o == 1 {printf("export ORC_STRUCT_SIZE=%d\n", $4); o = 2}
|
|
||||||
+ f == 2 {printf("export KLP_SUPPORT_FORCE=y\n"); f = 3}
|
|
||||||
|
|
||||||
# Bail out once we have everything
|
|
||||||
- a == 2 && b == 2 && (p == 2 || skip_p) && e == 2 && (o == 2 || skip_o) {exit}')"
|
|
||||||
+ a == 2 && b == 2 && (p == 2 || skip_p) && e == 2 && (o == 2 || skip_o) && f == 3 {exit}')"
|
|
||||||
|
|
||||||
[[ -n "$SPECIAL_VARS" ]] && eval "$SPECIAL_VARS"
|
|
||||||
|
|
||||||
@@ -957,6 +961,10 @@ if [[ -n "$NO_STACK_CHECK" ]];then
|
|
||||||
export KCPPFLAGS="-D__ALL_FORCE__ $KCPPFLAGS"
|
|
||||||
fi
|
|
||||||
|
|
||||||
+if [[ -n "$KLP_SUPPORT_FORCE" ]];then
|
|
||||||
+ export KCPPFLAGS="-D__KLP_SUPPORT_FORCE__ $KCPPFLAGS"
|
|
||||||
+fi
|
|
||||||
+
|
|
||||||
echo "Building patch module: $MODNAME.ko"
|
|
||||||
|
|
||||||
if [[ -z "$USERSRCDIR" ]] && [[ "$DISTRO" = ubuntu ]]; then
|
|
||||||
--
|
|
||||||
1.7.5.4
|
|
||||||
|
|
||||||
@ -1,118 +0,0 @@
|
|||||||
From 87203483495fec8ad1394def83fa884a96b711ec Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
Date: Thu, 14 Feb 2019 14:21:20 +0000
|
|
||||||
Subject: [PATCH] kpatch-build: adapt for native compile_env
|
|
||||||
|
|
||||||
we check vmlinux to determine if klp_func and klp_object
|
|
||||||
have some members and set flag for livepatch-patch-hook.c.
|
|
||||||
support arm64 native compile enviroment.
|
|
||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
---
|
|
||||||
kpatch-build/kpatch-build | 46 ++++++++++++++++++++++++++++++++++----------
|
|
||||||
1 files changed, 35 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
|
||||||
index c227b44..18f79d4 100755
|
|
||||||
--- a/kpatch-build/kpatch-build
|
|
||||||
+++ b/kpatch-build/kpatch-build
|
|
||||||
@@ -279,7 +279,7 @@ find_special_section_data() {
|
|
||||||
# shellcheck disable=SC2086
|
|
||||||
SPECIAL_VARS="$(readelf -wi "$VMLINUX" |
|
|
||||||
gawk --non-decimal-data $AWK_OPTIONS '
|
|
||||||
- BEGIN { a = b = p = e = o = f = 0 }
|
|
||||||
+ BEGIN { a = b = p = e = o = c = f = s = i = r = j = h = 0 }
|
|
||||||
|
|
||||||
# Set state if name matches
|
|
||||||
a == 0 && /DW_AT_name.* alt_instr[[:space:]]*$/ {a = 1; next}
|
|
||||||
@@ -287,7 +287,8 @@ find_special_section_data() {
|
|
||||||
p == 0 && /DW_AT_name.* paravirt_patch_site[[:space:]]*$/ {p = 1; next}
|
|
||||||
e == 0 && /DW_AT_name.* exception_table_entry[[:space:]]*$/ {e = 1; next}
|
|
||||||
o == 0 && /DW_AT_name.* orc_entry[[:space:]]*$/ {o = 1; next}
|
|
||||||
- f == 0 && /DW_AT_name.* klp_func[[:space:]]*$/ {f = 1; next}
|
|
||||||
+ c == 0 && /DW_AT_name.* klp_func[[:space:]]*$/ {c = 1; next}
|
|
||||||
+ j == 0 && /DW_AT_name.* klp_object[[:space:]]*$/ {j = 1; next}
|
|
||||||
|
|
||||||
# Reset state unless this abbrev describes the struct size
|
|
||||||
a == 1 && !/DW_AT_byte_size/ { a = 0; next }
|
|
||||||
@@ -295,8 +296,13 @@ find_special_section_data() {
|
|
||||||
p == 1 && !/DW_AT_byte_size/ { p = 0; next }
|
|
||||||
e == 1 && !/DW_AT_byte_size/ { e = 0; next }
|
|
||||||
o == 1 && !/DW_AT_byte_size/ { o = 0; next }
|
|
||||||
- f == 1 && /DW_TAG_structure_type/ { f = 3; next }
|
|
||||||
- f == 1 && /DW_AT_name.* force[[:space:]]*$/ {f = 2; next}
|
|
||||||
+ c == 1 && /DW_TAG_structure_type/ { c = 3; next }
|
|
||||||
+ j == 1 && /DW_TAG_structure_type/ { j = 3; next }
|
|
||||||
+ c == 1 && /DW_AT_name.* force[[:space:]]*$/ {f = 2; next}
|
|
||||||
+ c == 1 && /DW_AT_name.* old_sympos[[:space:]]*$/ {s = 2; next}
|
|
||||||
+ i == 1 && /DW_AT_name.* immediate[[:space:]]*$/ {i = 2; next}
|
|
||||||
+ j == 1 && /DW_AT_name.* relocs[[:space:]]*$/ {r = 2; next}
|
|
||||||
+ j == 1 && /DW_AT_name.* hooks_load[[:space:]]*$/ {h = 2; next}
|
|
||||||
|
|
||||||
# Now that we know the size, stop parsing for it
|
|
||||||
a == 1 {printf("export ALT_STRUCT_SIZE=%d\n", $4); a = 2}
|
|
||||||
@@ -304,10 +310,14 @@ find_special_section_data() {
|
|
||||||
p == 1 {printf("export PARA_STRUCT_SIZE=%d\n", $4); p = 2}
|
|
||||||
e == 1 {printf("export EX_STRUCT_SIZE=%d\n", $4); e = 2}
|
|
||||||
o == 1 {printf("export ORC_STRUCT_SIZE=%d\n", $4); o = 2}
|
|
||||||
- f == 2 {printf("export KLP_SUPPORT_FORCE=y\n"); f = 3}
|
|
||||||
+ f == 2 {printf("export KLP_SUPPORT_FORCE=y\n"); f = 3}
|
|
||||||
+ s == 2 {printf("export KLP_SUPPORT_OLD_SYMPOS=y\n"); s = 3}
|
|
||||||
+ i == 2 {printf("export KLP_SUPPORT_IMMEDIATE=y\n"); i = 3}
|
|
||||||
+ r == 2 {printf("export KLP_SUPPORT_RELOCS=y\n"); r = 3}
|
|
||||||
+ h == 2 {printf("export KLP_SUPPORT_LOADHOOKS=y\n"); h = 3}
|
|
||||||
|
|
||||||
# Bail out once we have everything
|
|
||||||
- a == 2 && b == 2 && (p == 2 || skip_p) && e == 2 && (o == 2 || skip_o) && f == 3 {exit}')"
|
|
||||||
+ a == 2 && b == 2 && (p == 2 || skip_p) && e == 2 && (o == 2 || skip_o) && c == 3 && j == 3 {exit}')"
|
|
||||||
|
|
||||||
[[ -n "$SPECIAL_VARS" ]] && eval "$SPECIAL_VARS"
|
|
||||||
|
|
||||||
@@ -406,7 +416,9 @@ arch_export() {
|
|
||||||
export GCC_ADD_OPTION=
|
|
||||||
elif [[ $E_MACHINE -eq 183 ]]; then
|
|
||||||
export ARCH=arm64
|
|
||||||
- export ARCH_COMPILE=aarch64-linux-gnu-
|
|
||||||
+ if [ $(arch) != "aarch64" ]; then
|
|
||||||
+ export ARCH_COMPILE=aarch64-linux-gnu-
|
|
||||||
+ fi
|
|
||||||
export ENDIAN=little
|
|
||||||
if grep "\-mlong-calls" $SRCDIR/Makefile > /dev/null; then
|
|
||||||
export GCC_ADD_OPTION="-fno-section-anchors -mlong-calls"
|
|
||||||
@@ -953,10 +965,6 @@ if "$KPATCH_MODULE"; then
|
|
||||||
export KCPPFLAGS="-D__KPATCH_MODULE__"
|
|
||||||
fi
|
|
||||||
|
|
||||||
-if grep "hulk" $SRCDIR/Makefile > /dev/null; then
|
|
||||||
- export KCPPFLAGS="-D__HULK__ $KCPPFLAGS"
|
|
||||||
-fi
|
|
||||||
-
|
|
||||||
if [[ -n "$NO_STACK_CHECK" ]];then
|
|
||||||
export KCPPFLAGS="-D__ALL_FORCE__ $KCPPFLAGS"
|
|
||||||
fi
|
|
||||||
@@ -965,6 +973,22 @@ if [[ -n "$KLP_SUPPORT_FORCE" ]];then
|
|
||||||
export KCPPFLAGS="-D__KLP_SUPPORT_FORCE__ $KCPPFLAGS"
|
|
||||||
fi
|
|
||||||
|
|
||||||
+if [[ -n "$KLP_SUPPORT_OLD_SYMPOS" ]];then
|
|
||||||
+ export KCPPFLAGS="-DHAVE_SYMPOS $KCPPFLAGS"
|
|
||||||
+fi
|
|
||||||
+
|
|
||||||
+if [[ -n "$KLP_SUPPORT_IMMEDIATE" ]];then
|
|
||||||
+ export KCPPFLAGS="-DHAVE_IMMEDIATE $KCPPFLAGS"
|
|
||||||
+fi
|
|
||||||
+
|
|
||||||
+if [[ -n "$KLP_SUPPORT_RELOCS" ]];then
|
|
||||||
+ export KCPPFLAGS="-DHAVE_ELF_RELOCS $KCPPFLAGS"
|
|
||||||
+fi
|
|
||||||
+
|
|
||||||
+if [[ -n "$KLP_SUPPORT_LOADHOOKS" ]];then
|
|
||||||
+ export KCPPFLAGS="-DHAVE_LOADHOOKS $KCPPFLAGS"
|
|
||||||
+fi
|
|
||||||
+
|
|
||||||
echo "Building patch module: $MODNAME.ko"
|
|
||||||
|
|
||||||
if [[ -z "$USERSRCDIR" ]] && [[ "$DISTRO" = ubuntu ]]; then
|
|
||||||
--
|
|
||||||
1.7.5.4
|
|
||||||
|
|
||||||
@ -1,96 +0,0 @@
|
|||||||
From d53b2d1f87f5e891ba8f6945765134da9ee2d29d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
Date: Thu, 7 Mar 2019 14:38:15 +0000
|
|
||||||
Subject: [PATCH] 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/kpatch-build | 56 ++++++++++++++++++++++++++++++++++++++-
|
|
||||||
1 file changed, 55 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/kpatch-build/kpatch-build b/kpatch-build/kpatch-build
|
|
||||||
index 18f79d4..59af250 100755
|
|
||||||
--- a/kpatch-build/kpatch-build
|
|
||||||
+++ b/kpatch-build/kpatch-build
|
|
||||||
@@ -266,12 +266,66 @@ find_special_section_data_ppc64le() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
+find_special_section_data_arm64() {
|
|
||||||
+
|
|
||||||
+ # 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 = c = f = s = i = r = j = h = 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}
|
|
||||||
+ c == 0 && /DW_AT_name.* klp_func[[:space:]]*$/ {c = 1; next}
|
|
||||||
+ j == 0 && /DW_AT_name.* klp_object[[: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 }
|
|
||||||
+ c == 1 && /DW_TAG_structure_type/ { c = 3; next }
|
|
||||||
+ j == 1 && /DW_TAG_structure_type/ { j = 3; next }
|
|
||||||
+ c == 1 && /DW_AT_name.* force[[:space:]]*$/ {f = 2; next}
|
|
||||||
+ c == 1 && /DW_AT_name.* old_sympos[[:space:]]*$/ {s = 2; next}
|
|
||||||
+ i == 1 && /DW_AT_name.* immediate[[:space:]]*$/ {i = 2; next}
|
|
||||||
+ j == 1 && /DW_AT_name.* relocs[[:space:]]*$/ {r = 2; next}
|
|
||||||
+ j == 1 && /DW_AT_name.* hooks_load[[:space:]]*$/ {h = 2; 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}
|
|
||||||
+ f == 2 {printf("export KLP_SUPPORT_FORCE=y\n"); f = 3}
|
|
||||||
+ s == 2 {printf("export KLP_SUPPORT_OLD_SYMPOS=y\n"); s = 3}
|
|
||||||
+ i == 2 {printf("export KLP_SUPPORT_IMMEDIATE=y\n"); i = 3}
|
|
||||||
+ r == 2 {printf("export KLP_SUPPORT_RELOCS=y\n"); r = 3}
|
|
||||||
+ h == 2 {printf("export KLP_SUPPORT_LOADHOOKS=y\n"); h = 3}
|
|
||||||
+
|
|
||||||
+ # Bail out once we have everything
|
|
||||||
+ a == 2 && b == 2 && e == 2 && c == 3 && j == 3 {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"
|
|
||||||
+
|
|
||||||
+ return
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
find_special_section_data() {
|
|
||||||
if [[ "$ARCH" = "ppc64le" ]]; then
|
|
||||||
find_special_section_data_ppc64le
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
+ if [[ "$ARCH" = "arm64" ]]; then
|
|
||||||
+ find_special_section_data_arm64
|
|
||||||
+ return
|
|
||||||
+ fi
|
|
||||||
+
|
|
||||||
[[ "$CONFIG_PARAVIRT" -eq 0 ]] && AWK_OPTIONS="-vskip_p=1"
|
|
||||||
[[ "$CONFIG_UNWINDER_ORC" -eq 0 ]] && AWK_OPTIONS="$AWK_OPTIONS -vskip_o=1"
|
|
||||||
|
|
||||||
@@ -323,7 +377,7 @@ find_special_section_data() {
|
|
||||||
|
|
||||||
[[ -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 paravirt_patch_site size"
|
|
||||||
+ [[ -z "$EX_STRUCT_SIZE" ]] && die "can't find special struct exception_table_entry size"
|
|
||||||
[[ -z "$PARA_STRUCT_SIZE" && "$CONFIG_PARAVIRT" -ne 0 ]] && die "can't find special struct paravirt_patch_site size"
|
|
||||||
[[ -z "$ORC_STRUCT_SIZE" && "$CONFIG_UNWINDER_ORC" -ne 0 ]] && die "can't find special struct orc_entry size"
|
|
||||||
|
|
||||||
--
|
|
||||||
2.19.1
|
|
||||||
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
From 1069d212fd848f1f1e2425dffe8e9aea188c6150 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
Date: Tue, 21 Dec 2083 12:18:38 +0800
|
|
||||||
Subject: [PATCH] fix ref static local symbol for longname symbol
|
|
||||||
|
|
||||||
static local symbol have a "." which will confuse
|
|
||||||
the kernel livepatch klp_resolve_symbols. So, pass
|
|
||||||
static local symbols in lookup_ref_symbol_offset.
|
|
||||||
|
|
||||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
||||||
---
|
|
||||||
kpatch-build/lookup.c | 3 ++-
|
|
||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c
|
|
||||||
index 2e55862..01abc41 100644
|
|
||||||
--- a/kpatch-build/lookup.c
|
|
||||||
+++ b/kpatch-build/lookup.c
|
|
||||||
@@ -591,7 +591,8 @@ int lookup_ref_symbol_offset(struct lookup_table *table, char *name,
|
|
||||||
/*find a unique symbol in the same section first*/
|
|
||||||
for_each_obj_symbol(i, sym, table) {
|
|
||||||
if (!strcmp(sym->name, name) || sym->type == STT_FILE ||
|
|
||||||
- sym->sec_index != orig_sym->sec_index)
|
|
||||||
+ sym->sec_index != orig_sym->sec_index ||
|
|
||||||
+ strchr(sym->name, '.'))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!lookup_is_duplicate_symbol(table, sym->name, objname, 1)) {
|
|
||||||
--
|
|
||||||
2.19.1
|
|
||||||
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
From da3eed612df1d26e19b0678763e116f666da13b2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Artem Savkov <asavkov@redhat.com>
|
|
||||||
Date: Wed, 14 Nov 2018 12:33:13 +0100
|
|
||||||
Subject: [PATCH] kmod/core: fix compilation with
|
|
||||||
CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
|
|
||||||
|
|
||||||
Kernel commit 7290d5809571 "module: use relative references for
|
|
||||||
__ksymtab entries" changed kernel_symbol structure on some
|
|
||||||
architectures. Adjust kmod/core/core.c accordingly.
|
|
||||||
|
|
||||||
Signed-off-by: Artem Savkov <asavkov@redhat.com>
|
|
||||||
---
|
|
||||||
kmod/core/core.c | 4 ++++
|
|
||||||
1 file changed, 4 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/kmod/core/core.c b/kmod/core/core.c
|
|
||||||
index 4a73a47..a91d417 100644
|
|
||||||
--- a/kmod/core/core.c
|
|
||||||
+++ b/kmod/core/core.c
|
|
||||||
@@ -651,7 +651,11 @@ static int kpatch_find_external_symbol(const char *objname, const char *name,
|
|
||||||
sym = find_symbol(name, NULL, NULL, true, true);
|
|
||||||
preempt_enable();
|
|
||||||
if (sym) {
|
|
||||||
+#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
|
|
||||||
+ *addr = (unsigned long)offset_to_ptr(&sym->value_offset);
|
|
||||||
+#else
|
|
||||||
*addr = sym->value;
|
|
||||||
+#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.19.1
|
|
||||||
|
|
||||||
Binary file not shown.
BIN
kpatch-0.9.0.tar.gz
Normal file
BIN
kpatch-0.9.0.tar.gz
Normal file
Binary file not shown.
60
kpatch.spec
60
kpatch.spec
@ -1,8 +1,8 @@
|
|||||||
%global raw_version 0.6.1
|
%global raw_version 0.9.0
|
||||||
|
|
||||||
Name: kpatch
|
Name: kpatch
|
||||||
Version: 2.0
|
Version: 2.0
|
||||||
Release: 3.1.23
|
Release: 3.1.24
|
||||||
Summary: A Linux dynamic kernel patching infrastructure
|
Summary: A Linux dynamic kernel patching infrastructure
|
||||||
|
|
||||||
License: GPLv2
|
License: GPLv2
|
||||||
@ -13,36 +13,23 @@ Source1: os_hotpatch
|
|||||||
Source2: livepatch
|
Source2: livepatch
|
||||||
Source3: make_hotpatch
|
Source3: make_hotpatch
|
||||||
|
|
||||||
Patch9001: 9001-livepatch-patch-hook-don-t-active-patch-when-insmod.patch
|
Patch0001:0001-support-compile-kpatch-on-aarch64.patch
|
||||||
Patch9002: 9002-kpatch-build-support-third-party-module-make-hotpatc.patch
|
Patch0002:0002-kpatch-build-support-build-patch-for-aarch64.patch
|
||||||
Patch9003: 9003-kpatch-build-support-makefile-not-in-third-party-mod.patch
|
Patch0003:0003-create-diff-object-new-static-var-should-be-included.patch
|
||||||
Patch9004: 9004-create-diff-object-new-static-var-should-be-included.patch
|
Patch0004:0004-livepatch-fix-use-THIS-modname-as-the-name-of-ddebug.patch
|
||||||
Patch9005: 9005-livepatch-fix-use-THIS-modname-as-the-name-of-ddebug.patch
|
Patch0005:0005-create-diff-object-fix-correlate-static-local-variab.patch
|
||||||
Patch9006: 9006-create-diff-object-fix-correlate-static-local-variab.patch
|
Patch0006:0006-create-diff-object-don-t-create-dynamic-reloc-for-sy.patch
|
||||||
Patch9007: 9007-create-diff-object-don-t-create-dynamic-reloc-for-sy.patch
|
Patch0007:0007-create-diff-object-create-dynamic-relocs-for-changed.patch
|
||||||
Patch9008: 9008-livepatch-patch-hook-support-force-enable-disable-fu.patch
|
Patch0008:0008-fix-rodata.str-problem.patch
|
||||||
Patch9009: 9009-kmod-kpatch-build-support-build-patch-for-old-kernel.patch
|
Patch0009:0009-livepatch-patch-hook-don-t-active-patch-when-insmod.patch
|
||||||
Patch9010: 9010-kmod-kpatch-build-support-cross-compile-hotpatch-for.patch
|
Patch0010:0010-kpatch-build-enhance-for-out-of-tree-module.patch
|
||||||
Patch9011: 9011-kpatch-build-use-.klp.rela-in-euleros-7.5-kernel.patch
|
Patch0011:0011-support-c-plus-kernel-module.patch
|
||||||
Patch9012: 9012-create-diff-object-create-dynamic-relocs-for-changed.patch
|
Patch0012:0012-symbol-lookup-enhancement.patch
|
||||||
Patch9013: 9013-kmod-kpatch-build-fix-duplicate-symbol-relocation-fo.patch
|
Patch0013:0013-Add-running-kernel-symbol-table-to-help-symbol-looku.patch
|
||||||
Patch9014: 9014-create-diff-object-add-dynamic-reloction-for-functio.patch
|
Patch0014:0014-livepatch-patch-hook-support-force-enable-disable.patch
|
||||||
Patch9015: 9015-create-diff-object-exclude-line-only-change-for-arm6.patch
|
Patch0015:0015-kpatch-build-ignore-debuginfo-in-patch.patch
|
||||||
Patch9016: 9016-kpatch-build-include-secsym-in-kpatch_mark_ignored_s.patch
|
Patch0016:0016-add-object-in-kpatch.patch
|
||||||
Patch9017: 9017-support-compile-kpatch-on-aarch64.patch
|
Patch0017:0017-create-diff-object-fix-.orc_unwind_ip-error.patch
|
||||||
Patch9018: 9018-support-c-plus-kernel-module.patch
|
|
||||||
Patch9019: 9019-fix-rodata.str-problem.patch
|
|
||||||
Patch9020: 0001-Add-__addressable_-to-maybe_discarded_sym.patch
|
|
||||||
Patch9021: 0002-kmod-patch-fix-patch-linking-with-4.20.patch
|
|
||||||
Patch9022: 0003-kmod-patch-more-linking-fixes.patch
|
|
||||||
Patch9023: 9023-kpatch-build-adapt-for-ksymtab-in-4.19-kernel.patch
|
|
||||||
Patch9024: 9024-support-force-enable-disable-for-kernel-4.19.patch
|
|
||||||
Patch9025: 9025-kpatch-build-adapt-for-native-compile_env.patch
|
|
||||||
Patch9026: 9026-add-find_special_section_data_arm64-for-arm64.patch
|
|
||||||
Patch9027: 9027-fix-ref-static-local-symbol-for-longname-symbol.patch
|
|
||||||
Patch9028: 9028-add-object-in-kpatch.patch
|
|
||||||
Patch9029: 0004-create-diff-object-allow-changing-subsections.patch
|
|
||||||
Patch9030: 9030-kmod-core-fix-compilation-with-CONFIG_HAVE_ARCH_PREL.patch
|
|
||||||
|
|
||||||
BuildRequires: gcc elfutils-libelf-devel uname-build-checks kernel kernel-devel
|
BuildRequires: gcc elfutils-libelf-devel uname-build-checks kernel kernel-devel
|
||||||
Requires: bc
|
Requires: bc
|
||||||
@ -89,9 +76,6 @@ popd
|
|||||||
%{_datadir}/%{name}/*
|
%{_datadir}/%{name}/*
|
||||||
%{_sysconfdir}/init/*
|
%{_sysconfdir}/init/*
|
||||||
/opt/patch_workspace/*
|
/opt/patch_workspace/*
|
||||||
%ifarch x86_64
|
|
||||||
%{_prefix}/lib/kpatch
|
|
||||||
%endif
|
|
||||||
|
|
||||||
%files runtime
|
%files runtime
|
||||||
%defattr(-,root,root)
|
%defattr(-,root,root)
|
||||||
@ -102,6 +86,12 @@ popd
|
|||||||
%{_mandir}/man1/*.1.gz
|
%{_mandir}/man1/*.1.gz
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Feb 26 2020 Zhipeng Xie<kangenbo@huawei.com> -2.0-3.1.24
|
||||||
|
- Type:enhancement
|
||||||
|
- ID:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:rebase from upstream version v0.9.0
|
||||||
|
|
||||||
* Mon Feb 17 2020 openEuler Buildteam <buildteam@openeuler.org> -2.0-3.1.23
|
* Mon Feb 17 2020 openEuler Buildteam <buildteam@openeuler.org> -2.0-3.1.23
|
||||||
- Type:enhancement
|
- Type:enhancement
|
||||||
- ID:NA
|
- ID:NA
|
||||||
|
|||||||
73
livepatch
73
livepatch
@ -1,19 +1,8 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License version 2 and
|
|
||||||
# only version 2 as published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
|
|
||||||
exe_tool=`which os_hotpatch`
|
exe_tool=`which os_hotpatch`
|
||||||
fn_help()
|
fn_help()
|
||||||
{
|
{
|
||||||
cat <<EOFE
|
cat <<EOFE
|
||||||
Usage: livepatch -l/--load -r/--remove -a/--activate -d/--deactivate <patch>
|
Usage: livepatch -l/--load -r/--remove -a/--activate -d/--deactivate <patch>
|
||||||
-q[patch]/--query[=patch]
|
-q[patch]/--query[=patch]
|
||||||
-h/--help -v/--version
|
-h/--help -v/--version
|
||||||
@ -28,38 +17,38 @@ input_args=`getopt -a -o l:a:r:d:q:v -l load:,activate:,remove:,deactivate:,quer
|
|||||||
eval set -- "${input_args}"
|
eval set -- "${input_args}"
|
||||||
while true;
|
while true;
|
||||||
do
|
do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
-l|--load)
|
-l|--load)
|
||||||
$exe_tool -l "$2"
|
$exe_tool -l "$2"
|
||||||
exit $?
|
exit $?
|
||||||
;;
|
;;
|
||||||
-a|--activate)
|
-a|--activate)
|
||||||
$exe_tool -a "klp_${2#klp_}"
|
$exe_tool -a "klp_${2#klp_}"
|
||||||
exit $?
|
exit $?
|
||||||
;;
|
;;
|
||||||
-d|--deactivate)
|
-d|--deactivate)
|
||||||
$exe_tool -r "klp_${2#klp_}"
|
$exe_tool -r "klp_${2#klp_}"
|
||||||
exit $?
|
exit $?
|
||||||
;;
|
;;
|
||||||
-r|--remove)
|
-r|--remove)
|
||||||
$exe_tool -d "klp_${2#klp_}"
|
$exe_tool -d "klp_${2#klp_}"
|
||||||
exit $?
|
exit $?
|
||||||
;;
|
;;
|
||||||
-q|--query)
|
-q|--query)
|
||||||
$exe_tool -q "klp_${2#klp_}"
|
$exe_tool -q "klp_${2#klp_}"
|
||||||
exit $?
|
exit $?
|
||||||
;;
|
;;
|
||||||
-h|--help)
|
-h|--help)
|
||||||
fn_help
|
fn_help
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
-v|--version)
|
-v|--version)
|
||||||
echo "LKP:livepatch version 2.0-00000"
|
echo "LKP:livepatch version 2.0-00000"
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
fn_help
|
fn_help
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|||||||
465
make_hotpatch
465
make_hotpatch
@ -1,14 +1,18 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/bash
|
||||||
# Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
|
#********************************************************************
|
||||||
#
|
# Copyright (C) Huawei Technologies, 2015-11
|
||||||
# This program is free software; you can redistribute it and/or modify
|
#
|
||||||
# it under the terms of the GNU General Public License version 2 and
|
# #FileName : make_hotpatch
|
||||||
# only version 2 as published by the Free Software Foundation.
|
# #Description : make hotpatch
|
||||||
#
|
# #Author :
|
||||||
# This program is distributed in the hope that it will be useful,
|
# #Language : shell
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# #Environment : Euler compile env
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# #Created : 2015-11
|
||||||
# GNU General Public License for more details.
|
# #History
|
||||||
|
# 1.Date:
|
||||||
|
# Author:
|
||||||
|
# Modification:
|
||||||
|
#********************************************************************
|
||||||
|
|
||||||
SHELL_DIR=$(dirname $0)
|
SHELL_DIR=$(dirname $0)
|
||||||
SHELL_DIR=$(cd $SHELL_DIR; pwd)
|
SHELL_DIR=$(cd $SHELL_DIR; pwd)
|
||||||
@ -72,12 +76,12 @@ Options:
|
|||||||
-p,--patch
|
-p,--patch
|
||||||
Specifies the patch file
|
Specifies the patch file
|
||||||
--kallsyms
|
--kallsyms
|
||||||
Specifies module kallsyms in running system(cat /proc/kallsyms|grep mod)
|
Specifies module kallsyms in running system(cat /proc/kallsyms|grep mod)
|
||||||
-h,--help
|
-h,--help
|
||||||
help info
|
help info
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -94,7 +98,7 @@ function fn_do_clean()
|
|||||||
unset NO_STACK_CHECK
|
unset NO_STACK_CHECK
|
||||||
unset KALLSYMS
|
unset KALLSYMS
|
||||||
rm -rf $G_TMP_DIR
|
rm -rf $G_TMP_DIR
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
@ -109,7 +113,7 @@ function fn_check_reg_char()
|
|||||||
local l_str_maxlen=$2
|
local l_str_maxlen=$2
|
||||||
local l_str_ex=$3
|
local l_str_ex=$3
|
||||||
local len_str=${#l_str}
|
local len_str=${#l_str}
|
||||||
|
|
||||||
if [ -z "$l_str" ];then
|
if [ -z "$l_str" ];then
|
||||||
echo "error: the string is empty, check string failed"
|
echo "error: the string is empty, check string failed"
|
||||||
return 1
|
return 1
|
||||||
@ -139,10 +143,10 @@ function fn_check_reg_char()
|
|||||||
else
|
else
|
||||||
echo "error: string $l_str can only contain characters included by ('0-9', 'a-z', 'A-Z', '-', '_')."
|
echo "error: string $l_str can only contain characters included by ('0-9', 'a-z', 'A-Z', '-', '_')."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
@ -159,7 +163,7 @@ function fn_check_id()
|
|||||||
echo "error: check hotpatch id failed"
|
echo "error: check hotpatch id failed"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
G_HOTPATCH_ID=$l_id
|
G_HOTPATCH_ID=$l_id
|
||||||
G_HOTPATCH=${G_PREFIX}_${G_HOTPATCH_ID}.ko
|
G_HOTPATCH=${G_PREFIX}_${G_HOTPATCH_ID}.ko
|
||||||
G_HOTPATCH_TAR=${G_PREFIX}_${G_HOTPATCH_ID}.tar.gz
|
G_HOTPATCH_TAR=${G_PREFIX}_${G_HOTPATCH_ID}.tar.gz
|
||||||
@ -197,8 +201,8 @@ function fn_check_jobs()
|
|||||||
function fn_check_patch(){
|
function fn_check_patch(){
|
||||||
local l_patch=$1
|
local l_patch=$1
|
||||||
if [ ! -f $1 ];then
|
if [ ! -f $1 ];then
|
||||||
echo "error:patch file $1 not exit"
|
echo "error:patch file $1 not exist"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
G_PATCHFILE=$l_patch
|
G_PATCHFILE=$l_patch
|
||||||
}
|
}
|
||||||
@ -324,136 +328,136 @@ function fn_verify_input()
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "`echo "$input_param" | grep -w "\-i"`" \
|
if [ -z "`echo "$input_param" | grep -w "\-i"`" \
|
||||||
-a -z "`echo $input_param | grep -w "\-\-id"`" \
|
-a -z "`echo $input_param | grep -w "\-\-id"`" \
|
||||||
-a $# -gt 1 ];then
|
-a $# -gt 1 ];then
|
||||||
echo "error: missing param -i or --id"
|
echo "error: missing param -i or --id"
|
||||||
fn_do_clean
|
fn_do_clean
|
||||||
fn_usage
|
fn_usage
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
if [ -z "`echo "$input_param" | grep -w "\-d"`" \
|
if [ -z "`echo "$input_param" | grep -w "\-d"`" \
|
||||||
-a -z "`echo $input_param | grep -w "\-\-diffext"`" \
|
-a -z "`echo $input_param | grep -w "\-\-diffext"`" \
|
||||||
-a -z "`echo $input_param | grep -w "\-p"`" \
|
-a -z "`echo $input_param | grep -w "\-p"`" \
|
||||||
-a -z "`echo $input_param | grep -w "\-\-patch"`" \
|
-a -z "`echo $input_param | grep -w "\-\-patch"`" \
|
||||||
-a $# -gt 1 ];then
|
-a $# -gt 1 ];then
|
||||||
echo "error: missing param -d,--diffext or -p,--patch"
|
echo "error: missing param -d,--diffext or -p,--patch"
|
||||||
fn_do_clean
|
fn_do_clean
|
||||||
fn_usage
|
fn_usage
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
while [ $# -ge 1 ]; do
|
while [ $# -ge 1 ]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
-h|--help)
|
-h|--help)
|
||||||
fn_usage
|
|
||||||
fn_do_clean
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
-j|--jobs)
|
|
||||||
fn_check_jobs $2
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
shift 2
|
|
||||||
else
|
|
||||||
fn_do_clean
|
|
||||||
fn_usage
|
fn_usage
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
-i|--id)
|
|
||||||
fn_check_id $2
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
shift 2
|
|
||||||
else
|
|
||||||
fn_do_clean
|
fn_do_clean
|
||||||
fn_usage
|
exit 0
|
||||||
exit 1
|
;;
|
||||||
fi
|
-j|--jobs)
|
||||||
;;
|
fn_check_jobs $2
|
||||||
-d|--diffext)
|
if [ $? -eq 0 ]; then
|
||||||
fn_check_diffext $2
|
shift 2
|
||||||
if [ $? -eq 0 ]; then
|
else
|
||||||
shift 2
|
fn_do_clean
|
||||||
else
|
fn_usage
|
||||||
fn_do_clean
|
exit 1
|
||||||
fn_usage
|
fi
|
||||||
exit 1
|
;;
|
||||||
fi
|
-i|--id)
|
||||||
;;
|
fn_check_id $2
|
||||||
-p|--patch)
|
if [ $? -eq 0 ]; then
|
||||||
fn_check_patch $2
|
shift 2
|
||||||
if [ $? -eq 0 ]; then
|
else
|
||||||
shift 2
|
fn_do_clean
|
||||||
else
|
fn_usage
|
||||||
fn_do_clean
|
exit 1
|
||||||
fn_usage
|
fi
|
||||||
exit 1
|
;;
|
||||||
fi
|
-d|--diffext)
|
||||||
;;
|
fn_check_diffext $2
|
||||||
-k|--kernelsrc)
|
if [ $? -eq 0 ]; then
|
||||||
fn_check_kernelsrc $2
|
shift 2
|
||||||
if [ $? -eq 0 ]; then
|
else
|
||||||
shift 2
|
fn_do_clean
|
||||||
else
|
fn_usage
|
||||||
fn_do_clean
|
exit 1
|
||||||
fn_usage
|
fi
|
||||||
exit 1
|
;;
|
||||||
fi
|
-p|--patch)
|
||||||
;;
|
fn_check_patch $2
|
||||||
-m|--modulesrc)
|
if [ $? -eq 0 ]; then
|
||||||
fn_check_modulesrc $2
|
shift 2
|
||||||
if [ $? -eq 0 ]; then
|
else
|
||||||
shift 2
|
fn_do_clean
|
||||||
else
|
fn_usage
|
||||||
fn_do_clean
|
exit 1
|
||||||
fn_usage
|
fi
|
||||||
exit 1
|
;;
|
||||||
fi
|
-k|--kernelsrc)
|
||||||
;;
|
fn_check_kernelsrc $2
|
||||||
-f|--makefile)
|
if [ $? -eq 0 ]; then
|
||||||
fn_check_makefile $2
|
shift 2
|
||||||
if [ $? -eq 0 ]; then
|
else
|
||||||
shift 2
|
fn_do_clean
|
||||||
else
|
fn_usage
|
||||||
fn_do_clean
|
exit 1
|
||||||
fn_usage
|
fi
|
||||||
exit 1
|
;;
|
||||||
fi
|
-m|--modulesrc)
|
||||||
;;
|
fn_check_modulesrc $2
|
||||||
--extra_flags)
|
if [ $? -eq 0 ]; then
|
||||||
fn_check_extra_flags $2
|
shift 2
|
||||||
if [ $? -eq 0 ]; then
|
else
|
||||||
shift 2
|
fn_do_clean
|
||||||
else
|
fn_usage
|
||||||
fn_do_clean
|
exit 1
|
||||||
fn_usage
|
fi
|
||||||
exit 1
|
;;
|
||||||
fi
|
-f|--makefile)
|
||||||
;;
|
fn_check_makefile $2
|
||||||
--no_stack_check)
|
if [ $? -eq 0 ]; then
|
||||||
|
shift 2
|
||||||
|
else
|
||||||
|
fn_do_clean
|
||||||
|
fn_usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
--extra_flags)
|
||||||
|
fn_check_extra_flags $2
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
shift 2
|
||||||
|
else
|
||||||
|
fn_do_clean
|
||||||
|
fn_usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
--no_stack_check)
|
||||||
export NO_STACK_CHECK="yes"
|
export NO_STACK_CHECK="yes"
|
||||||
shift 1
|
shift 1
|
||||||
;;
|
;;
|
||||||
--debug_info)
|
--debug_info)
|
||||||
G_DEBUG_INFO="-d"
|
G_DEBUG_INFO="-d"
|
||||||
shift 1
|
shift 1
|
||||||
;;
|
;;
|
||||||
--kallsyms)
|
--kallsyms)
|
||||||
export KALLSYMS=$(readlink -f $2)
|
if [ "$2" == "" ];then
|
||||||
if [ $? -eq 0 ]; then
|
echo "error: param --kallsyms need file parameter"
|
||||||
|
fn_do_clean
|
||||||
|
fn_usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
export KALLSYMS=$(readlink -f $2)
|
||||||
shift 2
|
shift 2
|
||||||
else
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "error: params is invalid,please check it."
|
||||||
fn_do_clean
|
fn_do_clean
|
||||||
fn_usage
|
fn_usage
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
;;
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
echo "error: params is invalid,please check it."
|
|
||||||
fn_do_clean
|
|
||||||
fn_usage
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
@ -474,11 +478,11 @@ function fn_init_module_build()
|
|||||||
local module=
|
local module=
|
||||||
|
|
||||||
module=`basename $l_modulesrc`
|
module=`basename $l_modulesrc`
|
||||||
|
|
||||||
if [ ! -e $G_PRIVATE_MODULE ];then
|
if [ ! -e $G_PRIVATE_MODULE ];then
|
||||||
mkdir -p $G_PRIVATE_MODULE
|
mkdir -p $G_PRIVATE_MODULE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -rf $G_PRIVATE_MODULE/*
|
rm -rf $G_PRIVATE_MODULE/*
|
||||||
if [ $? -ne 0 ];then
|
if [ $? -ne 0 ];then
|
||||||
echo "error: remove $G_PRIVATE_MODULE/$module or Makefile failed"
|
echo "error: remove $G_PRIVATE_MODULE/$module or Makefile failed"
|
||||||
@ -534,14 +538,15 @@ function fn_makepatch()
|
|||||||
|
|
||||||
G_PATCH_SRC=`readlink -f $G_KERNEL_SRC`
|
G_PATCH_SRC=`readlink -f $G_KERNEL_SRC`
|
||||||
if [ -d "$G_MODULE_SRC" ];then
|
if [ -d "$G_MODULE_SRC" ];then
|
||||||
echo "make out of tree module hotpath"
|
echo "make out of tree module hotpath"
|
||||||
G_PATCH_SRC=$G_MODULE_SRC
|
G_PATCH_SRC=$G_MODULE_SRC
|
||||||
#fn_init_module_build $G_MODULE_SRC $G_MODULE_MAKEFILE
|
#fn_init_module_build $G_MODULE_SRC $G_MODULE_MAKEFILE
|
||||||
#if [ $? -ne 0 ];then
|
#if [ $? -ne 0 ];then
|
||||||
# echo "error: init module build failed"
|
# echo "error: init module build failed"
|
||||||
# return 1
|
# return 1
|
||||||
#fi
|
#fi
|
||||||
l_extra_module="-m $G_MODULE_SRC"
|
l_extra_module="-m $G_MODULE_SRC"
|
||||||
|
USERMODBUILDDIR=$G_MODULE_SRC
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$G_JOBS" ];then
|
if [ -n "$G_JOBS" ];then
|
||||||
@ -551,63 +556,61 @@ function fn_makepatch()
|
|||||||
mkdir -p $G_TMP_DIR
|
mkdir -p $G_TMP_DIR
|
||||||
|
|
||||||
if [ -z "$G_PATCHFILE" ];then
|
if [ -z "$G_PATCHFILE" ];then
|
||||||
#generate src patch file from G_DIFFEXT
|
#generate src patch file from G_DIFFEXT
|
||||||
G_PATCHFILE=$G_TMP_DIR/$G_HOTPATCH_ID.patch
|
G_PATCHFILE=$G_TMP_DIR/$G_HOTPATCH_ID.patch
|
||||||
rm -rf $G_PATCHFILE
|
rm -rf $G_PATCHFILE
|
||||||
cd $G_PATCH_SRC &>/dev/null
|
cd $G_PATCH_SRC &>/dev/null
|
||||||
l_change_file=($(find -L -name "*$G_DIFFEXT" | xargs readlink -f 2>/dev/null| sort | uniq))
|
l_change_file=($(find -L -name "*$G_DIFFEXT" | xargs readlink -f 2>/dev/null| sort | uniq))
|
||||||
echo "detect change files:${l_change_file[@]}"
|
echo "detect change files:${l_change_file[@]}"
|
||||||
for file in ${l_change_file[@]};
|
for file in ${l_change_file[@]};
|
||||||
do
|
do
|
||||||
file="./${file#$(readlink -f $G_PATCH_SRC)}"
|
file="./${file#$(readlink -f $G_PATCH_SRC)}"
|
||||||
orig_file=${file%$G_DIFFEXT}
|
orig_file=${file%$G_DIFFEXT}
|
||||||
if [ "${orig_file##*.}" == "h" ]; then
|
if [ "${orig_file##*.}" == "h" ]; then
|
||||||
existflag=1 && break
|
existflag=1 && break
|
||||||
fi
|
fi
|
||||||
diff -u $orig_file $file >> $G_PATCHFILE
|
diff -u $orig_file $file >> $G_PATCHFILE
|
||||||
done
|
done
|
||||||
cd - &>/dev/null
|
cd - &>/dev/null
|
||||||
if [ ${existflag} -eq 1 ]; then
|
if [ ${existflag} -eq 1 ]; then
|
||||||
echo "error: do not modify the header file"
|
echo "error: do not modify the header file"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
if [ -f $G_PATCHFILE ];then
|
if [ -f $G_PATCHFILE ];then
|
||||||
echo "make patch $G_PATCHFILE"
|
echo "make patch $G_PATCHFILE"
|
||||||
else
|
else
|
||||||
echo "no change detected"
|
echo "no change detected"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
cp $G_PATCHFILE $G_TMP_DIR/${G_HOTPATCH_ID}.patch
|
cp $G_PATCHFILE $G_TMP_DIR/${G_HOTPATCH_ID}.patch
|
||||||
G_PATCHFILE=$G_TMP_DIR/${G_HOTPATCH_ID}.patch
|
G_PATCHFILE=$G_TMP_DIR/${G_HOTPATCH_ID}.patch
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
cd $G_TMP_DIR &>/dev/null
|
cd $G_TMP_DIR &>/dev/null
|
||||||
if [ -n "$G_MODULE_MAKEFILE" ];then
|
if [ -n "$G_MODULE_MAKEFILE" ];then
|
||||||
USERMODBUILDDIR=$(dirname $G_MODULE_MAKEFILE)
|
USERMODBUILDDIR=$(dirname $G_MODULE_MAKEFILE)
|
||||||
fi
|
fi
|
||||||
export USERMODBUILDDIR
|
export USERMODBUILDDIR
|
||||||
export USERMODFLAGS=`cat $G_KPATCH_FLAGS`
|
export USERMODFLAGS=`cat $G_KPATCH_FLAGS`
|
||||||
export NO_PROFILING_CALLS=yes
|
export NO_PROFILING_CALLS="yes"
|
||||||
kpatch-build -s $G_KERNEL_SRC $l_extra_module -c $G_KERNEL_CONFIG -v $G_VMLINUX --skip-gcc-check -n "${G_PREFIX}_${G_HOTPATCH_ID}" -b /lib/modules/`uname -r`/build $G_DEBUG_INFO $G_PATCHFILE
|
export DISABLE_AFTER_LOAD="yes"
|
||||||
|
kpatch-build -s $G_PATCH_SRC -c $G_KERNEL_CONFIG -v $G_VMLINUX --skip-gcc-check -n "${G_PREFIX}_${G_HOTPATCH_ID}" $G_DEBUG_INFO $G_PATCHFILE
|
||||||
l_ret=$?
|
l_ret=$?
|
||||||
cd - &>/dev/null
|
cd - &>/dev/null
|
||||||
if [ $l_ret -eq 0 ] && [ -f "$G_TMP_DIR/$G_HOTPATCH" ];then
|
if [ $l_ret -eq 0 ] && [ -f "$G_TMP_DIR/$G_HOTPATCH" ];then
|
||||||
if grep -q "CONFIG_MODULE_SIG=y" .config ;then
|
cd /tmp &>/dev/null
|
||||||
echo "kernel compile with CONFIG_MODULE_SIG=y,please sign the patch module"
|
|
||||||
fi
|
|
||||||
cd /tmp &>/dev/null
|
|
||||||
l_env_file=$G_TMP_DIR/toolenv
|
l_env_file=$G_TMP_DIR/toolenv
|
||||||
if [ -n "`which rpm 2>/dev/null`" ]; then
|
if [ -n "`which rpm 2>/dev/null`" ]; then
|
||||||
echo "------------------------------------------------------------------------ " > "${l_env_file}"
|
echo "------------------------------------------------------------------------ " > "${l_env_file}"
|
||||||
echo >> "${l_env_file}"
|
echo >> "${l_env_file}"
|
||||||
echo "The kpatch tool version info and release date:" >> "${l_env_file}"
|
echo "The kpatch tool version info and release date:" >> "${l_env_file}"
|
||||||
rpm -qi kpatch >> "${l_env_file}"
|
rpm -qi kpatch >> "${l_env_file}"
|
||||||
echo >> "${l_env_file}"
|
echo >> "${l_env_file}"
|
||||||
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
||||||
else
|
else
|
||||||
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo >> "${l_env_file}"
|
echo >> "${l_env_file}"
|
||||||
@ -617,41 +620,41 @@ function fn_makepatch()
|
|||||||
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
||||||
|
|
||||||
if [ -f "/etc/EulerLinux.conf" ]; then
|
if [ -f "/etc/EulerLinux.conf" ]; then
|
||||||
echo >> "${l_env_file}"
|
echo >> "${l_env_file}"
|
||||||
echo "The euler compile env version info:" >> "${l_env_file}"
|
echo "The euler compile env version info:" >> "${l_env_file}"
|
||||||
cat /etc/EulerLinux.conf >> "${l_env_file}"
|
cat /etc/EulerLinux.conf >> "${l_env_file}"
|
||||||
echo >> "${l_env_file}"
|
echo >> "${l_env_file}"
|
||||||
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "${G_MODULE_SRC}" ]; then
|
if [ -n "${G_MODULE_SRC}" ]; then
|
||||||
echo >> "${l_env_file}"
|
echo >> "${l_env_file}"
|
||||||
echo "The module hotpatch compile path info:" >> "${l_env_file}"
|
echo "The module hotpatch compile path info:" >> "${l_env_file}"
|
||||||
echo "MODULE_SRC=${G_MODULE_SRC}" >> "${l_env_file}"
|
echo "MODULE_SRC=${G_MODULE_SRC}" >> "${l_env_file}"
|
||||||
echo "MODULE_MAKEFILE=${G_MODULE_MAKEFILE}" >> "${l_env_file}"
|
echo "MODULE_MAKEFILE=${G_MODULE_MAKEFILE}" >> "${l_env_file}"
|
||||||
echo >> "${l_env_file}"
|
echo >> "${l_env_file}"
|
||||||
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -f "${G_EXT_FLAGS}" ]; then
|
if [ -f "${G_EXT_FLAGS}" ]; then
|
||||||
echo >> "${l_env_file}"
|
echo >> "${l_env_file}"
|
||||||
echo "The module hotpatch compile flags info:" >> "${l_env_file}"
|
echo "The module hotpatch compile flags info:" >> "${l_env_file}"
|
||||||
cat "${G_EXT_FLAGS}" >> "${l_env_file}"
|
cat "${G_EXT_FLAGS}" >> "${l_env_file}"
|
||||||
echo >> "${l_env_file}"
|
echo >> "${l_env_file}"
|
||||||
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "${G_DEBUG_INFO}" ]; then
|
if [ -n "${G_DEBUG_INFO}" ]; then
|
||||||
echo >> "${l_env_file}"
|
echo >> "${l_env_file}"
|
||||||
echo "The debug option info:" >> "${l_env_file}"
|
echo "The debug option info:" >> "${l_env_file}"
|
||||||
echo "${G_DEBUG_INFO}" >> "${l_env_file}"
|
echo "${G_DEBUG_INFO}" >> "${l_env_file}"
|
||||||
echo >> "${l_env_file}"
|
echo >> "${l_env_file}"
|
||||||
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
echo "------------------------------------------------------------------------ " >> "${l_env_file}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
tar -czf $G_HOTPATCH_TAR ${G_PREFIX}_${G_HOTPATCH_ID}
|
tar -czf $G_HOTPATCH_TAR ${G_PREFIX}_${G_HOTPATCH_ID}
|
||||||
mv ${G_HOTPATCH_TAR} ${G_HOTPATCH_DIR}
|
mv ${G_HOTPATCH_TAR} ${G_HOTPATCH_DIR}
|
||||||
cd - &>/dev/null
|
cd - &>/dev/null
|
||||||
if [ $? -ne 0 ];then
|
if [ $? -ne 0 ];then
|
||||||
echo "error: move ${G_HOTPATCH} to ${G_KSPLICE_HOTPATCH} failed"
|
echo "error: move ${G_HOTPATCH} to ${G_KSPLICE_HOTPATCH} failed"
|
||||||
return 1
|
return 1
|
||||||
@ -682,43 +685,43 @@ function fn_main()
|
|||||||
fn_do_clean
|
fn_do_clean
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
fn_do_clean
|
fn_do_clean
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function fn_prepare()
|
function fn_prepare()
|
||||||
{
|
{
|
||||||
kerver=`uname -r`
|
kerver=`uname -r`
|
||||||
kerver=${kerver%.x86_64}
|
kerver=${kerver%.x86_64}
|
||||||
kerver=${kerver%.aarch64}
|
kerver=${kerver%.aarch64}
|
||||||
echo kernel version:$kerver
|
echo kernel version:$kerver
|
||||||
if [ ! -L kernel-source ];then
|
if [ ! -L kernel-source ];then
|
||||||
if [ -d /arm/arm_kernel ];then
|
if [ -d /arm/arm_kernel ];then
|
||||||
ln -s /arm/arm_kernel/linux-$kerver kernel-source
|
ln -s /arm/arm_kernel/linux-$kerver kernel-source
|
||||||
else
|
else
|
||||||
ln -s /usr/src/kernels/linux-$kerver kernel-source
|
ln -s /usr/src/kernels/linux-$kerver kernel-source
|
||||||
cp /lib/modules/`uname -r`/build/Makefile /usr/src/kernels/linux-$kerver
|
cp /lib/modules/`uname -r`/build/Makefile /usr/src/kernels/linux-$kerver
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if [ ! -L .config ];then
|
if [ ! -L .config ];then
|
||||||
if [ -d /arm/arm_kernel ];then
|
if [ -d /arm/arm_kernel ];then
|
||||||
ln -s /arm/arm_kernel/linux-$kerver/.config .config
|
ln -s /arm/arm_kernel/linux-$kerver/.config .config
|
||||||
else
|
else
|
||||||
ln -s /usr/src/kernels/linux-$kerver/.config .config
|
ln -s /usr/src/kernels/linux-$kerver/.config .config
|
||||||
cp /lib/modules/`uname -r`/build/.config /usr/src/kernels/linux-$kerver
|
cp /lib/modules/`uname -r`/build/.config /usr/src/kernels/linux-$kerver
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
rm -rf $G_KPATCH_FLAGS
|
rm -rf $G_KPATCH_FLAGS
|
||||||
touch $G_KPATCH_FLAGS
|
touch $G_KPATCH_FLAGS
|
||||||
}
|
}
|
||||||
|
|
||||||
G_NUM=`pidof -x make_hotpatch | wc -w`
|
G_NUM=`pidof -x make_hotpatch | wc -w`
|
||||||
if [ $G_NUM -gt 2 ];then
|
if [ $G_NUM -gt 2 ];then
|
||||||
echo "[$0]someone is making, please try again later."
|
echo "[$0]someone is making, please try again later."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
fn_prepare
|
fn_prepare
|
||||||
|
|||||||
439
os_hotpatch
439
os_hotpatch
@ -1,17 +1,21 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Copyright (C) 2019. Huawei Technologies Co., Ltd. All rights reserved.
|
#********************************************************************
|
||||||
#
|
# Copyright (C) Huawei Technologies, 2015-11
|
||||||
# This program is free software; you can redistribute it and/or modify
|
#
|
||||||
# it under the terms of the GNU General Public License version 2 and
|
# #FileName : make_hotpatch
|
||||||
# only version 2 as published by the Free Software Foundation.
|
# #Description : make hotpatch
|
||||||
#
|
# #Author :
|
||||||
# This program is distributed in the hope that it will be useful,
|
# #Language : shell
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# #Environment : Euler compile env
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# #Created : 2015-11
|
||||||
# GNU General Public License for more details.
|
# #History
|
||||||
|
# 1.Date:
|
||||||
|
# Author:
|
||||||
|
# Modification:2015-12-7
|
||||||
|
#********************************************************************
|
||||||
|
|
||||||
SYS_LIVEPATCH=/sys/kernel/livepatch
|
SYS_LIVEPATCH=/sys/kernel/livepatch
|
||||||
G_TMP_DIR=/tmp/hotpatch.$$
|
G_TMP_DIR=/lib/modules/hotpatch.$$
|
||||||
G_PATCH_FILE=
|
G_PATCH_FILE=
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
@ -21,14 +25,14 @@ G_PATCH_FILE=
|
|||||||
#########################################################
|
#########################################################
|
||||||
OS_HP_HELP()
|
OS_HP_HELP()
|
||||||
{
|
{
|
||||||
echo "usage: os_hotpatch"
|
echo "usage: os_hotpatch"
|
||||||
echo "-w|--check <filepath> : check hotpatch"
|
echo "-w|--check <filepath> : check hotpatch"
|
||||||
echo "-l|--load <filepath> : load hotpatch"
|
echo "-l|--load <filepath> : load hotpatch"
|
||||||
echo "-a|--active <patchname> : active hotpatch"
|
echo "-a|--active <patchname> : active hotpatch"
|
||||||
echo "-r|--rollback <patchname> : rollback/deactive hotpatch"
|
echo "-r|--rollback <patchname> : rollback/deactive hotpatch"
|
||||||
echo "-d|--delete <patchname> : delete/unload hotpatch"
|
echo "-d|--delete <patchname> : delete/unload hotpatch"
|
||||||
echo "-q|--query <patchname>/all : query hotpatch"
|
echo "-q|--query <patchname>/all : query hotpatch"
|
||||||
echo "-h|--help : show this help information"
|
echo "-h|--help : show this help information"
|
||||||
}
|
}
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
@ -39,20 +43,20 @@ OS_HP_HELP()
|
|||||||
#########################################################
|
#########################################################
|
||||||
OS_HP_CHECK()
|
OS_HP_CHECK()
|
||||||
{
|
{
|
||||||
path=$1
|
path=$1
|
||||||
if [ ! -f "$path" ]; then
|
if [ ! -f "$path" ]; then
|
||||||
echo "The file $path is not exit"
|
echo "The file $path is not exit"
|
||||||
exit 1;
|
exit 1;
|
||||||
fi
|
fi
|
||||||
EXTRACT_HP $path
|
EXTRACT_HP $path
|
||||||
if [ $? -ne 0 -o ! -f "$G_PATCH_FILE" ];then
|
if [ $? -ne 0 -o ! -f "$G_PATCH_FILE" ];then
|
||||||
echo "The file $path is invalid"
|
echo "The file $path is invalid"
|
||||||
|
CLEAN_UP
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
CLEAN_UP
|
CLEAN_UP
|
||||||
exit 1;
|
echo "The file $path is valid"
|
||||||
fi
|
exit 0
|
||||||
CLEAN_UP
|
|
||||||
echo "The file $path is valid"
|
|
||||||
exit 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
@ -63,30 +67,30 @@ OS_HP_CHECK()
|
|||||||
#########################################################
|
#########################################################
|
||||||
OS_HP_ACTIVE()
|
OS_HP_ACTIVE()
|
||||||
{
|
{
|
||||||
file=$1
|
file=$1
|
||||||
patch_name=`echo ${file%.tar.gz}|tr '-' '_'`
|
patch_name=`echo ${file%.tar.gz}|tr '-' '_'`
|
||||||
patch_install=`lsmod | grep -w $patch_name`
|
patch_install=`lsmod | grep -w $patch_name`
|
||||||
|
|
||||||
if [ "$patch_install" == "" ]; then
|
if [ "$patch_install" == "" ]; then
|
||||||
echo "patch $file not load"
|
echo "patch $file not load"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
||||||
if [ ${is_active} == 1 ]; then
|
if [ ${is_active} == 1 ]; then
|
||||||
echo "patch already active"
|
echo "patch already active"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo 1 > ${SYS_LIVEPATCH}/${patch_name}/enabled
|
echo 1 > ${SYS_LIVEPATCH}/${patch_name}/enabled
|
||||||
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
||||||
if [ ${is_active} == 1 ]; then
|
if [ ${is_active} == 1 ]; then
|
||||||
echo "active patch $file success"
|
echo "active patch $file success"
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
echo "active patch $file fail"
|
echo "active patch $file fail"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
@ -97,30 +101,30 @@ OS_HP_ACTIVE()
|
|||||||
#########################################################
|
#########################################################
|
||||||
OS_HP_DEACTIVE()
|
OS_HP_DEACTIVE()
|
||||||
{
|
{
|
||||||
file=$1
|
file=$1
|
||||||
patch_name=`echo ${file%.tar.gz}|tr '-' '_'`
|
patch_name=`echo ${file%.tar.gz}|tr '-' '_'`
|
||||||
patch_install=`lsmod | grep -w $patch_name`
|
patch_install=`lsmod | grep -w $patch_name`
|
||||||
|
|
||||||
if [ "$patch_install" == "" ]; then
|
if [ "$patch_install" == "" ]; then
|
||||||
echo "patch $file not load"
|
echo "patch $file not load"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
||||||
if [ ${is_active} == 0 ]; then
|
if [ ${is_active} == 0 ]; then
|
||||||
echo "patch $file already deactive"
|
echo "patch $file already deactive"
|
||||||
exit 0
|
exit 0
|
||||||
else
|
|
||||||
echo 0 > ${SYS_LIVEPATCH}/${patch_name}/enabled
|
|
||||||
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
|
||||||
if [ ${is_active} != 1 ]; then
|
|
||||||
echo "deactive patch $file success"
|
|
||||||
exit 0
|
|
||||||
else
|
else
|
||||||
echo "deactive patch $file fail"
|
echo 0 > ${SYS_LIVEPATCH}/${patch_name}/enabled
|
||||||
exit 1
|
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
||||||
fi
|
if [ ${is_active} != 1 ]; then
|
||||||
fi
|
echo "deactive patch $file success"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "deactive patch $file fail"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
@ -131,31 +135,31 @@ OS_HP_DEACTIVE()
|
|||||||
#########################################################
|
#########################################################
|
||||||
OS_HP_REMOVE()
|
OS_HP_REMOVE()
|
||||||
{
|
{
|
||||||
file=$1
|
file=$1
|
||||||
patch_name=`echo ${file%.tar.gz}|tr '-' '_'`
|
patch_name=`echo ${file%.tar.gz}|tr '-' '_'`
|
||||||
patch_install=`lsmod | grep -w $patch_name`
|
patch_install=`lsmod | grep -w $patch_name`
|
||||||
|
|
||||||
if [ "$patch_install" == "" ]; then
|
if [ "$patch_install" == "" ]; then
|
||||||
echo "patch $file not load"
|
echo "patch $file not load"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
|
||||||
if [ ${is_active} == 0 ]; then
|
|
||||||
rmmod ${patch_name}
|
|
||||||
else
|
|
||||||
echo 0 > ${SYS_LIVEPATCH}/${patch_name}/enabled
|
|
||||||
rmmod ${patch_name}
|
|
||||||
fi
|
|
||||||
|
|
||||||
patch_install=`lsmod | grep -w $patch_name`
|
is_active=`cat ${SYS_LIVEPATCH}/${patch_name}/enabled`
|
||||||
if [ "$patch_install" == "" ]; then
|
if [ ${is_active} == 0 ]; then
|
||||||
echo "remove patch $file success"
|
rmmod ${patch_name}
|
||||||
exit 0
|
else
|
||||||
else
|
echo 0 > ${SYS_LIVEPATCH}/${patch_name}/enabled
|
||||||
echo "remove patch $file failed"
|
rmmod ${patch_name}
|
||||||
exit 1
|
fi
|
||||||
fi
|
|
||||||
|
patch_install=`lsmod | grep -w $patch_name`
|
||||||
|
if [ "$patch_install" == "" ]; then
|
||||||
|
echo "remove patch $file success"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "remove patch $file failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
@ -166,61 +170,61 @@ OS_HP_REMOVE()
|
|||||||
#########################################################
|
#########################################################
|
||||||
OS_HP_INQUIRY()
|
OS_HP_INQUIRY()
|
||||||
{
|
{
|
||||||
file=$1
|
file=$1
|
||||||
lret=0
|
lret=0
|
||||||
if [ "all" == $file ];then
|
if [ "all" == $file ];then
|
||||||
cd ${SYS_LIVEPATCH}
|
cd ${SYS_LIVEPATCH}
|
||||||
if [ -z "`ls -d */ 2>/dev/null`" ];then
|
if [ -z "`ls -d */ 2>/dev/null`" ];then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
for patch in `ls -d */ 2>/dev/null`
|
||||||
|
do
|
||||||
|
patch_id=${patch%/}
|
||||||
|
patch_id=${patch_id#klp_}
|
||||||
|
echo "Patch Name: ${patch_id}"
|
||||||
|
lstate=`cat /${SYS_LIVEPATCH}/${patch}/enabled 2>/dev/null`
|
||||||
|
if [ -z "$lstate" ];then
|
||||||
|
echo "Patch State: Removing"
|
||||||
|
echo "-----------------------------------------------------------"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if [ $lstate -eq 1 ];then
|
||||||
|
echo "Patch State: Active"
|
||||||
|
else
|
||||||
|
echo "Patch State: Deactive"
|
||||||
|
fi
|
||||||
|
cd ${SYS_LIVEPATCH}/${patch} 2>/dev/null
|
||||||
|
depends=`ls -d */ 2>/dev/null`
|
||||||
|
echo "Changes:"
|
||||||
|
ls -l ${SYS_LIVEPATCH}/${patch}/*/ 2>/dev/null|grep '^d'|awk -F ' ' '{print "\t"$9}'
|
||||||
|
echo "Denpendency: ${depends%/}"
|
||||||
|
echo "-----------------------------------------------------------"
|
||||||
|
done
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
for patch in `ls -d */ 2>/dev/null`
|
patch=`echo ${file%.tar.gz}|tr '-' '_'`
|
||||||
do
|
patch_install=`lsmod | grep -w $patch`
|
||||||
patch_id=${patch%/}
|
if [ "$patch_install" == "" ]; then
|
||||||
patch_id=${patch_id#klp_}
|
exit 1
|
||||||
echo "Patch Name: ${patch_id}"
|
fi
|
||||||
lstate=`cat /${SYS_LIVEPATCH}/${patch}/enabled 2>/dev/null`
|
patch_id=${patch%/}
|
||||||
if [ -z "$lstate" ];then
|
patch_id=${patch_id#klp_}
|
||||||
echo "Patch State: Removing"
|
echo "Patch Name: ${patch_id}"
|
||||||
echo "-----------------------------------------------------------"
|
if [ `cat /${SYS_LIVEPATCH}/${patch}/enabled` -eq 1 ];then
|
||||||
continue
|
echo "Patch State: Active"
|
||||||
fi
|
lret=3
|
||||||
if [ $lstate -eq 1 ];then
|
else
|
||||||
echo "Patch State: Active"
|
echo "Patch State: Deactive"
|
||||||
else
|
lret=2
|
||||||
echo "Patch State: Deactive"
|
fi
|
||||||
fi
|
cd ${SYS_LIVEPATCH}/${patch}
|
||||||
cd ${SYS_LIVEPATCH}/${patch} 2>/dev/null
|
depends=`ls -d */ 2>/dev/null`
|
||||||
depends=`ls -d */ 2>/dev/null`
|
echo "Changes:"
|
||||||
echo "Changes:"
|
ls -l ${SYS_LIVEPATCH}/${patch}/*/ 2>/dev/null|grep '^d'|awk -F ' ' '{print "\t"$9}'
|
||||||
ls -l ${SYS_LIVEPATCH}/${patch}/*/ 2>/dev/null|grep '^d'|awk -F ' ' '{print "\t"$9}'
|
echo "Denpendency: ${depends%/}"
|
||||||
echo "Denpendency: ${depends%/}"
|
echo "-----------------------------------------------------------"
|
||||||
echo "-----------------------------------------------------------"
|
|
||||||
done
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
patch=`echo ${file%.tar.gz}|tr '-' '_'`
|
|
||||||
patch_install=`lsmod | grep -w $patch`
|
|
||||||
if [ "$patch_install" == "" ]; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
patch_id=${patch%/}
|
|
||||||
patch_id=${patch_id#klp_}
|
|
||||||
echo "Patch Name: ${patch_id}"
|
|
||||||
if [ `cat /${SYS_LIVEPATCH}/${patch}/enabled` -eq 1 ];then
|
|
||||||
echo "Patch State: Active"
|
|
||||||
lret=3
|
|
||||||
else
|
|
||||||
echo "Patch State: Deactive"
|
|
||||||
lret=2
|
|
||||||
fi
|
|
||||||
cd ${SYS_LIVEPATCH}/${patch}
|
|
||||||
depends=`ls -d */ 2>/dev/null`
|
|
||||||
echo "Changes:"
|
|
||||||
ls -l ${SYS_LIVEPATCH}/${patch}/*/ 2>/dev/null|grep '^d'|awk -F ' ' '{print "\t"$9}'
|
|
||||||
echo "Denpendency: ${depends%/}"
|
|
||||||
echo "-----------------------------------------------------------"
|
|
||||||
|
|
||||||
exit $lret
|
exit $lret
|
||||||
}
|
}
|
||||||
#########################################################
|
#########################################################
|
||||||
# Description: extract hotpatch tar to tmp dir
|
# Description: extract hotpatch tar to tmp dir
|
||||||
@ -230,11 +234,12 @@ OS_HP_INQUIRY()
|
|||||||
#########################################################
|
#########################################################
|
||||||
EXTRACT_HP()
|
EXTRACT_HP()
|
||||||
{
|
{
|
||||||
mkdir $G_TMP_DIR
|
rm -rf $G_TMP_DIR
|
||||||
|
mkdir -p $G_TMP_DIR
|
||||||
tar xzf $1 -C $G_TMP_DIR
|
tar xzf $1 -C $G_TMP_DIR
|
||||||
l_ret=$?
|
l_ret=$?
|
||||||
if [ $l_ret -eq 0 ];then
|
if [ $l_ret -eq 0 ];then
|
||||||
#find the hotpatch module
|
#find the hotpatch module
|
||||||
G_PATCH_FILE=$(find $G_TMP_DIR|grep -w "klp.*\.ko")
|
G_PATCH_FILE=$(find $G_TMP_DIR|grep -w "klp.*\.ko")
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
@ -248,7 +253,7 @@ EXTRACT_HP()
|
|||||||
#########################################################
|
#########################################################
|
||||||
CLEAN_UP()
|
CLEAN_UP()
|
||||||
{
|
{
|
||||||
rm -rf $G_TMP_DIR
|
rm -rf $G_TMP_DIR
|
||||||
}
|
}
|
||||||
#########################################################
|
#########################################################
|
||||||
# Description: install a hotpatch
|
# Description: install a hotpatch
|
||||||
@ -258,80 +263,80 @@ CLEAN_UP()
|
|||||||
#########################################################
|
#########################################################
|
||||||
OS_HP_INSTALL()
|
OS_HP_INSTALL()
|
||||||
{
|
{
|
||||||
path=$1
|
path=$1
|
||||||
|
|
||||||
if [ ! -f "$path" ]; then
|
if [ ! -f "$path" ]; then
|
||||||
echo "The file $path is not exit"
|
echo "The file $path is not exit"
|
||||||
exit 1;
|
exit 1;
|
||||||
fi
|
fi
|
||||||
EXTRACT_HP $path
|
EXTRACT_HP $path
|
||||||
if [ $? -ne 0 -o ! -f "$G_PATCH_FILE" ];then
|
if [ $? -ne 0 -o ! -f "$G_PATCH_FILE" ];then
|
||||||
echo "The file $path is invalid!"
|
echo "The file $path is invalid!"
|
||||||
|
CLEAN_UP
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
patch_name=`echo ${G_PATCH_FILE%.ko}|tr '-' '_'`
|
||||||
|
patch_name=${patch_name##*/}
|
||||||
|
patch_install=`lsmod | grep -w $patch_name`
|
||||||
|
if [ "$patch_install" == "" ]; then
|
||||||
|
echo "insmod $G_PATCH_FILE"
|
||||||
|
insmod $G_PATCH_FILE
|
||||||
|
L_RET=$?
|
||||||
|
if [ 0 -ne ${L_RET} ]; then
|
||||||
|
echo "install patch $path fail"
|
||||||
|
CLEAN_UP
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
echo "install patch $path success"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "patch $path already install"
|
||||||
|
fi
|
||||||
CLEAN_UP
|
CLEAN_UP
|
||||||
exit 1;
|
return 0
|
||||||
fi
|
|
||||||
patch_name=`echo ${G_PATCH_FILE%.ko}|tr '-' '_'`
|
|
||||||
patch_name=${patch_name##*/}
|
|
||||||
patch_install=`lsmod | grep -w $patch_name`
|
|
||||||
if [ "$patch_install" == "" ]; then
|
|
||||||
echo "insmod $G_PATCH_FILE"
|
|
||||||
insmod $G_PATCH_FILE
|
|
||||||
L_RET=$?
|
|
||||||
if [ 0 -ne ${L_RET} ]; then
|
|
||||||
echo "install patch $path fail"
|
|
||||||
CLEAN_UP
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
echo "install patch $path success"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "patch $path already install"
|
|
||||||
fi
|
|
||||||
CLEAN_UP
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#----------------------------main-------------------------#
|
#----------------------------main-------------------------#
|
||||||
if [ ! -d ${SYS_LIVEPATCH} ];then
|
if [ ! -d ${SYS_LIVEPATCH} ];then
|
||||||
echo "this OS does not support kernel livepatch"
|
echo "this OS does not support kernel livepatch"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
input_args=`getopt -a -o l:a:r:d:w:q: -l load:,active:,delete:,check:,rollback:,query:,help, -- "$@" 2>&1`
|
input_args=`getopt -a -o l:a:r:d:w:q: -l load:,active:,delete:,check:,rollback:,query:,help, -- "$@" 2>&1`
|
||||||
eval set -- "${input_args}"
|
eval set -- "${input_args}"
|
||||||
while true;
|
while true;
|
||||||
do
|
do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
-w|--check)
|
-w|--check)
|
||||||
OS_HP_CHECK "$2"
|
OS_HP_CHECK "$2"
|
||||||
exit $?
|
exit $?
|
||||||
;;
|
;;
|
||||||
-l|--load)
|
-l|--load)
|
||||||
OS_HP_INSTALL "$2"
|
OS_HP_INSTALL "$2"
|
||||||
exit $?
|
exit $?
|
||||||
;;
|
;;
|
||||||
-a|--active)
|
-a|--active)
|
||||||
OS_HP_ACTIVE "$2"
|
OS_HP_ACTIVE "$2"
|
||||||
exit $?
|
exit $?
|
||||||
;;
|
;;
|
||||||
-r|--rollback)
|
-r|--rollback)
|
||||||
OS_HP_DEACTIVE "$2"
|
OS_HP_DEACTIVE "$2"
|
||||||
exit $?
|
exit $?
|
||||||
;;
|
;;
|
||||||
-d|--delete)
|
-d|--delete)
|
||||||
OS_HP_REMOVE "$2"
|
OS_HP_REMOVE "$2"
|
||||||
exit $?
|
exit $?
|
||||||
;;
|
;;
|
||||||
-q|--query)
|
-q|--query)
|
||||||
OS_HP_INQUIRY "$2"
|
OS_HP_INQUIRY "$2"
|
||||||
exit $?
|
exit $?
|
||||||
;;
|
;;
|
||||||
-h|--help)
|
-h|--help)
|
||||||
OS_HP_HELP
|
OS_HP_HELP
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
OS_HP_HELP
|
OS_HP_HELP
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user