]> granicus.if.org Git - llvm/commitdiff
[MC] Create unique .pdata sections for every .text section
authorReid Kleckner <rnk@google.com>
Mon, 2 May 2016 23:22:18 +0000 (23:22 +0000)
committerReid Kleckner <rnk@google.com>
Mon, 2 May 2016 23:22:18 +0000 (23:22 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268331 91177308-0d34-0410-b5e6-96231b3b80d8

14 files changed:
include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
include/llvm/MC/MCContext.h
include/llvm/MC/MCSectionCOFF.h
include/llvm/MC/MCStreamer.h
include/llvm/MC/MCWinEH.h
lib/CodeGen/AsmPrinter/WinException.cpp
lib/CodeGen/TargetLoweringObjectFileImpl.cpp
lib/MC/MCAsmStreamer.cpp
lib/MC/MCContext.cpp
lib/MC/MCStreamer.cpp
lib/MC/MCWin64EH.cpp
lib/MC/MCWinEH.cpp
test/MC/COFF/seh-section-2.s [new file with mode: 0644]
test/MC/COFF/seh-section.s

index 09ce5358380f986aba3d9d3af6c40e2e46d4fe75..c856435f5ddca48c0e9abfd6a4c3c891d88838bd 100644 (file)
@@ -140,6 +140,8 @@ public:
 
 
 class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
+  mutable unsigned NextUniqueID = 0;
+
 public:
   ~TargetLoweringObjectFileCOFF() override {}
 
index 44d195c1072e4da75605a5344258802b5217f993..98dd127c0c0baedd5fb5df38d23897ba68cf77ec 100644 (file)
@@ -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);
index d94682c8c381d866ac6b48496bfca0208af69406..c9fd8ea1605de0392280b4eafa09b7a54908cc5c 100644 (file)
@@ -32,6 +32,13 @@ class MCSectionCOFF final : public MCSection {
   /// 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; }
 };
 
index baaf20bdfa7916c3b180ea50c10031a5329f8274..adb30c7a2bc5b8fa0f955f113f5e05924cd968b8 100644 (file)
@@ -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.
index 723d7a397c496576d78a01034954724c16cdee76..4ca52a6654eb7f51ffd24ce82064d281d0935dc8 100644 (file)
 #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();
 
-  virtual ~UnwindEmitter() { }
-
-  //
-  // This emits the unwind info sections (.pdata and .xdata in PE/COFF).
-  //
+  /// 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;
 };
index 022c9a280bd29e4fab9cf416696f79b268316760..478396556d2757bf65c514b23505ced5a307a801 100644 (file)
@@ -124,10 +124,9 @@ void WinException::endFunction(const MachineFunction *MF) {
   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
index d540ea7d06f774fd2f169c716184de9c816b8354..bcede80b2369b2f8f09b2c88e7d5973647896e7b 100644 (file)
@@ -316,7 +316,7 @@ selectELFSectionForGlobal(MCContext &Ctx, const GlobalValue *GV,
     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::getExplicitSectionGlobal(
       Selection = 0;
     }
   }
-  return getContext().getCOFFSection(Name,
-                                     Characteristics,
-                                     Kind,
-                                     COMDATSymName,
+
+  return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName,
                                      Selection);
 }
 
@@ -968,16 +966,20 @@ MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal(
     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::getSectionForJumpTable(
   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(
index 506aa70056abafc3e603536c2a9e9615d9d76de1..c47ef73e7185e4815892a5a2749e1c19aaaba56d 100644 (file)
@@ -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";
index 48dd89f0d38224c3da72f31bd373fa30eb946de5..67463e583d732767c0336031ea9353f8e55d179d 100644 (file)
@@ -372,6 +372,7 @@ MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
                                          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(StringRef Section,
     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(StringRef Section,
                                          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(StringRef Section) {
 }
 
 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) {
index 896318d88f009f18aa48e13df9c26eb143ce31c2..59bbc2ece1d355a78ccf9ee7f8bdbc995ee2d74f 100644 (file)
 #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(const MCSymbol *Symbol) {
 
   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) {
index 1b73b7afb6a00ef28248b7792fad2759dfba2e68..fdc4c10cd6cef1815d071aeedcac58a3a11c301d 100644 (file)
@@ -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 &streamer, WinEH::FrameInfo *info) {
   }
 }
 
-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
 
index 83af203c7acb12e2d5b1557551f986343ec7ce57..21a913999f64eb408c7bd92c28d8e0045897ea8f 100644 (file)
 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() {}
 
 }
 }
diff --git a/test/MC/COFF/seh-section-2.s b/test/MC/COFF/seh-section-2.s
new file mode 100644 (file)
index 0000000..9a7156d
--- /dev/null
@@ -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: ]
index c95eece800bd90da3ae27c578d5723c2eed1591c..711b3eaccef2737e01f9ba5081acf12bbed76d2b 100644 (file)
@@ -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