diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h index 25f1349f15f288..75d0ddfab556d7 100644 --- a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h +++ b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h @@ -1215,8 +1215,11 @@ class LinkGraph { /// Make the given symbol an absolute with the given address (must not already /// be absolute). /// - /// Symbol size, linkage, scope, and callability, and liveness will be left - /// unchanged. Symbol offset will be reset to 0. + /// The symbol's size, linkage, and callability, and liveness will be left + /// unchanged, and its offset will be reset to 0. + /// + /// If the symbol was external then its scope will be set to local, otherwise + /// it will be left unchanged. void makeAbsolute(Symbol &Sym, orc::ExecutorAddr Address) { assert(!Sym.isAbsolute() && "Symbol is already absolute"); if (Sym.isExternal()) { @@ -1225,6 +1228,7 @@ class LinkGraph { assert(Sym.getOffset() == 0 && "External is not at offset 0"); ExternalSymbols.erase(&Sym); Sym.getAddressable().setAbsolute(true); + Sym.setScope(Scope::Local); } else { assert(Sym.isDefined() && "Sym is not a defined symbol"); Section &Sec = Sym.getBlock().getSection(); diff --git a/llvm/test/ExecutionEngine/JITLink/X86/ELF_external_to_absolute_conversion.s b/llvm/test/ExecutionEngine/JITLink/X86/ELF_external_to_absolute_conversion.s new file mode 100644 index 00000000000000..3cff5e0d1e7504 --- /dev/null +++ b/llvm/test/ExecutionEngine/JITLink/X86/ELF_external_to_absolute_conversion.s @@ -0,0 +1,26 @@ +# RUN: llvm-mc -triple=x86_64-unknown-linux-gnu -filetype=obj -o %t %s +# RUN: llvm-jitlink -phony-externals -noexec %t +# +# Check that symbol scope is demoted to local when external symbols are +# converted to absolutes. This is demotion is necessary to avoid "unexpected +# definition" errors. +# +# The reference to _GLOBAL_OFFSET_TABLE_ will trigger creation of an external +# _GLOBAL_OFFSET_TABLE_ symbol, and the GOTOFF relocation will force creation +# of a GOT symbol without actually introducing any GOT entries. Together these +# should cause the external _GLOBAL_OFFSET_TABLE_ symbol to be converted to an +# absolute symbol with address zero. If the scope is not demoted correctly this +# will trigger an "unexpected definition" error. + + .text + .file "ELF_external_to_absolute_conversion.s" + .globl main + .p2align 4, 0x90 + .type main,@function +main: +.L0$pb: + leaq .L0$pb(%rip), %rax + movabsq $_GLOBAL_OFFSET_TABLE_-.L0$pb, %rcx + movabsq $_foo@GOTOFF, %rax + xorq %rax, %rax + retq