2024-03-02 00:18:20 +08:00
|
|
|
From df00eb365c9011e32d3c191d6c908a8e745100b2 Mon Sep 17 00:00:00 2001
|
2020-02-27 17:15:29 -05:00
|
|
|
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
|
|
|
|
Date: Wed, 26 Feb 2020 07:36:59 -0500
|
2024-03-02 00:18:20 +08:00
|
|
|
Subject: [PATCH 09/38] support c++ kernel module
|
2020-02-27 17:15:29 -05:00
|
|
|
|
|
|
|
|
support GNU_UNIQUE type symbols.
|
|
|
|
|
support .group section corelation.
|
|
|
|
|
ignore compile warning for third party modules.
|
|
|
|
|
|
2020-03-22 06:56:43 -04:00
|
|
|
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
2020-02-27 17:15:29 -05:00
|
|
|
---
|
2021-11-16 12:10:06 +08:00
|
|
|
kpatch-build/create-diff-object.c | 48 ++++++++++++++++++++-----------
|
|
|
|
|
kpatch-build/kpatch-cc | 4 ++-
|
|
|
|
|
kpatch-build/kpatch-elf.c | 8 +++++-
|
|
|
|
|
kpatch-build/lookup.c | 5 +++-
|
|
|
|
|
4 files changed, 45 insertions(+), 20 deletions(-)
|
2020-02-27 17:15:29 -05:00
|
|
|
|
|
|
|
|
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
|
2024-03-02 00:18:20 +08:00
|
|
|
index 3cbfaee..d3088b1 100644
|
2020-02-27 17:15:29 -05:00
|
|
|
--- a/kpatch-build/create-diff-object.c
|
|
|
|
|
+++ b/kpatch-build/create-diff-object.c
|
2024-03-02 00:18:20 +08:00
|
|
|
@@ -598,7 +598,7 @@ static void kpatch_compare_correlated_nonrela_section(struct section *sec)
|
2020-02-27 17:15:29 -05:00
|
|
|
{
|
|
|
|
|
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
|
2024-03-02 00:18:20 +08:00
|
|
|
@@ -614,7 +614,7 @@ static void kpatch_compare_correlated_section(struct section *sec)
|
2020-02-27 17:15:29 -05:00
|
|
|
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 */
|
2024-03-02 00:18:20 +08:00
|
|
|
@@ -1050,6 +1050,34 @@ static void kpatch_correlate_section(struct section *sec_orig,
|
2021-11-16 12:10:06 +08:00
|
|
|
kpatch_correlate_symbol(sec_orig->sym, sec_patched->sym);
|
2020-02-27 17:15:29 -05:00
|
|
|
}
|
|
|
|
|
|
2021-11-16 12:10:06 +08:00
|
|
|
+static int kpatch_correlate_group_section(struct list_head *seclist_orig,
|
|
|
|
|
+ struct list_head *seclist_patched, struct section *sec1, struct section *sec2)
|
2020-02-27 17:15:29 -05:00
|
|
|
+{
|
|
|
|
|
+ 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) {
|
2021-11-16 12:10:06 +08:00
|
|
|
+ isec1 = find_section_by_index(seclist_orig, *data1);
|
2020-02-27 17:15:29 -05:00
|
|
|
+ if (!isec1)
|
|
|
|
|
+ ERROR("group section not found");
|
2021-11-16 12:10:06 +08:00
|
|
|
+ isec2 = find_section_by_index(seclist_patched, *data2);
|
2020-02-27 17:15:29 -05:00
|
|
|
+ if (!isec2)
|
|
|
|
|
+ ERROR("group section not found");
|
|
|
|
|
+ if (strcmp(isec1->name, isec2->name))
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ data1++;
|
|
|
|
|
+ data2++;
|
|
|
|
|
+ }
|
|
|
|
|
+ return 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
2021-11-16 12:10:06 +08:00
|
|
|
static void kpatch_correlate_sections(struct list_head *seclist_orig,
|
|
|
|
|
struct list_head *seclist_patched)
|
2020-02-27 17:15:29 -05:00
|
|
|
{
|
2024-03-02 00:18:20 +08:00
|
|
|
@@ -1076,10 +1104,7 @@ static void kpatch_correlate_sections(struct list_head *seclist_orig,
|
2021-11-16 12:10:06 +08:00
|
|
|
* Changed group sections are currently not supported.
|
2020-09-12 05:45:06 -04:00
|
|
|
*/
|
2021-11-16 12:10:06 +08:00
|
|
|
if (sec_orig->sh.sh_type == SHT_GROUP) {
|
|
|
|
|
- if (sec_orig->data->d_size != sec_patched->data->d_size)
|
2020-02-27 17:15:29 -05:00
|
|
|
- continue;
|
2021-11-16 12:10:06 +08:00
|
|
|
- if (memcmp(sec_orig->data->d_buf, sec_patched->data->d_buf,
|
|
|
|
|
- sec_orig->data->d_size))
|
|
|
|
|
+ if (kpatch_correlate_group_section(seclist_orig, seclist_patched, sec_orig, sec_patched))
|
2020-02-27 17:15:29 -05:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-02 00:18:20 +08:00
|
|
|
@@ -1740,17 +1765,6 @@ static void kpatch_verify_patchability(struct kpatch_elf *kelf)
|
2020-02-27 17:15:29 -05:00
|
|
|
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)
|
2021-11-16 12:10:06 +08:00
|
|
|
diff --git a/kpatch-build/kpatch-cc b/kpatch-build/kpatch-cc
|
2024-03-02 00:18:20 +08:00
|
|
|
index ce72e55..8f22978 100755
|
2021-11-16 12:10:06 +08:00
|
|
|
--- a/kpatch-build/kpatch-cc
|
|
|
|
|
+++ b/kpatch-build/kpatch-cc
|
|
|
|
|
@@ -13,7 +13,9 @@ fi
|
2020-02-27 17:15:29 -05:00
|
|
|
|
2021-11-16 12:10:06 +08:00
|
|
|
declare -a args=("$@")
|
2020-02-27 17:15:29 -05:00
|
|
|
|
2021-11-16 12:10:06 +08:00
|
|
|
-if [[ "$TOOLCHAINCMD" =~ ^(.*-)?gcc$ || "$TOOLCHAINCMD" =~ ^(.*-)?clang$ ]] ; then
|
|
|
|
|
+if [[ "$TOOLCHAINCMD" =~ ^(.*-)?gcc$ ||
|
|
|
|
|
+ "$TOOLCHAINCMD" =~ ^(.*-)?g\+\+$ ||
|
|
|
|
|
+ "$TOOLCHAINCMD" =~ ^(.*-)?clang$ ]] ; then
|
|
|
|
|
while [ "$#" -gt 0 ]; do
|
|
|
|
|
if [ "$1" = "-o" ]; then
|
|
|
|
|
obj="$2"
|
2020-02-27 17:15:29 -05:00
|
|
|
diff --git a/kpatch-build/kpatch-elf.c b/kpatch-build/kpatch-elf.c
|
2024-03-02 00:18:20 +08:00
|
|
|
index d4aee86..b639bc2 100644
|
2020-02-27 17:15:29 -05:00
|
|
|
--- a/kpatch-build/kpatch-elf.c
|
|
|
|
|
+++ b/kpatch-build/kpatch-elf.c
|
2024-03-02 00:18:20 +08:00
|
|
|
@@ -978,8 +978,14 @@ void kpatch_reindex_elements(struct kpatch_elf *kelf)
|
2020-02-27 17:15:29 -05:00
|
|
|
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++;
|
2020-09-12 05:45:06 -04:00
|
|
|
+ /*
|
2020-02-27 17:15:29 -05:00
|
|
|
+ * since we exclude .group section, we clear SHF_GROUP
|
|
|
|
|
+ * for every section in case of link error.
|
2020-09-12 05:45:06 -04:00
|
|
|
+ */
|
2020-02-27 17:15:29 -05:00
|
|
|
+ sec->sh.sh_flags &= (~SHF_GROUP);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
index = 0;
|
|
|
|
|
list_for_each_entry(sym, &kelf->symbols, list) {
|
|
|
|
|
diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c
|
2024-03-02 00:18:20 +08:00
|
|
|
index bd2b732..8905a1d 100644
|
2020-02-27 17:15:29 -05:00
|
|
|
--- a/kpatch-build/lookup.c
|
|
|
|
|
+++ b/kpatch-build/lookup.c
|
2024-03-02 00:18:20 +08:00
|
|
|
@@ -334,6 +334,8 @@ static void symtab_read(struct lookup_table *table, char *path)
|
2020-02-27 17:15:29 -05:00
|
|
|
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);
|
|
|
|
|
}
|
2024-03-02 00:18:20 +08:00
|
|
|
@@ -558,7 +560,8 @@ static bool lookup_global_symbol(struct lookup_table *table, char *name,
|
2020-02-27 17:15:29 -05:00
|
|
|
|
|
|
|
|
memset(result, 0, sizeof(*result));
|
|
|
|
|
for_each_obj_symbol(i, sym, table) {
|
|
|
|
|
- if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK) &&
|
2021-11-16 12:10:06 +08:00
|
|
|
++ if ((sym->bind == STB_GLOBAL || sym->bind == STB_WEAK
|
|
|
|
|
++ || sym->bind == STB_GNU_UNIQUE) &&
|
2020-02-27 17:15:29 -05:00
|
|
|
!strcmp(sym->name, name)) {
|
2021-11-16 12:10:06 +08:00
|
|
|
|
|
|
|
|
if (result->objname)
|
2020-02-27 17:15:29 -05:00
|
|
|
--
|
2023-01-30 16:10:43 +08:00
|
|
|
2.33.0
|
2020-09-12 05:45:06 -04:00
|
|
|
|