[lld] r209987 - [Mips] Implement .{ctors, dtors}.<priority> sections ordering.

Simon Atanasyan simon at atanasyan.com
Sat May 31 23:28:43 PDT 2014


Author: atanasyan
Date: Sun Jun  1 01:28:42 2014
New Revision: 209987

URL: http://llvm.org/viewvc/llvm-project?rev=209987&view=rev
Log:
[Mips] Implement .{ctors,dtors}.<priority> sections ordering.

Arrange .ctors/.dtors sections in the following order:
  .ctors from crtbegin.o or crtbegin?.o
  .ctors from regular object files
  .ctors.* (sorted) from regular object files
  .ctors from crtend.o or crtend?.o

This order is specific for MIPS traget. For example, on X86
the .ctors.* sections are merged into the .init_array section.

Added:
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.h
    lld/trunk/test/elf/Mips/ctors-order.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt?rev=209987&r1=209986&r2=209987&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt Sun Jun  1 01:28:42 2014
@@ -1,4 +1,5 @@
 add_lld_library(lldMipsELFTarget
+  MipsCtorsOrderPass.cpp
   MipsLinkingContext.cpp
   MipsRelocationHandler.cpp
   MipsRelocationPass.cpp

Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.cpp?rev=209987&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.cpp (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.cpp Sun Jun  1 01:28:42 2014
@@ -0,0 +1,74 @@
+//===- lib/ReaderWriter/ELF/Mips/Mips/CtorsOrderPass.cpp ------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MipsCtorsOrderPass.h"
+
+#include <algorithm>
+#include <climits>
+
+using namespace lld;
+using namespace lld::elf;
+
+static bool matchCrtObjName(StringRef objName, StringRef objPath) {
+  if (!objPath.endswith(".o"))
+    return false;
+
+  // check *<objName> case
+  objPath = objPath.drop_back(2);
+  if (objPath.endswith(objName))
+    return true;
+
+  // check *<objName>? case
+  return !objPath.empty() && objPath.drop_back(1).endswith(objName);
+}
+
+static int32_t getSectionPriority(StringRef path, StringRef sectionName) {
+  // Arrange .ctors/.dtors sections in the following order:
+  //   .ctors from crtbegin.o or crtbegin?.o
+  //   .ctors from regular object files
+  //   .ctors.* (sorted) from regular object files
+  //   .ctors from crtend.o or crtend?.o
+
+  if (matchCrtObjName("crtbegin", path))
+    return std::numeric_limits<int32_t>::min();
+  if (matchCrtObjName("crtend", path))
+    return std::numeric_limits<int32_t>::max();
+
+  StringRef num = sectionName.drop_front().rsplit('.').second;
+
+  int32_t priority = std::numeric_limits<int32_t>::min() + 1;
+  if (!num.empty())
+    num.getAsInteger(10, priority);
+
+  return priority;
+}
+
+void MipsCtorsOrderPass::perform(std::unique_ptr<MutableFile> &f) {
+  auto definedAtoms = f->definedAtoms();
+
+  auto last = std::stable_partition(definedAtoms.begin(), definedAtoms.end(),
+                                    [](const DefinedAtom *atom) {
+    if (atom->sectionChoice() != DefinedAtom::sectionCustomRequired)
+      return false;
+
+    StringRef name = atom->customSectionName();
+    return name.startswith(".ctors") || name.startswith(".dtors");
+  });
+
+  std::stable_sort(definedAtoms.begin(), last,
+                   [](const DefinedAtom *left, const DefinedAtom *right) {
+    StringRef leftSec = left->customSectionName();
+    StringRef rightSec = right->customSectionName();
+
+    int32_t leftPriority = getSectionPriority(left->file().path(), leftSec);
+    int32_t rightPriority = getSectionPriority(right->file().path(), rightSec);
+
+    return leftPriority < rightPriority;
+  });
+}

Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.h?rev=209987&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.h Sun Jun  1 01:28:42 2014
@@ -0,0 +1,25 @@
+//===- lib/ReaderWriter/ELF/Mips/MipsCtorsOrderPass.h ---------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_CTORS_ORDER_PASS_H
+#define LLD_READER_WRITER_ELF_MIPS_MIPS_CTORS_ORDER_PASS_H
+
+#include "lld/Core/Pass.h"
+
+namespace lld {
+namespace elf {
+/// \brief This pass sorts atoms in .{ctors,dtors}.<priority> sections.
+class MipsCtorsOrderPass : public Pass {
+public:
+  void perform(std::unique_ptr<MutableFile> &mergedFile) override;
+};
+}
+}
+
+#endif

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp?rev=209987&r1=209986&r2=209987&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp Sun Jun  1 01:28:42 2014
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "Atoms.h"
+#include "MipsCtorsOrderPass.h"
 #include "MipsLinkingContext.h"
 #include "MipsRelocationPass.h"
 #include "MipsTargetHandler.h"
@@ -44,6 +45,7 @@ void MipsLinkingContext::addPasses(PassM
   if (pass)
     pm.add(std::move(pass));
   ELFLinkingContext::addPasses(pm);
+  pm.add(std::unique_ptr<Pass>(new elf::MipsCtorsOrderPass()));
 }
 
 bool MipsLinkingContext::isDynamicRelocation(const DefinedAtom &,

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h?rev=209987&r1=209986&r2=209987&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h Sun Jun  1 01:28:42 2014
@@ -43,6 +43,23 @@ public:
                                                  order);
   }
 
+  StringRef getSectionName(const DefinedAtom *da) const override {
+    return llvm::StringSwitch<StringRef>(da->customSectionName())
+        .StartsWith(".ctors", ".ctors")
+        .StartsWith(".dtors", ".dtors")
+        .Default(TargetLayout<ELFType>::getSectionName(da));
+  }
+
+  Layout::SegmentType getSegmentType(Section<ELFType> *section) const override {
+    switch (section->order()) {
+    case DefaultLayout<ELFType>::ORDER_CTORS:
+    case DefaultLayout<ELFType>::ORDER_DTORS:
+      return llvm::ELF::PT_LOAD;
+    default:
+      return TargetLayout<ELFType>::getSegmentType(section);
+    }
+  }
+
   /// \brief GP offset relative to .got section.
   uint64_t getGPOffset() const { return 0x7FF0; }
 

Added: lld/trunk/test/elf/Mips/ctors-order.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/ctors-order.test?rev=209987&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/ctors-order.test (added)
+++ lld/trunk/test/elf/Mips/ctors-order.test Sun Jun  1 01:28:42 2014
@@ -0,0 +1,163 @@
+# Check ordering of .ctors.* sections.
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-crtbeginS.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-crtendS.o
+# RUN: yaml2obj -format=elf -docnum 3 %s > %t-obj.o
+# RUN: lld -flavor gnu -target mipsel -shared --output-filetype=yaml \
+# RUN:     %t-crtbeginS.o %t-obj.o %t-crtendS.o | FileCheck %s
+
+# CHECK:      defined-atoms:
+# CHECK-NEXT:   - ref-name:        L000
+# CHECK-NEXT:     type:            data
+# CHECK-NEXT:     alignment:       2^2
+# CHECK-NEXT:     section-choice:  custom-required
+# CHECK-NEXT:     section-name:    .ctors
+# CHECK-NEXT:     references:
+# CHECK-NEXT:       - kind:            layout-after
+# CHECK-NEXT:         offset:          0
+# CHECK-NEXT:         target:          __CTOR_LIST__
+# CHECK-NEXT:   - name:            __CTOR_LIST__
+# CHECK-NEXT:     type:            data
+# CHECK-NEXT:     content:         [ FF, FF, FF, FF ]
+# CHECK-NEXT:     alignment:       2^2
+# CHECK-NEXT:     section-choice:  custom-required
+# CHECK-NEXT:     section-name:    .ctors
+# CHECK-NEXT:     references:
+# CHECK-NEXT:       - kind:            in-group
+# CHECK-NEXT:         offset:          0
+# CHECK-NEXT:         target:          L000
+# CHECK-NEXT:   - type:            data
+# CHECK-NEXT:     content:         [ 11, 11, 11, 11 ]
+# CHECK-NEXT:     alignment:       2^2
+# CHECK-NEXT:     section-choice:  custom-required
+# CHECK-NEXT:     section-name:    .ctors.1
+# CHECK-NEXT:   - type:            data
+# CHECK-NEXT:     content:         [ 22, 22, 22, 22 ]
+# CHECK-NEXT:     alignment:       2^2
+# CHECK-NEXT:     section-choice:  custom-required
+# CHECK-NEXT:     section-name:    .ctors.2
+# CHECK-NEXT:   - ref-name:        L005
+# CHECK-NEXT:     type:            data
+# CHECK-NEXT:     alignment:       2^2
+# CHECK-NEXT:     section-choice:  custom-required
+# CHECK-NEXT:     section-name:    .ctors
+# CHECK-NEXT:     references:
+# CHECK-NEXT:       - kind:            layout-after
+# CHECK-NEXT:         offset:          0
+# CHECK-NEXT:         target:          __CTOR_END__
+# CHECK-NEXT:   - name:            __CTOR_END__
+# CHECK-NEXT:     type:            data
+# CHECK-NEXT:     content:         [ 00, 00, 00, 00 ]
+# CHECK-NEXT:     alignment:       2^2
+# CHECK-NEXT:     section-choice:  custom-required
+# CHECK-NEXT:     section-name:    .ctors
+
+# crtbeginS.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_NOREORDER, EF_MIPS_CPIC,
+                     EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2 ]
+Sections:
+  - Name:            .ctors
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x04
+    Content:         'FFFFFFFF'
+
+Symbols:
+  Local:
+    - Name:            .ctors
+      Type:            STT_SECTION
+      Section:         .ctors
+    - Name:            __CTOR_LIST__
+      Type:            STT_OBJECT
+      Section:         .ctors
+
+# crtendS.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_NOREORDER, EF_MIPS_CPIC,
+                     EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2 ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x04
+    Size:            0x0F
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    Info:            .text
+    AddressAlign:    0x04
+    Relocations:
+      - Offset:          0x00
+        Symbol:          .ctors
+        Type:            R_MIPS_HI16
+      - Offset:          0x04
+        Symbol:          .ctors
+        Type:            R_MIPS_LO16
+      - Offset:          0x08
+        Symbol:          .ctors
+        Type:            R_MIPS_HI16
+      - Offset:          0x0C
+        Symbol:          .ctors
+        Type:            R_MIPS_LO16
+  - Name:            .ctors
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x04
+    Size:            0x04
+
+Symbols:
+  Local:
+    - Name:            .text
+      Type:            STT_SECTION
+      Section:         .text
+    - Name:            .ctors
+      Type:            STT_SECTION
+      Section:         .ctors
+    - Name:            __CTOR_END__
+      Type:            STT_OBJECT
+      Section:         .ctors
+    - Name:            __do_global_ctors_aux
+      Type:            STT_FUNC
+      Section:         .text
+
+# obj.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_NOREORDER, EF_MIPS_CPIC,
+                     EF_MIPS_ABI_O32, EF_MIPS_ARCH_32 ]
+Sections:
+  - Name:            .ctors.2
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x04
+    Content:         '22222222'
+  - Name:            .ctors.1
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x04
+    Content:         '11111111'
+
+Symbols:
+  Local:
+    - Name:            .ctors.2
+      Type:            STT_SECTION
+      Section:         .ctors.2
+    - Name:            .ctors.1
+      Type:            STT_SECTION
+      Section:         .ctors.1
+...





More information about the llvm-commits mailing list