Skip to content

Commit 97837b7

Browse files
committed
[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 llvm-svn: 268331
1 parent 9102fc2 commit 97837b7

File tree

14 files changed

+308
-144
lines changed

14 files changed

+308
-144
lines changed

llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
140140

141141

142142
class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
143+
mutable unsigned NextUniqueID = 0;
144+
143145
public:
144146
~TargetLoweringObjectFileCOFF() override {}
145147

llvm/include/llvm/MC/MCContext.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,16 +200,19 @@ namespace llvm {
200200
std::string SectionName;
201201
StringRef GroupName;
202202
int SelectionKey;
203+
unsigned UniqueID;
203204
COFFSectionKey(StringRef SectionName, StringRef GroupName,
204-
int SelectionKey)
205+
int SelectionKey, unsigned UniqueID)
205206
: SectionName(SectionName), GroupName(GroupName),
206-
SelectionKey(SelectionKey) {}
207+
SelectionKey(SelectionKey), UniqueID(UniqueID) {}
207208
bool operator<(const COFFSectionKey &Other) const {
208209
if (SectionName != Other.SectionName)
209210
return SectionName < Other.SectionName;
210211
if (GroupName != Other.GroupName)
211212
return GroupName < Other.GroupName;
212-
return SelectionKey < Other.SelectionKey;
213+
if (SelectionKey != Other.SelectionKey)
214+
return SelectionKey < Other.SelectionKey;
215+
return UniqueID < Other.UniqueID;
213216
}
214217
};
215218

@@ -315,6 +318,13 @@ namespace llvm {
315318
/// \name Section Management
316319
/// @{
317320

321+
enum : unsigned {
322+
/// Pass this value as the UniqueID during section creation to get the
323+
/// generic section with the given name and characteristics. The usual
324+
/// sections such as .text use this ID.
325+
GenericSectionID = ~0U
326+
};
327+
318328
/// Return the MCSection for the specified mach-o section. This requires
319329
/// the operands to be valid.
320330
MCSectionMachO *getMachOSection(StringRef Segment, StringRef Section,
@@ -382,6 +392,7 @@ namespace llvm {
382392
MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
383393
SectionKind Kind, StringRef COMDATSymName,
384394
int Selection,
395+
unsigned UniqueID = GenericSectionID,
385396
const char *BeginSymName = nullptr);
386397

387398
MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
@@ -394,8 +405,9 @@ namespace llvm {
394405
/// section containing KeySym. For example, to create a debug info section
395406
/// associated with an inline function, pass the normal debug info section
396407
/// as Sec and the function symbol as KeySym.
397-
MCSectionCOFF *getAssociativeCOFFSection(MCSectionCOFF *Sec,
398-
const MCSymbol *KeySym);
408+
MCSectionCOFF *
409+
getAssociativeCOFFSection(MCSectionCOFF *Sec, const MCSymbol *KeySym,
410+
unsigned UniqueID = GenericSectionID);
399411

400412
// Create and save a copy of STI and return a reference to the copy.
401413
MCSubtargetInfo &getSubtargetCopy(const MCSubtargetInfo &STI);

llvm/include/llvm/MC/MCSectionCOFF.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ class MCSectionCOFF final : public MCSection {
3232
/// below.
3333
mutable unsigned Characteristics;
3434

35+
/// The unique IDs used with the .pdata and .xdata sections created internally
36+
/// by the assembler. This ID is used to ensure that for every .text section,
37+
/// there is exactly one .pdata and one .xdata section, which is required by
38+
/// the Microsoft incremental linker. This data is mutable because this ID is
39+
/// not notionally part of the section.
40+
mutable unsigned WinCFISectionID = ~0U;
41+
3542
/// The COMDAT symbol of this section. Only valid if this is a COMDAT section.
3643
/// Two COMDAT sections are merged if they have the same COMDAT symbol.
3744
MCSymbol *COMDATSymbol;
@@ -71,6 +78,12 @@ class MCSectionCOFF final : public MCSection {
7178
bool UseCodeAlign() const override;
7279
bool isVirtualSection() const override;
7380

81+
unsigned getOrAssignWinCFISectionID(unsigned *NextID) const {
82+
if (WinCFISectionID == ~0U)
83+
WinCFISectionID = (*NextID)++;
84+
return WinCFISectionID;
85+
}
86+
7487
static bool classof(const MCSection *S) { return S->getVariant() == SV_COFF; }
7588
};
7689

llvm/include/llvm/MC/MCStreamer.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,12 @@ class MCStreamer {
183183
/// PushSection.
184184
SmallVector<std::pair<MCSectionSubPair, MCSectionSubPair>, 4> SectionStack;
185185

186+
/// The next unique ID to use when creating a WinCFI-related section (.pdata
187+
/// or .xdata). This ID ensures that we have a one-to-one mapping from
188+
/// code section to unwind info section, which MSVC's incremental linker
189+
/// requires.
190+
unsigned NextWinCFIID = 0;
191+
186192
protected:
187193
MCStreamer(MCContext &Ctx);
188194

@@ -720,6 +726,14 @@ class MCStreamer {
720726
virtual void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except);
721727
virtual void EmitWinEHHandlerData();
722728

729+
/// Get the .pdata section used for the given section. Typically the given
730+
/// section is either the main .text section or some other COMDAT .text
731+
/// section, but it may be any section containing code.
732+
MCSection *getAssociatedPDataSection(const MCSection *TextSec);
733+
734+
/// Get the .xdata section used for the given section.
735+
MCSection *getAssociatedXDataSection(const MCSection *TextSec);
736+
723737
virtual void EmitSyntaxDirective();
724738

725739
/// \brief Emit a .reloc directive.

llvm/include/llvm/MC/MCWinEH.h

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,9 @@
1313
#include <vector>
1414

1515
namespace llvm {
16-
class MCContext;
1716
class MCSection;
1817
class MCStreamer;
1918
class MCSymbol;
20-
class StringRef;
2119

2220
namespace WinEH {
2321
struct Instruction {
@@ -31,50 +29,35 @@ struct Instruction {
3129
};
3230

3331
struct FrameInfo {
34-
const MCSymbol *Begin;
35-
const MCSymbol *End;
36-
const MCSymbol *ExceptionHandler;
37-
const MCSymbol *Function;
38-
const MCSymbol *PrologEnd;
39-
const MCSymbol *Symbol;
32+
const MCSymbol *Begin = nullptr;
33+
const MCSymbol *End = nullptr;
34+
const MCSymbol *ExceptionHandler = nullptr;
35+
const MCSymbol *Function = nullptr;
36+
const MCSymbol *PrologEnd = nullptr;
37+
const MCSymbol *Symbol = nullptr;
38+
const MCSection *TextSection = nullptr;
4039

41-
bool HandlesUnwind;
42-
bool HandlesExceptions;
40+
bool HandlesUnwind = false;
41+
bool HandlesExceptions = false;
4342

44-
int LastFrameInst;
45-
const FrameInfo *ChainedParent;
43+
int LastFrameInst = -1;
44+
const FrameInfo *ChainedParent = nullptr;
4645
std::vector<Instruction> Instructions;
4746

48-
FrameInfo()
49-
: Begin(nullptr), End(nullptr), ExceptionHandler(nullptr),
50-
Function(nullptr), PrologEnd(nullptr), Symbol(nullptr),
51-
HandlesUnwind(false), HandlesExceptions(false), LastFrameInst(-1),
52-
ChainedParent(nullptr), Instructions() {}
47+
FrameInfo() = default;
5348
FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel)
54-
: Begin(BeginFuncEHLabel), End(nullptr), ExceptionHandler(nullptr),
55-
Function(Function), PrologEnd(nullptr), Symbol(nullptr),
56-
HandlesUnwind(false), HandlesExceptions(false), LastFrameInst(-1),
57-
ChainedParent(nullptr), Instructions() {}
49+
: Begin(BeginFuncEHLabel), Function(Function) {}
5850
FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel,
5951
const FrameInfo *ChainedParent)
60-
: Begin(BeginFuncEHLabel), End(nullptr), ExceptionHandler(nullptr),
61-
Function(Function), PrologEnd(nullptr), Symbol(nullptr),
62-
HandlesUnwind(false), HandlesExceptions(false), LastFrameInst(-1),
63-
ChainedParent(ChainedParent), Instructions() {}
52+
: Begin(BeginFuncEHLabel), Function(Function),
53+
ChainedParent(ChainedParent) {}
6454
};
6555

6656
class UnwindEmitter {
6757
public:
68-
static MCSection *getPDataSection(const MCSymbol *Function,
69-
MCContext &Context);
70-
static MCSection *getXDataSection(const MCSymbol *Function,
71-
MCContext &Context);
58+
virtual ~UnwindEmitter();
7259

73-
virtual ~UnwindEmitter() { }
74-
75-
//
76-
// This emits the unwind info sections (.pdata and .xdata in PE/COFF).
77-
//
60+
/// This emits the unwind info sections (.pdata and .xdata in PE/COFF).
7861
virtual void Emit(MCStreamer &Streamer) const = 0;
7962
virtual void EmitUnwindInfo(MCStreamer &Streamer, FrameInfo *FI) const = 0;
8063
};

llvm/lib/CodeGen/AsmPrinter/WinException.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,9 @@ void WinException::endFunction(const MachineFunction *MF) {
124124
if (shouldEmitPersonality || shouldEmitLSDA) {
125125
Asm->OutStreamer->PushSection();
126126

127-
// Just switch sections to the right xdata section. This use of CurrentFnSym
128-
// assumes that we only emit the LSDA when ending the parent function.
129-
MCSection *XData = WinEH::UnwindEmitter::getXDataSection(Asm->CurrentFnSym,
130-
Asm->OutContext);
127+
// Just switch sections to the right xdata section.
128+
MCSection *XData = Asm->OutStreamer->getAssociatedXDataSection(
129+
Asm->OutStreamer->getCurrentSectionOnly());
131130
Asm->OutStreamer->SwitchSection(XData);
132131

133132
// Emit the tables appropriate to the personality function in use. If we

llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ selectELFSectionForGlobal(MCContext &Ctx, const GlobalValue *GV,
316316
Name.push_back('.');
317317
TM.getNameWithPrefix(Name, GV, Mang, true);
318318
}
319-
unsigned UniqueID = ~0;
319+
unsigned UniqueID = MCContext::GenericSectionID;
320320
if (EmitUniqueSection && !UniqueSectionNames) {
321321
UniqueID = *NextUniqueID;
322322
(*NextUniqueID)++;
@@ -924,10 +924,8 @@ MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal(
924924
Selection = 0;
925925
}
926926
}
927-
return getContext().getCOFFSection(Name,
928-
Characteristics,
929-
Kind,
930-
COMDATSymName,
927+
928+
return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName,
931929
Selection);
932930
}
933931

@@ -968,16 +966,20 @@ MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal(
968966
else
969967
ComdatGV = GV;
970968

969+
unsigned UniqueID = MCContext::GenericSectionID;
970+
if (EmitUniquedSection)
971+
UniqueID = NextUniqueID++;
972+
971973
if (!ComdatGV->hasPrivateLinkage()) {
972974
MCSymbol *Sym = TM.getSymbol(ComdatGV, Mang);
973975
StringRef COMDATSymName = Sym->getName();
974976
return getContext().getCOFFSection(Name, Characteristics, Kind,
975-
COMDATSymName, Selection);
977+
COMDATSymName, Selection, UniqueID);
976978
} else {
977979
SmallString<256> TmpData;
978980
Mang.getNameWithPrefix(TmpData, GV, /*CannotUsePrivateLabel=*/true);
979981
return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData,
980-
Selection);
982+
Selection, UniqueID);
981983
}
982984
}
983985

@@ -1031,9 +1033,10 @@ MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable(
10311033
const char *Name = getCOFFSectionNameForUniqueGlobal(Kind);
10321034
unsigned Characteristics = getCOFFSectionFlags(Kind);
10331035
Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
1036+
unsigned UniqueID = NextUniqueID++;
10341037

10351038
return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName,
1036-
COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE);
1039+
COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
10371040
}
10381041

10391042
void TargetLoweringObjectFileCOFF::
@@ -1068,13 +1071,13 @@ emitModuleFlags(MCStreamer &Streamer,
10681071
MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection(
10691072
unsigned Priority, const MCSymbol *KeySym) const {
10701073
return getContext().getAssociativeCOFFSection(
1071-
cast<MCSectionCOFF>(StaticCtorSection), KeySym);
1074+
cast<MCSectionCOFF>(StaticCtorSection), KeySym, 0);
10721075
}
10731076

10741077
MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
10751078
unsigned Priority, const MCSymbol *KeySym) const {
10761079
return getContext().getAssociativeCOFFSection(
1077-
cast<MCSectionCOFF>(StaticDtorSection), KeySym);
1080+
cast<MCSectionCOFF>(StaticDtorSection), KeySym, 0);
10781081
}
10791082

10801083
void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal(

llvm/lib/MC/MCAsmStreamer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,8 +1288,8 @@ void MCAsmStreamer::EmitWinEHHandlerData() {
12881288
// We only do this so the section switch that terminates the handler
12891289
// data block is visible.
12901290
WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
1291-
MCSection *XData =
1292-
WinEH::UnwindEmitter::getXDataSection(CurFrame->Function, getContext());
1291+
MCSection *TextSec = &CurFrame->Function->getSection();
1292+
MCSection *XData = getAssociatedXDataSection(TextSec);
12931293
SwitchSectionNoChange(XData);
12941294

12951295
OS << "\t.seh_handlerdata";

llvm/lib/MC/MCContext.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -372,15 +372,17 @@ MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
372372
unsigned Characteristics,
373373
SectionKind Kind,
374374
StringRef COMDATSymName, int Selection,
375+
unsigned UniqueID,
375376
const char *BeginSymName) {
376377
MCSymbol *COMDATSymbol = nullptr;
377378
if (!COMDATSymName.empty()) {
378379
COMDATSymbol = getOrCreateSymbol(COMDATSymName);
379380
COMDATSymName = COMDATSymbol->getName();
380381
}
381382

383+
382384
// Do the lookup, if we have a hit, return it.
383-
COFFSectionKey T{Section, COMDATSymName, Selection};
385+
COFFSectionKey T{Section, COMDATSymName, Selection, UniqueID};
384386
auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr));
385387
auto Iter = IterBool.first;
386388
if (!IterBool.second)
@@ -402,30 +404,37 @@ MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
402404
unsigned Characteristics,
403405
SectionKind Kind,
404406
const char *BeginSymName) {
405-
return getCOFFSection(Section, Characteristics, Kind, "", 0, BeginSymName);
407+
return getCOFFSection(Section, Characteristics, Kind, "", 0, GenericSectionID,
408+
BeginSymName);
406409
}
407410

408411
MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
409-
COFFSectionKey T{Section, "", 0};
412+
COFFSectionKey T{Section, "", 0, GenericSectionID};
410413
auto Iter = COFFUniquingMap.find(T);
411414
if (Iter == COFFUniquingMap.end())
412415
return nullptr;
413416
return Iter->second;
414417
}
415418

416419
MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec,
417-
const MCSymbol *KeySym) {
418-
// Return the normal section if we don't have to be associative.
419-
if (!KeySym)
420+
const MCSymbol *KeySym,
421+
unsigned UniqueID) {
422+
// Return the normal section if we don't have to be associative or unique.
423+
if (!KeySym && UniqueID == GenericSectionID)
420424
return Sec;
421425

422-
// Make an associative section with the same name and kind as the normal
423-
// section.
424-
unsigned Characteristics =
425-
Sec->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT;
426+
// If we have a key symbol, make an associative section with the same name and
427+
// kind as the normal section.
428+
unsigned Characteristics = Sec->getCharacteristics();
429+
if (KeySym) {
430+
Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
431+
return getCOFFSection(Sec->getSectionName(), Characteristics,
432+
Sec->getKind(), KeySym->getName(),
433+
COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
434+
}
435+
426436
return getCOFFSection(Sec->getSectionName(), Characteristics, Sec->getKind(),
427-
KeySym->getName(),
428-
COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE);
437+
"", 0, UniqueID);
429438
}
430439

431440
MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {

0 commit comments

Comments
 (0)