mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 20:51:03 +02:00
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
This commit is contained in:
@@ -467,13 +467,20 @@ static int create_static_call_sections(struct objtool_file *file)
|
|||||||
|
|
||||||
/* populate reloc for 'addr' */
|
/* populate reloc for 'addr' */
|
||||||
reloc = malloc(sizeof(*reloc));
|
reloc = malloc(sizeof(*reloc));
|
||||||
|
|
||||||
if (!reloc) {
|
if (!reloc) {
|
||||||
perror("malloc");
|
perror("malloc");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memset(reloc, 0, sizeof(*reloc));
|
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->type = R_X86_64_PC32;
|
||||||
reloc->offset = idx * sizeof(struct static_call_site);
|
reloc->offset = idx * sizeof(struct static_call_site);
|
||||||
reloc->sec = reloc_sec;
|
reloc->sec = reloc_sec;
|
||||||
|
@@ -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);
|
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)
|
static int read_sections(struct elf *elf)
|
||||||
{
|
{
|
||||||
Elf_Scn *s = NULL;
|
Elf_Scn *s = NULL;
|
||||||
|
@@ -140,6 +140,8 @@ struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, uns
|
|||||||
struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
|
struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
|
||||||
unsigned long offset, unsigned int len);
|
unsigned long offset, unsigned int len);
|
||||||
struct symbol *find_func_containing(struct section *sec, unsigned long offset);
|
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);
|
int elf_rebuild_reloc_section(struct elf *elf, struct section *sec);
|
||||||
|
|
||||||
#define for_each_sec(file, sec) \
|
#define for_each_sec(file, sec) \
|
||||||
|
@@ -105,30 +105,11 @@ static int create_orc_entry(struct elf *elf, struct section *u_sec, struct secti
|
|||||||
}
|
}
|
||||||
memset(reloc, 0, sizeof(*reloc));
|
memset(reloc, 0, sizeof(*reloc));
|
||||||
|
|
||||||
if (insn_sec->sym) {
|
insn_to_reloc_sym_addend(insn_sec, insn_off, reloc);
|
||||||
reloc->sym = insn_sec->sym;
|
if (!reloc->sym) {
|
||||||
reloc->addend = insn_off;
|
WARN("missing symbol for insn at offset 0x%lx",
|
||||||
} else {
|
insn_off);
|
||||||
/*
|
return -1;
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reloc->type = R_X86_64_PC32;
|
reloc->type = R_X86_64_PC32;
|
||||||
|
Reference in New Issue
Block a user