[llvm] r217176 - MC Win64: Put unwind info for COMDAT code into the same COMDAT group
Reid Kleckner
reid at kleckner.net
Thu Sep 4 10:42:03 PDT 2014
Author: rnk
Date: Thu Sep 4 12:42:03 2014
New Revision: 217176
URL: http://llvm.org/viewvc/llvm-project?rev=217176&view=rev
Log:
MC Win64: Put unwind info for COMDAT code into the same COMDAT group
Summary:
This fixes a long standing issue where we would emit many little .text
sections and only one .pdata and .xdata section. Now we generate one
.pdata / .xdata pair per .text section and associate them correctly.
Fixes PR19667.
Reviewers: majnemer
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D5181
Added:
llvm/trunk/test/MC/COFF/seh-linkonce.s
Modified:
llvm/trunk/include/llvm/MC/MCContext.h
llvm/trunk/include/llvm/MC/MCWinEH.h
llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
llvm/trunk/lib/MC/MCAsmStreamer.cpp
llvm/trunk/lib/MC/MCContext.cpp
llvm/trunk/lib/MC/MCWin64EH.cpp
llvm/trunk/lib/MC/MCWinEH.cpp
Modified: llvm/trunk/include/llvm/MC/MCContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCContext.h?rev=217176&r1=217175&r2=217176&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCContext.h (original)
+++ llvm/trunk/include/llvm/MC/MCContext.h Thu Sep 4 12:42:03 2014
@@ -284,6 +284,13 @@ namespace llvm {
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
Modified: llvm/trunk/include/llvm/MC/MCWinEH.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCWinEH.h?rev=217176&r1=217175&r2=217176&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCWinEH.h (original)
+++ llvm/trunk/include/llvm/MC/MCWinEH.h Thu Sep 4 12:42:03 2014
@@ -65,9 +65,10 @@ struct FrameInfo {
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() { }
Modified: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=217176&r1=217175&r2=217176&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Thu Sep 4 12:42:03 2014
@@ -967,29 +967,14 @@ emitModuleFlags(MCStreamer &Streamer,
}
}
-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<MCSectionCOFF>(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<MCSectionCOFF>(StaticCtorSection), KeySym);
}
const MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
unsigned Priority, const MCSymbol *KeySym) const {
- return getAssociativeCOFFSection(getContext(), StaticDtorSection, KeySym);
+ return getContext().getAssociativeCOFFSection(
+ cast<MCSectionCOFF>(StaticDtorSection), KeySym);
}
Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=217176&r1=217175&r2=217176&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Thu Sep 4 12:42:03 2014
@@ -1095,9 +1095,8 @@ void MCAsmStreamer::EmitWinEHHandlerData
// 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";
Modified: llvm/trunk/lib/MC/MCContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCContext.cpp?rev=217176&r1=217175&r2=217176&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCContext.cpp (original)
+++ llvm/trunk/lib/MC/MCContext.cpp Thu Sep 4 12:42:03 2014
@@ -317,6 +317,22 @@ const MCSectionCOFF *MCContext::getCOFFS
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
//===----------------------------------------------------------------------===//
Modified: llvm/trunk/lib/MC/MCWin64EH.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCWin64EH.cpp?rev=217176&r1=217175&r2=217176&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCWin64EH.cpp (original)
+++ llvm/trunk/lib/MC/MCWin64EH.cpp Thu Sep 4 12:42:03 2014
@@ -225,7 +225,7 @@ void UnwindEmitter::Emit(MCStreamer &Str
// 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 @@ void UnwindEmitter::Emit(MCStreamer &Str
// 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 @@ void UnwindEmitter::EmitUnwindInfo(MCStr
// 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);
Modified: llvm/trunk/lib/MC/MCWinEH.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCWinEH.cpp?rev=217176&r1=217175&r2=217176&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCWinEH.cpp (original)
+++ llvm/trunk/lib/MC/MCWinEH.cpp Thu Sep 4 12:42:03 2014
@@ -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 @@ StringRef UnwindEmitter::GetSectionSuffi
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<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.
+ 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<MCSectionCOFF>(Context.getObjectFileInfo()->getPDataSection());
+ return getUnwindInfoSection(".pdata", PData, Function, Context);
+}
+
+const MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function,
+ MCContext &Context) {
+ const MCSectionCOFF *XData =
+ cast<MCSectionCOFF>(Context.getObjectFileInfo()->getXDataSection());
+ return getUnwindInfoSection(".xdata", XData, Function, Context);
+}
+
}
}
Added: llvm/trunk/test/MC/COFF/seh-linkonce.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/seh-linkonce.s?rev=217176&view=auto
==============================================================================
--- llvm/trunk/test/MC/COFF/seh-linkonce.s (added)
+++ llvm/trunk/test/MC/COFF/seh-linkonce.s Thu Sep 4 12:42:03 2014
@@ -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: ]
More information about the llvm-commits
mailing list