[lld] r304140 - [ELF] - Do not allow -r to eat comdats.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Mon May 29 01:37:50 PDT 2017
Author: grimar
Date: Mon May 29 03:37:50 2017
New Revision: 304140
URL: http://llvm.org/viewvc/llvm-project?rev=304140&view=rev
Log:
[ELF] - Do not allow -r to eat comdats.
This is PR33052, "Bug 33052 - -r eats comdats ".
To fix it I stop removing group section from out when -r is given
and fixing SHT_GROUP content when writing it just like we do some
other fixup, e.g. for Rel[a]. (it needs fix for section indices that
are in group).
Differential revision: https://reviews.llvm.org/D33485
Added:
lld/trunk/test/ELF/relocatable-comdat.s
Modified:
lld/trunk/ELF/InputFiles.cpp
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/InputSection.h
lld/trunk/ELF/OutputSections.cpp
Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=304140&r1=304139&r2=304140&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Mon May 29 03:37:50 2017
@@ -305,13 +305,22 @@ void elf::ObjectFile<ELFT>::initializeSe
}
switch (Sec.sh_type) {
- case SHT_GROUP:
- this->Sections[I] = &InputSection::Discarded;
- if (ComdatGroups
- .insert(
- CachedHashStringRef(getShtGroupSignature(ObjSections, Sec)))
- .second)
+ case SHT_GROUP: {
+ // We discard comdat sections usually. When -r we should not do that. We
+ // still do deduplication in this case to simplify implementation, because
+ // otherwise merging group sections together would requre additional
+ // regeneration of its contents.
+ bool New = ComdatGroups
+ .insert(CachedHashStringRef(
+ getShtGroupSignature(ObjSections, Sec)))
+ .second;
+ if (New && Config->Relocatable)
+ this->Sections[I] = createInputSection(Sec, SectionStringTable);
+ else
+ this->Sections[I] = &InputSection::Discarded;
+ if (New)
continue;
+
for (uint32_t SecIndex : getShtGroupEntries(Sec)) {
if (SecIndex >= Size)
fatal(toString(this) +
@@ -319,6 +328,7 @@ void elf::ObjectFile<ELFT>::initializeSe
this->Sections[SecIndex] = &InputSection::Discarded;
}
break;
+ }
case SHT_SYMTAB:
this->initSymtab(ObjSections, &Sec);
break;
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=304140&r1=304139&r2=304140&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Mon May 29 03:37:50 2017
@@ -295,6 +295,24 @@ bool InputSectionBase::classof(const Sec
return S->kind() != Output;
}
+void InputSection::copyShtGroup(uint8_t *Buf) {
+ assert(this->Type == SHT_GROUP);
+
+ ArrayRef<uint32_t> From = getDataAs<uint32_t>();
+ uint32_t *To = reinterpret_cast<uint32_t *>(Buf);
+
+ // First entry is a flag word, we leave it unchanged.
+ *To++ = From[0];
+
+ // Here we adjust indices of sections that belong to group as it
+ // might change during linking.
+ ArrayRef<InputSectionBase *> Sections = this->File->getSections();
+ for (uint32_t Val : From.slice(1)) {
+ uint32_t Index = read32(&Val, Config->Endianness);
+ write32(To++, Sections[Index]->OutSec->SectionIndex, Config->Endianness);
+ }
+}
+
InputSectionBase *InputSection::getRelocatedSection() {
assert(this->Type == SHT_RELA || this->Type == SHT_REL);
ArrayRef<InputSectionBase *> Sections = this->File->getSections();
@@ -680,6 +698,13 @@ template <class ELFT> void InputSection:
return;
}
+ // If -r is given, linker should keep SHT_GROUP sections. We should fixup
+ // them, see copyShtGroup().
+ if (this->Type == SHT_GROUP) {
+ copyShtGroup(Buf + OutSecOff);
+ return;
+ }
+
// Copy section contents from source object file to output file
// and then apply relocations.
memcpy(Buf + OutSecOff, Data.data(), Data.size());
Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=304140&r1=304139&r2=304140&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Mon May 29 03:37:50 2017
@@ -319,6 +319,8 @@ public:
private:
template <class ELFT, class RelTy>
void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
+
+ void copyShtGroup(uint8_t *Buf);
};
// The list of all input sections.
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=304140&r1=304139&r2=304140&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Mon May 29 03:37:50 2017
@@ -112,6 +112,19 @@ template <class ELFT> void OutputSection
Flags |= SHF_COMPRESSED;
}
+template <class ELFT> static void finalizeShtGroup(OutputSection *Sec) {
+ // sh_link field for SHT_GROUP sections should contain the section index of
+ // the symbol table.
+ Sec->Link = InX::SymTab->OutSec->SectionIndex;
+
+ // sh_link then contain index of an entry in symbol table section which
+ // provides signature of the section group.
+ elf::ObjectFile<ELFT> *Obj = Sec->Sections[0]->getFile<ELFT>();
+ assert(Config->Relocatable && Sec->Sections.size() == 1);
+ ArrayRef<SymbolBody *> Symbols = Obj->getSymbols();
+ Sec->Info = InX::SymTab->getSymbolIndex(Symbols[Sec->Sections[0]->Info - 1]);
+}
+
template <class ELFT> void OutputSection::finalize() {
if ((this->Flags & SHF_LINK_ORDER) && !this->Sections.empty()) {
std::sort(Sections.begin(), Sections.end(), compareByFilePosition);
@@ -126,6 +139,11 @@ template <class ELFT> void OutputSection
}
uint32_t Type = this->Type;
+ if (Type == SHT_GROUP) {
+ finalizeShtGroup<ELFT>(this);
+ return;
+ }
+
if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL))
return;
@@ -355,7 +373,10 @@ void OutputSectionFactory::addInputSec(I
return;
}
- uint64_t Flags = IS->Flags & ~(uint64_t)SHF_GROUP;
+ uint64_t Flags = IS->Flags;
+ if (!Config->Relocatable)
+ Flags &= ~(uint64_t)SHF_GROUP;
+
if (Sec) {
if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags))
error("incompatible section flags for " + Sec->Name +
Added: lld/trunk/test/ELF/relocatable-comdat.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/relocatable-comdat.s?rev=304140&view=auto
==============================================================================
--- lld/trunk/test/ELF/relocatable-comdat.s (added)
+++ lld/trunk/test/ELF/relocatable-comdat.s Mon May 29 03:37:50 2017
@@ -0,0 +1,45 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld -r %t.o %t.o -o %t
+# RUN: llvm-readobj -elf-section-groups -sections %t | FileCheck %s
+
+# CHECK: Name: .text.bar
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: SHF_EXECINSTR
+# CHECK-NEXT: SHF_GROUP
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address:
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size: 8
+# CHECK: Section {
+# CHECK-NEXT: Index: 4
+# CHECK-NEXT: Name: .text.foo
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: SHF_EXECINSTR
+# CHECK-NEXT: SHF_GROUP
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address:
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size: 4
+
+# CHECK: Groups {
+# CHECK-NEXT: Group {
+# CHECK-NEXT: Name: .group
+# CHECK-NEXT: Index: 2
+# CHECK-NEXT: Type: COMDAT
+# CHECK-NEXT: Signature: abc
+# CHECK-NEXT: Section(s) in group [
+# CHECK-NEXT: .text.bar
+# CHECK-NEXT: .text.foo
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+
+.section .text.bar,"axG", at progbits,abc,comdat
+.quad 42
+.section .text.foo,"axG", at progbits,abc,comdat
+.long 42
More information about the llvm-commits
mailing list