Index: include/llvm/MC/MCContext.h =================================================================== --- include/llvm/MC/MCContext.h +++ include/llvm/MC/MCContext.h @@ -241,7 +241,7 @@ unsigned EntrySize, const MCSymbolELF *Group, unsigned UniqueID, - const MCSectionELF *Associated); + const MCSymbolELF *Associated); public: explicit MCContext(const MCAsmInfo *MAI, const MCRegisterInfo *MRI, @@ -372,12 +372,12 @@ MCSectionELF *getELFSection(const Twine &Section, unsigned Type, unsigned Flags, unsigned EntrySize, const Twine &Group, unsigned UniqueID, - const MCSectionELF *Associated); + const MCSymbolELF *Associated); MCSectionELF *getELFSection(const Twine &Section, unsigned Type, unsigned Flags, unsigned EntrySize, const MCSymbolELF *Group, unsigned UniqueID, - const MCSectionELF *Associated); + const MCSymbolELF *Associated); /// Get a section with the provided group identifier. This section is /// named by concatenating \p Prefix with '.' then \p Suffix. The \p Type @@ -390,7 +390,7 @@ MCSectionELF *createELFRelSection(const Twine &Name, unsigned Type, unsigned Flags, unsigned EntrySize, const MCSymbolELF *Group, - const MCSectionELF *Associated); + const MCSectionELF *RelInfoSection); void renameELFSection(MCSectionELF *Section, StringRef Name); Index: include/llvm/MC/MCSectionELF.h =================================================================== --- include/llvm/MC/MCSectionELF.h +++ include/llvm/MC/MCSectionELF.h @@ -45,18 +45,21 @@ const MCSymbolELF *Group; - /// Depending on the type of the section this is sh_link or sh_info. - const MCSectionELF *Associated; + /// sh_link for REL and RELA sections. + const MCSectionELF *RelInfoSection; + + /// sh_info for SHF_LINK_ORDER (can be null). + const MCSymbol *AssociatedSymbol; private: friend class MCContext; MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K, unsigned entrySize, const MCSymbolELF *group, unsigned UniqueID, - MCSymbol *Begin, const MCSectionELF *Associated) + MCSymbol *Begin, const MCSymbolELF *AssociatedSymbol) : MCSection(SV_ELF, K, Begin), SectionName(Section), Type(type), Flags(flags), UniqueID(UniqueID), EntrySize(entrySize), Group(group), - Associated(Associated) { + RelInfoSection(nullptr), AssociatedSymbol(AssociatedSymbol) { if (Group) Group->setIsSignature(); } @@ -86,7 +89,10 @@ bool isUnique() const { return UniqueID != ~0U; } unsigned getUniqueID() const { return UniqueID; } - const MCSectionELF *getAssociatedSection() const { return Associated; } + const MCSectionELF *getRelInfoSection() const { return RelInfoSection; } + void setRelInfoSection(const MCSectionELF* S) { RelInfoSection = S; } + + const MCSymbol *getAssociatedSymbol() const { return AssociatedSymbol; } static bool classof(const MCSection *S) { return S->getVariant() == SV_ELF; Index: lib/MC/ELFObjectWriter.cpp =================================================================== --- lib/MC/ELFObjectWriter.cpp +++ lib/MC/ELFObjectWriter.cpp @@ -1153,7 +1153,7 @@ case ELF::SHT_RELA: { sh_link = SymbolTableIndex; assert(sh_link && ".symtab not found"); - const MCSectionELF *InfoSection = Section.getAssociatedSection(); + const MCSectionELF *InfoSection = Section.getRelInfoSection(); sh_info = SectionIndexMap.lookup(InfoSection); break; } @@ -1174,8 +1174,12 @@ break; } - if (Section.getFlags() & ELF::SHF_LINK_ORDER) - sh_link = SectionIndexMap.lookup(Section.getAssociatedSection()); + if (Section.getFlags() & ELF::SHF_LINK_ORDER) { + const MCSymbol *Sym = Section.getAssociatedSymbol(); + assert(Sym && Sym->isInSection()); + const MCSectionELF *Sec = dyn_cast(&Sym->getSection()); + sh_link = SectionIndexMap.lookup(Sec); + } WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getSectionName()), Section.getType(), Section.getFlags(), 0, Offset, Size, @@ -1299,7 +1303,7 @@ // Remember the offset into the file for this section. uint64_t SecStart = getStream().tell(); - writeRelocations(Asm, *RelSection->getAssociatedSection()); + writeRelocations(Asm, *RelSection->getRelInfoSection()); uint64_t SecEnd = getStream().tell(); SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd); Index: lib/MC/MCContext.cpp =================================================================== --- lib/MC/MCContext.cpp +++ lib/MC/MCContext.cpp @@ -312,7 +312,7 @@ unsigned EntrySize, const MCSymbolELF *Group, unsigned UniqueID, - const MCSectionELF *Associated) { + const MCSymbolELF *Associated) { MCSymbolELF *R; MCSymbol *&Sym = Symbols[Section]; if (Sym && Sym->isUndefined()) { @@ -341,15 +341,17 @@ MCSectionELF *MCContext::createELFRelSection(const Twine &Name, unsigned Type, unsigned Flags, unsigned EntrySize, const MCSymbolELF *Group, - const MCSectionELF *Associated) { + const MCSectionELF *RelInfoSection) { StringMap::iterator I; bool Inserted; std::tie(I, Inserted) = ELFRelSecNames.insert(std::make_pair(Name.str(), true)); - return createELFSectionImpl(I->getKey(), Type, Flags, - SectionKind::getReadOnly(), EntrySize, Group, - true, Associated); + MCSectionELF *Section = + createELFSectionImpl(I->getKey(), Type, Flags, SectionKind::getReadOnly(), + EntrySize, Group, true, nullptr); + Section->setRelInfoSection(RelInfoSection); + return Section; } MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix, @@ -362,7 +364,7 @@ MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type, unsigned Flags, unsigned EntrySize, const Twine &Group, unsigned UniqueID, - const MCSectionELF *Associated) { + const MCSymbolELF *Associated) { MCSymbolELF *GroupSym = nullptr; if (!Group.isTriviallyEmpty() && !Group.str().empty()) GroupSym = cast(getOrCreateSymbol(Group)); @@ -375,7 +377,7 @@ unsigned Flags, unsigned EntrySize, const MCSymbolELF *GroupSym, unsigned UniqueID, - const MCSectionELF *Associated) { + const MCSymbolELF *Associated) { StringRef Group = ""; if (GroupSym) Group = GroupSym->getName(); Index: lib/MC/MCParser/ELFAsmParser.cpp =================================================================== --- lib/MC/MCParser/ELFAsmParser.cpp +++ lib/MC/MCParser/ELFAsmParser.cpp @@ -157,7 +157,7 @@ bool maybeParseSectionType(StringRef &TypeName); bool parseMergeSize(int64_t &Size); bool parseGroup(StringRef &GroupName); - bool parseMetadataSym(MCSectionELF *&Associated); + bool parseMetadataSym(MCSymbolELF *&Associated); bool maybeParseUniqueID(int64_t &UniqueID); }; @@ -429,7 +429,7 @@ return false; } -bool ELFAsmParser::parseMetadataSym(MCSectionELF *&Associated) { +bool ELFAsmParser::parseMetadataSym(MCSymbolELF *&Associated) { MCAsmLexer &L = getLexer(); if (L.isNot(AsmToken::Comma)) return TokError("expected metadata symbol"); @@ -437,10 +437,9 @@ StringRef Name; if (getParser().parseIdentifier(Name)) return true; - MCSymbol *Sym = getContext().lookupSymbol(Name); - if (!Sym || !Sym->isInSection()) + Associated = dyn_cast_or_null(getContext().lookupSymbol(Name)); + if (!Associated || !Associated->isInSection()) return TokError("symbol is not in a section: " + Name); - Associated = cast(&Sym->getSection()); return false; } @@ -479,7 +478,7 @@ const MCExpr *Subsection = nullptr; bool UseLastGroup = false; StringRef UniqueStr; - MCSectionELF *Associated = nullptr; + MCSymbolELF *Associated = nullptr; int64_t UniqueID = ~0; // Set the defaults first. @@ -594,8 +593,9 @@ } } - MCSection *ELFSection = getContext().getELFSection( - SectionName, Type, Flags, Size, GroupName, UniqueID, Associated); + MCSection *ELFSection = + getContext().getELFSection(SectionName, Type, Flags, Size, GroupName, + UniqueID, Associated); getStreamer().SwitchSection(ELFSection, Subsection); if (getContext().getGenDwarfForAssembly()) { Index: lib/MC/MCSectionELF.cpp =================================================================== --- lib/MC/MCSectionELF.cpp +++ lib/MC/MCSectionELF.cpp @@ -102,6 +102,8 @@ OS << 'S'; if (Flags & ELF::SHF_TLS) OS << 'T'; + if (Flags & ELF::SHF_LINK_ORDER) + OS << 'm'; // If there are target-specific flags, print them. Triple::ArchType Arch = T.getArch(); @@ -152,6 +154,11 @@ OS << ",comdat"; } + if (Flags & ELF::SHF_LINK_ORDER) { + OS << ","; + printName(OS, AssociatedSymbol->getName()); + } + if (isUnique()) OS << ",unique," << UniqueID; Index: lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -1139,7 +1139,8 @@ if (Group) Flags |= ELF::SHF_GROUP; MCSectionELF *EHSection = getContext().getELFSection( - EHSecName, Type, Flags, 0, Group, FnSection.getUniqueID(), &FnSection); + EHSecName, Type, Flags, 0, Group, FnSection.getUniqueID(), + dyn_cast(&Fn)); assert(EHSection && "Failed to get the required EH section"); Index: test/MC/ELF/section.s =================================================================== --- test/MC/ELF/section.s +++ test/MC/ELF/section.s @@ -1,4 +1,5 @@ // RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -s | FileCheck %s +// RUN: llvm-mc -filetype=asm -triple x86_64-pc-linux-gnu %s -o - | FileCheck %s --check-prefix=ASM // Test that these names are accepted. @@ -164,6 +165,9 @@ .section .shf_metadata1,"am",@progbits,.Lshf_metadata_target2_1 .section .shf_metadata2,"am",@progbits,.Lshf_metadata_target2_2 .section .shf_metadata3,"am",@progbits,.shf_metadata_target1 +// ASM: .section .shf_metadata1,"am",@progbits,.Lshf_metadata_target2_1 +// ASM: .section .shf_metadata2,"am",@progbits,.Lshf_metadata_target2_2 +// ASM: .section .shf_metadata3,"am",@progbits,.shf_metadata_target1 // CHECK: Section { // CHECK: Index: 22