Bring r267164 back with a fix.

The fix is to handle local symbols referring to SHF_MERGE sections.

Original message:

GC entries of SHF_MERGE sections.

It is a fairly direct extension of the gc algorithm. For merge sections
instead of remembering just a live bit, we remember which offsets
were used.

This reduces the .rodata sections in chromium from 9648861 to 9477472
bytes.

llvm-svn: 267233
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 65a59bd..efcfcb3 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -1132,7 +1132,7 @@
     } else {
       if (!HasReloc)
         fatal("FDE doesn't reference another section");
-      InputSectionBase<ELFT> *Target = S->getRelocTarget(*RelI);
+      InputSectionBase<ELFT> *Target = S->getRelocTarget(*RelI).first;
       if (Target && Target->Live) {
         uint32_t CieOffset = Offset + 4 - ID;
         auto I = OffsetToIndex.find(CieOffset);
@@ -1227,19 +1227,6 @@
   }
 }
 
-static size_t findNull(StringRef S, size_t EntSize) {
-  // Optimize the common case.
-  if (EntSize == 1)
-    return S.find(0);
-
-  for (unsigned I = 0, N = S.size(); I != N; I += EntSize) {
-    const char *B = S.begin() + I;
-    if (std::all_of(B, B + EntSize, [](char C) { return C == 0; }))
-      return I;
-  }
-  return StringRef::npos;
-}
-
 template <class ELFT>
 void MergeOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
   auto *S = cast<MergeInputSection<ELFT>>(C);
@@ -1250,31 +1237,32 @@
   StringRef Data((const char *)D.data(), D.size());
   uintX_t EntSize = S->getSectionHdr()->sh_entsize;
   this->Header.sh_entsize = EntSize;
+  MutableArrayRef<std::pair<uintX_t, uintX_t>> Offsets = S->Offsets;
 
   // If this is of type string, the contents are null-terminated strings.
   if (this->Header.sh_flags & SHF_STRINGS) {
-    uintX_t Offset = 0;
-    while (!Data.empty()) {
-      size_t End = findNull(Data, EntSize);
-      if (End == StringRef::npos)
-        fatal("string is not null terminated");
-      StringRef Entry = Data.substr(0, End + EntSize);
+    for (unsigned I = 0, N = Offsets.size(); I != N; ++I) {
+      auto &P = Offsets[I];
+      if (P.second == (uintX_t)-1)
+        continue;
+
+      uintX_t Start = P.first;
+      uintX_t End = (I == N - 1) ? Data.size() : Offsets[I + 1].first;
+      StringRef Entry = Data.substr(Start, End - Start);
       uintX_t OutputOffset = Builder.add(Entry);
       if (shouldTailMerge())
         OutputOffset = -1;
-      S->Offsets.push_back(std::make_pair(Offset, OutputOffset));
-      uintX_t Size = End + EntSize;
-      Data = Data.substr(Size);
-      Offset += Size;
+      P.second = OutputOffset;
     }
     return;
   }
 
   // If this is not of type string, every entry has the same size.
-  for (unsigned I = 0, N = Data.size(); I != N; I += EntSize) {
-    StringRef Entry = Data.substr(I, EntSize);
-    size_t OutputOffset = Builder.add(Entry);
-    S->Offsets.push_back(std::make_pair(I, OutputOffset));
+  for (auto &P : Offsets) {
+    if (P.second == (uintX_t)-1)
+      continue;
+    StringRef Entry = Data.substr(P.first, EntSize);
+    P.second = Builder.add(Entry);
   }
 }