Blame 0100-kpatch-build-for-clang-use-.strtab-if-no-.shstrtab.patch

642cd7
From 5f6c5965f117cb9b2b21749da49b22b23305d114 Mon Sep 17 00:00:00 2001
642cd7
From: Pete Swain <swine@google.com>
642cd7
Date: Tue, 27 Sep 2022 15:56:06 -0400
642cd7
Subject: [PATCH 100/108] kpatch-build: for clang, use .strtab if no .shstrtab
642cd7
642cd7
While gcc puts strings in .strtab and .shstrtab sections,
642cd7
llvm toolchain just uses .strtab.
642cd7
642cd7
Adapt kpatch to handle both styles.
642cd7
642cd7
Signed-off-by: Pete Swain <swine@google.com>
642cd7
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com> [small changes]
642cd7
---
642cd7
 kpatch-build/kpatch-elf.c | 33 +++++++++++++++++++++++++++++----
642cd7
 1 file changed, 29 insertions(+), 4 deletions(-)
642cd7
642cd7
diff --git a/kpatch-build/kpatch-elf.c b/kpatch-build/kpatch-elf.c
642cd7
index 58dbe1a..c7d12ec 100644
642cd7
--- a/kpatch-build/kpatch-elf.c
642cd7
+++ b/kpatch-build/kpatch-elf.c
642cd7
@@ -607,7 +607,7 @@ void kpatch_create_shstrtab(struct kpatch_elf *kelf)
642cd7
 
642cd7
 	shstrtab = find_section_by_name(&kelf->sections, ".shstrtab");
642cd7
 	if (!shstrtab)
642cd7
-		ERROR("find_section_by_name");
642cd7
+		return;
642cd7
 
642cd7
 	/* determine size of string table */
642cd7
 	size = 1; /* for initial NULL terminator */
642cd7
@@ -648,7 +648,7 @@ void kpatch_create_shstrtab(struct kpatch_elf *kelf)
642cd7
 
642cd7
 void kpatch_create_strtab(struct kpatch_elf *kelf)
642cd7
 {
642cd7
-	struct section *strtab;
642cd7
+	struct section *strtab, *shstrtab;
642cd7
 	struct symbol *sym;
642cd7
 	size_t size = 0, offset = 0, len;
642cd7
 	char *buf;
642cd7
@@ -657,6 +657,8 @@ void kpatch_create_strtab(struct kpatch_elf *kelf)
642cd7
 	if (!strtab)
642cd7
 		ERROR("find_section_by_name");
642cd7
 
642cd7
+	shstrtab = find_section_by_name(&kelf->sections, ".shstrtab");
642cd7
+
642cd7
 	/* determine size of string table */
642cd7
 	list_for_each_entry(sym, &kelf->symbols, list) {
642cd7
 		if (sym->type == STT_SECTION)
642cd7
@@ -664,6 +666,15 @@ void kpatch_create_strtab(struct kpatch_elf *kelf)
642cd7
 		size += strlen(sym->name) + 1; /* include NULL terminator */
642cd7
 	}
642cd7
 
642cd7
+	/* and when covering for missing .shstrtab ... */
642cd7
+	if (!shstrtab) {
642cd7
+		/* factor out into common (sh)strtab feeder */
642cd7
+		struct section *sec;
642cd7
+
642cd7
+		list_for_each_entry(sec, &kelf->sections, list)
642cd7
+			size += strlen(sec->name) + 1; /* include NULL terminator */
642cd7
+	}
642cd7
+
642cd7
 	/* allocate data buffer */
642cd7
 	buf = malloc(size);
642cd7
 	if (!buf)
642cd7
@@ -682,8 +693,20 @@ void kpatch_create_strtab(struct kpatch_elf *kelf)
642cd7
 		offset += len;
642cd7
 	}
642cd7
 
642cd7
+	if (!shstrtab) {
642cd7
+		struct section *sec;
642cd7
+
642cd7
+		/* populate string table and link with section header */
642cd7
+		list_for_each_entry(sec, &kelf->sections, list) {
642cd7
+			len = strlen(sec->name) + 1;
642cd7
+			sec->sh.sh_name = (unsigned int)offset;
642cd7
+			memcpy(buf + offset, sec->name, len);
642cd7
+			offset += len;
642cd7
+		}
642cd7
+	}
642cd7
+
642cd7
 	if (offset != size)
642cd7
-		ERROR("shstrtab size mismatch");
642cd7
+		ERROR("strtab size mismatch");
642cd7
 
642cd7
 	strtab->data->d_buf = buf;
642cd7
 	strtab->data->d_size = size;
642cd7
@@ -928,7 +951,9 @@ void kpatch_write_output_elf(struct kpatch_elf *kelf, Elf *elf, char *outfile,
642cd7
 
642cd7
 	shstrtab = find_section_by_name(&kelf->sections, ".shstrtab");
642cd7
 	if (!shstrtab)
642cd7
-		ERROR("missing .shstrtab section");
642cd7
+		shstrtab = find_section_by_name(&kelf->sections, ".strtab");
642cd7
+	if (!shstrtab)
642cd7
+		ERROR("missing .shstrtab, .strtab sections");
642cd7
 
642cd7
 	ehout.e_shstrndx = (unsigned short)shstrtab->index;
642cd7
 
642cd7
-- 
642cd7
2.37.3
642cd7