]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 13 Feb 2021 13:15:59 +0000 (14:15 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 13 Feb 2021 13:15:59 +0000 (14:15 +0100)
added patches:
objtool-fix-seg-fault-with-clang-non-section-symbols.patch

queue-5.10/objtool-fix-seg-fault-with-clang-non-section-symbols.patch [new file with mode: 0644]
queue-5.10/series [new file with mode: 0644]
queue-5.4/series [new file with mode: 0644]

diff --git a/queue-5.10/objtool-fix-seg-fault-with-clang-non-section-symbols.patch b/queue-5.10/objtool-fix-seg-fault-with-clang-non-section-symbols.patch
new file mode 100644 (file)
index 0000000..4248a64
--- /dev/null
@@ -0,0 +1,144 @@
+From 44f6a7c0755d8dd453c70557e11687bb080a6f21 Mon Sep 17 00:00:00 2001
+From: Josh Poimboeuf <jpoimboe@redhat.com>
+Date: Mon, 14 Dec 2020 16:04:20 -0600
+Subject: objtool: Fix seg fault with Clang non-section symbols
+
+From: Josh Poimboeuf <jpoimboe@redhat.com>
+
+commit 44f6a7c0755d8dd453c70557e11687bb080a6f21 upstream.
+
+The Clang assembler likes to strip section symbols, which means objtool
+can't reference some text code by its section.  This confuses objtool
+greatly, causing it to seg fault.
+
+The fix is similar to what was done before, for ORC reloc generation:
+
+  e81e07244325 ("objtool: Support Clang non-section symbols in ORC generation")
+
+Factor out that code into a common helper and use it for static call
+reloc generation as well.
+
+Reported-by: Arnd Bergmann <arnd@kernel.org>
+Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
+Reviewed-by: Miroslav Benes <mbenes@suse.cz>
+Link: https://github.com/ClangBuiltLinux/linux/issues/1207
+Link: https://lkml.kernel.org/r/ba6b6c0f0dd5acbba66e403955a967d9fdd1726a.1607983452.git.jpoimboe@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/objtool/check.c   |   11 +++++++++--
+ tools/objtool/elf.c     |   26 ++++++++++++++++++++++++++
+ tools/objtool/elf.h     |    2 ++
+ tools/objtool/orc_gen.c |   29 +++++------------------------
+ 4 files changed, 42 insertions(+), 26 deletions(-)
+
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -467,13 +467,20 @@ static int create_static_call_sections(s
+               /* populate reloc for 'addr' */
+               reloc = malloc(sizeof(*reloc));
++
+               if (!reloc) {
+                       perror("malloc");
+                       return -1;
+               }
+               memset(reloc, 0, sizeof(*reloc));
+-              reloc->sym = insn->sec->sym;
+-              reloc->addend = insn->offset;
++
++              insn_to_reloc_sym_addend(insn->sec, insn->offset, reloc);
++              if (!reloc->sym) {
++                      WARN_FUNC("static call tramp: missing containing symbol",
++                                insn->sec, insn->offset);
++                      return -1;
++              }
++
+               reloc->type = R_X86_64_PC32;
+               reloc->offset = idx * sizeof(struct static_call_site);
+               reloc->sec = reloc_sec;
+--- a/tools/objtool/elf.c
++++ b/tools/objtool/elf.c
+@@ -262,6 +262,32 @@ struct reloc *find_reloc_by_dest(const s
+       return find_reloc_by_dest_range(elf, sec, offset, 1);
+ }
++void insn_to_reloc_sym_addend(struct section *sec, unsigned long offset,
++                            struct reloc *reloc)
++{
++      if (sec->sym) {
++              reloc->sym = sec->sym;
++              reloc->addend = offset;
++              return;
++      }
++
++      /*
++       * The Clang assembler strips section symbols, so we have to reference
++       * the function symbol instead:
++       */
++      reloc->sym = find_symbol_containing(sec, offset);
++      if (!reloc->sym) {
++              /*
++               * Hack alert.  This happens when we need to reference the NOP
++               * pad insn immediately after the function.
++               */
++              reloc->sym = find_symbol_containing(sec, offset - 1);
++      }
++
++      if (reloc->sym)
++              reloc->addend = offset - reloc->sym->offset;
++}
++
+ static int read_sections(struct elf *elf)
+ {
+       Elf_Scn *s = NULL;
+--- a/tools/objtool/elf.h
++++ b/tools/objtool/elf.h
+@@ -140,6 +140,8 @@ struct reloc *find_reloc_by_dest(const s
+ struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
+                                    unsigned long offset, unsigned int len);
+ struct symbol *find_func_containing(struct section *sec, unsigned long offset);
++void insn_to_reloc_sym_addend(struct section *sec, unsigned long offset,
++                            struct reloc *reloc);
+ int elf_rebuild_reloc_section(struct elf *elf, struct section *sec);
+ #define for_each_sec(file, sec)                                               \
+--- a/tools/objtool/orc_gen.c
++++ b/tools/objtool/orc_gen.c
+@@ -105,30 +105,11 @@ static int create_orc_entry(struct elf *
+       }
+       memset(reloc, 0, sizeof(*reloc));
+-      if (insn_sec->sym) {
+-              reloc->sym = insn_sec->sym;
+-              reloc->addend = insn_off;
+-      } else {
+-              /*
+-               * The Clang assembler doesn't produce section symbols, so we
+-               * have to reference the function symbol instead:
+-               */
+-              reloc->sym = find_symbol_containing(insn_sec, insn_off);
+-              if (!reloc->sym) {
+-                      /*
+-                       * Hack alert.  This happens when we need to reference
+-                       * the NOP pad insn immediately after the function.
+-                       */
+-                      reloc->sym = find_symbol_containing(insn_sec,
+-                                                         insn_off - 1);
+-              }
+-              if (!reloc->sym) {
+-                      WARN("missing symbol for insn at offset 0x%lx\n",
+-                           insn_off);
+-                      return -1;
+-              }
+-
+-              reloc->addend = insn_off - reloc->sym->offset;
++      insn_to_reloc_sym_addend(insn_sec, insn_off, reloc);
++      if (!reloc->sym) {
++              WARN("missing symbol for insn at offset 0x%lx",
++                   insn_off);
++              return -1;
+       }
+       reloc->type = R_X86_64_PC32;
diff --git a/queue-5.10/series b/queue-5.10/series
new file mode 100644 (file)
index 0000000..c6022b0
--- /dev/null
@@ -0,0 +1 @@
+objtool-fix-seg-fault-with-clang-non-section-symbols.patch
diff --git a/queue-5.4/series b/queue-5.4/series
new file mode 100644 (file)
index 0000000..e69de29