Revert two changes that break Android builds.

* Earlier versions of lld were able to replace Android's
  lld.gold and link most files.
* With two recent lld changes, debuggerd_test64 and some other files
  failed to link because libunwindstack.a is linked like --whole-archive.
  We need to revert the following two changes:
  * "Put undefined symbols from shared libraries in the symbol table."
     lld/trunk@326242
  * "Make undefined symbol in DSO to pull out object files from archive files."
     lld/trunk@325849

Bug: 74755833
Change-Id: I21b0df5e3c19bdfff4ea6c0ff9e9e562bd73f921
diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp
index e2aa7e9..ad4d549 100644
--- a/ELF/Driver.cpp
+++ b/ELF/Driver.cpp
@@ -1544,6 +1544,10 @@
   // They also might be exported if referenced by DSOs.
   Script->declareSymbols();
 
+  // Handle undefined symbols in DSOs.
+  if (!Config->Shared)
+    Symtab->scanShlibUndefined<ELFT>();
+
   // Handle the -exclude-libs option.
   if (Args.hasArg(OPT_exclude_libs))
     excludeLibs<ELFT>(Args);
diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp
index c3e5b2f..edeb80c 100644
--- a/ELF/InputFiles.cpp
+++ b/ELF/InputFiles.cpp
@@ -1018,10 +1018,7 @@
     }
 
     if (Sym.isUndefined()) {
-      Symbol *S = Symtab->addUndefined<ELFT>(Name, Sym.getBinding(),
-                                             Sym.st_other, Sym.getType(),
-                                             /*CanOmitFromDynSym=*/false, this);
-      S->ExportDynamic = true;
+      this->Undefs.insert(Name);
       continue;
     }
 
diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h
index 105e5ec..1d7081b 100644
--- a/ELF/InputFiles.h
+++ b/ELF/InputFiles.h
@@ -93,6 +93,13 @@
     return Symbols;
   }
 
+  // Returns undefined symbols of a shared library.
+  // It is a runtime error to call this function on files of other types.
+  const llvm::DenseSet<StringRef> &getUndefinedSymbols() {
+    assert(FileKind == SharedKind);
+    return Undefs;
+  }
+
   // Filename of .a which contained this file. If this file was
   // not in an archive file, it is the empty string. We use this
   // string for creating error messages.
@@ -139,6 +146,7 @@
   InputFile(Kind K, MemoryBufferRef M);
   std::vector<InputSectionBase *> Sections;
   std::vector<Symbol *> Symbols;
+  llvm::DenseSet<StringRef> Undefs;
 
 private:
   const Kind FileKind;
diff --git a/ELF/LinkerScript.cpp b/ELF/LinkerScript.cpp
index 2341938..4beb5b2 100644
--- a/ELF/LinkerScript.cpp
+++ b/ELF/LinkerScript.cpp
@@ -156,6 +156,10 @@
   Symbol *B = Symtab->find(Cmd->Name);
   if (B && !B->isDefined())
     return true;
+  // It might also be referenced by a DSO.
+  for (InputFile *F : SharedFiles)
+    if (F->getUndefinedSymbols().count(Cmd->Name))
+      return true;
   return false;
 }
 
diff --git a/ELF/SymbolTable.cpp b/ELF/SymbolTable.cpp
index e25682f..f5fb41c 100644
--- a/ELF/SymbolTable.cpp
+++ b/ELF/SymbolTable.cpp
@@ -599,6 +599,24 @@
     addFile<ELFT>(File);
 }
 
+// This function takes care of the case in which shared libraries depend on
+// the user program (not the other way, which is usual). Shared libraries
+// may have undefined symbols, expecting that the user program provides
+// the definitions for them. An example is BSD's __progname symbol.
+// We need to put such symbols to the main program's .dynsym so that
+// shared libraries can find them.
+// Except this, we ignore undefined symbols in DSOs.
+template <class ELFT> void SymbolTable::scanShlibUndefined() {
+  for (InputFile *F : SharedFiles) {
+    for (StringRef U : F->getUndefinedSymbols()) {
+      Symbol *Sym = find(U);
+      if (!Sym || !Sym->isDefined())
+        continue;
+      Sym->ExportDynamic = true;
+    }
+  }
+}
+
 // Initialize DemangledSyms with a map from demangled symbols to symbol
 // objects. Used to handle "extern C++" directive in version scripts.
 //
@@ -814,3 +832,9 @@
 template void SymbolTable::addShared<ELF64BE>(StringRef, SharedFile<ELF64BE> &,
                                               const typename ELF64BE::Sym &,
                                               uint32_t Alignment, uint32_t);
+
+template void SymbolTable::scanShlibUndefined<ELF32LE>();
+template void SymbolTable::scanShlibUndefined<ELF32BE>();
+template void SymbolTable::scanShlibUndefined<ELF64LE>();
+template void SymbolTable::scanShlibUndefined<ELF64BE>();
+
diff --git a/ELF/SymbolTable.h b/ELF/SymbolTable.h
index 9822ed7..654e362 100644
--- a/ELF/SymbolTable.h
+++ b/ELF/SymbolTable.h
@@ -71,6 +71,7 @@
 
   template <class ELFT> void fetchLazy(Symbol *Sym);
 
+  template <class ELFT> void scanShlibUndefined();
   void scanVersionScript();
 
   Symbol *find(StringRef Name);
diff --git a/test/ELF/shlib-undefined-archive.s b/test/ELF/shlib-undefined-archive.s
deleted file mode 100644
index 940d8d7..0000000
--- a/test/ELF/shlib-undefined-archive.s
+++ /dev/null
@@ -1,19 +0,0 @@
-# REQUIRES: x86
-
-# Undefined symbols in a DSO should pull out object files from archives
-# to resolve them.
-
-# RUN: echo '.globl foo' | llvm-mc -filetype=obj -triple=x86_64-linux-gnu -o %t1.o -
-# RUN: ld.lld -shared -o %t.so %t1.o
-
-# RUN: llvm-mc -filetype=obj -triple=x86_64-linux-gnu -o %t2.o %s
-# RUN: rm -f %t.a
-# RUN: llvm-ar cru %t.a %t2.o
-# RUN: ld.lld -o %t.exe %t.so %t.a
-# RUN: llvm-nm -D %t.exe | FileCheck %s
-
-# CHECK: T foo
-
-.globl foo
-foo:
-  ret
diff --git a/test/ELF/trace-symbols.s b/test/ELF/trace-symbols.s
index 63004b7..58aeb5d 100644
--- a/test/ELF/trace-symbols.s
+++ b/test/ELF/trace-symbols.s
@@ -72,7 +72,7 @@
 
 # RUN: ld.lld -y foo -y bar %t %t1.so %t2.so -o %t3 | \
 # RUN:   FileCheck -check-prefix=SHLIBRBAR %s
-# SHLIBRBAR: trace-symbols.s.tmp1.so: reference to bar
+# SHLIBRBAR-NOT: trace-symbols.s.tmp1.so: reference to bar
 
 # RUN: ld.lld -y foo -y bar %t -u bar --start-lib %t1 %t2 --end-lib -o %t3 | \
 # RUN:   FileCheck -check-prefix=STARTLIB %s