summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2017-02-09 14:59:20 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2017-02-09 14:59:20 +0000
commitdc1c3011fd2dfb75f6a1f4f20fa73344956a54a4 (patch)
tree468a5687f782aa72ed347cc62bc2ed5f6cc9b437
parent6953b324750de9978e7c9d1d50c269a12fb38cc1 (diff)
downloadbcm5719-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.rst18
-rw-r--r--llvm/include/llvm/MC/MCContext.h10
-rw-r--r--llvm/lib/MC/ELFObjectWriter.cpp3
-rw-r--r--llvm/lib/MC/MCContext.cpp5
-rw-r--r--llvm/lib/MC/MCParser/ELFAsmParser.cpp27
-rw-r--r--llvm/test/MC/ELF/section-metadata-err1.s5
-rw-r--r--llvm/test/MC/ELF/section-metadata-err2.s6
-rw-r--r--llvm/test/MC/ELF/section-metadata-err3.s6
-rw-r--r--llvm/test/MC/ELF/section-metadata-err4.s5
-rw-r--r--llvm/test/MC/ELF/section.s66
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
OpenPOWER on IntegriCloud