diff options
author | Serge Guelton <sguelton@quarkslab.com> | 2019-01-24 17:56:08 +0000 |
---|---|---|
committer | Serge Guelton <sguelton@quarkslab.com> | 2019-01-24 17:56:08 +0000 |
commit | 1fa239f5002934f36b3de53989052bc9071e15fd (patch) | |
tree | 3ee31f5a9493680a83096a1463d1711ad9f60330 | |
parent | 58e9833e980e07f9ca4407d703417eecde4dc541 (diff) | |
download | bcm5719-llvm-1fa239f5002934f36b3de53989052bc9071e15fd.tar.gz bcm5719-llvm-1fa239f5002934f36b3de53989052bc9071e15fd.zip |
Partial support of SHT_GROUP without flag
This does *not* implement full SHT_GROUP semantic, yet it is a simple step forward:
Sections within a group are still considered valid, but they do not behave as
specified by the standard in case of garbage collection.
Differential Revision: https://reviews.llvm.org/D56437
llvm-svn: 352068
-rw-r--r-- | lld/ELF/InputFiles.cpp | 41 | ||||
-rw-r--r-- | lld/test/ELF/sht-group-empty.test | 55 |
2 files changed, 74 insertions, 22 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index e35e85dba9b..8b455c66e69 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -319,17 +319,6 @@ StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections, return Signature; } -template <class ELFT> -ArrayRef<typename ObjFile<ELFT>::Elf_Word> -ObjFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) { - const ELFFile<ELFT> &Obj = this->getObj(); - ArrayRef<Elf_Word> Entries = - CHECK(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), this); - if (Entries.empty() || Entries[0] != GRP_COMDAT) - fatal(toString(this) + ": unsupported SHT_GROUP format"); - return Entries.slice(1); -} - template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) { // On a regular link we don't merge sections if -O0 (default is -O1). This // sometimes makes the linker significantly faster, although the output will @@ -439,26 +428,34 @@ void ObjFile<ELFT>::initializeSections( case SHT_GROUP: { // De-duplicate section groups by their signatures. StringRef Signature = getShtGroupSignature(ObjSections, Sec); - bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second; this->Sections[I] = &InputSection::Discarded; - // We only support GRP_COMDAT type of group. Get the all entries of the - // section here to let getShtGroupEntries to check the type early for us. - ArrayRef<Elf_Word> Entries = getShtGroupEntries(Sec); - // If it is a new section group, we want to keep group members. - // Group leader sections, which contain indices of group members, are - // discarded because they are useless beyond this point. The only - // exception is the -r option because in order to produce re-linkable - // object files, we want to pass through basically everything. + ArrayRef<Elf_Word> Entries = + CHECK(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), this); + if (Entries.empty()) + fatal(toString(this) + ": empty SHT_GROUP"); + + // The first word of a SHT_GROUP section contains flags. Currently, + // the standard defines only "GRP_COMDAT" flag for the COMDAT group. + // An group with the empty flag doesn't define anything; such sections + // are just skipped. + if (Entries[0] == 0) + continue; + + if (Entries[0] != GRP_COMDAT) + fatal(toString(this) + ": unsupported SHT_GROUP format"); + + bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second; if (IsNew) { if (Config->Relocatable) this->Sections[I] = createInputSection(Sec); - continue; + continue; } + // Otherwise, discard group members. - for (uint32_t SecIndex : Entries) { + for (uint32_t SecIndex : Entries.slice(1)) { if (SecIndex >= Size) fatal(toString(this) + ": invalid section index in group: " + Twine(SecIndex)); diff --git a/lld/test/ELF/sht-group-empty.test b/lld/test/ELF/sht-group-empty.test new file mode 100644 index 00000000000..46c77f332e7 --- /dev/null +++ b/lld/test/ELF/sht-group-empty.test @@ -0,0 +1,55 @@ +# RUN: yaml2obj %s -o %t.o +# RUN: ld.lld %t.o %t.o -o %t -r +# RUN: llvm-readobj -s %t | FileCheck %s + +# CHECK: Name: .text.foo +# CHECK: Name: .rela.text.foo + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .group + Type: SHT_GROUP + Link: .symtab + Info: foo + Members: + - SectionOrType: GRP_COMDAT + - SectionOrType: .text.foo + - SectionOrType: .text.bar + - SectionOrType: .note + - Name: .note + Type: SHT_NOTE + Flags: [ SHF_GROUP ] + - Name: .text.foo + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ] + - Name: .text.bar + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ] + - Name: .rela.text.foo + Type: SHT_RELA + Flags: [ SHF_INFO_LINK, SHF_GROUP ] + Link: .symtab + Info: .text.foo + Relocations: + - Offset: 0x0000000000000000 + Symbol: foo + Type: R_X86_64_64 + - Name: .rela.text.bar + Type: SHT_RELA + Flags: [ SHF_INFO_LINK, SHF_GROUP ] + Link: .symtab + Info: .text.bar + Relocations: + - Offset: 0x0000000000000000 + Symbol: bar + Type: R_X86_64_64 +Symbols: + Global: + - Name: foo + - Name: bar + |