objtool: Fix seg fault with Clang non-section symbols
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:
e81e072443
("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>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
de53befa79
commit
2b02985bf8
@@ -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;
|
||||
|
Reference in New Issue
Block a user