summaryrefslogtreecommitdiffstats
path: root/tools/objtool/elf.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-12-27 09:08:23 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2020-12-27 09:08:23 -0800
commitcce622ab9284a27257dd75bb35eccdd619bf96d1 (patch)
tree3384128c908f1d614c36627621d15b9e3c9dbd36 /tools/objtool/elf.c
parent6be5f58215f1dcbd697a695ad5db9986c28c50c3 (diff)
parent44f6a7c0755d8dd453c70557e11687bb080a6f21 (diff)
downloadlinux-cce622ab9284a27257dd75bb35eccdd619bf96d1.tar.bz2
Merge tag 'objtool-urgent-2020-12-27' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull objtool fix from Ingo Molnar: "Fix a segfault that occurs when built with Clang" * tag 'objtool-urgent-2020-12-27' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: objtool: Fix seg fault with Clang non-section symbols
Diffstat (limited to 'tools/objtool/elf.c')
-rw-r--r--tools/objtool/elf.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 4e1d7460574b..be89c741ba9a 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -262,6 +262,32 @@ struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, uns
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;