Skip to content

[COFF] Preserve UniqueID used to create MCSectionCOFF #123869

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ class MCAsmParserExtension {

bool parseDirectiveCGProfile(StringRef, SMLoc);

bool maybeParseUniqueID(int64_t &UniqueID);

bool check(bool P, const Twine &Msg) {
return getParser().check(P, Msg);
}
Expand Down
10 changes: 8 additions & 2 deletions llvm/include/llvm/MC/MCSectionCOFF.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,19 @@ class MCSectionCOFF final : public MCSection {
/// section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0
mutable int Selection;

unsigned UniqueID;

private:
friend class MCContext;
// The storage of Name is owned by MCContext's COFFUniquingMap.
MCSectionCOFF(StringRef Name, unsigned Characteristics,
MCSymbol *COMDATSymbol, int Selection, MCSymbol *Begin)
MCSymbol *COMDATSymbol, int Selection, unsigned UniqueID,
MCSymbol *Begin)
: MCSection(SV_COFF, Name, Characteristics & COFF::IMAGE_SCN_CNT_CODE,
Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA,
Begin),
Characteristics(Characteristics), COMDATSymbol(COMDATSymbol),
Selection(Selection) {
Selection(Selection), UniqueID(UniqueID) {
assert((Characteristics & 0x00F00000) == 0 &&
"alignment must not be set upon section creation");
}
Expand All @@ -72,6 +75,9 @@ class MCSectionCOFF final : public MCSection {

void setSelection(int Selection) const;

bool isUnique() const { return UniqueID != NonUniqueID; }
unsigned getUniqueID() const { return UniqueID; }

void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
raw_ostream &OS,
uint32_t Subsection) const override;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/MC/MCContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
StringRef CachedName = Iter->first.SectionName;
MCSymbol *Begin = getOrCreateSectionSymbol<MCSymbolCOFF>(Section);
MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF(
CachedName, Characteristics, COMDATSymbol, Selection, Begin);
CachedName, Characteristics, COMDATSymbol, Selection, UniqueID, Begin);
Iter->second = Result;
auto *F = allocInitialFragment(*Result);
Begin->setFragment(F);
Expand Down
21 changes: 14 additions & 7 deletions llvm/lib/MC/MCParser/COFFAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ class COFFAsmParser : public MCAsmParserExtension {
bool parseSectionSwitch(StringRef Section, unsigned Characteristics);

bool parseSectionSwitch(StringRef Section, unsigned Characteristics,
StringRef COMDATSymName, COFF::COMDATType Type);
StringRef COMDATSymName, COFF::COMDATType Type,
unsigned UniqueID);

bool parseSectionName(StringRef &SectionName);
bool parseSectionFlags(StringRef SectionName, StringRef FlagsString,
unsigned *Flags);

void Initialize(MCAsmParser &Parser) override {
// Call the base implementation.
MCAsmParserExtension::Initialize(Parser);
Expand Down Expand Up @@ -315,19 +315,21 @@ bool COFFAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) {

bool COFFAsmParser::parseSectionSwitch(StringRef Section,
unsigned Characteristics) {
return parseSectionSwitch(Section, Characteristics, "", (COFF::COMDATType)0);
return parseSectionSwitch(Section, Characteristics, "", (COFF::COMDATType)0,
MCSection::NonUniqueID);
}

bool COFFAsmParser::parseSectionSwitch(StringRef Section,
unsigned Characteristics,
StringRef COMDATSymName,
COFF::COMDATType Type) {
COFF::COMDATType Type,
unsigned UniqueID) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in section switching directive");
Lex();

getStreamer().switchSection(getContext().getCOFFSection(
Section, Characteristics, COMDATSymName, Type));
Section, Characteristics, COMDATSymName, Type, UniqueID));

return false;
}
Expand Down Expand Up @@ -386,7 +388,8 @@ bool COFFAsmParser::parseSectionArguments(StringRef, SMLoc) {

COFF::COMDATType Type = (COFF::COMDATType)0;
StringRef COMDATSymName;
if (getLexer().is(AsmToken::Comma)) {
if (getLexer().is(AsmToken::Comma) &&
getLexer().peekTok().getString() != "unique") {
Type = COFF::IMAGE_COMDAT_SELECT_ANY;
Lex();

Expand All @@ -407,6 +410,10 @@ bool COFFAsmParser::parseSectionArguments(StringRef, SMLoc) {
return TokError("expected identifier in directive");
}

int64_t UniqueID = MCSection::NonUniqueID;
if (maybeParseUniqueID(UniqueID))
return true;

if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");

Expand All @@ -415,7 +422,7 @@ bool COFFAsmParser::parseSectionArguments(StringRef, SMLoc) {
if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
Flags |= COFF::IMAGE_SCN_MEM_16BIT;
}
parseSectionSwitch(SectionName, Flags, COMDATSymName, Type);
parseSectionSwitch(SectionName, Flags, COMDATSymName, Type, UniqueID);
return false;
}

Expand Down
23 changes: 0 additions & 23 deletions llvm/lib/MC/MCParser/ELFAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ class ELFAsmParser : public MCAsmParserExtension {
bool parseMergeSize(int64_t &Size);
bool parseGroup(StringRef &GroupName, bool &IsComdat);
bool parseLinkedToSym(MCSymbolELF *&LinkedToSym);
bool maybeParseUniqueID(int64_t &UniqueID);
};

} // end anonymous namespace
Expand Down Expand Up @@ -474,28 +473,6 @@ bool ELFAsmParser::parseLinkedToSym(MCSymbolELF *&LinkedToSym) {
return false;
}

bool ELFAsmParser::maybeParseUniqueID(int64_t &UniqueID) {
MCAsmLexer &L = getLexer();
if (L.isNot(AsmToken::Comma))
return false;
Lex();
StringRef UniqueStr;
if (getParser().parseIdentifier(UniqueStr))
return TokError("expected identifier");
if (UniqueStr != "unique")
return TokError("expected 'unique'");
if (L.isNot(AsmToken::Comma))
return TokError("expected commma");
Lex();
if (getParser().parseAbsoluteExpression(UniqueID))
return true;
if (UniqueID < 0)
return TokError("unique id must be positive");
if (!isUInt<32>(UniqueID) || UniqueID == ~0U)
return TokError("unique id is too large");
return false;
}

static bool hasPrefix(StringRef SectionName, StringRef Prefix) {
return SectionName.consume_front(Prefix) &&
(SectionName.empty() || SectionName[0] == '.');
Expand Down
22 changes: 22 additions & 0 deletions llvm/lib/MC/MCParser/MCAsmParserExtension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,25 @@ bool MCAsmParserExtension::parseDirectiveCGProfile(StringRef, SMLoc) {
MCSymbolRefExpr::create(ToSym, getContext(), ToLoc), Count);
return false;
}

bool MCAsmParserExtension::maybeParseUniqueID(int64_t &UniqueID) {
MCAsmLexer &L = getLexer();
if (L.isNot(AsmToken::Comma))
return false;
Lex();
StringRef UniqueStr;
if (getParser().parseIdentifier(UniqueStr))
return TokError("expected identifier");
if (UniqueStr != "unique")
return TokError("expected 'unique'");
if (L.isNot(AsmToken::Comma))
return TokError("expected commma");
Lex();
if (getParser().parseAbsoluteExpression(UniqueID))
return true;
if (UniqueID < 0)
return TokError("unique id must be positive");
if (!isUInt<32>(UniqueID) || UniqueID == ~0U)
return TokError("unique id is too large");
return false;
}
10 changes: 9 additions & 1 deletion llvm/lib/MC/MCSectionCOFF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ using namespace llvm;
// should be printed before the section name
bool MCSectionCOFF::shouldOmitSectionDirective(StringRef Name,
const MCAsmInfo &MAI) const {
if (COMDATSymbol)
if (COMDATSymbol || isUnique())
return false;

// FIXME: Does .section .bss/.data/.text work everywhere??
Expand Down Expand Up @@ -67,6 +67,10 @@ void MCSectionCOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
OS << 'i';
OS << '"';

// unique should be tail of .section directive.
if (isUnique() && !COMDATSymbol)
OS << ",unique," << UniqueID;

if (getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
if (COMDATSymbol)
OS << ",";
Expand Down Expand Up @@ -103,6 +107,10 @@ void MCSectionCOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
COMDATSymbol->print(OS, &MAI);
}
}

if (isUnique() && COMDATSymbol)
OS << ",unique," << UniqueID;

OS << '\n';
}

Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/X86/constructor.ll
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ entry:
; MCU-CTORS: .section .ctors,"aw",@progbits
; MCU-INIT-ARRAY: .section .init_array,"aw",@init_array

; COFF-CTOR: .section .ctors.65520,"dw",associative,v
; COFF-CTOR: .section .ctors.65520,"dw",associative,v,unique,0
; COFF-CTOR-NEXT: .p2align 3
; COFF-CTOR-NEXT: .quad g
; COFF-CTOR-NEXT: .section .ctors.09980,"dw",associative,v
; COFF-CTOR-NEXT: .section .ctors.09980,"dw",associative,v,unique,0
; COFF-CTOR-NEXT: .p2align 3
; COFF-CTOR-NEXT: .quad h
; COFF-CTOR-NEXT: .section .ctors,"dw"
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/X86/ctor-priority-coff.ll
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
; CHECK: .section .CRT$XCC00250,"dr"
; CHECK: .p2align 3
; CHECK: .quad k
; CHECK: .section .CRT$XCL,"dr"
; CHECK: .section .CRT$XCL,"dr",unique,0
; CHECK: .p2align 3
; CHECK: .quad j
; CHECK: .section .CRT$XCT12345,"dr"
; CHECK: .p2align 3
; CHECK: .quad g
; CHECK: .section .CRT$XCT23456,"dr",associative,h
; CHECK: .section .CRT$XCT23456,"dr",associative,h,unique,0
; CHECK: .p2align 3
; CHECK: .quad init_h

Expand Down
8 changes: 4 additions & 4 deletions llvm/test/CodeGen/X86/data-section-prefix.ll
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
; ELF-NOUNIQ: .section .bss.unlikely.,"aw",@nobits,unique,3
; ELF-NOUNIQ: .section .bss,"aw",@nobits,unique,4

; COFF-MSVC: .section .data,"dw",one_only,foo
; COFF-MSVC: .section .data,"dw",one_only,bar
; COFF-MSVC: .section .bss,"bw",one_only,baz
; COFF-MSVC: .section .bss,"bw",one_only,quz
; COFF-MSVC: .section .data,"dw",one_only,foo,unique,0
; COFF-MSVC: .section .data,"dw",one_only,bar,unique,1
; COFF-MSVC: .section .bss,"bw",one_only,baz,unique,2
; COFF-MSVC: .section .bss,"bw",one_only,quz,unique,3

@foo = global i32 1, !section_prefix !0
@bar = global i32 2
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/X86/dtor-priority-coff.ll
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
; CHECK: .section .CRT$XTT12345,"dr"
; CHECK: .p2align 3
; CHECK: .quad g
; CHECK: .section .CRT$XTT23456,"dr",associative,h
; CHECK: .section .CRT$XTT23456,"dr",associative,h,unique,0
; CHECK: .p2align 3
; CHECK: .quad init_h
; CHECK: .section .CRT$XTX,"dr"
Expand Down
18 changes: 9 additions & 9 deletions llvm/test/CodeGen/X86/global-sections.ll
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ define void @F1() {
ret void
}

; WIN32-SECTIONS: .section .text,"xr",one_only,_F1
; WIN32-SECTIONS: .section .text,"xr",one_only,_F1,unique,0
; WIN32-SECTIONS: .globl _F1

define void @F2(i32 %y) {
Expand Down Expand Up @@ -49,9 +49,9 @@ bb5:
; LINUX-FUNC-SECTIONS-NEXT: .cfi_endproc
; LINUX-FUNC-SECTIONS-NEXT: .section .rodata.F2,"a",@progbits

; WIN32-FUNC-SECTIONS: .section .text,"xr",one_only,_F2
; WIN32-FUNC-SECTIONS: .section .text,"xr",one_only,_F2,unique,1
; WIN32-FUNC-SECTIONS-NOT: .section
; WIN32-FUNC-SECTIONS: .section .rdata,"dr",associative,_F2
; WIN32-FUNC-SECTIONS: .section .rdata,"dr",associative,_F2,unique,2


; LINUX-SECTIONS-PIC: .section .text.F2,"ax",@progbits
Expand Down Expand Up @@ -138,7 +138,7 @@ bb7:
; LINUX-SECTIONS: .section .rodata.G3,"a",@progbits
; LINUX-SECTIONS: .globl G3

; WIN32-SECTIONS: .section .rdata,"dr",one_only,_G3
; WIN32-SECTIONS: .section .rdata,"dr",one_only,_G3,unique,6
; WIN32-SECTIONS: .globl _G3


Expand Down Expand Up @@ -213,7 +213,7 @@ bb7:
; LINUX-SECTIONS: .section .rodata.str1.1,"aMS",@progbits,1
; LINUX-SECTIONS: .globl G7

; WIN32-SECTIONS: .section .rdata,"dr",one_only,_G7
; WIN32-SECTIONS: .section .rdata,"dr",one_only,_G7,unique,11
; WIN32-SECTIONS: .globl _G7


Expand Down Expand Up @@ -276,7 +276,7 @@ bb7:
; LINUX-SECTIONS: .asciz "foo"
; LINUX-SECTIONS: .size .LG14, 4

; WIN32-SECTIONS: .section .rdata,"dr",one_only,_G14
; WIN32-SECTIONS: .section .rdata,"dr",one_only,_G14,unique,18
; WIN32-SECTIONS: _G14:
; WIN32-SECTIONS: .asciz "foo"

Expand All @@ -298,7 +298,7 @@ bb7:
; LINUX-SECTIONS: .section .rodata.cst8,"aM",@progbits,8
; LINUX-SECTIONS: G15:

; WIN32-SECTIONS: .section .rdata,"dr",one_only,_G15
; WIN32-SECTIONS: .section .rdata,"dr",one_only,_G15,unique,19
; WIN32-SECTIONS: _G15:

@G16 = unnamed_addr constant i256 0
Expand All @@ -309,7 +309,7 @@ bb7:
; LINUX-SECTIONS: .section .rodata.cst32,"aM",@progbits,32
; LINUX-SECTIONS: G16:

; WIN32-SECTIONS: .section .rdata,"dr",one_only,_G16
; WIN32-SECTIONS: .section .rdata,"dr",one_only,_G16,unique,20
; WIN32-SECTIONS: _G16:

; PR26570
Expand All @@ -326,7 +326,7 @@ bb7:
; LINUX-SECTIONS: .byte 0
; LINUX-SECTIONS: .size G17, 1

; WIN32-SECTIONS: .section .bss,"bw",one_only,_G17
; WIN32-SECTIONS: .section .bss,"bw",one_only,_G17,unique,21
; WIN32-SECTIONS: _G17:
; WIN32-SECTIONS:.byte 0

Expand Down
18 changes: 9 additions & 9 deletions llvm/test/CodeGen/X86/mingw-comdats.ll
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,23 @@ entry:
ret i32 %call
}

; CHECK: .section .text,"xr",one_only,main
; CHECK: .section .text,"xr",one_only,main,unique,0
; CHECK: main:
; GNU: .section .text$main,"xr",one_only,main
; GNU: .section .text$main,"xr",one_only,main,unique,0
; GNU: main:
; GNU32: .section .text$main,"xr",one_only,_main
; GNU32: .section .text$main,"xr",one_only,_main,unique,0
; GNU32: _main:

define dso_local x86_fastcallcc i32 @fastcall(i32 %x, i32 %y) {
%rv = add i32 %x, %y
ret i32 %rv
}

; CHECK: .section .text,"xr",one_only,fastcall
; CHECK: .section .text,"xr",one_only,fastcall,unique,1
; CHECK: fastcall:
; GNU: .section .text$fastcall,"xr",one_only,fastcall
; GNU: .section .text$fastcall,"xr",one_only,fastcall,unique,1
; GNU: fastcall:
; GNU32: .section .text$fastcall,"xr",one_only,@fastcall@8
; GNU32: .section .text$fastcall,"xr",one_only,@fastcall@8,unique,1
; GNU32: @fastcall@8:

; Function Attrs: inlinehint uwtable
Expand All @@ -55,19 +55,19 @@ entry:
ret i32 %add
}

; CHECK: .section .text,"xr",discard,_Z3fooi
; CHECK: .section .text,"xr",discard,_Z3fooi,unique,2
; CHECK: _Z3fooi:
; CHECK: .section .data,"dw",discard,gv
; CHECK: gv:
; CHECK: .long 42

; GNU: .section .text$_Z3fooi,"xr",discard,_Z3fooi
; GNU: .section .text$_Z3fooi,"xr",discard,_Z3fooi,unique,2
; GNU: _Z3fooi:
; GNU: .section .data$gv,"dw",discard,gv
; GNU: gv:
; GNU: .long 42

; GNU32: .section .text$_Z3fooi,"xr",discard,__Z3fooi
; GNU32: .section .text$_Z3fooi,"xr",discard,__Z3fooi,unique,2
; GNU32: __Z3fooi:
; GNU32: .section .data$gv,"dw",discard,_gv
; GNU32: _gv:
Expand Down
Loading
Loading