[lld] r297313 - Remove DefinedSynthetic.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 8 14:36:29 PST 2017


Author: rafael
Date: Wed Mar  8 16:36:28 2017
New Revision: 297313

URL: http://llvm.org/viewvc/llvm-project?rev=297313&view=rev
Log:
Remove DefinedSynthetic.

With this we have a single section hierarchy. It is a bit less code,
but the main advantage will be in a future patch being able to handle

foo = symbol_in_obj;

in a linker script. Currently that fails since we try to find the
output section of symbol_in_obj.  With this we should be able to just
return an InputSection from the expression.

Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/InputSection.h
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/LinkerScript.h
    lld/trunk/ELF/MarkLive.cpp
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/SymbolTable.h
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Wed Mar  8 16:36:28 2017
@@ -55,10 +55,11 @@ InputSectionBase::InputSectionBase(Input
                                    uint32_t Link, uint32_t Info,
                                    uint32_t Alignment, ArrayRef<uint8_t> Data,
                                    StringRef Name, Kind SectionKind)
-    : File(File), Data(Data), Name(Name), SectionKind(SectionKind),
-      Live(!Config->GcSections || !(Flags & SHF_ALLOC)), Assigned(false),
-      Flags(Flags), Entsize(Entsize), Type(Type), Link(Link), Info(Info),
-      Repl(this) {
+    : SectionBase(SectionKind, Name, Flags, Entsize, Alignment, Type, Info,
+                  Link),
+      File(File), Data(Data), Repl(this) {
+  Live = !Config->GcSections || !(Flags & SHF_ALLOC);
+  Assigned = false;
   NumRelocations = 0;
   AreRelocsRela = false;
 
@@ -98,15 +99,20 @@ uint64_t InputSectionBase::getOffsetInFi
   return SecStart - FileStart;
 }
 
-uint64_t InputSectionBase::getOffset(uint64_t Offset) const {
+uint64_t SectionBase::getOffset(uint64_t Offset) const {
   switch (kind()) {
+  case Output: {
+    auto *OS = cast<OutputSection>(this);
+    // For output sections we treat offset -1 as the end of the section.
+    return Offset == uint64_t(-1) ? OS->Size : Offset;
+  }
   case Regular:
     return cast<InputSection>(this)->OutSecOff + Offset;
-  case Synthetic:
+  case Synthetic: {
+    auto *IS = cast<InputSection>(this);
     // For synthetic sections we treat offset -1 as the end of the section.
-    // The same approach is used for synthetic symbols (DefinedSynthetic).
-    return cast<InputSection>(this)->OutSecOff +
-           (Offset == uint64_t(-1) ? getSize() : Offset);
+    return IS->OutSecOff + (Offset == uint64_t(-1) ? IS->getSize() : Offset);
+  }
   case EHFrame:
     // The file crtbeginT.o has relocations pointing to the start of an empty
     // .eh_frame that is known to be the first in the link. It does that to
@@ -121,12 +127,14 @@ uint64_t InputSectionBase::getOffset(uin
   llvm_unreachable("invalid section kind");
 }
 
-OutputSection *InputSectionBase::getOutputSection() const {
+OutputSection *SectionBase::getOutputSection() {
+  if (auto *IS = dyn_cast<InputSection>(this))
+    return IS->OutSec;
   if (auto *MS = dyn_cast<MergeInputSection>(this))
     return MS->MergeSec ? MS->MergeSec->OutSec : nullptr;
   if (auto *EH = dyn_cast<EhInputSection>(this))
     return EH->EHSec->OutSec;
-  return OutSec;
+  return cast<OutputSection>(this);
 }
 
 // Uncompress section contents. Note that this function is called
@@ -150,7 +158,7 @@ template <class ELFT> void InputSectionB
   Data = ArrayRef<uint8_t>((uint8_t *)OutputBuf, Size);
 }
 
-uint64_t InputSectionBase::getOffset(const DefinedRegular &Sym) const {
+uint64_t SectionBase::getOffset(const DefinedRegular &Sym) const {
   return getOffset(Sym.Value);
 }
 
@@ -199,9 +207,13 @@ InputSection::InputSection(elf::ObjectFi
                            const typename ELFT::Shdr *Header, StringRef Name)
     : InputSectionBase(F, Header, Name, InputSectionBase::Regular) {}
 
-bool InputSection::classof(const InputSectionBase *S) {
-  return S->kind() == InputSectionBase::Regular ||
-         S->kind() == InputSectionBase::Synthetic;
+bool InputSection::classof(const SectionBase *S) {
+  return S->kind() == SectionBase::Regular ||
+         S->kind() == SectionBase::Synthetic;
+}
+
+bool InputSectionBase::classof(const SectionBase *S) {
+  return S->kind() != Output;
 }
 
 template <class ELFT> InputSectionBase *InputSection::getRelocatedSection() {
@@ -248,14 +260,14 @@ void InputSection::copyRelocations(uint8
       // avoid having to parse and recreate .eh_frame, we just replace any
       // relocation in it pointing to discarded sections with R_*_NONE, which
       // hopefully creates a frame that is ignored at runtime.
-      InputSectionBase *Section = cast<DefinedRegular>(Body).Section;
+      SectionBase *Section = cast<DefinedRegular>(Body).Section;
       if (Section == &InputSection::Discarded) {
         P->setSymbolAndType(0, 0, false);
         continue;
       }
 
       if (Config->isRela()) {
-        P->r_addend += Body.getVA<ELFT>() - Section->OutSec->Addr;
+        P->r_addend += Body.getVA<ELFT>() - Section->getOutputSection()->Addr;
       } else if (Config->Relocatable) {
         const uint8_t *BufLoc = RelocatedSection->Data.begin() + Rel.r_offset;
         RelocatedSection->Relocations.push_back(
@@ -587,7 +599,7 @@ EhInputSection::EhInputSection(elf::Obje
   this->Live = true;
 }
 
-bool EhInputSection::classof(const InputSectionBase *S) {
+bool EhInputSection::classof(const SectionBase *S) {
   return S->kind() == InputSectionBase::EHFrame;
 }
 
@@ -710,7 +722,7 @@ void MergeInputSection::splitIntoPieces(
       this->getSectionPiece(Off)->Live = true;
 }
 
-bool MergeInputSection::classof(const InputSectionBase *S) {
+bool MergeInputSection::classof(const SectionBase *S) {
   return S->kind() == InputSectionBase::Merge;
 }
 

Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Wed Mar  8 16:36:28 2017
@@ -34,21 +34,23 @@ class MergeSyntheticSection;
 template <class ELFT> class ObjectFile;
 class OutputSection;
 
-// This corresponds to a section of an input file.
-class InputSectionBase {
+// This is the base class of all sections that lld handles. Some are sections in
+// input files, some are sections in the produced output file and some exist
+// just as a convenience for implementing special ways of combining some
+// sections.
+class SectionBase {
 public:
-  enum Kind { Regular, EHFrame, Merge, Synthetic, };
+  enum Kind { Regular, EHFrame, Merge, Synthetic, Output };
 
   Kind kind() const { return (Kind)SectionKind; }
-  // The file this section is from.
-  InputFile *File;
-
-  ArrayRef<uint8_t> Data;
 
   StringRef Name;
 
   unsigned SectionKind : 3;
 
+  // The next two bit fields are only used by InputSectionBase, but we
+  // put them here so the struct packs better.
+
   // The garbage collector sets sections' Live bits.
   // If GC is disabled, all sections are considered live by default.
   unsigned Live : 1;     // for garbage collection
@@ -63,12 +65,48 @@ public:
   uint32_t Link;
   uint32_t Info;
 
+  OutputSection *getOutputSection();
+  const OutputSection *getOutputSection() const {
+    return const_cast<SectionBase *>(this)->getOutputSection();
+  }
+
+  // Translate an offset in the input section to an offset in the output
+  // section.
+  uint64_t getOffset(uint64_t Offset) const;
+
+  uint64_t getOffset(const DefinedRegular &Sym) const;
+
+protected:
+  SectionBase(Kind SectionKind, StringRef Name, uint64_t Flags,
+              uint64_t Entsize, uint64_t Alignment, uint32_t Type,
+              uint32_t Info, uint32_t Link)
+      : Name(Name), SectionKind(SectionKind), Alignment(Alignment),
+        Flags(Flags), Entsize(Entsize), Type(Type), Link(Link), Info(Info) {
+    Live = false;
+    Assigned = false;
+  }
+};
+
+// This corresponds to a section of an input file.
+class InputSectionBase : public SectionBase {
+public:
+  static bool classof(const SectionBase *S);
+
+  // The file this section is from.
+  InputFile *File;
+
+  ArrayRef<uint8_t> Data;
   uint64_t getOffsetInFile() const;
 
   static InputSectionBase Discarded;
 
   InputSectionBase()
-      : SectionKind(Regular), Live(false), Assigned(false), Repl(this) {
+      : SectionBase(Regular, "", /*Flags*/ 0, /*Entsize*/ 0, /*Alignment*/ 0,
+                    /*Type*/ 0,
+                    /*Info*/ 0, /*Link*/ 0),
+        Repl(this) {
+    Live = false;
+    Assigned = false;
     NumRelocations = 0;
     AreRelocsRela = false;
   }
@@ -113,20 +151,13 @@ public:
   // Returns the size of this section (even if this is a common or BSS.)
   size_t getSize() const;
 
-  OutputSection *getOutputSection() const;
-
   template <class ELFT> ObjectFile<ELFT> *getFile() const;
 
   template <class ELFT> llvm::object::ELFFile<ELFT> getObj() const {
     return getFile<ELFT>()->getObj();
   }
 
-  uint64_t getOffset(const DefinedRegular &Sym) const;
-
   template <class ELFT> InputSectionBase *getLinkOrderDep() const;
-  // Translate an offset in the input section to an offset in the output
-  // section.
-  uint64_t getOffset(uint64_t Offset) const;
 
   template <class ELFT> void uncompress();
 
@@ -165,7 +196,7 @@ public:
   template <class ELFT>
   MergeInputSection(ObjectFile<ELFT> *F, const typename ELFT::Shdr *Header,
                     StringRef Name);
-  static bool classof(const InputSectionBase *S);
+  static bool classof(const SectionBase *S);
   void splitIntoPieces();
 
   // Mark the piece at a given offset live. Used by GC.
@@ -237,7 +268,7 @@ public:
   template <class ELFT>
   EhInputSection(ObjectFile<ELFT> *F, const typename ELFT::Shdr *Header,
                  StringRef Name);
-  static bool classof(const InputSectionBase *S);
+  static bool classof(const SectionBase *S);
   template <class ELFT> void split();
   template <class ELFT, class RelTy> void split(ArrayRef<RelTy> Rels);
 
@@ -267,7 +298,7 @@ public:
   // to. The writer sets a value.
   uint64_t OutSecOff = 0;
 
-  static bool classof(const InputSectionBase *S);
+  static bool classof(const SectionBase *S);
 
   template <class ELFT> InputSectionBase *getRelocatedSection();
 

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Wed Mar  8 16:36:28 2017
@@ -63,21 +63,10 @@ template <class ELFT> static SymbolBody
       Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false,
       /*File*/ nullptr);
   Sym->Binding = STB_GLOBAL;
+  OutputSection *Sec =
+      Cmd->Expression.IsAbsolute() ? nullptr : Cmd->Expression.Section();
   replaceBody<DefinedRegular>(Sym, Cmd->Name, /*IsLocal=*/false, Visibility,
-                              STT_NOTYPE, 0, 0, nullptr, nullptr);
-  return Sym->body();
-}
-
-template <class ELFT> static SymbolBody *addSynthetic(SymbolAssignment *Cmd) {
-  Symbol *Sym;
-  uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
-  const OutputSection *Sec =
-      ScriptConfig->HasSections ? nullptr : Cmd->Expression.Section();
-  std::tie(Sym, std::ignore) = Symtab<ELFT>::X->insert(
-      Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false,
-      /*File*/ nullptr);
-  Sym->Binding = STB_GLOBAL;
-  replaceBody<DefinedSynthetic>(Sym, Cmd->Name, 0, Sec);
+                              STT_NOTYPE, 0, 0, Sec, nullptr);
   return Sym->body();
 }
 
@@ -119,18 +108,14 @@ void LinkerScript<ELFT>::assignSymbol(Sy
   if (!Cmd->Sym)
     return;
 
-  if (auto *Body = dyn_cast<DefinedSynthetic>(Cmd->Sym)) {
-    Body->Section = Cmd->Expression.Section();
-    if (Body->Section) {
-      uint64_t VA = 0;
-      if (Body->Section->Flags & SHF_ALLOC)
-        VA = Body->Section->Addr;
-      Body->Value = Cmd->Expression(Dot) - VA;
-    }
-    return;
+  auto *Sym = cast<DefinedRegular>(Cmd->Sym);
+  Sym->Value = Cmd->Expression(Dot);
+  if (!Cmd->Expression.IsAbsolute()) {
+    Sym->Section = Cmd->Expression.Section();
+    if (auto *Sec = dyn_cast_or_null<OutputSection>(Sym->Section))
+      if (Sec->Flags & SHF_ALLOC)
+        Sym->Value -= Sec->Addr;
   }
-
-  cast<DefinedRegular>(Cmd->Sym)->Value = Cmd->Expression(Dot);
 }
 
 template <class ELFT>
@@ -144,12 +129,7 @@ void LinkerScript<ELFT>::addSymbol(Symbo
   if (Cmd->Provide && (!B || B->isDefined()))
     return;
 
-  // Otherwise, create a new symbol if one does not exist or an
-  // undefined one does exist.
-  if (Cmd->Expression.IsAbsolute())
-    Cmd->Sym = addRegular<ELFT>(Cmd);
-  else
-    Cmd->Sym = addSynthetic<ELFT>(Cmd);
+  Cmd->Sym = addRegular<ELFT>(Cmd);
 
   // If there are sections, then let the value be assigned later in
   // `assignAddresses`.
@@ -321,6 +301,19 @@ LinkerScript<ELFT>::createInputSectionLi
 
 template <class ELFT>
 void LinkerScript<ELFT>::processCommands(OutputSectionFactory &Factory) {
+  // A symbol can be assigned before any section is mentioned in the linker
+  // script. In an DSO, the symbol values are addresses, so the only important
+  // section values are:
+  // * SHN_UNDEF
+  // * SHN_ABS
+  // * Any value meaning a regular section.
+  // To handle that, create a dummy aether section that fills the void before
+  // the linker scripts switches to another section. It has an index of one
+  // which will map to whatever the first actual section is.
+  Aether = make<OutputSection>("", 0, SHF_ALLOC);
+  Aether->SectionIndex = 1;
+  CurOutSec = Aether;
+
   for (unsigned I = 0; I < Opt.Commands.size(); ++I) {
     auto Iter = Opt.Commands.begin() + I;
     const std::unique_ptr<BaseCommand> &Base1 = *Iter;
@@ -385,6 +378,7 @@ void LinkerScript<ELFT>::processCommands
         Factory.addInputSec<ELFT>(S, Cmd->Name);
     }
   }
+  CurOutSec = nullptr;
 }
 
 // Add sections that didn't match any sections command.
@@ -772,18 +766,6 @@ template <class ELFT>
 void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
   // Assign addresses as instructed by linker script SECTIONS sub-commands.
   Dot = 0;
-
-  // A symbol can be assigned before any section is mentioned in the linker
-  // script. In an DSO, the symbol values are addresses, so the only important
-  // section values are:
-  // * SHN_UNDEF
-  // * SHN_ABS
-  // * Any value meaning a regular section.
-  // To handle that, create a dummy aether section that fills the void before
-  // the linker scripts switches to another section. It has an index of one
-  // which will map to whatever the first actual section is.
-  auto *Aether = make<OutputSection>("", 0, SHF_ALLOC);
-  Aether->SectionIndex = 1;
   switchTo(Aether);
 
   for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
@@ -924,8 +906,8 @@ template <class ELFT> bool LinkerScript<
 }
 
 template <class ELFT>
-const OutputSection *LinkerScript<ELFT>::getOutputSection(const Twine &Loc,
-                                                          StringRef Name) {
+OutputSection *LinkerScript<ELFT>::getOutputSection(const Twine &Loc,
+                                                    StringRef Name) {
   static OutputSection FakeSec("", 0, 0);
 
   for (OutputSection *Sec : *OutputSections)
@@ -976,7 +958,7 @@ template <class ELFT> bool LinkerScript<
 // specific section but isn't absolute at the same time, so we try
 // to find suitable section for it as well.
 template <class ELFT>
-const OutputSection *LinkerScript<ELFT>::getSymbolSection(StringRef S) {
+OutputSection *LinkerScript<ELFT>::getSymbolSection(StringRef S) {
   if (SymbolBody *Sym = Symtab<ELFT>::X->find(S))
     return Sym->getOutputSection<ELFT>();
   return CurOutSec;
@@ -1634,7 +1616,7 @@ Expr ScriptParser::readExpr() {
 static Expr combine(StringRef Op, Expr L, Expr R) {
   auto IsAbs = [=] { return L.IsAbsolute() && R.IsAbsolute(); };
   auto GetOutSec = [=] {
-    const OutputSection *S = L.Section();
+    OutputSection *S = L.Section();
     return S ? S : R.Section();
   };
 

Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Wed Mar  8 16:36:28 2017
@@ -47,13 +47,13 @@ struct Expr {
 
   // If expression is section-relative the function below is used
   // to get the output section pointer.
-  std::function<const OutputSection *()> Section;
+  std::function<OutputSection *()> Section;
 
   uint64_t operator()(uint64_t Dot) const { return Val(Dot); }
   operator bool() const { return (bool)Val; }
 
   Expr(std::function<uint64_t(uint64_t)> Val, std::function<bool()> IsAbsolute,
-       std::function<const OutputSection *()> Section)
+       std::function<OutputSection *()> Section)
       : Val(Val), IsAbsolute(IsAbsolute), Section(Section) {}
   template <typename T>
   Expr(T V) : Expr(V, [] { return true; }, [] { return nullptr; }) {}
@@ -207,15 +207,15 @@ struct MemoryRegion {
 class LinkerScriptBase {
 protected:
   ~LinkerScriptBase() = default;
+  OutputSection *Aether;
 
 public:
   virtual uint64_t getHeaderSize() = 0;
   virtual uint64_t getSymbolValue(const Twine &Loc, StringRef S) = 0;
   virtual bool isDefined(StringRef S) = 0;
   virtual bool isAbsolute(StringRef S) = 0;
-  virtual const OutputSection *getSymbolSection(StringRef S) = 0;
-  virtual const OutputSection *getOutputSection(const Twine &Loc,
-                                                StringRef S) = 0;
+  virtual OutputSection *getSymbolSection(StringRef S) = 0;
+  virtual OutputSection *getOutputSection(const Twine &Loc, StringRef S) = 0;
   virtual uint64_t getOutputSectionSize(StringRef S) = 0;
 };
 
@@ -268,8 +268,8 @@ public:
   uint64_t getSymbolValue(const Twine &Loc, StringRef S) override;
   bool isDefined(StringRef S) override;
   bool isAbsolute(StringRef S) override;
-  const OutputSection *getSymbolSection(StringRef S) override;
-  const OutputSection *getOutputSection(const Twine &Loc, StringRef S) override;
+  OutputSection *getSymbolSection(StringRef S) override;
+  OutputSection *getOutputSection(const Twine &Loc, StringRef S) override;
   uint64_t getOutputSectionSize(StringRef S) override;
 
   std::vector<OutputSection *> *OutputSections;

Modified: lld/trunk/ELF/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MarkLive.cpp?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/MarkLive.cpp (original)
+++ lld/trunk/ELF/MarkLive.cpp Wed Mar  8 16:36:28 2017
@@ -78,7 +78,7 @@ static void resolveReloc(InputSectionBas
     typename ELFT::uint Offset = D->Value;
     if (D->isSection())
       Offset += getAddend<ELFT>(Sec, Rel);
-    Fn({D->Section->Repl, Offset});
+    Fn({cast<InputSectionBase>(D->Section)->Repl, Offset});
   } else if (auto *U = dyn_cast<Undefined>(&B)) {
     for (InputSectionBase *Sec : CNamedSections.lookup(U->getName()))
       Fn({Sec, 0});
@@ -223,7 +223,7 @@ template <class ELFT> void elf::markLive
 
   auto MarkSymbol = [&](const SymbolBody *Sym) {
     if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym))
-      Enqueue({D->Section, D->Value});
+      Enqueue({cast<InputSectionBase>(D->Section), D->Value});
   };
 
   // Add GC root symbols.

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Wed Mar  8 16:36:28 2017
@@ -67,7 +67,9 @@ void OutputSection::writeHeaderTo(typena
 }
 
 OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t Flags)
-    : Name(Name), Flags(Flags), Alignment(1), Type(Type) {}
+    : SectionBase(Output, Name, Flags, /*Entsize*/ 0, /*Alignment*/ 1, Type,
+                  /*Info*/ 0,
+                  /*Link*/ 0) {}
 
 template <typename ELFT>
 static bool compareByFilePosition(InputSection *A, InputSection *B) {

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Wed Mar  8 16:36:28 2017
@@ -11,6 +11,7 @@
 #define LLD_ELF_OUTPUT_SECTIONS_H
 
 #include "Config.h"
+#include "InputSection.h"
 #include "Relocations.h"
 
 #include "lld/Core/LLVM.h"
@@ -37,10 +38,14 @@ class DefinedRegular;
 // It is composed of multiple InputSections.
 // The writer creates multiple OutputSections and assign them unique,
 // non-overlapping file offsets and VAs.
-class OutputSection final {
+class OutputSection final : public SectionBase {
 public:
   OutputSection(StringRef Name, uint32_t Type, uint64_t Flags);
 
+  static bool classof(const SectionBase *S) {
+    return S->kind() == SectionBase::Output;
+  }
+
   uint64_t getLMA() const { return Addr + LMAOffset; }
   template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr);
 
@@ -65,20 +70,12 @@ public:
   // formula: Off = Off_first + VA - VA_first.
   OutputSection *FirstInPtLoad = nullptr;
 
-  StringRef Name;
-
   // The following fields correspond to Elf_Shdr members.
   uint64_t Size = 0;
-  uint64_t Entsize = 0;
   uint64_t Offset = 0;
-  uint64_t Flags = 0;
   uint64_t LMAOffset = 0;
   uint64_t Addr = 0;
-  uint32_t Alignment = 0;
   uint32_t ShName = 0;
-  uint32_t Type = 0;
-  uint32_t Info = 0;
-  uint32_t Link = 0;
 
   void addSection(InputSectionBase *C);
   void sort(std::function<int(InputSectionBase *S)> Order);

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Wed Mar  8 16:36:28 2017
@@ -369,7 +369,8 @@ static void reportDuplicate(SymbolBody *
     return;
   }
 
-  std::string OldLoc = D->Section->template getLocation<ELFT>(D->Value);
+  std::string OldLoc =
+      cast<InputSectionBase>(D->Section)->template getLocation<ELFT>(D->Value);
   std::string NewLoc = ErrSec->getLocation<ELFT>(ErrOffset);
 
   print(NewLoc + ": duplicate symbol '" + toString(*Existing) + "'");
@@ -377,10 +378,10 @@ static void reportDuplicate(SymbolBody *
 }
 
 template <typename ELFT>
-Symbol *
-SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
-                              uint64_t Value, uint64_t Size, uint8_t Binding,
-                              InputSectionBase *Section, InputFile *File) {
+Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t StOther,
+                                      uint8_t Type, uint64_t Value,
+                                      uint64_t Size, uint8_t Binding,
+                                      SectionBase *Section, InputFile *File) {
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name, Type, getVisibility(StOther),
@@ -391,24 +392,8 @@ SymbolTable<ELFT>::addRegular(StringRef
     replaceBody<DefinedRegular>(S, Name, /*IsLocal=*/false, StOther, Type,
                                 Value, Size, Section, File);
   else if (Cmp == 0)
-    reportDuplicate<ELFT>(S->body(), Section, Value);
-  return S;
-}
-
-template <typename ELFT>
-Symbol *SymbolTable<ELFT>::addSynthetic(StringRef N,
-                                        const OutputSection *Section,
-                                        uint64_t Value, uint8_t StOther) {
-  Symbol *S;
-  bool WasInserted;
-  std::tie(S, WasInserted) = insert(N, STT_NOTYPE, getVisibility(StOther),
-                                    /*CanOmitFromDynSym*/ false, nullptr);
-  int Cmp = compareDefinedNonCommon<ELFT>(S, WasInserted, STB_GLOBAL,
-                                          /*IsAbsolute*/ false, /*Value*/ 0);
-  if (Cmp > 0)
-    replaceBody<DefinedSynthetic>(S, N, Value, Section);
-  else if (Cmp == 0)
-    reportDuplicate(S->body(), nullptr);
+    reportDuplicate<ELFT>(S->body(),
+                          dyn_cast_or_null<InputSectionBase>(Section), Value);
   return S;
 }
 

Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Wed Mar  8 16:36:28 2017
@@ -58,10 +58,7 @@ public:
 
   Symbol *addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
                      uint64_t Value, uint64_t Size, uint8_t Binding,
-                     InputSectionBase *Section, InputFile *File);
-
-  Symbol *addSynthetic(StringRef N, const OutputSection *Section,
-                       uint64_t Value, uint8_t StOther);
+                     SectionBase *Section, InputFile *File);
 
   void addShared(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym,
                  const typename ELFT::Verdef *Verdef);

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Wed Mar  8 16:36:28 2017
@@ -28,14 +28,12 @@ using namespace llvm::ELF;
 using namespace lld;
 using namespace lld::elf;
 
-InputSectionBase *DefinedRegular::NullInputSection;
-
-DefinedSynthetic *ElfSym::Etext;
-DefinedSynthetic *ElfSym::Etext2;
-DefinedSynthetic *ElfSym::Edata;
-DefinedSynthetic *ElfSym::Edata2;
-DefinedSynthetic *ElfSym::End;
-DefinedSynthetic *ElfSym::End2;
+DefinedRegular *ElfSym::Etext;
+DefinedRegular *ElfSym::Etext2;
+DefinedRegular *ElfSym::Edata;
+DefinedRegular *ElfSym::Edata2;
+DefinedRegular *ElfSym::End;
+DefinedRegular *ElfSym::End2;
 DefinedRegular *ElfSym::MipsGpDisp;
 DefinedRegular *ElfSym::MipsLocalGp;
 DefinedRegular *ElfSym::MipsGp;
@@ -43,18 +41,11 @@ DefinedRegular *ElfSym::MipsGp;
 template <class ELFT>
 static typename ELFT::uint getSymVA(const SymbolBody &Body, int64_t &Addend) {
   switch (Body.kind()) {
-  case SymbolBody::DefinedSyntheticKind: {
-    auto &D = cast<DefinedSynthetic>(Body);
-    const OutputSection *Sec = D.Section;
-    if (!Sec)
-      return D.Value;
-    if (D.Value == uint64_t(-1))
-      return Sec->Addr + Sec->Size;
-    return Sec->Addr + D.Value;
-  }
   case SymbolBody::DefinedRegularKind: {
     auto &D = cast<DefinedRegular>(Body);
-    InputSectionBase *IS = D.Section;
+    SectionBase *IS = D.Section;
+    if (auto *ISB = dyn_cast_or_null<InputSectionBase>(IS))
+      IS = ISB->Repl;
 
     // According to the ELF spec reference to a local symbol from outside
     // the group are not allowed. Unfortunately .eh_frame breaks that rule
@@ -207,8 +198,7 @@ template <class ELFT> typename ELFT::uin
   return 0;
 }
 
-template <class ELFT>
-const OutputSection *SymbolBody::getOutputSection() const {
+template <class ELFT> OutputSection *SymbolBody::getOutputSection() const {
   if (auto *S = dyn_cast<DefinedRegular>(this)) {
     if (S->Section)
       return S->Section->getOutputSection();
@@ -227,8 +217,6 @@ const OutputSection *SymbolBody::getOutp
     return nullptr;
   }
 
-  if (auto *S = dyn_cast<DefinedSynthetic>(this))
-    return S->Section;
   return nullptr;
 }
 
@@ -279,7 +267,11 @@ template <class ELFT> bool DefinedRegula
   if (!Section || !isFunc())
     return false;
   return (this->StOther & STO_MIPS_MIPS16) == STO_MIPS_PIC ||
-         (Section->getFile<ELFT>()->getObj().getHeader()->e_flags &
+         (cast<InputSectionBase>(Section)
+              ->template getFile<ELFT>()
+              ->getObj()
+              .getHeader()
+              ->e_flags &
           EF_MIPS_PIC);
 }
 
@@ -419,14 +411,10 @@ template uint32_t SymbolBody::template g
 template uint64_t SymbolBody::template getSize<ELF64LE>() const;
 template uint64_t SymbolBody::template getSize<ELF64BE>() const;
 
-template const OutputSection *
-    SymbolBody::template getOutputSection<ELF32LE>() const;
-template const OutputSection *
-    SymbolBody::template getOutputSection<ELF32BE>() const;
-template const OutputSection *
-    SymbolBody::template getOutputSection<ELF64LE>() const;
-template const OutputSection *
-    SymbolBody::template getOutputSection<ELF64BE>() const;
+template OutputSection *SymbolBody::template getOutputSection<ELF32LE>() const;
+template OutputSection *SymbolBody::template getOutputSection<ELF32BE>() const;
+template OutputSection *SymbolBody::template getOutputSection<ELF64LE>() const;
+template OutputSection *SymbolBody::template getOutputSection<ELF64BE>() const;
 
 template bool DefinedRegular::template isMipsPIC<ELF32LE>() const;
 template bool DefinedRegular::template isMipsPIC<ELF32BE>() const;

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Wed Mar  8 16:36:28 2017
@@ -43,8 +43,7 @@ public:
     DefinedRegularKind = DefinedFirst,
     SharedKind,
     DefinedCommonKind,
-    DefinedSyntheticKind,
-    DefinedLast = DefinedSyntheticKind,
+    DefinedLast = DefinedCommonKind,
     UndefinedKind,
     LazyArchiveKind,
     LazyObjectKind,
@@ -84,7 +83,7 @@ public:
   template <class ELFT> typename ELFT::uint getGotPltVA() const;
   template <class ELFT> typename ELFT::uint getPltVA() const;
   template <class ELFT> typename ELFT::uint getSize() const;
-  template <class ELFT> const OutputSection *getOutputSection() const;
+  template <class ELFT> OutputSection *getOutputSection() const;
 
   // The file from which this symbol was created.
   InputFile *File = nullptr;
@@ -177,11 +176,10 @@ public:
 class DefinedRegular : public Defined {
 public:
   DefinedRegular(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type,
-                 uint64_t Value, uint64_t Size, InputSectionBase *Section,
+                 uint64_t Value, uint64_t Size, SectionBase *Section,
                  InputFile *File)
       : Defined(SymbolBody::DefinedRegularKind, Name, IsLocal, StOther, Type),
-        Value(Value), Size(Size),
-        Section(Section ? Section->Repl : NullInputSection) {
+        Value(Value), Size(Size), Section(Section) {
     this->File = File;
   }
 
@@ -194,37 +192,7 @@ public:
 
   uint64_t Value;
   uint64_t Size;
-
-  // The input section this symbol belongs to. Notice that this is
-  // a reference to a pointer. We are using two levels of indirections
-  // because of ICF. If ICF decides two sections need to be merged, it
-  // manipulates this Section pointers so that they point to the same
-  // section. This is a bit tricky, so be careful to not be confused.
-  // If this is null, the symbol is an absolute symbol.
-  InputSectionBase *&Section;
-
-private:
-  static InputSectionBase *NullInputSection;
-};
-
-// DefinedSynthetic is a class to represent linker-generated ELF symbols.
-// The difference from the regular symbol is that DefinedSynthetic symbols
-// don't belong to any input files or sections. Thus, its constructor
-// takes an output section to calculate output VA, etc.
-// If Section is null, this symbol is relative to the image base.
-class DefinedSynthetic : public Defined {
-public:
-  DefinedSynthetic(StringRef Name, uint64_t Value, const OutputSection *Section)
-      : Defined(SymbolBody::DefinedSyntheticKind, Name, /*IsLocal=*/false,
-                llvm::ELF::STV_HIDDEN, 0 /* Type */),
-        Value(Value), Section(Section) {}
-
-  static bool classof(const SymbolBody *S) {
-    return S->kind() == SymbolBody::DefinedSyntheticKind;
-  }
-
-  uint64_t Value;
-  const OutputSection *Section;
+  SectionBase *Section;
 };
 
 class Undefined : public SymbolBody {
@@ -334,16 +302,16 @@ public:
 // DefinedRegular symbols.
 struct ElfSym {
   // The content for _etext and etext symbols.
-  static DefinedSynthetic *Etext;
-  static DefinedSynthetic *Etext2;
+  static DefinedRegular *Etext;
+  static DefinedRegular *Etext2;
 
   // The content for _edata and edata symbols.
-  static DefinedSynthetic *Edata;
-  static DefinedSynthetic *Edata2;
+  static DefinedRegular *Edata;
+  static DefinedRegular *Edata2;
 
   // The content for _end and end symbols.
-  static DefinedSynthetic *End;
-  static DefinedSynthetic *End2;
+  static DefinedRegular *End;
+  static DefinedRegular *End2;
 
   // The content for _gp_disp/__gnu_local_gp symbols for MIPS target.
   static DefinedRegular *MipsGpDisp;
@@ -395,8 +363,8 @@ struct Symbol {
   // This field is used to store the Symbol's SymbolBody. This instantiation of
   // AlignedCharArrayUnion gives us a struct with a char array field that is
   // large and aligned enough to store any derived class of SymbolBody.
-  llvm::AlignedCharArrayUnion<DefinedCommon, DefinedRegular, DefinedSynthetic,
-                              Undefined, SharedSymbol, LazyArchive, LazyObject>
+  llvm::AlignedCharArrayUnion<DefinedCommon, DefinedRegular, Undefined,
+                              SharedSymbol, LazyArchive, LazyObject>
       Body;
 
   SymbolBody *body() { return reinterpret_cast<SymbolBody *>(Body.buffer); }

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Wed Mar  8 16:36:28 2017
@@ -460,7 +460,8 @@ bool EhFrameSection<ELFT>::isFdeLive(EhS
   auto *D = dyn_cast<DefinedRegular>(&B);
   if (!D || !D->Section)
     return false;
-  InputSectionBase *Target = D->Section->Repl;
+  auto *Target =
+      cast<InputSectionBase>(cast<InputSectionBase>(D->Section)->Repl);
   return Target && Target->Live;
 }
 
@@ -1357,8 +1358,8 @@ size_t SymbolTableSection<ELFT>::getSymb
     // This is used for -r, so we have to handle multiple section
     // symbols being combined.
     if (Body->Type == STT_SECTION && E.Symbol->Type == STT_SECTION)
-      return cast<DefinedRegular>(Body)->Section->OutSec ==
-             cast<DefinedRegular>(E.Symbol)->Section->OutSec;
+      return cast<DefinedRegular>(Body)->Section->getOutputSection() ==
+             cast<DefinedRegular>(E.Symbol)->Section->getOutputSection();
     return false;
   });
   if (I == Symbols.end())

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=297313&r1=297312&r2=297313&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Mar  8 16:36:28 2017
@@ -453,7 +453,7 @@ template <class ELFT> void Writer<ELFT>:
 }
 
 template <class ELFT>
-static bool shouldKeepInSymtab(InputSectionBase *Sec, StringRef SymName,
+static bool shouldKeepInSymtab(SectionBase *Sec, StringRef SymName,
                                const SymbolBody &B) {
   if (B.isFile() || B.isSection())
     return false;
@@ -485,12 +485,17 @@ template <class ELFT> static bool includ
 
   if (auto *D = dyn_cast<DefinedRegular>(&B)) {
     // Always include absolute symbols.
-    if (!D->Section)
+    SectionBase *Sec = D->Section;
+    if (!Sec)
       return true;
-    // Exclude symbols pointing to garbage-collected sections.
-    if (!D->Section->Live)
-      return false;
-    if (auto *S = dyn_cast<MergeInputSection>(D->Section))
+    if (auto *IS = dyn_cast<InputSectionBase>(Sec)) {
+      Sec = IS->Repl;
+      IS = cast<InputSectionBase>(Sec);
+      // Exclude symbols pointing to garbage-collected sections.
+      if (!IS->Live)
+        return false;
+    }
+    if (auto *S = dyn_cast<MergeInputSection>(Sec))
       if (!S->getSectionPiece(D->Value)->Live)
         return false;
   }
@@ -515,7 +520,7 @@ template <class ELFT> void Writer<ELFT>:
       if (!includeInSymtab<ELFT>(*B))
         continue;
 
-      InputSectionBase *Sec = DR->Section;
+      SectionBase *Sec = DR->Section;
       if (!shouldKeepInSymtab<ELFT>(Sec, B->getName(), *B))
         continue;
       In<ELFT>::SymTab->addSymbol(B);
@@ -733,35 +738,27 @@ void PhdrEntry::add(OutputSection *Sec)
 }
 
 template <class ELFT>
-static DefinedSynthetic *addOptionalSynthetic(StringRef Name,
-                                              OutputSection *Sec, uint64_t Val,
-                                              uint8_t StOther = STV_HIDDEN) {
-  if (SymbolBody *S = Symtab<ELFT>::X->find(Name))
-    if (!S->isInCurrentDSO())
-      return cast<DefinedSynthetic>(
-          Symtab<ELFT>::X->addSynthetic(Name, Sec, Val, StOther)->body());
-  return nullptr;
-}
-
-template <class ELFT>
-static Symbol *addRegular(StringRef Name, InputSectionBase *Sec,
-                          uint64_t Value) {
+static Symbol *addRegular(StringRef Name, SectionBase *Sec, uint64_t Value,
+                          uint8_t StOther = STV_HIDDEN,
+                          uint8_t Binding = STB_WEAK) {
   // The linker generated symbols are added as STB_WEAK to allow user defined
   // ones to override them.
-  return Symtab<ELFT>::X->addRegular(Name, STV_HIDDEN, STT_NOTYPE, Value,
-                                     /*Size=*/0, STB_WEAK, Sec,
+  return Symtab<ELFT>::X->addRegular(Name, StOther, STT_NOTYPE, Value,
+                                     /*Size=*/0, Binding, Sec,
                                      /*File=*/nullptr);
 }
 
 template <class ELFT>
-static Symbol *addOptionalRegular(StringRef Name, InputSectionBase *IS,
-                                  uint64_t Value) {
+static DefinedRegular *
+addOptionalRegular(StringRef Name, SectionBase *Sec, uint64_t Val,
+                   uint8_t StOther = STV_HIDDEN, uint8_t Binding = STB_GLOBAL) {
   SymbolBody *S = Symtab<ELFT>::X->find(Name);
   if (!S)
     return nullptr;
   if (S->isInCurrentDSO())
-    return S->symbol();
-  return addRegular<ELFT>(Name, IS, Value);
+    return nullptr;
+  return cast<DefinedRegular>(
+      addRegular<ELFT>(Name, Sec, Val, StOther, Binding)->body());
 }
 
 // The beginning and the ending of .rel[a].plt section are marked
@@ -774,10 +771,10 @@ template <class ELFT> void Writer<ELFT>:
   if (In<ELFT>::DynSymTab)
     return;
   StringRef S = Config->isRela() ? "__rela_iplt_start" : "__rel_iplt_start";
-  addOptionalRegular<ELFT>(S, In<ELFT>::RelaIplt, 0);
+  addOptionalRegular<ELFT>(S, In<ELFT>::RelaIplt, 0, STV_HIDDEN, STB_WEAK);
 
   S = Config->isRela() ? "__rela_iplt_end" : "__rel_iplt_end";
-  addOptionalRegular<ELFT>(S, In<ELFT>::RelaIplt, -1);
+  addOptionalRegular<ELFT>(S, In<ELFT>::RelaIplt, -1, STV_HIDDEN, STB_WEAK);
 }
 
 // The linker is expected to define some symbols depending on
@@ -837,14 +834,13 @@ template <class ELFT> void Writer<ELFT>:
     return;
 
   // __ehdr_start is the location of ELF file headers.
-  addOptionalSynthetic<ELFT>("__ehdr_start", Out::ElfHeader, 0);
+  addOptionalRegular<ELFT>("__ehdr_start", Out::ElfHeader, 0, STV_HIDDEN);
 
-  auto Define = [](StringRef S, DefinedSynthetic *&Sym1,
-                   DefinedSynthetic *&Sym2) {
-    Sym1 = addOptionalSynthetic<ELFT>(S, nullptr, 0, STV_DEFAULT);
+  auto Define = [](StringRef S, DefinedRegular *&Sym1, DefinedRegular *&Sym2) {
+    Sym1 = addOptionalRegular<ELFT>(S, Out::ElfHeader, 0, STV_DEFAULT);
     assert(S.startswith("_"));
     S = S.substr(1);
-    Sym2 = addOptionalSynthetic<ELFT>(S, nullptr, 0, STV_DEFAULT);
+    Sym2 = addOptionalRegular<ELFT>(S, Out::ElfHeader, 0, STV_DEFAULT);
   };
 
   Define("_end", ElfSym::End, ElfSym::End2);
@@ -880,7 +876,7 @@ static void sortBySymbolsOrder(ArrayRef<
     SymbolOrder.insert({S, Priority++});
 
   // Build a map from sections to their priorities.
-  DenseMap<InputSectionBase *, int> SectionOrder;
+  DenseMap<SectionBase *, int> SectionOrder;
   for (elf::ObjectFile<ELFT> *File : Symtab<ELFT>::X->getObjectFiles()) {
     for (SymbolBody *Body : File->getSymbols()) {
       auto *D = dyn_cast<DefinedRegular>(Body);
@@ -1208,8 +1204,10 @@ template <class ELFT> void Writer<ELFT>:
   auto Define = [&](StringRef Start, StringRef End, OutputSection *OS) {
     // These symbols resolve to the image base if the section does not exist.
     // A special value -1 indicates end of the section.
-    addOptionalSynthetic<ELFT>(Start, OS, 0);
-    addOptionalSynthetic<ELFT>(End, OS, OS ? -1 : 0);
+    if (!OS && Config->pic())
+      OS = Out::ElfHeader;
+    addOptionalRegular<ELFT>(Start, OS, 0);
+    addOptionalRegular<ELFT>(End, OS, OS ? -1 : 0);
   };
 
   Define("__preinit_array_start", "__preinit_array_end", Out::PreinitArray);
@@ -1230,8 +1228,8 @@ void Writer<ELFT>::addStartStopSymbols(O
   StringRef S = Sec->Name;
   if (!isValidCIdentifier(S))
     return;
-  addOptionalSynthetic<ELFT>(Saver.save("__start_" + S), Sec, 0, STV_DEFAULT);
-  addOptionalSynthetic<ELFT>(Saver.save("__stop_" + S), Sec, -1, STV_DEFAULT);
+  addOptionalRegular<ELFT>(Saver.save("__start_" + S), Sec, 0, STV_DEFAULT);
+  addOptionalRegular<ELFT>(Saver.save("__stop_" + S), Sec, -1, STV_DEFAULT);
 }
 
 template <class ELFT> OutputSection *Writer<ELFT>::findSection(StringRef Name) {
@@ -1638,7 +1636,7 @@ static uint16_t getELFType() {
 // to each section. This function fixes some predefined
 // symbol values that depend on section address and size.
 template <class ELFT> void Writer<ELFT>::fixPredefinedSymbols() {
-  auto Set = [](DefinedSynthetic *S1, DefinedSynthetic *S2, OutputSection *Sec,
+  auto Set = [](DefinedRegular *S1, DefinedRegular *S2, OutputSection *Sec,
                 uint64_t Value) {
     if (S1) {
       S1->Section = Sec;




More information about the llvm-commits mailing list