From 5a2d92c7cf7bf6ea69d25886c2101276d49522be Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 9 Feb 2017 14:59:20 +0000 Subject: [PATCH] Make it possible to set SHF_LINK_ORDER explicitly. This will make it possible to add support for gcing user metadata (asan for example). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294589 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/Extensions.rst | 18 ++++++++ include/llvm/MC/MCContext.h | 10 ++++- lib/MC/ELFObjectWriter.cpp | 3 +- lib/MC/MCContext.cpp | 5 ++- lib/MC/MCParser/ELFAsmParser.cpp | 27 +++++++++++- test/MC/ELF/section-metadata-err1.s | 5 +++ test/MC/ELF/section-metadata-err2.s | 6 +++ test/MC/ELF/section-metadata-err3.s | 6 +++ test/MC/ELF/section-metadata-err4.s | 5 +++ test/MC/ELF/section.s | 66 +++++++++++++++++++++++++++++ 10 files changed, 144 insertions(+), 7 deletions(-) create mode 100644 test/MC/ELF/section-metadata-err1.s create mode 100644 test/MC/ELF/section-metadata-err2.s create mode 100644 test/MC/ELF/section-metadata-err3.s create mode 100644 test/MC/ELF/section-metadata-err4.s diff --git a/docs/Extensions.rst b/docs/Extensions.rst index 56bb2793059..782539dda58 100644 --- a/docs/Extensions.rst +++ b/docs/Extensions.rst @@ -204,6 +204,24 @@ For example, the following code creates two sections named ``.text``. The unique number is not present in the resulting object at all. It is just used in the assembler to differentiate the sections. +The 'm' flag is mapped to SHF_LINK_ORDER. If it is present, a symbol +must be given that identifies the section to be placed is the +.sh_link. + +.. code-block:: gas + + .section .foo,"a",@progbits + .Ltmp: + .section .bar,"am",@progbits,.Ltmp + +which is equivalent to just + +.. code-block:: gas + + .section .foo,"a",@progbits + .section .bar,"am",@progbits,.foo + + Target Specific Behaviour ========================= diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index b73c74db5d7..edfbfaef232 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -357,7 +357,15 @@ namespace llvm { MCSectionELF *getELFSection(const Twine &Section, unsigned Type, unsigned Flags, unsigned EntrySize, - const Twine &Group, unsigned UniqueID); + const Twine &Group, unsigned UniqueID) { + return getELFSection(Section, Type, Flags, EntrySize, Group, UniqueID, + nullptr); + } + + MCSectionELF *getELFSection(const Twine &Section, unsigned Type, + unsigned Flags, unsigned EntrySize, + const Twine &Group, unsigned UniqueID, + const MCSectionELF *Associated); MCSectionELF *getELFSection(const Twine &Section, unsigned Type, unsigned Flags, unsigned EntrySize, diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index e9f4f1cce33..3d1a16c904c 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -1157,8 +1157,7 @@ void ELFObjectWriter::writeSection(const SectionIndexMapTy &SectionIndexMap, break; } - if (TargetObjectWriter->getEMachine() == ELF::EM_ARM && - Section.getType() == ELF::SHT_ARM_EXIDX) + if (Section.getFlags() & ELF::SHF_LINK_ORDER) sh_link = SectionIndexMap.lookup(Section.getAssociatedSection()); WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getSectionName()), diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index 2bfd8e55cad..19aa73efc21 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -358,13 +358,14 @@ MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix, MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type, unsigned Flags, unsigned EntrySize, - const Twine &Group, unsigned UniqueID) { + const Twine &Group, unsigned UniqueID, + const MCSectionELF *Associated) { MCSymbolELF *GroupSym = nullptr; if (!Group.isTriviallyEmpty() && !Group.str().empty()) GroupSym = cast(getOrCreateSymbol(Group)); return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID, - nullptr); + Associated); } MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type, diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp index 3bee12f6824..b9426566b5c 100644 --- a/lib/MC/MCParser/ELFAsmParser.cpp +++ b/lib/MC/MCParser/ELFAsmParser.cpp @@ -157,6 +157,7 @@ private: bool maybeParseSectionType(StringRef &TypeName); bool parseMergeSize(int64_t &Size); bool parseGroup(StringRef &GroupName); + bool parseMetadataSym(MCSectionELF *&Associated); bool maybeParseUniqueID(int64_t &UniqueID); }; @@ -297,6 +298,9 @@ static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) { case 'w': flags |= ELF::SHF_WRITE; break; + case 'm': + flags |= ELF::SHF_LINK_ORDER; + break; case 'M': flags |= ELF::SHF_MERGE; break; @@ -425,6 +429,21 @@ bool ELFAsmParser::parseGroup(StringRef &GroupName) { return false; } +bool ELFAsmParser::parseMetadataSym(MCSectionELF *&Associated) { + MCAsmLexer &L = getLexer(); + if (L.isNot(AsmToken::Comma)) + return TokError("expected metadata symbol"); + Lex(); + StringRef Name; + if (getParser().parseIdentifier(Name)) + return true; + MCSymbol *Sym = getContext().lookupSymbol(Name); + if (!Sym || !Sym->isInSection()) + return TokError("symbol is not in a section: " + Name); + Associated = cast(&Sym->getSection()); + return false; +} + bool ELFAsmParser::maybeParseUniqueID(int64_t &UniqueID) { MCAsmLexer &L = getLexer(); if (L.isNot(AsmToken::Comma)) @@ -460,6 +479,7 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { const MCExpr *Subsection = nullptr; bool UseLastGroup = false; StringRef UniqueStr; + MCSectionELF *Associated = nullptr; int64_t UniqueID = ~0; // Set the defaults first. @@ -522,6 +542,9 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { if (Group) if (parseGroup(GroupName)) return true; + if (Flags & ELF::SHF_LINK_ORDER) + if (parseMetadataSym(Associated)) + return true; if (maybeParseUniqueID(UniqueID)) return true; } @@ -571,8 +594,8 @@ EndStmt: } } - MCSection *ELFSection = getContext().getELFSection(SectionName, Type, Flags, - Size, GroupName, UniqueID); + MCSection *ELFSection = getContext().getELFSection( + SectionName, Type, Flags, Size, GroupName, UniqueID, Associated); getStreamer().SwitchSection(ELFSection, Subsection); if (getContext().getGenDwarfForAssembly()) { diff --git a/test/MC/ELF/section-metadata-err1.s b/test/MC/ELF/section-metadata-err1.s new file mode 100644 index 00000000000..eb468f6b937 --- /dev/null +++ b/test/MC/ELF/section-metadata-err1.s @@ -0,0 +1,5 @@ +// RUN: not llvm-mc -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s + +// CHECK: error: symbol is not in a section: foo + + .section .shf_metadata,"am",@progbits,foo diff --git a/test/MC/ELF/section-metadata-err2.s b/test/MC/ELF/section-metadata-err2.s new file mode 100644 index 00000000000..032e000453b --- /dev/null +++ b/test/MC/ELF/section-metadata-err2.s @@ -0,0 +1,6 @@ +// RUN: not llvm-mc -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s + +// CHECK: error: symbol is not in a section: foo + + .quad foo + .section .shf_metadata,"am",@progbits,foo diff --git a/test/MC/ELF/section-metadata-err3.s b/test/MC/ELF/section-metadata-err3.s new file mode 100644 index 00000000000..4d8d0e23f96 --- /dev/null +++ b/test/MC/ELF/section-metadata-err3.s @@ -0,0 +1,6 @@ +// RUN: not llvm-mc -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s + +// CHECK: error: symbol is not in a section: foo + + foo = 42 + .section .shf_metadata,"am",@progbits,foo diff --git a/test/MC/ELF/section-metadata-err4.s b/test/MC/ELF/section-metadata-err4.s new file mode 100644 index 00000000000..3c843c04643 --- /dev/null +++ b/test/MC/ELF/section-metadata-err4.s @@ -0,0 +1,5 @@ +// RUN: not llvm-mc -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s + +// CHECK: error: expected metadata symbol + + .section .shf_metadata,"am",@progbits diff --git a/test/MC/ELF/section.s b/test/MC/ELF/section.s index 0277be52236..f70139f36ba 100644 --- a/test/MC/ELF/section.s +++ b/test/MC/ELF/section.s @@ -149,3 +149,69 @@ bar: // CHECK: Name: bar-"foo" // CHECK: Section { // CHECK: Name: foo + +// Test SHF_LINK_ORDER + +.section .shf_metadata_target1, "a" + .quad 0 +.section .shf_metadata_target2, "a", @progbits, unique, 1 +.Lshf_metadata_target2_1: + .quad 0 +.section .shf_metadata_target2, "a", @progbits, unique, 2 +.Lshf_metadata_target2_2: + .quad 0 + +.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 + +// CHECK: Section { +// CHECK: Index: 22 +// CHECK-NEXT: Name: .shf_metadata_target1 + +// CHECK: Section { +// CHECK: Index: 23 +// CHECK-NEXT: Name: .shf_metadata_target2 + +// CHECK: Section { +// CHECK: Index: 24 +// CHECK-NEXT: Name: .shf_metadata_target2 + +// CHECK: Section { +// CHECK: Name: .shf_metadata1 +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_LINK_ORDER +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: +// CHECK-NEXT: Link: 23 +// CHECK-NEXT: Info: 0 + +// CHECK: Section { +// CHECK: Name: .shf_metadata2 +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_LINK_ORDER +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: +// CHECK-NEXT: Link: 24 +// CHECK-NEXT: Info: 0 + +// CHECK: Section { +// CHECK: Name: .shf_metadata3 +// CHECK-NEXT: Type: SHT_PROGBITS +// CHECK-NEXT: Flags [ +// CHECK-NEXT: SHF_ALLOC +// CHECK-NEXT: SHF_LINK_ORDER +// CHECK-NEXT: ] +// CHECK-NEXT: Address: +// CHECK-NEXT: Offset: +// CHECK-NEXT: Size: +// CHECK-NEXT: Link: 22 +// CHECK-NEXT: Info: 0 -- 2.50.1