1 //===- lib/ReaderWriter/ELF/Mips/Mips/CtorsOrderPass.cpp ------------------===//
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MipsCtorsOrderPass.h"
15 using namespace lld::elf;
17 static bool matchCrtObjName(StringRef objName, StringRef objPath) {
18 if (!objPath.endswith(".o"))
21 // check *<objName> case
22 objPath = objPath.drop_back(2);
23 if (objPath.endswith(objName))
26 // check *<objName>? case
27 return !objPath.empty() && objPath.drop_back(1).endswith(objName);
30 static int32_t getSectionPriority(StringRef path, StringRef sectionName) {
31 // Arrange .ctors/.dtors sections in the following order:
32 // .ctors from crtbegin.o or crtbegin?.o
33 // .ctors from regular object files
34 // .ctors.* (sorted) from regular object files
35 // .ctors from crtend.o or crtend?.o
37 if (matchCrtObjName("crtbegin", path))
38 return std::numeric_limits<int32_t>::min();
39 if (matchCrtObjName("crtend", path))
40 return std::numeric_limits<int32_t>::max();
42 StringRef num = sectionName.drop_front().rsplit('.').second;
44 int32_t priority = std::numeric_limits<int32_t>::min() + 1;
46 num.getAsInteger(10, priority);
51 void MipsCtorsOrderPass::perform(std::unique_ptr<MutableFile> &f) {
52 auto definedAtoms = f->definedAtoms();
54 auto last = std::stable_partition(definedAtoms.begin(), definedAtoms.end(),
55 [](const DefinedAtom *atom) {
56 if (atom->sectionChoice() != DefinedAtom::sectionCustomRequired)
59 StringRef name = atom->customSectionName();
60 return name.startswith(".ctors") || name.startswith(".dtors");
63 std::stable_sort(definedAtoms.begin(), last,
64 [](const DefinedAtom *left, const DefinedAtom *right) {
65 StringRef leftSec = left->customSectionName();
66 StringRef rightSec = right->customSectionName();
68 int32_t leftPriority = getSectionPriority(left->file().path(), leftSec);
69 int32_t rightPriority = getSectionPriority(right->file().path(), rightSec);
71 return leftPriority < rightPriority;