[llvm] r268331 - [MC] Create unique .pdata sections for every .text section

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Mon May 2 16:22:19 PDT 2016


Author: rnk
Date: Mon May  2 18:22:18 2016
New Revision: 268331

URL: http://llvm.org/viewvc/llvm-project?rev=268331&view=rev
Log:
[MC] Create unique .pdata sections for every .text section

Summary:
This adds a unique ID to the COFF section uniquing map, similar to the
one we have for ELF.  The unique id is not currently exposed via the
assembler because we don't have a use case for it yet. Users generally
create .pdata with the .seh_* family of directives, and the assembler
internally needs to produce .pdata and .xdata sections corresponding to
the code section.

The association between .text sections and the assembler-created .xdata
and .pdata sections is maintained as an ID field of MCSectionCOFF. The
CFI-related sections are created with the given unique ID, so if more
code is added to the same text section, we can find and reuse the CFI
sections that were already created.

Reviewers: majnemer, rafael

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D19376

Added:
    llvm/trunk/test/MC/COFF/seh-section-2.s
Modified:
    llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
    llvm/trunk/include/llvm/MC/MCContext.h
    llvm/trunk/include/llvm/MC/MCSectionCOFF.h
    llvm/trunk/include/llvm/MC/MCStreamer.h
    llvm/trunk/include/llvm/MC/MCWinEH.h
    llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
    llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/trunk/lib/MC/MCAsmStreamer.cpp
    llvm/trunk/lib/MC/MCContext.cpp
    llvm/trunk/lib/MC/MCStreamer.cpp
    llvm/trunk/lib/MC/MCWin64EH.cpp
    llvm/trunk/lib/MC/MCWinEH.cpp
    llvm/trunk/test/MC/COFF/seh-section.s

Modified: llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h?rev=268331&r1=268330&r2=268331&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h (original)
+++ llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h Mon May  2 18:22:18 2016
@@ -140,6 +140,8 @@ public:
 
 
 class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
+  mutable unsigned NextUniqueID = 0;
+
 public:
   ~TargetLoweringObjectFileCOFF() override {}
 

Modified: llvm/trunk/include/llvm/MC/MCContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCContext.h?rev=268331&r1=268330&r2=268331&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCContext.h (original)
+++ llvm/trunk/include/llvm/MC/MCContext.h Mon May  2 18:22:18 2016
@@ -200,16 +200,19 @@ namespace llvm {
       std::string SectionName;
       StringRef GroupName;
       int SelectionKey;
+      unsigned UniqueID;
       COFFSectionKey(StringRef SectionName, StringRef GroupName,
-                     int SelectionKey)
+                     int SelectionKey, unsigned UniqueID)
           : SectionName(SectionName), GroupName(GroupName),
-            SelectionKey(SelectionKey) {}
+            SelectionKey(SelectionKey), UniqueID(UniqueID) {}
       bool operator<(const COFFSectionKey &Other) const {
         if (SectionName != Other.SectionName)
           return SectionName < Other.SectionName;
         if (GroupName != Other.GroupName)
           return GroupName < Other.GroupName;
-        return SelectionKey < Other.SelectionKey;
+        if (SelectionKey != Other.SelectionKey)
+          return SelectionKey < Other.SelectionKey;
+        return UniqueID < Other.UniqueID;
       }
     };
 
@@ -315,6 +318,13 @@ namespace llvm {
     /// \name Section Management
     /// @{
 
+    enum : unsigned {
+      /// Pass this value as the UniqueID during section creation to get the
+      /// generic section with the given name and characteristics. The usual
+      /// sections such as .text use this ID.
+      GenericSectionID = ~0U
+    };
+
     /// Return the MCSection for the specified mach-o section.  This requires
     /// the operands to be valid.
     MCSectionMachO *getMachOSection(StringRef Segment, StringRef Section,
@@ -382,6 +392,7 @@ namespace llvm {
     MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
                                   SectionKind Kind, StringRef COMDATSymName,
                                   int Selection,
+                                  unsigned UniqueID = GenericSectionID,
                                   const char *BeginSymName = nullptr);
 
     MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
@@ -394,8 +405,9 @@ namespace llvm {
     /// section containing KeySym. For example, to create a debug info section
     /// associated with an inline function, pass the normal debug info section
     /// as Sec and the function symbol as KeySym.
-    MCSectionCOFF *getAssociativeCOFFSection(MCSectionCOFF *Sec,
-                                             const MCSymbol *KeySym);
+    MCSectionCOFF *
+    getAssociativeCOFFSection(MCSectionCOFF *Sec, const MCSymbol *KeySym,
+                              unsigned UniqueID = GenericSectionID);
 
     // Create and save a copy of STI and return a reference to the copy.
     MCSubtargetInfo &getSubtargetCopy(const MCSubtargetInfo &STI);

Modified: llvm/trunk/include/llvm/MC/MCSectionCOFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSectionCOFF.h?rev=268331&r1=268330&r2=268331&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCSectionCOFF.h (original)
+++ llvm/trunk/include/llvm/MC/MCSectionCOFF.h Mon May  2 18:22:18 2016
@@ -32,6 +32,13 @@ class MCSectionCOFF final : public MCSec
   /// below.
   mutable unsigned Characteristics;
 
+  /// The unique IDs used with the .pdata and .xdata sections created internally
+  /// by the assembler. This ID is used to ensure that for every .text section,
+  /// there is exactly one .pdata and one .xdata section, which is required by
+  /// the Microsoft incremental linker. This data is mutable because this ID is
+  /// not notionally part of the section.
+  mutable unsigned WinCFISectionID = ~0U;
+
   /// The COMDAT symbol of this section. Only valid if this is a COMDAT section.
   /// Two COMDAT sections are merged if they have the same COMDAT symbol.
   MCSymbol *COMDATSymbol;
@@ -71,6 +78,12 @@ public:
   bool UseCodeAlign() const override;
   bool isVirtualSection() const override;
 
+  unsigned getOrAssignWinCFISectionID(unsigned *NextID) const {
+    if (WinCFISectionID == ~0U)
+      WinCFISectionID = (*NextID)++;
+    return WinCFISectionID;
+  }
+
   static bool classof(const MCSection *S) { return S->getVariant() == SV_COFF; }
 };
 

Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=268331&r1=268330&r2=268331&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Mon May  2 18:22:18 2016
@@ -183,6 +183,12 @@ class MCStreamer {
   /// PushSection.
   SmallVector<std::pair<MCSectionSubPair, MCSectionSubPair>, 4> SectionStack;
 
+  /// The next unique ID to use when creating a WinCFI-related section (.pdata
+  /// or .xdata). This ID ensures that we have a one-to-one mapping from
+  /// code section to unwind info section, which MSVC's incremental linker
+  /// requires.
+  unsigned NextWinCFIID = 0;
+
 protected:
   MCStreamer(MCContext &Ctx);
 
@@ -720,6 +726,14 @@ public:
   virtual void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except);
   virtual void EmitWinEHHandlerData();
 
+  /// Get the .pdata section used for the given section. Typically the given
+  /// section is either the main .text section or some other COMDAT .text
+  /// section, but it may be any section containing code.
+  MCSection *getAssociatedPDataSection(const MCSection *TextSec);
+
+  /// Get the .xdata section used for the given section.
+  MCSection *getAssociatedXDataSection(const MCSection *TextSec);
+
   virtual void EmitSyntaxDirective();
 
   /// \brief Emit a .reloc directive.

Modified: llvm/trunk/include/llvm/MC/MCWinEH.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCWinEH.h?rev=268331&r1=268330&r2=268331&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCWinEH.h (original)
+++ llvm/trunk/include/llvm/MC/MCWinEH.h Mon May  2 18:22:18 2016
@@ -13,11 +13,9 @@
 #include <vector>
 
 namespace llvm {
-class MCContext;
 class MCSection;
 class MCStreamer;
 class MCSymbol;
-class StringRef;
 
 namespace WinEH {
 struct Instruction {
@@ -31,50 +29,35 @@ struct Instruction {
 };
 
 struct FrameInfo {
-  const MCSymbol *Begin;
-  const MCSymbol *End;
-  const MCSymbol *ExceptionHandler;
-  const MCSymbol *Function;
-  const MCSymbol *PrologEnd;
-  const MCSymbol *Symbol;
+  const MCSymbol *Begin = nullptr;
+  const MCSymbol *End = nullptr;
+  const MCSymbol *ExceptionHandler = nullptr;
+  const MCSymbol *Function = nullptr;
+  const MCSymbol *PrologEnd = nullptr;
+  const MCSymbol *Symbol = nullptr;
+  const MCSection *TextSection = nullptr;
 
-  bool HandlesUnwind;
-  bool HandlesExceptions;
+  bool HandlesUnwind = false;
+  bool HandlesExceptions = false;
 
-  int LastFrameInst;
-  const FrameInfo *ChainedParent;
+  int LastFrameInst = -1;
+  const FrameInfo *ChainedParent = nullptr;
   std::vector<Instruction> Instructions;
 
-  FrameInfo()
-    : Begin(nullptr), End(nullptr), ExceptionHandler(nullptr),
-      Function(nullptr), PrologEnd(nullptr), Symbol(nullptr),
-      HandlesUnwind(false), HandlesExceptions(false), LastFrameInst(-1),
-      ChainedParent(nullptr), Instructions() {}
+  FrameInfo() = default;
   FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel)
-    : Begin(BeginFuncEHLabel), End(nullptr), ExceptionHandler(nullptr),
-      Function(Function), PrologEnd(nullptr), Symbol(nullptr),
-      HandlesUnwind(false), HandlesExceptions(false), LastFrameInst(-1),
-      ChainedParent(nullptr), Instructions() {}
+      : Begin(BeginFuncEHLabel), Function(Function) {}
   FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel,
             const FrameInfo *ChainedParent)
-    : Begin(BeginFuncEHLabel), End(nullptr), ExceptionHandler(nullptr),
-      Function(Function), PrologEnd(nullptr), Symbol(nullptr),
-      HandlesUnwind(false), HandlesExceptions(false), LastFrameInst(-1),
-      ChainedParent(ChainedParent), Instructions() {}
+      : Begin(BeginFuncEHLabel), Function(Function),
+        ChainedParent(ChainedParent) {}
 };
 
 class UnwindEmitter {
 public:
-  static MCSection *getPDataSection(const MCSymbol *Function,
-                                    MCContext &Context);
-  static MCSection *getXDataSection(const MCSymbol *Function,
-                                    MCContext &Context);
-
-  virtual ~UnwindEmitter() { }
-
-  //
-  // This emits the unwind info sections (.pdata and .xdata in PE/COFF).
-  //
+  virtual ~UnwindEmitter();
+
+  /// This emits the unwind info sections (.pdata and .xdata in PE/COFF).
   virtual void Emit(MCStreamer &Streamer) const = 0;
   virtual void EmitUnwindInfo(MCStreamer &Streamer, FrameInfo *FI) const = 0;
 };

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp?rev=268331&r1=268330&r2=268331&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp Mon May  2 18:22:18 2016
@@ -124,10 +124,9 @@ void WinException::endFunction(const Mac
   if (shouldEmitPersonality || shouldEmitLSDA) {
     Asm->OutStreamer->PushSection();
 
-    // Just switch sections to the right xdata section. This use of CurrentFnSym
-    // assumes that we only emit the LSDA when ending the parent function.
-    MCSection *XData = WinEH::UnwindEmitter::getXDataSection(Asm->CurrentFnSym,
-                                                             Asm->OutContext);
+    // Just switch sections to the right xdata section.
+    MCSection *XData = Asm->OutStreamer->getAssociatedXDataSection(
+        Asm->OutStreamer->getCurrentSectionOnly());
     Asm->OutStreamer->SwitchSection(XData);
 
     // Emit the tables appropriate to the personality function in use. If we

Modified: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=268331&r1=268330&r2=268331&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Mon May  2 18:22:18 2016
@@ -316,7 +316,7 @@ selectELFSectionForGlobal(MCContext &Ctx
     Name.push_back('.');
     TM.getNameWithPrefix(Name, GV, Mang, true);
   }
-  unsigned UniqueID = ~0;
+  unsigned UniqueID = MCContext::GenericSectionID;
   if (EmitUniqueSection && !UniqueSectionNames) {
     UniqueID = *NextUniqueID;
     (*NextUniqueID)++;
@@ -924,10 +924,8 @@ MCSection *TargetLoweringObjectFileCOFF:
       Selection = 0;
     }
   }
-  return getContext().getCOFFSection(Name,
-                                     Characteristics,
-                                     Kind,
-                                     COMDATSymName,
+
+  return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName,
                                      Selection);
 }
 
@@ -968,16 +966,20 @@ MCSection *TargetLoweringObjectFileCOFF:
     else
       ComdatGV = GV;
 
+    unsigned UniqueID = MCContext::GenericSectionID;
+    if (EmitUniquedSection)
+      UniqueID = NextUniqueID++;
+
     if (!ComdatGV->hasPrivateLinkage()) {
       MCSymbol *Sym = TM.getSymbol(ComdatGV, Mang);
       StringRef COMDATSymName = Sym->getName();
       return getContext().getCOFFSection(Name, Characteristics, Kind,
-                                         COMDATSymName, Selection);
+                                         COMDATSymName, Selection, UniqueID);
     } else {
       SmallString<256> TmpData;
       Mang.getNameWithPrefix(TmpData, GV, /*CannotUsePrivateLabel=*/true);
       return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData,
-                                         Selection);
+                                         Selection, UniqueID);
     }
   }
 
@@ -1031,9 +1033,10 @@ MCSection *TargetLoweringObjectFileCOFF:
   const char *Name = getCOFFSectionNameForUniqueGlobal(Kind);
   unsigned Characteristics = getCOFFSectionFlags(Kind);
   Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
+  unsigned UniqueID = NextUniqueID++;
 
   return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName,
-                                     COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE);
+                                     COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
 }
 
 void TargetLoweringObjectFileCOFF::
@@ -1068,13 +1071,13 @@ emitModuleFlags(MCStreamer &Streamer,
 MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection(
     unsigned Priority, const MCSymbol *KeySym) const {
   return getContext().getAssociativeCOFFSection(
-      cast<MCSectionCOFF>(StaticCtorSection), KeySym);
+      cast<MCSectionCOFF>(StaticCtorSection), KeySym, 0);
 }
 
 MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
     unsigned Priority, const MCSymbol *KeySym) const {
   return getContext().getAssociativeCOFFSection(
-      cast<MCSectionCOFF>(StaticDtorSection), KeySym);
+      cast<MCSectionCOFF>(StaticDtorSection), KeySym, 0);
 }
 
 void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal(

Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=268331&r1=268330&r2=268331&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Mon May  2 18:22:18 2016
@@ -1288,8 +1288,8 @@ void MCAsmStreamer::EmitWinEHHandlerData
   // We only do this so the section switch that terminates the handler
   // data block is visible.
   WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
-  MCSection *XData =
-      WinEH::UnwindEmitter::getXDataSection(CurFrame->Function, getContext());
+  MCSection *TextSec = &CurFrame->Function->getSection();
+  MCSection *XData = getAssociatedXDataSection(TextSec);
   SwitchSectionNoChange(XData);
 
   OS << "\t.seh_handlerdata";

Modified: llvm/trunk/lib/MC/MCContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCContext.cpp?rev=268331&r1=268330&r2=268331&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCContext.cpp (original)
+++ llvm/trunk/lib/MC/MCContext.cpp Mon May  2 18:22:18 2016
@@ -372,6 +372,7 @@ MCSectionCOFF *MCContext::getCOFFSection
                                          unsigned Characteristics,
                                          SectionKind Kind,
                                          StringRef COMDATSymName, int Selection,
+                                         unsigned UniqueID,
                                          const char *BeginSymName) {
   MCSymbol *COMDATSymbol = nullptr;
   if (!COMDATSymName.empty()) {
@@ -379,8 +380,9 @@ MCSectionCOFF *MCContext::getCOFFSection
     COMDATSymName = COMDATSymbol->getName();
   }
 
+
   // Do the lookup, if we have a hit, return it.
-  COFFSectionKey T{Section, COMDATSymName, Selection};
+  COFFSectionKey T{Section, COMDATSymName, Selection, UniqueID};
   auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr));
   auto Iter = IterBool.first;
   if (!IterBool.second)
@@ -402,11 +404,12 @@ MCSectionCOFF *MCContext::getCOFFSection
                                          unsigned Characteristics,
                                          SectionKind Kind,
                                          const char *BeginSymName) {
-  return getCOFFSection(Section, Characteristics, Kind, "", 0, BeginSymName);
+  return getCOFFSection(Section, Characteristics, Kind, "", 0, GenericSectionID,
+                        BeginSymName);
 }
 
 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
-  COFFSectionKey T{Section, "", 0};
+  COFFSectionKey T{Section, "", 0, GenericSectionID};
   auto Iter = COFFUniquingMap.find(T);
   if (Iter == COFFUniquingMap.end())
     return nullptr;
@@ -414,18 +417,24 @@ MCSectionCOFF *MCContext::getCOFFSection
 }
 
 MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec,
-                                                    const MCSymbol *KeySym) {
-  // Return the normal section if we don't have to be associative.
-  if (!KeySym)
+                                                    const MCSymbol *KeySym,
+                                                    unsigned UniqueID) {
+  // Return the normal section if we don't have to be associative or unique.
+  if (!KeySym && UniqueID == GenericSectionID)
     return Sec;
 
-  // Make an associative section with the same name and kind as the normal
-  // section.
-  unsigned Characteristics =
-      Sec->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT;
+  // If we have a key symbol, make an associative section with the same name and
+  // kind as the normal section.
+  unsigned Characteristics = Sec->getCharacteristics();
+  if (KeySym) {
+    Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
+    return getCOFFSection(Sec->getSectionName(), Characteristics,
+                          Sec->getKind(), KeySym->getName(),
+                          COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
+  }
+
   return getCOFFSection(Sec->getSectionName(), Characteristics, Sec->getKind(),
-                        KeySym->getName(),
-                        COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE);
+                        "", 0, UniqueID);
 }
 
 MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {

Modified: llvm/trunk/lib/MC/MCStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=268331&r1=268330&r2=268331&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCStreamer.cpp Mon May  2 18:22:18 2016
@@ -19,8 +19,10 @@
 #include "llvm/MC/MCObjectFileInfo.h"
 #include "llvm/MC/MCObjectWriter.h"
 #include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSectionCOFF.h"
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/MC/MCWin64EH.h"
+#include "llvm/Support/COFF.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/raw_ostream.h"
@@ -446,6 +448,7 @@ void MCStreamer::EmitWinCFIStartProc(con
 
   WinFrameInfos.push_back(new WinEH::FrameInfo(Symbol, StartProc));
   CurrentWinFrameInfo = WinFrameInfos.back();
+  CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
 }
 
 void MCStreamer::EmitWinCFIEndProc() {
@@ -467,6 +470,7 @@ void MCStreamer::EmitWinCFIStartChained(
   WinFrameInfos.push_back(new WinEH::FrameInfo(CurrentWinFrameInfo->Function,
                                                StartProc, CurrentWinFrameInfo));
   CurrentWinFrameInfo = WinFrameInfos.back();
+  CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
 }
 
 void MCStreamer::EmitWinCFIEndChained() {
@@ -502,6 +506,38 @@ void MCStreamer::EmitWinEHHandlerData()
     report_fatal_error("Chained unwind areas can't have handlers!");
 }
 
+static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
+                                   MCSection *MainCFISec,
+                                   const MCSection *TextSec) {
+  // If this is the main .text section, use the main unwind info section.
+  if (TextSec == Context.getObjectFileInfo()->getTextSection())
+    return MainCFISec;
+
+  const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
+  unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
+
+  // If this section is COMDAT, this unwind section should be COMDAT associative
+  // with its group.
+  const MCSymbol *KeySym = nullptr;
+  if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)
+    KeySym = TextSecCOFF->getCOMDATSymbol();
+
+  return Context.getAssociativeCOFFSection(cast<MCSectionCOFF>(MainCFISec),
+                                           KeySym, UniqueID);
+}
+
+MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
+  return getWinCFISection(getContext(), &NextWinCFIID,
+                          getContext().getObjectFileInfo()->getPDataSection(),
+                          TextSec);
+}
+
+MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
+  return getWinCFISection(getContext(), &NextWinCFIID,
+                          getContext().getObjectFileInfo()->getXDataSection(),
+                          TextSec);
+}
+
 void MCStreamer::EmitSyntaxDirective() {}
 
 void MCStreamer::EmitWinCFIPushReg(unsigned Register) {

Modified: llvm/trunk/lib/MC/MCWin64EH.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCWin64EH.cpp?rev=268331&r1=268330&r2=268331&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCWin64EH.cpp (original)
+++ llvm/trunk/lib/MC/MCWin64EH.cpp Mon May  2 18:22:18 2016
@@ -17,7 +17,7 @@
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/Support/Win64EH.h"
 
-namespace llvm {
+using namespace llvm;
 
 // NOTE: All relocations generated here are 4-byte image-relative.
 
@@ -218,35 +218,29 @@ static void EmitUnwindInfo(MCStreamer &s
   }
 }
 
-namespace Win64EH {
-void UnwindEmitter::Emit(MCStreamer &Streamer) const {
-  MCContext &Context = Streamer.getContext();
-
+void llvm::Win64EH::UnwindEmitter::Emit(MCStreamer &Streamer) const {
   // Emit the unwind info structs first.
-  for (const auto &CFI : Streamer.getWinFrameInfos()) {
-    MCSection *XData = getXDataSection(CFI->Function, Context);
+  for (WinEH::FrameInfo *CFI : Streamer.getWinFrameInfos()) {
+    MCSection *XData = Streamer.getAssociatedXDataSection(CFI->TextSection);
     Streamer.SwitchSection(XData);
-    EmitUnwindInfo(Streamer, CFI);
+    ::EmitUnwindInfo(Streamer, CFI);
   }
 
   // Now emit RUNTIME_FUNCTION entries.
-  for (const auto &CFI : Streamer.getWinFrameInfos()) {
-    MCSection *PData = getPDataSection(CFI->Function, Context);
+  for (WinEH::FrameInfo *CFI : Streamer.getWinFrameInfos()) {
+    MCSection *PData = Streamer.getAssociatedPDataSection(CFI->TextSection);
     Streamer.SwitchSection(PData);
     EmitRuntimeFunction(Streamer, CFI);
   }
 }
 
-void UnwindEmitter::EmitUnwindInfo(MCStreamer &Streamer,
-                                   WinEH::FrameInfo *info) const {
+void llvm::Win64EH::UnwindEmitter::EmitUnwindInfo(
+    MCStreamer &Streamer, WinEH::FrameInfo *info) const {
   // Switch sections (the static function above is meant to be called from
   // here and from Emit().
-  MCContext &context = Streamer.getContext();
-  MCSection *xdataSect = getXDataSection(info->Function, context);
-  Streamer.SwitchSection(xdataSect);
+  MCSection *XData = Streamer.getAssociatedXDataSection(info->TextSection);
+  Streamer.SwitchSection(XData);
 
-  llvm::EmitUnwindInfo(Streamer, info);
-}
+  ::EmitUnwindInfo(Streamer, info);
 }
-} // End of namespace llvm
 

Modified: llvm/trunk/lib/MC/MCWinEH.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCWinEH.cpp?rev=268331&r1=268330&r2=268331&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCWinEH.cpp (original)
+++ llvm/trunk/lib/MC/MCWinEH.cpp Mon May  2 18:22:18 2016
@@ -19,60 +19,7 @@
 namespace llvm {
 namespace WinEH {
 
-/// We can't have one section for all .pdata or .xdata because the Microsoft
-/// linker seems to want all code relocations to refer to the same object file
-/// section. If the code described is comdat, create a new comdat section
-/// associated with that comdat. If the code described is not in the main .text
-/// section, make a new section for it. Otherwise use the main unwind info
-/// section.
-static MCSection *getUnwindInfoSection(StringRef SecName,
-                                       MCSectionCOFF *UnwindSec,
-                                       const MCSymbol *Function,
-                                       MCContext &Context) {
-  if (Function && Function->isInSection()) {
-    // If Function is in a COMDAT, get or create an unwind info section in that
-    // COMDAT group.
-    const MCSectionCOFF *FunctionSection =
-        cast<MCSectionCOFF>(&Function->getSection());
-    if (FunctionSection->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
-      return Context.getAssociativeCOFFSection(
-          UnwindSec, FunctionSection->getCOMDATSymbol());
-    }
-
-    // If Function is in a section other than .text, create a new .pdata section.
-    // Otherwise use the plain .pdata section.
-    if (const auto *Section = dyn_cast<MCSectionCOFF>(FunctionSection)) {
-      StringRef CodeSecName = Section->getSectionName();
-      if (CodeSecName == ".text")
-        return UnwindSec;
-
-      if (CodeSecName.startswith(".text$"))
-        CodeSecName = CodeSecName.substr(6);
-
-      return Context.getCOFFSection((SecName + Twine('$') + CodeSecName).str(),
-                                    COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
-                                        COFF::IMAGE_SCN_MEM_READ,
-                                    SectionKind::getData());
-    }
-  }
-
-  return UnwindSec;
-
-}
-
-MCSection *UnwindEmitter::getPDataSection(const MCSymbol *Function,
-                                          MCContext &Context) {
-  MCSectionCOFF *PData =
-      cast<MCSectionCOFF>(Context.getObjectFileInfo()->getPDataSection());
-  return getUnwindInfoSection(".pdata", PData, Function, Context);
-}
-
-MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function,
-                                          MCContext &Context) {
-  MCSectionCOFF *XData =
-      cast<MCSectionCOFF>(Context.getObjectFileInfo()->getXDataSection());
-  return getUnwindInfoSection(".xdata", XData, Function, Context);
-}
+UnwindEmitter::~UnwindEmitter() {}
 
 }
 }

Added: llvm/trunk/test/MC/COFF/seh-section-2.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/seh-section-2.s?rev=268331&view=auto
==============================================================================
--- llvm/trunk/test/MC/COFF/seh-section-2.s (added)
+++ llvm/trunk/test/MC/COFF/seh-section-2.s Mon May  2 18:22:18 2016
@@ -0,0 +1,154 @@
+# RUN: llvm-mc -filetype=obj -triple x86_64-pc-win32 %s | llvm-readobj -symbols | FileCheck %s
+
+# This assembly should make an object with two .text sections, two .xdata
+# sections, and two .pdata sections.
+
+        .def     f;
+        .scl    2;
+        .type   32;
+        .endef
+        .section        .text,"xr",discard,f
+        .globl  f
+        .p2align        4, 0x90
+f:                                      # @f
+.Ltmp0:
+.seh_proc f
+# BB#0:
+        subq    $40, %rsp
+.Ltmp1:
+        .seh_stackalloc 40
+.Ltmp2:
+        .seh_endprologue
+        callq   g
+        nop
+        addq    $40, %rsp
+        retq
+        .seh_handlerdata
+        .section        .text,"xr",discard,f
+.Ltmp3:
+        .seh_endproc
+
+        .def     g;
+        .scl    3;
+        .type   32;
+        .endef
+        .section        .text,"xr",associative,f
+        .p2align        4, 0x90
+g:                                      # @g
+.Ltmp4:
+.seh_proc g
+# BB#0:
+.Ltmp5:
+        .seh_endprologue
+        retq
+        .seh_handlerdata
+        .section        .text,"xr",associative,f
+.Ltmp6:
+        .seh_endproc
+
+
+# CHECK: Symbols [
+# CHECK:   Symbol {
+# CHECK:     Name: .text
+# CHECK:     Section: .text (4)
+# CHECK:     AuxSymbolCount: 1
+# CHECK:     AuxSectionDef {
+# CHECK:       Length: 15
+# CHECK:       RelocationCount: 1
+# CHECK:       LineNumberCount: 0
+# CHECK:       Checksum: 0xE17CBB7
+# CHECK:       Number: 4
+# CHECK:       Selection: Any (0x2)
+# CHECK:     }
+# CHECK:   }
+# CHECK:   Symbol {
+# CHECK:     Name: .xdata
+# CHECK:     Value: 0
+# CHECK:     Section: .xdata (5)
+# CHECK:     BaseType: Null (0x0)
+# CHECK:     ComplexType: Null (0x0)
+# CHECK:     StorageClass: Static (0x3)
+# CHECK:     AuxSymbolCount: 1
+# CHECK:     AuxSectionDef {
+# CHECK:       Length: 8
+# CHECK:       RelocationCount: 0
+# CHECK:       LineNumberCount: 0
+# CHECK:       Checksum: 0xFC539D1
+# CHECK:       Number: 4
+# CHECK:       Selection: Associative (0x5)
+# CHECK:       AssocSection: .text (4)
+# CHECK:     }
+# CHECK:   }
+# CHECK:   Symbol {
+# CHECK:     Name: .text
+# CHECK:     Value: 0
+# CHECK:     Section: .text (6)
+# CHECK:     BaseType: Null (0x0)
+# CHECK:     ComplexType: Null (0x0)
+# CHECK:     StorageClass: Static (0x3)
+# CHECK:     AuxSymbolCount: 1
+# CHECK:     AuxSectionDef {
+# CHECK:       Length: 1
+# CHECK:       RelocationCount: 0
+# CHECK:       LineNumberCount: 0
+# CHECK:       Checksum: 0x26D930A
+# CHECK:       Number: 4
+# CHECK:       Selection: Associative (0x5)
+# CHECK:       AssocSection: .text (4)
+# CHECK:     }
+# CHECK:   }
+# CHECK:   Symbol {
+# CHECK:     Name: .xdata
+# CHECK:     Value: 0
+# CHECK:     Section: .xdata (7)
+# CHECK:     BaseType: Null (0x0)
+# CHECK:     ComplexType: Null (0x0)
+# CHECK:     StorageClass: Static (0x3)
+# CHECK:     AuxSymbolCount: 1
+# CHECK:     AuxSectionDef {
+# CHECK:       Length: 8
+# CHECK:       RelocationCount: 0
+# CHECK:       LineNumberCount: 0
+# CHECK:       Checksum: 0xCCAA009E
+# CHECK:       Number: 4
+# CHECK:       Selection: Associative (0x5)
+# CHECK:       AssocSection: .text (4)
+# CHECK:     }
+# CHECK:   }
+# CHECK:   Symbol {
+# CHECK:     Name: .pdata
+# CHECK:     Value: 0
+# CHECK:     Section: .pdata (8)
+# CHECK:     BaseType: Null (0x0)
+# CHECK:     ComplexType: Null (0x0)
+# CHECK:     StorageClass: Static (0x3)
+# CHECK:     AuxSymbolCount: 1
+# CHECK:     AuxSectionDef {
+# CHECK:       Length: 12
+# CHECK:       RelocationCount: 3
+# CHECK:       LineNumberCount: 0
+# CHECK:       Checksum: 0xD92012AC
+# CHECK:       Number: 4
+# CHECK:       Selection: Associative (0x5)
+# CHECK:       AssocSection: .text (4)
+# CHECK:     }
+# CHECK:   }
+# CHECK:   Symbol {
+# CHECK:     Name: .pdata
+# CHECK:     Value: 0
+# CHECK:     Section: .pdata (9)
+# CHECK:     BaseType: Null (0x0)
+# CHECK:     ComplexType: Null (0x0)
+# CHECK:     StorageClass: Static (0x3)
+# CHECK:     AuxSymbolCount: 1
+# CHECK:     AuxSectionDef {
+# CHECK:       Length: 12
+# CHECK:       RelocationCount: 3
+# CHECK:       LineNumberCount: 0
+# CHECK:       Checksum: 0xCCAA009E
+# CHECK:       Number: 4
+# CHECK:       Selection: Associative (0x5)
+# CHECK:       AssocSection: .text (4)
+# CHECK:     }
+# CHECK:   }
+# CHECK: ]

Modified: llvm/trunk/test/MC/COFF/seh-section.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/seh-section.s?rev=268331&r1=268330&r2=268331&view=diff
==============================================================================
--- llvm/trunk/test/MC/COFF/seh-section.s (original)
+++ llvm/trunk/test/MC/COFF/seh-section.s Mon May  2 18:22:18 2016
@@ -1,10 +1,8 @@
 // This test ensures functions in custom sections get unwind info emitted in a
-// distinct .xdata section. Ideally we'd just emit a second .xdata section with
-// the same name and characteristics, but MC uniques sections by name and
-// characteristics, so that is not possible.
+// distinct .xdata section.
 // RUN: llvm-mc -filetype=obj -triple x86_64-pc-win32 %s | llvm-readobj -s -sd | FileCheck %s
 
-// CHECK:      Name: .xdata$foo
+// CHECK:      Name: .xdata
 // CHECK-NEXT: VirtualSize
 // CHECK-NEXT: VirtualAddress
 // CHECK-NEXT: RawDataSize: 8
@@ -22,7 +20,7 @@
 // CHECK-NEXT:   0000: 01050200 05500402
 // CHECK-NEXT: )
 
-// CHECK:      Name: .xdata$.mytext
+// CHECK:      Name: .xdata
 // CHECK-NEXT: VirtualSize
 // CHECK-NEXT: VirtualAddress
 // CHECK-NEXT: RawDataSize: 8




More information about the llvm-commits mailing list