Index: ELF/Relocations.cpp =================================================================== --- ELF/Relocations.cpp +++ ELF/Relocations.cpp @@ -445,7 +445,10 @@ (Name.empty() ? "readonly segment" : "symbol " + Name)); return Expr; } - if (Body.getVisibility() != STV_DEFAULT) { + + // GNU linkers allows non PIC program calls to a protected + // function in a shared library. We do the same. + if (!Body.isFunc() && Body.getVisibility() != STV_DEFAULT) { error("cannot preempt symbol " + Body.getName()); return Expr; } Index: test/ELF/Inputs/protected-shared-func.s =================================================================== --- test/ELF/Inputs/protected-shared-func.s +++ test/ELF/Inputs/protected-shared-func.s @@ -0,0 +1,5 @@ +.text +.protected bar +.globl bar +.type bar,@function +bar: Index: test/ELF/protected-shared-func.s =================================================================== --- test/ELF/protected-shared-func.s +++ test/ELF/protected-shared-func.s @@ -0,0 +1,16 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/protected-shared-func.s -o %t2.o +# RUN: ld.lld -shared %t2.o -o %t2.so +# RUN: ld.lld %t.o %t2.so -o %t +# RUN: llvm-readobj -r %t | FileCheck %s + +# CHECK: Relocations [ +# CHECK-NEXT: Section ({{.*}}) .rela.plt { +# CHECK-NEXT: 0x13018 R_X86_64_JUMP_SLOT bar 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: ] + +.globl _start +_start: + callq bar