diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index c61cf399f82..70a46759d70 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 5c0cfad7c36..eb4665a2e99 100644 --- a/include/llvm/MC/MCWin64EH.h +++ b/include/llvm/MC/MCWin64EH.h @@ -20,6 +20,7 @@ #include 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 cd93c2ba0e8..c30409d9f98 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 78d49a96a6a..3991035ce06 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 9376d55e717..ada3a70bf65 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 018bb7cf6f8..9453f5c2a96 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(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