Index: ELF/Config.h
===================================================================
--- ELF/Config.h
+++ ELF/Config.h
@@ -126,7 +126,8 @@
   bool HasDynamicList = false;
   bool HasDynSymTab;
   bool ICF;
-  bool ICFData;
+  bool IgnoreDataAddressEquality;
+  bool IgnoreFunctionAddressEquality;
   bool MergeArmExidx;
   bool MipsN32Abi = false;
   bool NoGnuUnique;
Index: ELF/Driver.cpp
===================================================================
--- ELF/Driver.cpp
+++ ELF/Driver.cpp
@@ -618,7 +618,10 @@
   Config->GcSections = Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false);
   Config->GdbIndex = Args.hasFlag(OPT_gdb_index, OPT_no_gdb_index, false);
   Config->ICF = Args.hasFlag(OPT_icf_all, OPT_icf_none, false);
-  Config->ICFData = Args.hasArg(OPT_icf_data);
+  Config->IgnoreDataAddressEquality =
+      Args.hasArg(OPT_ignore_data_address_equality);
+  Config->IgnoreFunctionAddressEquality =
+      Args.hasArg(OPT_ignore_function_address_equality);
   Config->Init = Args.getLastArgValue(OPT_init, "_init");
   Config->LTOAAPipeline = Args.getLastArgValue(OPT_lto_aa_pipeline);
   Config->LTONewPmPasses = Args.getLastArgValue(OPT_lto_newpm_passes);
Index: ELF/ICF.cpp
===================================================================
--- ELF/ICF.cpp
+++ ELF/ICF.cpp
@@ -161,8 +161,9 @@
 
 // Returns true if section S is subject of ICF.
 static bool isEligible(InputSection *S) {
-  // Don't merge read only data sections unless --icf-data was passed.
-  if (!(S->Flags & SHF_EXECINSTR) && !Config->ICFData)
+  // Don't merge read only data sections unless
+  // --ignore-data-address-equality was passed.
+  if (!(S->Flags & SHF_EXECINSTR) && !Config->IgnoreDataAddressEquality)
     return false;
 
   // .init and .fini contains instructions that must be executed to
Index: ELF/Options.td
===================================================================
--- ELF/Options.td
+++ ELF/Options.td
@@ -143,11 +143,14 @@
 
 def icf_all: F<"icf=all">, HelpText<"Enable identical code folding">;
 
-def icf_data: F<"icf-data">,
-  HelpText<"Enable ICF to also fold identical read only data">;
-
 def icf_none: F<"icf=none">, HelpText<"Disable identical code folding">;
 
+def ignore_function_address_equality: F<"ignore-function-address-equality">,
+  HelpText<"LLD can break the address equality of functions">;
+
+def ignore_data_address_equality: F<"ignore-data-address-equality">,
+  HelpText<"LLD can break the address equality of data">;
+
 defm image_base : Eq<"image-base">, HelpText<"Set the base address">;
 
 defm init: Eq<"init">, HelpText<"Specify an initializer function">,
Index: ELF/Relocations.cpp
===================================================================
--- ELF/Relocations.cpp
+++ ELF/Relocations.cpp
@@ -554,6 +554,29 @@
     warn(Msg);
 }
 
+// Return true if we can define a symbol in the executable that
+// contains the value/function of a symbol defined in a shared
+// library.
+static bool canDefineSymbolInExecutable(Symbol &Sym) {
+  // If the symbol has default visibility the symbol defined in the
+  // executable will preempt it.
+  if (Sym.getVisibility() == STV_DEFAULT)
+    return true;
+
+  // If we are allowed to break address equality of functions, defining
+  // a plt entry will allow the program to call the function in the
+  // .so, but the .so and the executable will no agree on the address
+  // of the function.
+  if (Sym.isFunc() && Config->IgnoreFunctionAddressEquality)
+    return true;
+
+  // Similar, but for objects.
+  if (Sym.isObject() && Config->IgnoreDataAddressEquality)
+    return true;
+
+  return false;
+}
+
 template <class ELFT>
 static RelExpr adjustExpr(Symbol &Sym, RelExpr Expr, RelType Type,
                           InputSectionBase &S, uint64_t RelOff) {
@@ -593,7 +616,7 @@
     return Expr;
   }
 
-  if (Sym.getVisibility() != STV_DEFAULT) {
+  if (!canDefineSymbolInExecutable(Sym)) {
     error("cannot preempt symbol: " + toString(Sym) +
           getLocation<ELFT>(S, Sym, RelOff));
     return Expr;
Index: test/ELF/Inputs/protected-data-access.s
===================================================================
--- /dev/null
+++ test/ELF/Inputs/protected-data-access.s
@@ -0,0 +1,7 @@
+        .section .rodata,"a"
+        .global foo
+        .protected foo
+        .type foo, @object
+        .size foo, 8
+foo:
+        .quad 42
Index: test/ELF/Inputs/protected-function-access.s
===================================================================
--- /dev/null
+++ test/ELF/Inputs/protected-function-access.s
@@ -0,0 +1,5 @@
+        .global foo
+        .protected foo
+        .type foo, @function
+foo:
+        ret
Index: test/ELF/icf9.s
===================================================================
--- test/ELF/icf9.s
+++ test/ELF/icf9.s
@@ -11,7 +11,7 @@
 # CHECK-NOT: selected .rodata.d2
 
 # We do merge rodata if passed --icf-data
-# RUN: ld.lld %t -o %t2 --icf=all --verbose --icf-data 2>&1 | FileCheck --check-prefix=DATA %s
+# RUN: ld.lld %t -o %t2 --icf=all --verbose --ignore-data-address-equality 2>&1 | FileCheck --check-prefix=DATA %s
 # RUN: llvm-readelf -S -W %t2 | FileCheck --check-prefix=DATA-SEC %s
 
 # DATA: selected .rodata.d1
Index: test/ELF/protected-data-access.s
===================================================================
--- /dev/null
+++ test/ELF/protected-data-access.s
@@ -0,0 +1,27 @@
+# REQUIRES: x86
+# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %p/Inputs/protected-data-access.s -o %t2.o
+# RUN: ld.lld %t2.o -o %t2.so -shared
+# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t.o
+
+# RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck --check-prefix=ERR %s
+# ERR: error: cannot preempt symbol: foo
+
+# RUN: ld.lld --ignore-data-address-equality %t.o %t2.so -o %t
+# RUN: llvm-readobj --dyn-symbols --relocations %t | FileCheck %s
+
+# Check that we have a capy relocation.
+
+# CHECK: R_X86_64_COPY foo 0x0
+
+# CHECK:      Name: foo
+# CHECK-NEXT: Value:
+# CHECK-NEXT: Size: 8
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: Object
+# CHECK-NEXT: Other:
+# CHECK-NEXT: Section: .bss.rel.ro
+
+.global _start
+_start:
+  .quad foo
+
Index: test/ELF/protected-function-access.s
===================================================================
--- /dev/null
+++ test/ELF/protected-function-access.s
@@ -0,0 +1,27 @@
+# REQUIRES: x86
+# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %p/Inputs/protected-function-access.s -o %t2.o
+# RUN: ld.lld %t2.o -o %t2.so -shared
+# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t.o
+
+# RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck --check-prefix=ERR %s
+# ERR: error: cannot preempt symbol: foo
+
+# RUN: ld.lld --ignore-function-address-equality %t.o %t2.so -o %t
+# RUN: llvm-readobj --dyn-symbols --relocations %t | FileCheck %s
+
+# Check that we have a relocation and an undefined symbol with a non zero address
+
+# CHECK: R_X86_64_JUMP_SLOT foo 0x0
+
+# CHECK:      Name: foo
+# CHECK-NEXT: Value: 0x201020
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: Function
+# CHECK-NEXT: Other:
+# CHECK-NEXT: Section: Undefined
+
+.global _start
+_start:
+  .quad foo
+