summaryrefslogtreecommitdiff
path: root/lib/MC
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2016-05-02 23:22:18 +0000
committerReid Kleckner <rnk@google.com>2016-05-02 23:22:18 +0000
commit7f90dd23539d7e18d826451605cceb142ea15575 (patch)
tree9744625aa268b3713c72de66ffd05b171712fe3a /lib/MC
parentcde8f4fdcc39b26ab2b63b63bf876fa4e72d394c (diff)
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268331 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/MCAsmStreamer.cpp4
-rw-r--r--lib/MC/MCContext.cpp33
-rw-r--r--lib/MC/MCStreamer.cpp36
-rw-r--r--lib/MC/MCWin64EH.cpp30
-rw-r--r--lib/MC/MCWinEH.cpp55
5 files changed, 72 insertions, 86 deletions
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index 506aa70056a..c47ef73e718 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -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";
diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp
index 48dd89f0d38..67463e583d7 100644
--- a/lib/MC/MCContext.cpp
+++ b/lib/MC/MCContext.cpp
@@ -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) {
diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp
index 896318d88f0..59bbc2ece1d 100644
--- a/lib/MC/MCStreamer.cpp
+++ b/lib/MC/MCStreamer.cpp
@@ -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(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) {
diff --git a/lib/MC/MCWin64EH.cpp b/lib/MC/MCWin64EH.cpp
index 1b73b7afb6a..fdc4c10cd6c 100644
--- a/lib/MC/MCWin64EH.cpp
+++ b/lib/MC/MCWin64EH.cpp
@@ -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
diff --git a/lib/MC/MCWinEH.cpp b/lib/MC/MCWinEH.cpp
index 83af203c7ac..21a913999f6 100644
--- a/lib/MC/MCWinEH.cpp
+++ b/lib/MC/MCWinEH.cpp
@@ -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() {}
}
}