代码拉取完成,页面将自动刷新
From df00eb365c9011e32d3c191d6c908a8e745100b2 Mon Sep 17 00:00:00 2001
From: Zhipeng Xie <xiezhipeng1@huawei.com>
Date: Wed, 26 Feb 2020 07:36:59 -0500
Subject: [PATCH 09/38] support c++ kernel module
support GNU_UNIQUE type symbols.
support .group section corelation.
ignore compile warning for third party modules.
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
---
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(-)
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
index 3cbfaee..d3088b1 100644
--- a/kpatch-build/create-diff-object.c
+++ b/kpatch-build/create-diff-object.c
@@ -598,7 +598,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
@@ -614,7 +614,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 */
@@ -1050,6 +1050,34 @@ static void kpatch_correlate_section(struct section *sec_orig,
kpatch_correlate_symbol(sec_orig->sym, sec_patched->sym);
}
+static int kpatch_correlate_group_section(struct list_head *seclist_orig,
+ struct list_head *seclist_patched, 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(seclist_orig, *data1);
+ if (!isec1)
+ ERROR("group section not found");
+ isec2 = find_section_by_index(seclist_patched, *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 *seclist_orig,
struct list_head *seclist_patched)
{
@@ -1076,10 +1104,7 @@ static void kpatch_correlate_sections(struct list_head *seclist_orig,
* Changed group sections are currently not supported.
*/
if (sec_orig->sh.sh_type == SHT_GROUP) {
- if (sec_orig->data->d_size != sec_patched->data->d_size)
- continue;
- 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))
continue;
}
@@ -1740,17 +1765,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-cc b/kpatch-build/kpatch-cc
index ce72e55..8f22978 100755
--- a/kpatch-build/kpatch-cc
+++ b/kpatch-build/kpatch-cc
@@ -13,7 +13,9 @@ fi
declare -a args=("$@")
-if [[ "$TOOLCHAINCMD" =~ ^(.*-)?gcc$ || "$TOOLCHAINCMD" =~ ^(.*-)?clang$ ]] ; then
+if [[ "$TOOLCHAINCMD" =~ ^(.*-)?gcc$ ||
+ "$TOOLCHAINCMD" =~ ^(.*-)?g\+\+$ ||
+ "$TOOLCHAINCMD" =~ ^(.*-)?clang$ ]] ; then
while [ "$#" -gt 0 ]; do
if [ "$1" = "-o" ]; then
obj="$2"
diff --git a/kpatch-build/kpatch-elf.c b/kpatch-build/kpatch-elf.c
index d4aee86..b639bc2 100644
--- a/kpatch-build/kpatch-elf.c
+++ b/kpatch-build/kpatch-elf.c
@@ -978,8 +978,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/lookup.c b/kpatch-build/lookup.c
index bd2b732..8905a1d 100644
--- a/kpatch-build/lookup.c
+++ b/kpatch-build/lookup.c
@@ -334,6 +334,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);
}
@@ -558,7 +560,8 @@ static bool 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)) {
if (result->objname)
--
2.33.0
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。