Index: llvm/trunk/include/llvm/MC/MCContext.h =================================================================== --- llvm/trunk/include/llvm/MC/MCContext.h +++ llvm/trunk/include/llvm/MC/MCContext.h @@ -284,6 +284,13 @@ const MCSectionCOFF *getCOFFSection(StringRef Section); + /// Gets or creates a section equivalent to Sec that is associated with the + /// 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. + const MCSectionCOFF *getAssociativeCOFFSection(const MCSectionCOFF *Sec, + const MCSymbol *KeySym); + /// @} /// @name Dwarf Management Index: llvm/trunk/include/llvm/MC/MCWinEH.h =================================================================== --- llvm/trunk/include/llvm/MC/MCWinEH.h +++ llvm/trunk/include/llvm/MC/MCWinEH.h @@ -65,9 +65,10 @@ class UnwindEmitter { public: - static StringRef GetSectionSuffix(const MCSymbol *Function); - static const MCSection *GetPDataSection(StringRef Suffix, MCContext &Context); - static const MCSection *GetXDataSection(StringRef Suffix, MCContext &Context); + static const MCSection *getPDataSection(const MCSymbol *Function, + MCContext &Context); + static const MCSection *getXDataSection(const MCSymbol *Function, + MCContext &Context); virtual ~UnwindEmitter() { } Index: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp =================================================================== --- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -967,29 +967,14 @@ } } -static const MCSection *getAssociativeCOFFSection(MCContext &Ctx, - const MCSection *Sec, - const MCSymbol *KeySym) { - // Return the normal section if we don't have to be associative. - if (!KeySym) - return Sec; - - // Make an associative section with the same name and kind as the normal - // section. - const MCSectionCOFF *SecCOFF = cast(Sec); - unsigned Characteristics = - SecCOFF->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT; - return Ctx.getCOFFSection(SecCOFF->getSectionName(), Characteristics, - SecCOFF->getKind(), KeySym->getName(), - COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE); -} - const MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection( unsigned Priority, const MCSymbol *KeySym) const { - return getAssociativeCOFFSection(getContext(), StaticCtorSection, KeySym); + return getContext().getAssociativeCOFFSection( + cast(StaticCtorSection), KeySym); } const MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( unsigned Priority, const MCSymbol *KeySym) const { - return getAssociativeCOFFSection(getContext(), StaticDtorSection, KeySym); + return getContext().getAssociativeCOFFSection( + cast(StaticDtorSection), KeySym); } Index: llvm/trunk/lib/MC/MCAsmStreamer.cpp =================================================================== --- llvm/trunk/lib/MC/MCAsmStreamer.cpp +++ llvm/trunk/lib/MC/MCAsmStreamer.cpp @@ -1095,9 +1095,8 @@ // We only do this so the section switch that terminates the handler // data block is visible. WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo(); - StringRef Suffix = WinEH::UnwindEmitter::GetSectionSuffix(CurFrame->Function); - if (const MCSection *XData = - WinEH::UnwindEmitter::GetXDataSection(Suffix, getContext())) + if (const MCSection *XData = WinEH::UnwindEmitter::getXDataSection( + CurFrame->Function, getContext())) SwitchSectionNoChange(XData); OS << "\t.seh_handlerdata"; Index: llvm/trunk/lib/MC/MCContext.cpp =================================================================== --- llvm/trunk/lib/MC/MCContext.cpp +++ llvm/trunk/lib/MC/MCContext.cpp @@ -317,6 +317,22 @@ return Iter->second; } +const MCSectionCOFF * +MCContext::getAssociativeCOFFSection(const MCSectionCOFF *Sec, + const MCSymbol *KeySym) { + // Return the normal section if we don't have to be associative. + if (!KeySym) + 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; + return getCOFFSection(Sec->getSectionName(), Characteristics, Sec->getKind(), + KeySym->getName(), + COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE); +} + //===----------------------------------------------------------------------===// // Dwarf Management //===----------------------------------------------------------------------===// Index: llvm/trunk/lib/MC/MCWin64EH.cpp =================================================================== --- llvm/trunk/lib/MC/MCWin64EH.cpp +++ llvm/trunk/lib/MC/MCWin64EH.cpp @@ -225,7 +225,7 @@ // Emit the unwind info structs first. for (const auto &CFI : Streamer.getWinFrameInfos()) { const MCSection *XData = - GetXDataSection(GetSectionSuffix(CFI->Function), Context); + getXDataSection(CFI->Function, Context); Streamer.SwitchSection(XData); EmitUnwindInfo(Streamer, CFI); } @@ -233,7 +233,7 @@ // Now emit RUNTIME_FUNCTION entries. for (const auto &CFI : Streamer.getWinFrameInfos()) { const MCSection *PData = - GetPDataSection(GetSectionSuffix(CFI->Function), Context); + getPDataSection(CFI->Function, Context); Streamer.SwitchSection(PData); EmitRuntimeFunction(Streamer, CFI); } @@ -245,7 +245,7 @@ // here and from Emit(). MCContext &context = Streamer.getContext(); const MCSection *xdataSect = - GetXDataSection(GetSectionSuffix(info->Function), context); + getXDataSection(info->Function, context); Streamer.SwitchSection(xdataSect); llvm::EmitUnwindInfo(Streamer, info); Index: llvm/trunk/lib/MC/MCWinEH.cpp =================================================================== --- llvm/trunk/lib/MC/MCWinEH.cpp +++ llvm/trunk/lib/MC/MCWinEH.cpp @@ -17,27 +17,7 @@ namespace llvm { namespace WinEH { -const MCSection *UnwindEmitter::GetPDataSection(StringRef Suffix, - MCContext &Context) { - if (Suffix.empty()) - return Context.getObjectFileInfo()->getPDataSection(); - return Context.getCOFFSection((".pdata" + Suffix).str(), - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getDataRel()); -} - -const MCSection *UnwindEmitter::GetXDataSection(StringRef Suffix, - MCContext &Context) { - if (Suffix.empty()) - return Context.getObjectFileInfo()->getXDataSection(); - return Context.getCOFFSection((".xdata" + Suffix).str(), - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getDataRel()); -} - -StringRef UnwindEmitter::GetSectionSuffix(const MCSymbol *Function) { +static StringRef getSectionSuffix(const MCSymbol *Function) { if (!Function || !Function->isInSection()) return ""; @@ -59,6 +39,46 @@ return ""; } + +static const MCSection *getUnwindInfoSection( + StringRef SecName, const MCSectionCOFF *UnwindSec, const MCSymbol *Function, + MCContext &Context) { + // If Function is in a COMDAT, get or create an unwind info section in that + // COMDAT group. + if (Function && Function->isInSection()) { + const MCSectionCOFF *FunctionSection = + cast(&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. + StringRef Suffix = getSectionSuffix(Function); + if (Suffix.empty()) + return UnwindSec; + return Context.getCOFFSection((SecName + Suffix).str(), + COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getDataRel()); +} + +const MCSection *UnwindEmitter::getPDataSection(const MCSymbol *Function, + MCContext &Context) { + const MCSectionCOFF *PData = + cast(Context.getObjectFileInfo()->getPDataSection()); + return getUnwindInfoSection(".pdata", PData, Function, Context); +} + +const MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function, + MCContext &Context) { + const MCSectionCOFF *XData = + cast(Context.getObjectFileInfo()->getXDataSection()); + return getUnwindInfoSection(".xdata", XData, Function, Context); +} + } } Index: llvm/trunk/test/MC/COFF/seh-linkonce.s =================================================================== --- llvm/trunk/test/MC/COFF/seh-linkonce.s +++ llvm/trunk/test/MC/COFF/seh-linkonce.s @@ -0,0 +1,85 @@ +// RUN: llvm-mc -triple x86_64-pc-win32 -filetype=obj %s | llvm-readobj -sections -section-symbols | FileCheck %s + + .text + .def weak_func; + .scl 2; + .type 32; + .endef + .section .text,"xr",discard,weak_func + .globl weak_func + .align 16, 0x90 +weak_func: # @weak_func +.Ltmp0: +.seh_proc weak_func +# BB#0: # %entry + pushq %rbp +.Ltmp1: + .seh_pushreg 5 + movq %rsp, %rbp +.Ltmp2: + .seh_setframe 5, 0 +.Ltmp3: + .seh_endprologue + xorl %eax, %eax + popq %rbp + retq +.Leh_func_end0: +.Ltmp4: + .seh_endproc + +// CHECK: Sections [ +// CHECK: Section { +// CHECK: Name: .text +// CHECK: } +// CHECK: Section { +// CHECK: Name: .data +// CHECK: } +// CHECK: Section { +// CHECK: Name: .bss +// CHECK: } +// CHECK: Section { +// CHECK: Number: [[TEXT_SECNUM:[0-9]+]] +// CHECK: Name: .text +// CHECK: Characteristics [ +// CHECK: IMAGE_SCN_LNK_COMDAT +// CHECK: ] +// CHECK: } +// CHECK: Section { +// CHECK: Number: [[XDATA_SECNUM:[0-9]+]] +// CHECK: Name: .xdata +// CHECK: Characteristics [ +// CHECK: IMAGE_SCN_LNK_COMDAT +// CHECK: ] +// CHECK: Symbols [ +// CHECK: Symbol { +// CHECK: Name: .xdata +// CHECK: Section: .xdata ([[XDATA_SECNUM]]) +// CHECK: StorageClass: Static (0x3) +// CHECK: AuxSymbolCount: 1 +// CHECK: AuxSectionDef { +// CHECK: Selection: Associative (0x5) +// CHECK: AssocSection: .text ([[TEXT_SECNUM]]) +// CHECK: } +// CHECK: } +// CHECK: ] +// CHECK: } +// CHECK: Section { +// CHECK: Number: [[PDATA_SECNUM:[0-9]+]] +// CHECK: Name: .pdata +// CHECK: Characteristics [ +// CHECK: IMAGE_SCN_LNK_COMDAT +// CHECK: ] +// CHECK: Symbols [ +// CHECK: Symbol { +// CHECK: Name: .pdata +// CHECK: Section: .pdata ([[PDATA_SECNUM]]) +// CHECK: StorageClass: Static (0x3) +// CHECK: AuxSymbolCount: 1 +// CHECK: AuxSectionDef { +// CHECK: Selection: Associative (0x5) +// CHECK: AssocSection: .text ([[TEXT_SECNUM]]) +// CHECK: } +// CHECK: } +// CHECK: ] +// CHECK: } +// CHECK: ]