diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp index cab181f2f30dd..e3cfe7040a13c 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp @@ -155,6 +155,7 @@ class ELFLinkGraphBuilder_x86_64 : public ELFLinkGraphBuilder { switch (ELFReloc) { case ELF::R_X86_64_PC32: + case ELF::R_X86_64_GOTPC32: Kind = x86_64::Delta32; break; case ELF::R_X86_64_PC64: @@ -293,6 +294,22 @@ class ELFJITLinker_x86_64 : public JITLinker { Linkage::Strong, Scope::Local, false, true); } + // If we still haven't found a GOT symbol then double check the externals. + // We may have a GOT-relative reference but no GOT section, in which case + // we just need to point the GOT symbol at some address in this graph. + if (!GOTSymbol) { + for (auto *Sym : G.external_symbols()) { + if (Sym->getName() == ELFGOTSymbolName) { + auto Blocks = G.blocks(); + if (!Blocks.empty()) { + G.makeAbsolute(*Sym, (*Blocks.begin())->getAddress()); + GOTSymbol = Sym; + break; + } + } + } + } + return Error::success(); } diff --git a/llvm/test/ExecutionEngine/JITLink/x86-64/ELF_R_X86_64_GOTPC32.s b/llvm/test/ExecutionEngine/JITLink/x86-64/ELF_R_X86_64_GOTPC32.s new file mode 100644 index 0000000000000..241bbb7b85187 --- /dev/null +++ b/llvm/test/ExecutionEngine/JITLink/x86-64/ELF_R_X86_64_GOTPC32.s @@ -0,0 +1,18 @@ +# RUN: llvm-mc -triple=x86_64-unknown-linux -position-independent \ +# RUN: -filetype=obj -o %t.o %s +# RUN: llvm-jitlink -noexec -check=%s %t.o + +# jitlink-check: decode_operand(main, 4) = _GLOBAL_OFFSET_TABLE_ - next_pc(main) + + .text + .section .text.main,"ax",@progbits + .globl main + .p2align 4, 0x90 + .type main,@function +main: + leal _GLOBAL_OFFSET_TABLE_(%rip), %ebx + xorl %eax, %eax + retq +.Lfunc_end0: + .size main, .Lfunc_end0-main + diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp index 2b798f95edb25..5200dbcf90366 100644 --- a/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp @@ -151,6 +151,11 @@ Error registerELFGraphInfo(Session &S, LinkGraph &G) { } } + // Add symbol info for absolute symbols. + for (auto *Sym : G.absolute_symbols()) + S.SymbolInfos[Sym->getName()] = {Sym->getSize(), + Sym->getAddress().getValue()}; + auto SecAddr = FirstSym->getAddress(); auto SecSize = (LastSym->getBlock().getAddress() + LastSym->getBlock().getSize()) -