[lld] r286398 - [ELF][MIPS] Convert .MIPS.abiflags section to synthetic input section

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 9 13:37:07 PST 2016


Author: atanasyan
Date: Wed Nov  9 15:37:06 2016
New Revision: 286398

URL: http://llvm.org/viewvc/llvm-project?rev=286398&view=rev
Log:
[ELF][MIPS] Convert .MIPS.abiflags section to synthetic input section

Previously, we have both input and output section for .MIPS.abiflags.
Now we have only one class for .MIPS.abiflags, which is MipsAbiFlagsSection.
This class is a synthetic input section.

.MIPS.abiflags sections are handled as regular sections until
the control reaches Writer. Writer then aggregates all sections
whose type is SHT_MIPS_ABIFLAGS to create a single synthesized
input section. The synthesized section is then processed normally
as if it came from an input file.

Removed:
    lld/trunk/test/ELF/invalid/mips-multiple-abiflags.test
Modified:
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputFiles.h
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/InputSection.h
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/mips-n32-rels.s

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=286398&r1=286397&r2=286398&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Wed Nov  9 15:37:06 2016
@@ -340,12 +340,6 @@ elf::ObjectFile<ELFT>::createInputSectio
     // FIXME: ARM meta-data section. At present attributes are ignored,
     // they can be used to reason about object compatibility.
     return &InputSection<ELFT>::Discarded;
-  case SHT_MIPS_ABIFLAGS:
-    if (MipsAbiFlags)
-      fatal(getFilename(this) +
-            ": multiple SHT_MIPS_ABIFLAGS sections are not allowed");
-    MipsAbiFlags.reset(new MipsAbiFlagsInputSection<ELFT>(this, &Sec, Name));
-    return MipsAbiFlags.get();
   case SHT_RELA:
   case SHT_REL: {
     // This section contains relocation information.

Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=286398&r1=286397&r2=286398&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Wed Nov  9 15:37:06 2016
@@ -194,9 +194,6 @@ private:
   // List of all symbols referenced or defined by this file.
   std::vector<SymbolBody *> SymbolBodies;
 
-  // MIPS .MIPS.abiflags section defined by this file.
-  std::unique_ptr<MipsAbiFlagsInputSection<ELFT>> MipsAbiFlags;
-
   // Debugging information to retrieve source file and line for error
   // reporting. Linker may find reasonable number of errors in a
   // single object file, so we cache debugging information in order to

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=286398&r1=286397&r2=286398&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Wed Nov  9 15:37:06 2016
@@ -103,15 +103,6 @@ typename ELFT::uint InputSectionBase<ELF
     return Offset;
   case Merge:
     return cast<MergeInputSection<ELFT>>(this)->getOffset(Offset);
-  case MipsAbiFlags:
-    // .MIPS.abiflags sections is consumed
-    // by the linker, and the linker produces a single output section. It is
-    // possible that input files contain section symbol points to the
-    // corresponding input section. Redirect it to the produced output section.
-    if (Offset != 0)
-      fatal(getName(this) + ": unsupported reference to the middle of '" +
-            Name + "' section");
-    return this->OutSec->Addr;
   }
   llvm_unreachable("invalid section kind");
 }
@@ -798,25 +789,6 @@ template <class ELFT> void MergeInputSec
   }
 }
 
-template <class ELFT>
-MipsAbiFlagsInputSection<ELFT>::MipsAbiFlagsInputSection(
-    elf::ObjectFile<ELFT> *F, const Elf_Shdr *Hdr, StringRef Name)
-    : InputSectionBase<ELFT>(F, Hdr, Name,
-                             InputSectionBase<ELFT>::MipsAbiFlags) {
-  // Initialize this->Flags.
-  ArrayRef<uint8_t> Data = this->Data;
-  if (Data.size() != sizeof(Elf_Mips_ABIFlags<ELFT>)) {
-    error("invalid size of .MIPS.abiflags section");
-    return;
-  }
-  Flags = reinterpret_cast<const Elf_Mips_ABIFlags<ELFT> *>(Data.data());
-}
-
-template <class ELFT>
-bool MipsAbiFlagsInputSection<ELFT>::classof(const InputSectionData *S) {
-  return S->kind() == InputSectionBase<ELFT>::MipsAbiFlags;
-}
-
 template class elf::InputSectionBase<ELF32LE>;
 template class elf::InputSectionBase<ELF32BE>;
 template class elf::InputSectionBase<ELF64LE>;
@@ -836,8 +808,3 @@ template class elf::MergeInputSection<EL
 template class elf::MergeInputSection<ELF32BE>;
 template class elf::MergeInputSection<ELF64LE>;
 template class elf::MergeInputSection<ELF64BE>;
-
-template class elf::MipsAbiFlagsInputSection<ELF32LE>;
-template class elf::MipsAbiFlagsInputSection<ELF32BE>;
-template class elf::MipsAbiFlagsInputSection<ELF64LE>;
-template class elf::MipsAbiFlagsInputSection<ELF64BE>;

Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=286398&r1=286397&r2=286398&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Wed Nov  9 15:37:06 2016
@@ -39,7 +39,7 @@ template <class ELFT> class OutputSectio
 // section
 class InputSectionData {
 public:
-  enum Kind { Regular, EHFrame, Merge, MipsAbiFlags };
+  enum Kind { Regular, EHFrame, Merge };
 
   // The garbage collector sets sections' Live bits.
   // If GC is disabled, all sections are considered live by default.
@@ -288,18 +288,6 @@ private:
 
 template <class ELFT> InputSection<ELFT> InputSection<ELFT>::Discarded;
 
-template <class ELFT>
-class MipsAbiFlagsInputSection : public InputSectionBase<ELFT> {
-  typedef typename ELFT::Shdr Elf_Shdr;
-
-public:
-  MipsAbiFlagsInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Hdr,
-                           StringRef Name);
-  static bool classof(const InputSectionData *S);
-
-  const llvm::object::Elf_Mips_ABIFlags<ELFT> *Flags = nullptr;
-};
-
 } // namespace elf
 } // namespace lld
 

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=286398&r1=286397&r2=286398&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Wed Nov  9 15:37:06 2016
@@ -918,6 +918,8 @@ OutputSection<ELFT>::OutputSection(Strin
   else if (Type == SHT_MIPS_OPTIONS)
     this->Entsize =
         sizeof(Elf_Mips_Options<ELFT>) + sizeof(Elf_Mips_RegInfo<ELFT>);
+  else if (Type == SHT_MIPS_ABIFLAGS)
+    this->Entsize = sizeof(Elf_Mips_ABIFlags<ELFT>);
 }
 
 template <class ELFT> void OutputSection<ELFT>::finalize() {
@@ -1730,46 +1732,6 @@ template <class ELFT> void VersionNeedSe
 }
 
 template <class ELFT>
-MipsAbiFlagsOutputSection<ELFT>::MipsAbiFlagsOutputSection()
-    : OutputSectionBase<ELFT>(".MIPS.abiflags", SHT_MIPS_ABIFLAGS, SHF_ALLOC) {
-  this->Addralign = 8;
-  this->Entsize = sizeof(Elf_Mips_ABIFlags);
-  this->Size = sizeof(Elf_Mips_ABIFlags);
-  memset(&Flags, 0, sizeof(Flags));
-}
-
-template <class ELFT>
-void MipsAbiFlagsOutputSection<ELFT>::writeTo(uint8_t *Buf) {
-  memcpy(Buf, &Flags, sizeof(Flags));
-}
-
-template <class ELFT>
-void MipsAbiFlagsOutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
-  // Check compatibility and merge fields from input .MIPS.abiflags
-  // to the output one.
-  auto *S = cast<MipsAbiFlagsInputSection<ELFT>>(C);
-  S->OutSec = this;
-  if (S->Flags->version != 0) {
-    error(getFilename(S->getFile()) + ": unexpected .MIPS.abiflags version " +
-          Twine(S->Flags->version));
-    return;
-  }
-  // LLD checks ISA compatibility in getMipsEFlags(). Here we just
-  // select the highest number of ISA/Rev/Ext.
-  Flags.isa_level = std::max(Flags.isa_level, S->Flags->isa_level);
-  Flags.isa_rev = std::max(Flags.isa_rev, S->Flags->isa_rev);
-  Flags.isa_ext = std::max(Flags.isa_ext, S->Flags->isa_ext);
-  Flags.gpr_size = std::max(Flags.gpr_size, S->Flags->gpr_size);
-  Flags.cpr1_size = std::max(Flags.cpr1_size, S->Flags->cpr1_size);
-  Flags.cpr2_size = std::max(Flags.cpr2_size, S->Flags->cpr2_size);
-  Flags.ases |= S->Flags->ases;
-  Flags.flags1 |= S->Flags->flags1;
-  Flags.flags2 |= S->Flags->flags2;
-  Flags.fp_abi = elf::getMipsFpAbiFlag(Flags.fp_abi, S->Flags->fp_abi,
-                                       getFilename(S->getFile()));
-}
-
-template <class ELFT>
 static typename ELFT::uint getOutFlags(InputSectionBase<ELFT> *S) {
   return S->Flags & ~SHF_GROUP & ~SHF_COMPRESSED;
 }
@@ -1823,9 +1785,6 @@ OutputSectionFactory<ELFT>::create(const
   case InputSectionBase<ELFT>::Merge:
     Sec = make<MergeOutputSection<ELFT>>(Key.Name, Type, Flags, Key.Alignment);
     break;
-  case InputSectionBase<ELFT>::MipsAbiFlags:
-    Sec = make<MipsAbiFlagsOutputSection<ELFT>>();
-    break;
   }
   return {Sec, true};
 }
@@ -1919,11 +1878,6 @@ template class EhOutputSection<ELF32BE>;
 template class EhOutputSection<ELF64LE>;
 template class EhOutputSection<ELF64BE>;
 
-template class MipsAbiFlagsOutputSection<ELF32LE>;
-template class MipsAbiFlagsOutputSection<ELF32BE>;
-template class MipsAbiFlagsOutputSection<ELF64LE>;
-template class MipsAbiFlagsOutputSection<ELF64BE>;
-
 template class MergeOutputSection<ELF32LE>;
 template class MergeOutputSection<ELF32BE>;
 template class MergeOutputSection<ELF64LE>;

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=286398&r1=286397&r2=286398&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Wed Nov  9 15:37:06 2016
@@ -56,7 +56,6 @@ public:
     GotPlt,
     HashTable,
     Merge,
-    MipsAbiFlags,
     Plt,
     Regular,
     Reloc,
@@ -630,24 +629,6 @@ private:
   void Add(Entry E) { Entries.push_back(E); }
 };
 
-template <class ELFT>
-class MipsAbiFlagsOutputSection final : public OutputSectionBase<ELFT> {
-  typedef llvm::object::Elf_Mips_ABIFlags<ELFT> Elf_Mips_ABIFlags;
-  typedef OutputSectionBase<ELFT> Base;
-
-public:
-  MipsAbiFlagsOutputSection();
-  void writeTo(uint8_t *Buf) override;
-  void addSection(InputSectionBase<ELFT> *S) override;
-  typename Base::Kind getKind() const override { return Base::MipsAbiFlags; }
-  static bool classof(const Base *B) {
-    return B->getKind() == Base::MipsAbiFlags;
-  }
-
-private:
-  Elf_Mips_ABIFlags Flags;
-};
-
 // --eh-frame-hdr option tells linker to construct a header for all the
 // .eh_frame sections. This header is placed to a section named .eh_frame_hdr
 // and also to a PT_GNU_EH_FRAME segment.

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=286398&r1=286397&r2=286398&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Wed Nov  9 15:37:06 2016
@@ -23,6 +23,7 @@
 #include "Strings.h"
 #include "SymbolTable.h"
 #include "Target.h"
+#include "Writer.h"
 
 #include "lld/Core/Parallel.h"
 #include "llvm/Support/Endian.h"
@@ -92,6 +93,42 @@ static void iterateSectionContents(
   }
 }
 
+// .MIPS.abiflags section.
+template <class ELFT>
+MipsAbiFlagsSection<ELFT>::MipsAbiFlagsSection()
+    : InputSection<ELFT>(SHF_ALLOC, SHT_MIPS_ABIFLAGS, 8, ArrayRef<uint8_t>(),
+                         ".MIPS.abiflags") {
+  auto Func = [this](ObjectFile<ELFT> *F, ArrayRef<uint8_t> D) {
+    if (D.size() != sizeof(Elf_Mips_ABIFlags)) {
+      error(getFilename(F) + ": invalid size of .MIPS.abiflags section");
+      return;
+    }
+    auto *S = reinterpret_cast<const Elf_Mips_ABIFlags *>(D.data());
+    if (S->version != 0) {
+      error(getFilename(F) + ": unexpected .MIPS.abiflags version " +
+            Twine(S->version));
+      return;
+    }
+    // LLD checks ISA compatibility in getMipsEFlags(). Here we just
+    // select the highest number of ISA/Rev/Ext.
+    Flags.isa_level = std::max(Flags.isa_level, S->isa_level);
+    Flags.isa_rev = std::max(Flags.isa_rev, S->isa_rev);
+    Flags.isa_ext = std::max(Flags.isa_ext, S->isa_ext);
+    Flags.gpr_size = std::max(Flags.gpr_size, S->gpr_size);
+    Flags.cpr1_size = std::max(Flags.cpr1_size, S->cpr1_size);
+    Flags.cpr2_size = std::max(Flags.cpr2_size, S->cpr2_size);
+    Flags.ases |= S->ases;
+    Flags.flags1 |= S->flags1;
+    Flags.flags2 |= S->flags2;
+    Flags.fp_abi =
+        elf::getMipsFpAbiFlag(Flags.fp_abi, S->fp_abi, getFilename(F));
+  };
+  iterateSectionContents<ELFT>(SHT_MIPS_ABIFLAGS, Func);
+
+  this->Data = ArrayRef<uint8_t>((const uint8_t *)&Flags, sizeof(Flags));
+  this->Live = true;
+}
+
 // .MIPS.options section.
 template <class ELFT>
 MipsOptionsSection<ELFT>::MipsOptionsSection()
@@ -282,6 +319,11 @@ template InputSection<ELF32BE> *elf::cre
 template InputSection<ELF64LE> *elf::createInterpSection();
 template InputSection<ELF64BE> *elf::createInterpSection();
 
+template class elf::MipsAbiFlagsSection<ELF32LE>;
+template class elf::MipsAbiFlagsSection<ELF32BE>;
+template class elf::MipsAbiFlagsSection<ELF64LE>;
+template class elf::MipsAbiFlagsSection<ELF64BE>;
+
 template class elf::MipsOptionsSection<ELF32LE>;
 template class elf::MipsOptionsSection<ELF32BE>;
 template class elf::MipsOptionsSection<ELF64LE>;

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=286398&r1=286397&r2=286398&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Wed Nov  9 15:37:06 2016
@@ -15,6 +15,18 @@
 namespace lld {
 namespace elf {
 
+// .MIPS.abiflags section.
+template <class ELFT>
+class MipsAbiFlagsSection final : public InputSection<ELFT> {
+  typedef llvm::object::Elf_Mips_ABIFlags<ELFT> Elf_Mips_ABIFlags;
+
+public:
+  MipsAbiFlagsSection();
+
+private:
+  Elf_Mips_ABIFlags Flags = {};
+};
+
 // .MIPS.options section.
 template <class ELFT>
 class MipsOptionsSection final : public InputSection<ELFT> {
@@ -105,6 +117,7 @@ template <class ELFT> struct In {
   static BuildIdSection<ELFT> *BuildId;
   static InputSection<ELFT> *Common;
   static InputSection<ELFT> *Interp;
+  static MipsAbiFlagsSection<ELFT> *MipsAbiFlags;
   static MipsOptionsSection<ELFT> *MipsOptions;
   static MipsReginfoSection<ELFT> *MipsReginfo;
 };
@@ -112,6 +125,7 @@ template <class ELFT> struct In {
 template <class ELFT> BuildIdSection<ELFT> *In<ELFT>::BuildId;
 template <class ELFT> InputSection<ELFT> *In<ELFT>::Common;
 template <class ELFT> InputSection<ELFT> *In<ELFT>::Interp;
+template <class ELFT> MipsAbiFlagsSection<ELFT> *In<ELFT>::MipsAbiFlags;
 template <class ELFT> MipsOptionsSection<ELFT> *In<ELFT>::MipsOptions;
 template <class ELFT> MipsReginfoSection<ELFT> *In<ELFT>::MipsReginfo;
 

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=286398&r1=286397&r2=286398&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Nov  9 15:37:06 2016
@@ -293,6 +293,12 @@ template <class ELFT> void Writer<ELFT>:
   }
 
   if (Config->EMachine == EM_MIPS) {
+    // .MIPS.abiflags
+    auto *AbiFlags = make<MipsAbiFlagsSection<ELFT>>();
+    if (AbiFlags->Live) {
+      In<ELFT>::MipsAbiFlags = AbiFlags;
+      Symtab<ELFT>::X->Sections.push_back(AbiFlags);
+    }
     // .MIPS.options
     auto *OptSec = make<MipsOptionsSection<ELFT>>();
     if (OptSec->Live) {

Removed: lld/trunk/test/ELF/invalid/mips-multiple-abiflags.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/invalid/mips-multiple-abiflags.test?rev=286397&view=auto
==============================================================================
--- lld/trunk/test/ELF/invalid/mips-multiple-abiflags.test (original)
+++ lld/trunk/test/ELF/invalid/mips-multiple-abiflags.test (removed)
@@ -1,21 +0,0 @@
-# RUN: yaml2obj %s -o %t
-# RUN: not ld.lld %t -o %tout 2>&1 | FileCheck %s
-
---- !ELF
-FileHeader:
-  Class:    ELFCLASS32
-  Data:     ELFDATA2LSB
-  Type:     ET_REL
-  Machine:  EM_MIPS
-  Flags:    [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
-
-Sections:
-  - Name:          .foo1
-    Type:          SHT_MIPS_ABIFLAGS
-    ISA:           MIPS64
-
-  - Name:          .foo2
-    Type:          SHT_MIPS_ABIFLAGS
-    ISA:           MIPS64
-
-# CHECK: multiple SHT_MIPS_ABIFLAGS sections are not allowed

Modified: lld/trunk/test/ELF/mips-n32-rels.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-n32-rels.s?rev=286398&r1=286397&r2=286398&view=diff
==============================================================================
--- lld/trunk/test/ELF/mips-n32-rels.s (original)
+++ lld/trunk/test/ELF/mips-n32-rels.s Wed Nov  9 15:37:06 2016
@@ -38,7 +38,7 @@
 #                                                       ^-- %lo(0x17ff0)
 
 # CHECK:      Contents of section .rodata:
-# CHECK-NEXT:  10110 00020004
+# CHECK-NEXT:  100f4 00020004
 #                    ^-- loc
 
 # CHECK: 00020004      .text   00000000 loc




More information about the llvm-commits mailing list