2020-09-12 05:45:06 -04:00
|
|
|
|
From d170861502e78c396f0283f66f444a496efd11de 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
|
2020-09-12 05:45:06 -04:00
|
|
|
|
Subject: [PATCH 11/23] support c plus 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
|
|
|
|
---
|
2020-09-12 05:45:06 -04:00
|
|
|
|
kpatch-build/create-diff-object.c | 60 +++++++++++++++++++++----------
|
2020-02-27 17:15:29 -05:00
|
|
|
|
kpatch-build/kpatch-build | 2 +-
|
2020-09-12 05:45:06 -04:00
|
|
|
|
kpatch-build/kpatch-elf.c | 8 ++++-
|
2020-02-27 17:15:29 -05:00
|
|
|
|
kpatch-build/kpatch-gcc | 3 +-
|
|
|
|
|
|
kpatch-build/lookup.c | 5 ++-
|
2020-09-12 05:45:06 -04:00
|
|
|
|
5 files changed, 55 insertions(+), 23 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
|
2020-09-12 05:45:06 -04:00
|
|
|
|
index f37d404..d139f45 100644
|
2020-02-27 17:15:29 -05:00
|
|
|
|
--- a/kpatch-build/create-diff-object.c
|
|
|
|
|
|
+++ b/kpatch-build/create-diff-object.c
|
2020-09-12 05:45:06 -04:00
|
|
|
|
@@ -460,7 +460,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
|
2020-09-12 05:45:06 -04:00
|
|
|
|
@@ -476,7 +476,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 */
|
2020-09-12 05:45:06 -04:00
|
|
|
|
@@ -913,6 +913,34 @@ static void kpatch_correlate_section(struct section *sec1, struct section *sec2)
|
2020-02-27 17:15:29 -05:00
|
|
|
|
kpatch_correlate_symbol(sec1->sym, sec2->sym);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-12 05:45:06 -04:00
|
|
|
|
+static int kpatch_correlate_group_section(struct list_head *seclist1,
|
|
|
|
|
|
+ struct list_head *seclist2, 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) {
|
|
|
|
|
|
+ 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;
|
2020-09-12 05:45:06 -04:00
|
|
|
|
@@ -931,14 +959,19 @@ static void kpatch_correlate_sections(struct list_head *seclist1, struct list_he
|
2020-02-27 17:15:29 -05:00
|
|
|
|
continue;
|
|
|
|
|
|
|
2020-09-12 05:45:06 -04:00
|
|
|
|
/*
|
2020-02-27 17:15:29 -05:00
|
|
|
|
- * Group sections must match exactly to be correlated.
|
|
|
|
|
|
- * Changed group sections are currently not supported.
|
2020-09-12 05:45:06 -04:00
|
|
|
|
+ * Group section的格式为:
|
2020-02-27 17:15:29 -05:00
|
|
|
|
+ * flag
|
|
|
|
|
|
+ * section index
|
|
|
|
|
|
+ * section index
|
|
|
|
|
|
+ * ...
|
|
|
|
|
|
+ *
|
|
|
|
|
|
+ * 当C++代码发生修改时,section index可能会发生变化
|
|
|
|
|
|
+ * 这时候我们就比对一下section index所对应的section的
|
|
|
|
|
|
+ * name,如果相同,我们就认为这两个group是SAME
|
2020-09-12 05:45:06 -04:00
|
|
|
|
*/
|
2020-02-27 17:15:29 -05:00
|
|
|
|
+
|
|
|
|
|
|
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))
|
2020-09-12 05:45:06 -04:00
|
|
|
|
+ if (kpatch_correlate_group_section(seclist1, seclist2, sec1, sec2))
|
2020-02-27 17:15:29 -05:00
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-12 05:45:06 -04:00
|
|
|
|
@@ -1521,17 +1554,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)
|
|
|
|
|
|
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
|
2020-09-12 05:45:06 -04:00
|
|
|
|
index c6af59e..f76a9eb 100644
|
2020-02-27 17:15:29 -05:00
|
|
|
|
--- a/kpatch-build/kpatch-elf.c
|
|
|
|
|
|
+++ b/kpatch-build/kpatch-elf.c
|
2020-05-11 14:59:12 +08:00
|
|
|
|
@@ -710,8 +710,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/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
|
2020-09-12 05:45:06 -04:00
|
|
|
|
|