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
This commit is contained in:
Rafael Espindola 2017-02-09 14:59:20 +00:00
parent e6fa7df85c
commit 5a2d92c7cf
10 changed files with 144 additions and 7 deletions

View File

@ -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
=========================

View File

@ -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,

View File

@ -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()),

View File

@ -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,

View File

@ -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()) {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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