summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/ELF/ArrayOrderPass.cpp
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2015-01-31 02:05:01 +0000
committerRui Ueyama <ruiu@google.com>2015-01-31 02:05:01 +0000
commit33ab83bc4b421088b90f3885bf9fac5eb999bbdd (patch)
treef8783346f8d896a9cf12a72cbb37a5ad08aabb22 /lld/lib/ReaderWriter/ELF/ArrayOrderPass.cpp
parente41a26e4b403028d2f259af49a8e7fe36f780639 (diff)
downloadbcm5719-llvm-33ab83bc4b421088b90f3885bf9fac5eb999bbdd.tar.gz
bcm5719-llvm-33ab83bc4b421088b90f3885bf9fac5eb999bbdd.zip
ELF: Don't use LayoutPass.
Previously we applied the LayoutPass to order atoms and then apply elf::ArrayOrderPass to sort them again. The first pass is basically supposed to sort atoms in the normal fashion (which is to sort symbols in the same order as the input files). The second pass sorts atoms in {init,fini}_array.<priority> by priority. The problem is that the LayoutPass is overkill. It analyzes references between atoms to make a decision how to sort them. It's slow, hard to understand, and above all, it doesn't seem that we need its feature for ELF in the first place. This patch remove the LayoutPass from ELF pass list. Now all reordering is done in elf::OrderPass. That pass sorts atoms by {init,fini}_array, and if they are not in the special section, they are ordered as the same order as they appear in the command line. The new code is far easier to understand, faster, and still able to create valid executables. Unlike the previous layout pass, elf::OrderPass doesn't count any attributes of an atom (e.g. permissions) except its position. It's OK because the writer takes care of them if we have to. This patch changes the order of final output, although that's benign. Tests are updated. http://reviews.llvm.org/D7278 llvm-svn: 227666
Diffstat (limited to 'lld/lib/ReaderWriter/ELF/ArrayOrderPass.cpp')
-rw-r--r--lld/lib/ReaderWriter/ELF/ArrayOrderPass.cpp56
1 files changed, 0 insertions, 56 deletions
diff --git a/lld/lib/ReaderWriter/ELF/ArrayOrderPass.cpp b/lld/lib/ReaderWriter/ELF/ArrayOrderPass.cpp
deleted file mode 100644
index b279495d02b..00000000000
--- a/lld/lib/ReaderWriter/ELF/ArrayOrderPass.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-//===- lib/ReaderWriter/ELF/ArrayOrderPass.cpp ----------------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ArrayOrderPass.h"
-#include <algorithm>
-#include <limits>
-
-namespace lld {
-namespace elf {
-void ArrayOrderPass::perform(std::unique_ptr<MutableFile> &f) {
- auto definedAtoms = f->definedAtoms();
-
- // Move sections need to be sorted into the separate continious group.
- // That reduces a number of sorting elements and simplifies conditions
- // in the sorting predicate.
- 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(".init_array") || name.startswith(".fini_array");
- });
-
- std::stable_sort(definedAtoms.begin(), last,
- [](const DefinedAtom *left, const DefinedAtom *right) {
- StringRef leftSec = left->customSectionName();
- StringRef rightSec = right->customSectionName();
-
- // Drop the front dot from the section name and get
- // an optional section's number starting after the second dot.
- StringRef leftNum = leftSec.drop_front().rsplit('.').second;
- StringRef rightNum = rightSec.drop_front().rsplit('.').second;
-
- // Sort {.init_array, .fini_array}[.<num>] sections
- // according to their number. Sections without optional
- // numer suffix should go last.
-
- uint32_t leftPriority;
- uint32_t rightPriority;
- if (leftNum.getAsInteger(10, leftPriority))
- leftPriority = std::numeric_limits<uint32_t>::max();
- if (rightNum.getAsInteger(10, rightPriority))
- rightPriority = std::numeric_limits<uint32_t>::max();
-
- return leftPriority < rightPriority;
- });
-}
-} // end namespace elf
-} // end namespace lld
OpenPOWER on IntegriCloud