From: Rafael Espindola Date: Sat, 4 Apr 2015 18:02:01 +0000 (+0000) Subject: Implement unique sections with an unique ID. X-Git-Tag: android-x86-7.1-r4~49607 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=903f4a20512b454212d6275677d71e3fab894106;p=android-x86%2Fexternal-llvm.git Implement unique sections with an unique ID. This allows the compiler/assembly programmer to switch back to a section. This in turn fixes the bootstrap failure on powerpc (tested on gcc110) without changing the ppc codegen at all. I will try to cleanup the various getELFSection overloads in a followup patch. Just using a default argument now would lead to ambiguities. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234099 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/Extensions.rst b/docs/Extensions.rst index 271c08598b3..12eac5e0ed8 100644 --- a/docs/Extensions.rst +++ b/docs/Extensions.rst @@ -165,6 +165,29 @@ and ``.bar`` is associated to ``.foo``. .section .foo,"bw",discard, "sym" .section .bar,"rd",associative, "sym" + +ELF-Dependent +------------- + +``.section`` Directive +^^^^^^^^^^^^^^^^^^^^^^ + +In order to support creating multiple sections with the same name and comdat, +it is possible to add an unique number at the end of the ``.seciton`` directive. +For example, the following code creates two sections named ``.text``. + +.. code-block:: gas + + .section .text,"ax",@progbits,unique 1 + nop + + .section .text,"ax",@progbits,unique 2 + nop + + +The unique number is not present in the resulting object at all. It is just used +in the assembler to differentiate the sections. + Target Specific Behaviour ========================= diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 75920a3fea4..232678ef1f8 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -34,6 +34,7 @@ namespace llvm { class TargetLoweringObjectFileELF : public TargetLoweringObjectFile { bool UseInitArray; + mutable unsigned NextUniqueID = 0; public: TargetLoweringObjectFileELF() : UseInitArray(false) {} diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 63faeceec9d..e0688644575 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -165,12 +165,17 @@ namespace llvm { struct ELFSectionKey { std::string SectionName; StringRef GroupName; - ELFSectionKey(StringRef SectionName, StringRef GroupName) - : SectionName(SectionName), GroupName(GroupName) {} + unsigned UniqueID; + ELFSectionKey(StringRef SectionName, StringRef GroupName, + unsigned UniqueID) + : SectionName(SectionName), GroupName(GroupName), UniqueID(UniqueID) { + } bool operator<(const ELFSectionKey &Other) const { if (SectionName != Other.SectionName) return SectionName < Other.SectionName; - return GroupName < Other.GroupName; + if (GroupName != Other.GroupName) + return GroupName < Other.GroupName; + return UniqueID < Other.UniqueID; } }; @@ -303,7 +308,7 @@ namespace llvm { const MCSectionELF *getELFSection(StringRef Section, unsigned Type, unsigned Flags, unsigned EntrySize, - StringRef Group, bool Unique, + StringRef Group, unsigned UniqueID, const char *BeginSymName = nullptr); const MCSectionELF *createELFRelSection(StringRef Name, unsigned Type, diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index fc0fc7bc8ff..ab8968ef2ba 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -39,11 +39,10 @@ private: mutable MCSymbol *End; protected: - MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin, bool Unique) - : Begin(Begin), End(nullptr), Variant(V), Kind(K), Unique(Unique) {} + MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin) + : Begin(Begin), End(nullptr), Variant(V), Kind(K) {} SectionVariant Variant; SectionKind Kind; - bool Unique; public: virtual ~MCSection(); @@ -55,7 +54,6 @@ public: MCSymbol *getBeginSymbol() const { return Begin; } MCSymbol *getEndSymbol(MCContext &Ctx) const; bool hasEnded() const; - bool isUnique() const { return Unique; } virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS, const MCExpr *Subsection) const = 0; diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index 201c4fae294..b6ec1d852d4 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -47,7 +47,7 @@ class MCSymbol; MCSectionCOFF(StringRef Section, unsigned Characteristics, MCSymbol *COMDATSymbol, int Selection, SectionKind K, MCSymbol *Begin) - : MCSection(SV_COFF, K, Begin, /*Unique*/ false), SectionName(Section), + : MCSection(SV_COFF, K, Begin), SectionName(Section), Characteristics(Characteristics), COMDATSymbol(COMDATSymbol), Selection(Selection) { assert ((Characteristics & 0x00F00000) == 0 && diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index 2bbc81fd79b..cd15741fe20 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -39,6 +39,8 @@ class MCSectionELF : public MCSection { /// below. unsigned Flags; + unsigned UniqueID; + /// EntrySize - The size of each entry in this section. This size only /// makes sense for sections that contain fixed-sized entries. If a /// section does not contain fixed-sized entries 'EntrySize' will be 0. @@ -49,10 +51,10 @@ class MCSectionELF : public MCSection { private: friend class MCContext; MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K, - unsigned entrySize, const MCSymbol *group, bool Unique, + unsigned entrySize, const MCSymbol *group, unsigned UniqueID, MCSymbol *Begin) - : MCSection(SV_ELF, K, Begin, Unique), SectionName(Section), Type(type), - Flags(flags), EntrySize(entrySize), Group(group) {} + : MCSection(SV_ELF, K, Begin), SectionName(Section), Type(type), + Flags(flags), UniqueID(UniqueID), EntrySize(entrySize), Group(group) {} ~MCSectionELF(); void setSectionName(StringRef Name) { SectionName = Name; } @@ -74,6 +76,9 @@ public: bool UseCodeAlign() const override; bool isVirtualSection() const override; + bool isUnique() const { return UniqueID != ~0U; } + unsigned getUniqueID() const { return UniqueID; } + static bool classof(const MCSection *S) { return S->getVariant() == SV_ELF; } diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index bcf2aa72c4b..5b795e4b37b 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -245,9 +245,11 @@ static StringRef getSectionPrefixForGlobal(SectionKind Kind) { return ".data.rel.ro"; } -static const MCSectionELF *selectELFSectionForGlobal( - MCContext &Ctx, const GlobalValue *GV, SectionKind Kind, Mangler &Mang, - const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags) { +static const MCSectionELF * +selectELFSectionForGlobal(MCContext &Ctx, const GlobalValue *GV, + SectionKind Kind, Mangler &Mang, + const TargetMachine &TM, bool EmitUniqueSection, + unsigned Flags, unsigned *NextUniqueID) { unsigned EntrySize = 0; if (Kind.isMergeableCString()) { if (Kind.isMergeable2ByteCString()) { @@ -297,9 +299,13 @@ static const MCSectionELF *selectELFSectionForGlobal( Name.push_back('.'); TM.getNameWithPrefix(Name, GV, Mang, true); } + unsigned UniqueID = ~0; + if (EmitUniqueSection && !UniqueSectionNames) { + UniqueID = *NextUniqueID; + (*NextUniqueID)++; + } return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags, - EntrySize, Group, - EmitUniqueSection && !UniqueSectionNames); + EntrySize, Group, UniqueID); } const MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( @@ -319,7 +325,7 @@ const MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( EmitUniqueSection |= GV->hasComdat(); return selectELFSectionForGlobal(getContext(), GV, Kind, Mang, TM, - EmitUniqueSection, Flags); + EmitUniqueSection, Flags, &NextUniqueID); } const MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( @@ -332,7 +338,8 @@ const MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( return ReadOnlySection; return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(), - Mang, TM, EmitUniqueSection, ELF::SHF_ALLOC); + Mang, TM, EmitUniqueSection, ELF::SHF_ALLOC, + &NextUniqueID); } bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index 6e7a3bc4db7..4443fc00fe0 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -273,9 +273,12 @@ void MCContext::renameELFSection(const MCSectionELF *Section, StringRef Name) { if (const MCSymbol *Group = Section->getGroup()) GroupName = Group->getName(); - ELFUniquingMap.erase(ELFSectionKey{Section->getSectionName(), GroupName}); - auto I = ELFUniquingMap.insert(std::make_pair(ELFSectionKey{Name, GroupName}, - Section)).first; + unsigned UniqueID = Section->getUniqueID(); + ELFUniquingMap.erase( + ELFSectionKey{Section->getSectionName(), GroupName, UniqueID}); + auto I = ELFUniquingMap.insert(std::make_pair( + ELFSectionKey{Name, GroupName, UniqueID}, + Section)).first; StringRef CachedName = I->first.SectionName; const_cast(Section)->setSectionName(CachedName); } @@ -294,7 +297,7 @@ MCContext::createELFRelSection(StringRef Name, unsigned Type, unsigned Flags, const MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type, unsigned Flags, unsigned EntrySize, - StringRef Group, bool Unique, + StringRef Group, unsigned UniqueID, const char *BeginSymName) { MCSymbol *GroupSym = nullptr; if (!Group.empty()) { @@ -304,9 +307,9 @@ const MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type, // Do the lookup, if we have a hit, return it. auto IterBool = ELFUniquingMap.insert( - std::make_pair(ELFSectionKey{Section, Group}, nullptr)); + std::make_pair(ELFSectionKey{Section, Group, UniqueID}, nullptr)); auto &Entry = *IterBool.first; - if (!IterBool.second && !Unique) + if (!IterBool.second) return Entry.second; StringRef CachedName = Entry.first.SectionName; @@ -322,9 +325,8 @@ const MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type, Begin = createTempSymbol(BeginSymName, false); MCSectionELF *Result = new (*this) MCSectionELF( - CachedName, Type, Flags, Kind, EntrySize, GroupSym, Unique, Begin); - if (!Unique) - Entry.second = Result; + CachedName, Type, Flags, Kind, EntrySize, GroupSym, UniqueID, Begin); + Entry.second = Result; return Result; } @@ -332,14 +334,14 @@ const MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type, unsigned Flags, unsigned EntrySize, StringRef Group, const char *BeginSymName) { - return getELFSection(Section, Type, Flags, EntrySize, Group, false, + return getELFSection(Section, Type, Flags, EntrySize, Group, ~0, BeginSymName); } const MCSectionELF *MCContext::CreateELFGroupSection() { MCSectionELF *Result = new (*this) MCSectionELF(".group", ELF::SHT_GROUP, 0, SectionKind::getReadOnly(), 4, - nullptr, false, nullptr); + nullptr, ~0, nullptr); return Result; } diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp index 7a120a105d2..4cb3dfe9308 100644 --- a/lib/MC/MCParser/ELFAsmParser.cpp +++ b/lib/MC/MCParser/ELFAsmParser.cpp @@ -379,7 +379,7 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { const MCExpr *Subsection = nullptr; bool UseLastGroup = false; StringRef UniqueStr; - bool Unique = false; + int64_t UniqueID = ~0; // Set the defaults first. if (SectionName == ".fini" || SectionName == ".init" || @@ -470,7 +470,12 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { return TokError("expected identifier in directive"); if (UniqueStr != "unique") return TokError("expected 'unique'"); - Unique = true; + 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"); } } } @@ -520,7 +525,7 @@ EndStmt: } const MCSection *ELFSection = getContext().getELFSection( - SectionName, Type, Flags, Size, GroupName, Unique); + SectionName, Type, Flags, Size, GroupName, UniqueID); getStreamer().SwitchSection(ELFSection, Subsection); if (getContext().getGenDwarfForAssembly()) { diff --git a/lib/MC/MCSectionELF.cpp b/lib/MC/MCSectionELF.cpp index da3868273a7..2b9b8c63007 100644 --- a/lib/MC/MCSectionELF.cpp +++ b/lib/MC/MCSectionELF.cpp @@ -24,7 +24,7 @@ MCSectionELF::~MCSectionELF() {} // anchor. bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const { - if (Unique) + if (isUnique()) return false; // FIXME: Does .section .bss/.data/.text work everywhere?? @@ -148,8 +148,8 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, OS << ",comdat"; } - if (Unique) - OS << ",unique"; + if (isUnique()) + OS << ",unique " << UniqueID; OS << '\n'; diff --git a/lib/MC/MCSectionMachO.cpp b/lib/MC/MCSectionMachO.cpp index 606d0747528..c9f15914e4b 100644 --- a/lib/MC/MCSectionMachO.cpp +++ b/lib/MC/MCSectionMachO.cpp @@ -72,7 +72,7 @@ ENTRY(nullptr /*FIXME*/, S_ATTR_LOC_RELOC) MCSectionMachO::MCSectionMachO(StringRef Segment, StringRef Section, unsigned TAA, unsigned reserved2, SectionKind K, MCSymbol *Begin) - : MCSection(SV_MachO, K, Begin, /*Unique*/ false), TypeAndAttributes(TAA), + : MCSection(SV_MachO, K, Begin), TypeAndAttributes(TAA), Reserved2(reserved2) { assert(Segment.size() <= 16 && Section.size() <= 16 && "Segment or section string too long"); diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index 3db23455404..27d0355bb11 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -669,12 +669,6 @@ void MCStreamer::SwitchSection(const MCSection *Section, MCSectionSubPair curSection = SectionStack.back().first; SectionStack.back().second = curSection; if (MCSectionSubPair(Section, Subsection) != curSection) { - const MCSection *CurSec = curSection.first; - if (CurSec && CurSec->isUnique()) { - MCSymbol *Sym = curSection.first->getEndSymbol(Context); - if (!Sym->isInSection()) - EmitLabel(Sym); - } SectionStack.back().first = MCSectionSubPair(Section, Subsection); assert(!Section->hasEnded() && "Section already ended"); ChangeSection(Section, Subsection); diff --git a/lib/Target/NVPTX/NVPTXSection.h b/lib/Target/NVPTX/NVPTXSection.h index eb6194a23ee..0d2627d62eb 100644 --- a/lib/Target/NVPTX/NVPTXSection.h +++ b/lib/Target/NVPTX/NVPTXSection.h @@ -26,8 +26,7 @@ namespace llvm { class NVPTXSection : public MCSection { virtual void anchor(); public: - NVPTXSection(SectionVariant V, SectionKind K) - : MCSection(V, K, nullptr, /*Unique*/ false) {} + NVPTXSection(SectionVariant V, SectionKind K) : MCSection(V, K, nullptr) {} virtual ~NVPTXSection() {} /// Override this as NVPTX has its own way of printing switching diff --git a/test/CodeGen/X86/global-sections-comdat.ll b/test/CodeGen/X86/global-sections-comdat.ll index 46188e7153b..730050dda5f 100644 --- a/test/CodeGen/X86/global-sections-comdat.ll +++ b/test/CodeGen/X86/global-sections-comdat.ll @@ -36,7 +36,6 @@ bb5: ; LINUX-SECTIONS-SHORT: .section .text,"axG",@progbits,F1,comdat ; LINUX-SECTIONS-SHORT: .size F1, ; LINUX-SECTIONS-SHORT-NEXT: .cfi_endproc -; LINUX-SECTIONS-SHORT-NEXT: .Lsec_end0: ; LINUX-SECTIONS-SHORT-NEXT: .section .rodata,"aG",@progbits,F1,comdat $G16 = comdat any diff --git a/test/MC/ELF/section-unique-err1.s b/test/MC/ELF/section-unique-err1.s new file mode 100644 index 00000000000..0b4985ba1d6 --- /dev/null +++ b/test/MC/ELF/section-unique-err1.s @@ -0,0 +1,5 @@ +// RUN: not llvm-mc -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s + +// CHECK: error: expected absolute expression + + .section .text,"ax",@progbits,unique "abc" diff --git a/test/MC/ELF/section-unique-err2.s b/test/MC/ELF/section-unique-err2.s new file mode 100644 index 00000000000..b2ac4f8aecf --- /dev/null +++ b/test/MC/ELF/section-unique-err2.s @@ -0,0 +1,5 @@ +// RUN: not llvm-mc -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s + +// CHECK: error: unique id must be positive + + .section .text,"ax",@progbits,unique -1 diff --git a/test/MC/ELF/section-unique-err3.s b/test/MC/ELF/section-unique-err3.s new file mode 100644 index 00000000000..67e962bfac7 --- /dev/null +++ b/test/MC/ELF/section-unique-err3.s @@ -0,0 +1,5 @@ +// RUN: not llvm-mc -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s + +// CHECK: error: unique id is too large + + .section .text,"ax",@progbits,unique 4294967295 diff --git a/test/MC/ELF/section-unique.s b/test/MC/ELF/section-unique.s index b482af3d101..ffd11d944c5 100644 --- a/test/MC/ELF/section-unique.s +++ b/test/MC/ELF/section-unique.s @@ -1,22 +1,22 @@ // RUN: llvm-mc -triple x86_64-pc-linux-gnu %s -o - | FileCheck %s // RUN: llvm-mc -triple x86_64-pc-linux-gnu %s -filetype=obj -o - | llvm-readobj -t | FileCheck %s --check-prefix=OBJ - .section .text,"ax",@progbits,unique + .section .text,"ax",@progbits,unique 4294967293 .globl f f: nop - .section .text,"ax",@progbits,unique + .section .text,"ax",@progbits,unique 4294967294 .globl g g: nop // test that f and g are in different sections. -// CHECK: .section .text,"ax",@progbits,unique +// CHECK: .section .text,"ax",@progbits,unique 4294967293 // CHECK: f: -// CHECK: .section .text,"ax",@progbits,unique +// CHECK: .section .text,"ax",@progbits,unique 4294967294 // CHECK: g: // OBJ: Symbol {