summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/TargetLoweringObjectFileImpl.h18
-rw-r--r--include/llvm/MC/MCWin64EH.h2
-rw-r--r--include/llvm/Target/TargetAsmInfo.h8
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h4
-rw-r--r--lib/MC/MCAsmStreamer.cpp4
-rw-r--r--lib/MC/MCWin64EH.cpp46
6 files changed, 60 insertions, 22 deletions
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index c61cf399f8..70a46759d7 100644
--- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -58,8 +58,10 @@ public:
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
virtual const MCSection *getEHFrameSection() const;
- virtual const MCSection *getWin64EHFuncTableSection() const { return NULL; }
- virtual const MCSection *getWin64EHTableSection() const { return NULL; }
+ virtual const MCSection *getWin64EHFuncTableSection(StringRef) const {
+ return NULL;
+ }
+ virtual const MCSection *getWin64EHTableSection(StringRef) const{return NULL;}
virtual void emitPersonalityValue(MCStreamer &Streamer,
const TargetMachine &TM,
@@ -135,8 +137,10 @@ public:
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
virtual const MCSection *getEHFrameSection() const;
- virtual const MCSection *getWin64EHFuncTableSection() const { return NULL; }
- virtual const MCSection *getWin64EHTableSection() const { return NULL; }
+ virtual const MCSection *getWin64EHFuncTableSection(StringRef) const {
+ return NULL;
+ }
+ virtual const MCSection *getWin64EHTableSection(StringRef) const{return NULL;}
virtual const MCSection *
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
@@ -209,10 +213,12 @@ public:
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
virtual const MCSection *getEHFrameSection() const;
- virtual const MCSection *getWin64EHFuncTableSection() const {
+ virtual const MCSection *getWin64EHFuncTableSection(StringRef) const {
return PDataSection;
}
- virtual const MCSection *getWin64EHTableSection() const {return XDataSection;}
+ virtual const MCSection *getWin64EHTableSection(StringRef) const {
+ return XDataSection;
+ }
virtual const MCSection *getDrectveSection() const { return DrectveSection; }
diff --git a/include/llvm/MC/MCWin64EH.h b/include/llvm/MC/MCWin64EH.h
index 5c0cfad7c3..eb4665a2e9 100644
--- a/include/llvm/MC/MCWin64EH.h
+++ b/include/llvm/MC/MCWin64EH.h
@@ -20,6 +20,7 @@
#include <vector>
namespace llvm {
+ class StringRef;
class MCStreamer;
class MCSymbol;
@@ -80,6 +81,7 @@ namespace llvm {
class MCWin64EHUnwindEmitter {
public:
+ static StringRef GetSectionSuffix(const MCSymbol *func);
//
// This emits the unwind info sections (.pdata and .xdata in PE/COFF).
//
diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h
index cd93c2ba0e..c30409d9f9 100644
--- a/include/llvm/Target/TargetAsmInfo.h
+++ b/include/llvm/Target/TargetAsmInfo.h
@@ -63,12 +63,12 @@ public:
return TLOF->getDwarfFrameSection();
}
- const MCSection *getWin64EHFuncTableSection() const {
- return TLOF->getWin64EHFuncTableSection();
+ const MCSection *getWin64EHFuncTableSection(StringRef Suffix) const {
+ return TLOF->getWin64EHFuncTableSection(Suffix);
}
- const MCSection *getWin64EHTableSection() const {
- return TLOF->getWin64EHTableSection();
+ const MCSection *getWin64EHTableSection(StringRef Suffix) const {
+ return TLOF->getWin64EHTableSection(Suffix);
}
unsigned getFDEEncoding(bool CFI) const {
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 78d49a96a6..3991035ce0 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -155,8 +155,8 @@ public:
const MCSection *getTLSExtraDataSection() const {
return TLSExtraDataSection;
}
- virtual const MCSection *getWin64EHFuncTableSection() const = 0;
- virtual const MCSection *getWin64EHTableSection() const = 0;
+ virtual const MCSection *getWin64EHFuncTableSection(StringRef suffix)const=0;
+ virtual const MCSection *getWin64EHTableSection(StringRef suffix) const = 0;
/// shouldEmitUsedDirectiveFor - This hook allows targets to selectively
/// decide not to emit the UsedDirective for some symbols in llvm.used.
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index 9376d55e71..ada3a70bf6 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -977,8 +977,10 @@ void MCAsmStreamer::EmitWin64EHHandlerData() {
// cause the section switch to be visible in the emitted assembly.
// We only do this so the section switch that terminates the handler
// data block is visible.
+ MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo();
+ StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function);
const MCSection *xdataSect =
- getContext().getTargetAsmInfo().getWin64EHTableSection();
+ getContext().getTargetAsmInfo().getWin64EHTableSection(suffix);
if (xdataSect)
SwitchSectionNoChange(xdataSect);
diff --git a/lib/MC/MCWin64EH.cpp b/lib/MC/MCWin64EH.cpp
index 018bb7cf6f..9453f5c2a9 100644
--- a/lib/MC/MCWin64EH.cpp
+++ b/lib/MC/MCWin64EH.cpp
@@ -10,6 +10,8 @@
#include "llvm/MC/MCWin64EH.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/Target/TargetAsmInfo.h"
@@ -199,13 +201,33 @@ static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info) {
}
}
+StringRef MCWin64EHUnwindEmitter::GetSectionSuffix(const MCSymbol *func) {
+ if (!func || !func->isInSection()) return "";
+ const MCSection *section = &func->getSection();
+ const MCSectionCOFF *COFFSection;
+ if ((COFFSection = dyn_cast<MCSectionCOFF>(section))) {
+ StringRef name = COFFSection->getSectionName();
+ size_t dollar = name.find('$');
+ size_t dot = name.find('.', 1);
+ if (dollar == StringRef::npos && dot == StringRef::npos)
+ return "";
+ if (dot == StringRef::npos)
+ return name.substr(dollar);
+ if (dollar == StringRef::npos || dot < dollar)
+ return name.substr(dot);
+ return name.substr(dollar);
+ }
+ return "";
+}
+
void MCWin64EHUnwindEmitter::EmitUnwindInfo(MCStreamer &streamer,
MCWin64EHUnwindInfo *info) {
// Switch sections (the static function above is meant to be called from
// here and from Emit().
MCContext &context = streamer.getContext();
const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
- const MCSection *xdataSect = asmInfo.getWin64EHTableSection();
+ const MCSection *xdataSect =
+ asmInfo.getWin64EHTableSection(GetSectionSuffix(info->Function));
streamer.SwitchSection(xdataSect);
llvm::EmitUnwindInfo(streamer, info);
@@ -215,15 +237,21 @@ void MCWin64EHUnwindEmitter::Emit(MCStreamer &streamer) {
MCContext &context = streamer.getContext();
// Emit the unwind info structs first.
const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
- const MCSection *xdataSect = asmInfo.getWin64EHTableSection();
- streamer.SwitchSection(xdataSect);
- for (unsigned i = 0; i < streamer.getNumW64UnwindInfos(); ++i)
- llvm::EmitUnwindInfo(streamer, &streamer.getW64UnwindInfo(i));
+ for (unsigned i = 0; i < streamer.getNumW64UnwindInfos(); ++i) {
+ MCWin64EHUnwindInfo &info = streamer.getW64UnwindInfo(i);
+ const MCSection *xdataSect =
+ asmInfo.getWin64EHTableSection(GetSectionSuffix(info.Function));
+ streamer.SwitchSection(xdataSect);
+ llvm::EmitUnwindInfo(streamer, &info);
+ }
// Now emit RUNTIME_FUNCTION entries.
- const MCSection *pdataSect = asmInfo.getWin64EHFuncTableSection();
- streamer.SwitchSection(pdataSect);
- for (unsigned i = 0; i < streamer.getNumW64UnwindInfos(); ++i)
- EmitRuntimeFunction(streamer, &streamer.getW64UnwindInfo(i));
+ for (unsigned i = 0; i < streamer.getNumW64UnwindInfos(); ++i) {
+ MCWin64EHUnwindInfo &info = streamer.getW64UnwindInfo(i);
+ const MCSection *pdataSect =
+ asmInfo.getWin64EHFuncTableSection(GetSectionSuffix(info.Function));
+ streamer.SwitchSection(pdataSect);
+ EmitRuntimeFunction(streamer, &info);
+ }
}
} // End of namespace llvm