Index: lld/ELF/Driver.cpp
===================================================================
--- lld/ELF/Driver.cpp
+++ lld/ELF/Driver.cpp
@@ -969,6 +969,14 @@
   Symtab.scanShlibUndefined();
   Symtab.scanVersionScript();
 
+  // Pass wrapped symbols to LTO
+  for (auto *Arg : Args.filtered(OPT_wrap))
+    Symtab.addLTOSymbolWrap(Arg->getValue());
+
+  // Pass alias symbols to LTO
+  for (std::pair<StringRef, StringRef> &Def : getDefsym(Args))
+    Symtab.addLTOSymbolAlias(Def.first, Def.second);
+
   Symtab.addCombinedLTOObject();
   if (ErrorCount)
     return;
Index: lld/ELF/LTO.h
===================================================================
--- lld/ELF/LTO.h
+++ lld/ELF/LTO.h
@@ -43,7 +43,7 @@
   BitcodeCompiler();
   ~BitcodeCompiler();
 
-  void add(BitcodeFile &F);
+  void add(BitcodeFile &F, llvm::function_ref<bool(StringRef)> isRenamed);
   std::vector<InputFile *> compile();
 
 private:
Index: lld/ELF/LTO.cpp
===================================================================
--- lld/ELF/LTO.cpp
+++ lld/ELF/LTO.cpp
@@ -112,7 +112,7 @@
                          STV_DEFAULT, S->body()->Type, nullptr);
 }
 
-void BitcodeCompiler::add(BitcodeFile &F) {
+void BitcodeCompiler::add(BitcodeFile &F, function_ref<bool(StringRef)> isRenamed) {
   lto::InputFile &Obj = *F.Obj;
   unsigned SymNum = 0;
   std::vector<Symbol *> Syms = F.getSymbols();
@@ -136,6 +136,7 @@
         Sym->IsUsedInRegularObj || (R.Prevailing && Sym->includeInDynsym());
     if (R.Prevailing)
       undefine(Sym);
+    R.LinkerRedefined = isRenamed(B->getName());
   }
   checkError(LTOObj->add(std::move(F.Obj), Resols));
 }
Index: lld/ELF/SymbolTable.h
===================================================================
--- lld/ELF/SymbolTable.h
+++ lld/ELF/SymbolTable.h
@@ -39,6 +39,8 @@
 public:
   void addFile(InputFile *File);
   void addCombinedLTOObject();
+  void addLTOSymbolWrap(StringRef Name);
+  void addLTOSymbolAlias(StringRef Alias, StringRef Name);
 
   ArrayRef<Symbol *> getSymbols() const { return SymVector; }
   ArrayRef<ObjectFile<ELFT> *> getObjectFiles() const { return ObjectFiles; }
@@ -135,6 +137,8 @@
 
   // For LTO.
   std::unique_ptr<BitcodeCompiler> LTO;
+  // Save renamed symbols and their original pre-LTO bindings.
+  llvm::StringMap<uint8_t> RenamedSymbols;
 };
 
 template <class ELFT> struct Symtab { static SymbolTable<ELFT> *X; };
Index: lld/ELF/SymbolTable.cpp
===================================================================
--- lld/ELF/SymbolTable.cpp
+++ lld/ELF/SymbolTable.cpp
@@ -117,8 +117,11 @@
 
   // Compile bitcode files and replace bitcode symbols.
   LTO.reset(new BitcodeCompiler);
+  auto isRenamed = [&] (StringRef Name) {
+    return RenamedSymbols.find(Name) != RenamedSymbols.end();
+  };
   for (BitcodeFile *F : BitcodeFiles)
-    LTO->add(*F);
+    LTO->add(*F, isRenamed);
 
   for (InputFile *File : LTO->compile()) {
     ObjectFile<ELFT> *Obj = cast<ObjectFile<ELFT>>(File);
@@ -126,6 +129,17 @@
     Obj->parse(DummyGroups);
     ObjectFiles.push_back(Obj);
   }
+
+  // Restore bindings of renamed symbols.
+  for (StringMap<uint8_t>::iterator i = RenamedSymbols.begin();
+       i != RenamedSymbols.end();
+       i++) {
+    SymbolBody *Body = find(i->first());
+    if (Body) {
+      Symbol *Sym = Body->symbol();
+      Sym->Binding = i->second;
+    }
+  }
 }
 
 template <class ELFT>
@@ -154,6 +168,31 @@
   Symtab.insert({CachedHashStringRef(Name), {-1, true}});
 }
 
+static uint8_t getSymbolBinding(SymbolBody *SB) {
+  uint8_t Binding = STB_WEAK;
+  if (SB) {
+    Symbol *S = SB->symbol();
+    Binding = S->Binding;
+  }
+  return Binding;
+}
+
+template <class ELFT> void SymbolTable<ELFT>::addLTOSymbolWrap(StringRef Name) {
+  std::string WrappedName = "__wrap_" + Name.str();
+  std::string RealName = "__real_" + Name.str();
+  uint8_t Binding = getSymbolBinding(find(Name));
+  RenamedSymbols[WrappedName] = Binding;
+  RenamedSymbols[RealName] = Binding;
+  RenamedSymbols[Name] = Binding;
+}
+
+template <class ELFT> void SymbolTable<ELFT>::addLTOSymbolAlias(StringRef Alias,
+                                                                StringRef Name) {
+  uint8_t Binding = getSymbolBinding(find(Name));
+  RenamedSymbols[Name] = Binding;
+  RenamedSymbols[Name] = Binding;
+}
+
 // Rename SYM as __wrap_SYM. The original symbol is preserved as __real_SYM.
 // Used to implement --wrap.
 template <class ELFT> void SymbolTable<ELFT>::wrap(StringRef Name) {
Index: llvm/include/llvm/LTO/LTO.h
===================================================================
--- llvm/include/llvm/LTO/LTO.h
+++ llvm/include/llvm/LTO/LTO.h
@@ -366,7 +366,8 @@
 /// each global symbol based on its internal resolution of that symbol.
 struct SymbolResolution {
   SymbolResolution()
-      : Prevailing(0), FinalDefinitionInLinkageUnit(0), VisibleToRegularObj(0) {
+      : Prevailing(0), FinalDefinitionInLinkageUnit(0), VisibleToRegularObj(0),
+        LinkerRedefined(0) {
   }
   /// The linker has chosen this definition of the symbol.
   unsigned Prevailing : 1;
@@ -377,6 +378,10 @@
 
   /// The definition of this symbol is visible outside of the LTO unit.
   unsigned VisibleToRegularObj : 1;
+
+  /// Linker redefined version of the symbol which appeared in -wrap or -defsym
+  /// linker option.
+  unsigned LinkerRedefined : 1;
 };
 
 } // namespace lto
Index: llvm/lib/LTO/LTO.cpp
===================================================================
--- llvm/lib/LTO/LTO.cpp
+++ llvm/lib/LTO/LTO.cpp
@@ -407,7 +407,7 @@
   // Set the partition to external if we know it is used elsewhere, e.g.
   // it is visible to a regular object, is referenced from llvm.compiler_used,
   // or was already recorded as being referenced from a different partition.
-  if (Res.VisibleToRegularObj || Sym.isUsed() ||
+  if (Res.LinkerRedefined || Res.VisibleToRegularObj || Sym.isUsed() ||
       (GlobalRes.Partition != GlobalResolution::Unknown &&
        GlobalRes.Partition != Partition)) {
     GlobalRes.Partition = GlobalResolution::External;
@@ -418,7 +418,7 @@
   // Flag as visible outside of ThinLTO if visible from a regular object or
   // if this is a reference in the regular LTO partition.
   GlobalRes.VisibleOutsideThinLTO |=
-      (Res.VisibleToRegularObj || Sym.isUsed() ||
+      (Res.LinkerRedefined || Res.VisibleToRegularObj || Sym.isUsed() ||
        Partition == GlobalResolution::RegularLTO);
 }
 
@@ -438,6 +438,8 @@
       OS << 'l';
     if (Res.VisibleToRegularObj)
       OS << 'x';
+    if (Res.LinkerRedefined)
+      OS << 'r';
     OS << '\n';
   }
   OS.flush();
@@ -542,6 +544,8 @@
         if (Sym.isUndefined())
           continue;
         Keep.push_back(GV);
+        if (Res.LinkerRedefined)
+          GV->setLinkage(GlobalValue::WeakAnyLinkage);
         switch (GV->getLinkage()) {
         default:
           break;