Skip to content

Commit c600cad

Browse files
jpoimboexdevs23
authored andcommitted
objtool: Support Clang non-section symbols in ORC generation
When compiling the kernel with AS=clang, objtool produces a lot of warnings: warning: objtool: missing symbol for section .text warning: objtool: missing symbol for section .init.text warning: objtool: missing symbol for section .ref.text It then fails to generate the ORC table. The problem is that objtool assumes text section symbols always exist. But the Clang assembler is aggressive about removing them. When generating relocations for the ORC table, objtool always tries to reference instructions by their section symbol offset. If the section symbol doesn't exist, it bails. Do a fallback: when a section symbol isn't available, reference a function symbol instead. Reported-by: Dmitry Golovin <[email protected]> Signed-off-by: Josh Poimboeuf <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Tested-by: Nathan Chancellor <[email protected]> Reviewed-by: Miroslav Benes <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Link: ClangBuiltLinux/linux#669 Link: https://lkml.kernel.org/r/9a9cae7fcf628843aabe5a086b1a3c5bf50f42e8.1585761021.git.jpoimboe@redhat.com Signed-off-by: Simao Gomes Viana <[email protected]>
1 parent 30baeb5 commit c600cad

File tree

1 file changed

+26
-7
lines changed

1 file changed

+26
-7
lines changed

tools/objtool/orc_gen.c

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,6 @@ static int create_orc_entry(struct elf *elf, struct section *u_sec, struct secti
8888
struct orc_entry *orc;
8989
struct rela *rela;
9090

91-
if (!insn_sec->sym) {
92-
WARN("missing symbol for section %s", insn_sec->name);
93-
return -1;
94-
}
95-
9691
/* populate ORC data */
9792
orc = (struct orc_entry *)u_sec->data->d_buf + idx;
9893
memcpy(orc, o, sizeof(*orc));
@@ -105,8 +100,32 @@ static int create_orc_entry(struct elf *elf, struct section *u_sec, struct secti
105100
}
106101
memset(rela, 0, sizeof(*rela));
107102

108-
rela->sym = insn_sec->sym;
109-
rela->addend = insn_off;
103+
if (insn_sec->sym) {
104+
rela->sym = insn_sec->sym;
105+
rela->addend = insn_off;
106+
} else {
107+
/*
108+
* The Clang assembler doesn't produce section symbols, so we
109+
* have to reference the function symbol instead:
110+
*/
111+
rela->sym = find_symbol_containing(insn_sec, insn_off);
112+
if (!rela->sym) {
113+
/*
114+
* Hack alert. This happens when we need to reference
115+
* the NOP pad insn immediately after the function.
116+
*/
117+
rela->sym = find_symbol_containing(insn_sec,
118+
insn_off - 1);
119+
}
120+
if (!rela->sym) {
121+
WARN("missing symbol for insn at offset 0x%lx\n",
122+
insn_off);
123+
return -1;
124+
}
125+
126+
rela->addend = insn_off - rela->sym->offset;
127+
}
128+
110129
rela->type = R_X86_64_PC32;
111130
rela->offset = idx * sizeof(int);
112131
rela->sec = ip_relasec;

0 commit comments

Comments
 (0)