summaryrefslogtreecommitdiff
path: root/tools/objtool/orc_gen.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-04-27 09:33:21 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-04-27 09:33:21 +0200
commite947861d0ccbc765af4512a395251e6af6857600 (patch)
treee2b8d646f40016e887162bcaf53859edaae15bc9 /tools/objtool/orc_gen.c
parent6f1c0268a4871a80c0ec78142eeb1fe0556e898a (diff)
parent6a8b55ed4056ea5559ebe4f6a4b247f627870d4c (diff)
downloadlwn-e947861d0ccbc765af4512a395251e6af6857600.tar.gz
lwn-e947861d0ccbc765af4512a395251e6af6857600.zip
Merge 5.7-rc3 into tty-next
We need the tty/serial fixes in here too. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'tools/objtool/orc_gen.c')
-rw-r--r--tools/objtool/orc_gen.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c
index 41e4a2754da4..4c0dabd28000 100644
--- a/tools/objtool/orc_gen.c
+++ b/tools/objtool/orc_gen.c
@@ -88,11 +88,6 @@ static int create_orc_entry(struct elf *elf, struct section *u_sec, struct secti
struct orc_entry *orc;
struct rela *rela;
- if (!insn_sec->sym) {
- WARN("missing symbol for section %s", insn_sec->name);
- return -1;
- }
-
/* populate ORC data */
orc = (struct orc_entry *)u_sec->data->d_buf + idx;
memcpy(orc, o, sizeof(*orc));
@@ -105,8 +100,32 @@ static int create_orc_entry(struct elf *elf, struct section *u_sec, struct secti
}
memset(rela, 0, sizeof(*rela));
- rela->sym = insn_sec->sym;
- rela->addend = insn_off;
+ if (insn_sec->sym) {
+ rela->sym = insn_sec->sym;
+ rela->addend = insn_off;
+ } else {
+ /*
+ * The Clang assembler doesn't produce section symbols, so we
+ * have to reference the function symbol instead:
+ */
+ rela->sym = find_symbol_containing(insn_sec, insn_off);
+ if (!rela->sym) {
+ /*
+ * Hack alert. This happens when we need to reference
+ * the NOP pad insn immediately after the function.
+ */
+ rela->sym = find_symbol_containing(insn_sec,
+ insn_off - 1);
+ }
+ if (!rela->sym) {
+ WARN("missing symbol for insn at offset 0x%lx\n",
+ insn_off);
+ return -1;
+ }
+
+ rela->addend = insn_off - rela->sym->offset;
+ }
+
rela->type = R_X86_64_PC32;
rela->offset = idx * sizeof(int);
rela->sec = ip_relasec;