diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2017-02-09 14:59:20 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2017-02-09 14:59:20 +0000 |
commit | dc1c3011fd2dfb75f6a1f4f20fa73344956a54a4 (patch) | |
tree | 468a5687f782aa72ed347cc62bc2ed5f6cc9b437 | |
parent | 6953b324750de9978e7c9d1d50c269a12fb38cc1 (diff) | |
download | bcm5719-llvm-dc1c3011fd2dfb75f6a1f4f20fa73344956a54a4.tar.gz bcm5719-llvm-dc1c3011fd2dfb75f6a1f4f20fa73344956a54a4.zip |
Make it possible to set SHF_LINK_ORDER explicitly.
This will make it possible to add support for gcing user metadata
(asan for example).
llvm-svn: 294589
-rw-r--r-- | llvm/docs/Extensions.rst | 18 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCContext.h | 10 | ||||
-rw-r--r-- | llvm/lib/MC/ELFObjectWriter.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/MC/MCContext.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/ELFAsmParser.cpp | 27 | ||||
-rw-r--r-- | llvm/test/MC/ELF/section-metadata-err1.s | 5 | ||||
-rw-r--r-- | llvm/test/MC/ELF/section-metadata-err2.s | 6 | ||||
-rw-r--r-- | llvm/test/MC/ELF/section-metadata-err3.s | 6 | ||||
-rw-r--r-- | llvm/test/MC/ELF/section-metadata-err4.s | 5 | ||||
-rw-r--r-- | llvm/test/MC/ELF/section.s | 66 |
10 files changed, 144 insertions, 7 deletions
diff --git a/llvm/docs/Extensions.rst b/llvm/docs/Extensions.rst index 56bb2793059..782539dda58 100644 --- a/llvm/docs/Extensions.rst +++ b/llvm/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/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h index b73c74db5d7..edfbfaef232 100644 --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/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/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index e9f4f1cce33..3d1a16c904c 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/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/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp index 2bfd8e55cad..19aa73efc21 100644 --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/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<MCSymbolELF>(getOrCreateSymbol(Group)); return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID, - nullptr); + Associated); } MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type, diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp index 3bee12f6824..b9426566b5c 100644 --- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/llvm/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<MCSectionELF>(&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/llvm/test/MC/ELF/section-metadata-err1.s b/llvm/test/MC/ELF/section-metadata-err1.s new file mode 100644 index 00000000000..eb468f6b937 --- /dev/null +++ b/llvm/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/llvm/test/MC/ELF/section-metadata-err2.s b/llvm/test/MC/ELF/section-metadata-err2.s new file mode 100644 index 00000000000..032e000453b --- /dev/null +++ b/llvm/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/llvm/test/MC/ELF/section-metadata-err3.s b/llvm/test/MC/ELF/section-metadata-err3.s new file mode 100644 index 00000000000..4d8d0e23f96 --- /dev/null +++ b/llvm/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/llvm/test/MC/ELF/section-metadata-err4.s b/llvm/test/MC/ELF/section-metadata-err4.s new file mode 100644 index 00000000000..3c843c04643 --- /dev/null +++ b/llvm/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/llvm/test/MC/ELF/section.s b/llvm/test/MC/ELF/section.s index 0277be52236..f70139f36ba 100644 --- a/llvm/test/MC/ELF/section.s +++ b/llvm/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 |