[PATCH] D33485: [ELF] - Do not allow -r to eat comdats.
Rafael Avila de Espindola via llvm-commits
llvm-commits at lists.llvm.org
Thu May 25 10:15:42 PDT 2017
LGTM
George Rimar via Phabricator <reviews at reviews.llvm.org> writes:
> grimar updated this revision to Diff 100217.
> grimar added a comment.
>
> - Addressed review comments.
>
>
> https://reviews.llvm.org/D33485
>
> Files:
> ELF/InputFiles.cpp
> ELF/InputSection.cpp
> ELF/InputSection.h
> ELF/OutputSections.cpp
> test/ELF/relocatable-comdat.s
>
> Index: test/ELF/relocatable-comdat.s
> ===================================================================
> --- test/ELF/relocatable-comdat.s
> +++ test/ELF/relocatable-comdat.s
> @@ -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
> Index: ELF/OutputSections.cpp
> ===================================================================
> --- ELF/OutputSections.cpp
> +++ ELF/OutputSections.cpp
> @@ -126,6 +126,20 @@
> }
>
> uint32_t Type = this->Type;
> + if (Type == SHT_GROUP) {
> + // sh_link field for SHT_GROUP sections should contain the section index of
> + // the symbol table.
> + this->Link = InX::SymTab->OutSec->SectionIndex;
> +
> + // sh_link then contain index of an entry in symbol table section which
> + // provides signature of the section group.
> + InputSection *First = Sections[0];
> + elf::ObjectFile<ELFT> *Obj = First->getFile<ELFT>();
> + ArrayRef<SymbolBody *> Symbols = Obj->getSymbols();
> + this->Info = InX::SymTab->getSymbolIndex(Symbols[First->Info - 1]);
> + return;
> + }
> +
> if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL))
> return;
>
> @@ -260,6 +274,8 @@
> }
>
> static uint64_t getOutFlags(InputSectionBase *S) {
> + if (Config->Relocatable)
> + return S->Flags & ~SHF_COMPRESSED;
> return S->Flags & ~SHF_GROUP & ~SHF_COMPRESSED;
> }
>
> Index: ELF/InputSection.h
> ===================================================================
> --- ELF/InputSection.h
> +++ ELF/InputSection.h
> @@ -319,6 +319,9 @@
> private:
> template <class ELFT, class RelTy>
> void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
> +
> + template <class ELFT, class EntTy>
> + void copyGroup(uint8_t *Buf, llvm::ArrayRef<EntTy> Ents);
> };
>
> // The list of all input sections.
> Index: ELF/InputSection.cpp
> ===================================================================
> --- ELF/InputSection.cpp
> +++ ELF/InputSection.cpp
> @@ -294,6 +294,21 @@
> return S->kind() != Output;
> }
>
> +template <class ELFT, class EntTy>
> +void InputSection::copyGroup(uint8_t *Buf, llvm::ArrayRef<EntTy> Ents) {
> + assert(this->Type == SHT_GROUP);
> +
> + // First entry is a flag word, we leave it unchanged.
> + auto *P = reinterpret_cast<typename ELFT::Word *>(Buf);
> + *P++ = Ents[0];
> +
> + // Here we adjust indices of sections that belong to group as it
> + // might change during linking.
> + ArrayRef<InputSectionBase *> Sections = this->File->getSections();
> + for (const EntTy &Ent : Ents.slice(1))
> + *P++ = Sections[Ent]->OutSec->SectionIndex;
> +}
> +
> InputSectionBase *InputSection::getRelocatedSection() {
> assert(this->Type == SHT_RELA || this->Type == SHT_REL);
> ArrayRef<InputSectionBase *> Sections = this->File->getSections();
> @@ -679,6 +694,14 @@
> return;
> }
>
> + // If -r is given, linker should keep SHT_GROUP sections. We should fixup
> + // them, see copyGroup().
> + if (this->Type == SHT_GROUP) {
> + copyGroup<ELFT>(Buf + OutSecOff,
> + this->template getDataAs<typename ELFT::Word>());
> + return;
> + }
> +
> // Copy section contents from source object file to output file
> // and then apply relocations.
> memcpy(Buf + OutSecOff, Data.data(), Data.size());
> Index: ELF/InputFiles.cpp
> ===================================================================
> --- ELF/InputFiles.cpp
> +++ ELF/InputFiles.cpp
> @@ -303,17 +303,23 @@
> }
>
> switch (Sec.sh_type) {
> - case SHT_GROUP:
> - this->Sections[I] = &InputSection::Discarded;
> - if (ComdatGroups.insert(getShtGroupSignature(ObjSections, Sec)).second)
> + case SHT_GROUP: {
> + bool New =
> + ComdatGroups.insert(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) +
> ": invalid section index in group: " + Twine(SecIndex));
> this->Sections[SecIndex] = &InputSection::Discarded;
> }
> - break;
> + } break;
> case SHT_SYMTAB:
> this->initSymtab(ObjSections, &Sec);
> break;
More information about the llvm-commits
mailing list