1 //===- OutputSegment.cpp --------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "OutputSegment.h" 10 #include "ConcatOutputSection.h" 11 #include "InputSection.h" 12 #include "SyntheticSections.h" 13 14 #include "lld/Common/ErrorHandler.h" 15 #include "lld/Common/Memory.h" 16 #include "llvm/ADT/StringSwitch.h" 17 #include "llvm/BinaryFormat/MachO.h" 18 19 using namespace llvm; 20 using namespace llvm::MachO; 21 using namespace lld; 22 using namespace lld::macho; 23 24 static uint32_t initProt(StringRef name) { 25 auto it = find_if( 26 config->segmentProtections, 27 [&](const SegmentProtection &segprot) { return segprot.name == name; }); 28 if (it != config->segmentProtections.end()) 29 return it->initProt; 30 31 if (name == segment_names::text) 32 return VM_PROT_READ | VM_PROT_EXECUTE; 33 if (name == segment_names::pageZero) 34 return 0; 35 if (name == segment_names::linkEdit) 36 return VM_PROT_READ; 37 return VM_PROT_READ | VM_PROT_WRITE; 38 } 39 40 static uint32_t maxProt(StringRef name) { 41 assert(config->arch() != AK_i386 && 42 "TODO: i386 has different maxProt requirements"); 43 return initProt(name); 44 } 45 46 size_t OutputSegment::numNonHiddenSections() const { 47 size_t count = 0; 48 for (const OutputSection *osec : sections) 49 count += (!osec->isHidden() ? 1 : 0); 50 return count; 51 } 52 53 void OutputSegment::addOutputSection(OutputSection *osec) { 54 inputOrder = std::min(inputOrder, osec->inputOrder); 55 56 osec->parent = this; 57 sections.push_back(osec); 58 59 for (const SectionAlign §Align : config->sectionAlignments) 60 if (sectAlign.segName == name && sectAlign.sectName == osec->name) 61 osec->align = sectAlign.align; 62 } 63 64 template <typename T, typename F> static auto compareByOrder(F ord) { 65 return [=](T a, T b) { return ord(a) < ord(b); }; 66 } 67 68 static int segmentOrder(OutputSegment *seg) { 69 return StringSwitch<int>(seg->name) 70 .Case(segment_names::pageZero, -4) 71 .Case(segment_names::text, -3) 72 .Case(segment_names::dataConst, -2) 73 .Case(segment_names::data, -1) 74 .Case(segment_names::llvm, std::numeric_limits<int>::max() - 1) 75 // Make sure __LINKEDIT is the last segment (i.e. all its hidden 76 // sections must be ordered after other sections). 77 .Case(segment_names::linkEdit, std::numeric_limits<int>::max()) 78 .Default(seg->inputOrder); 79 } 80 81 static int sectionOrder(OutputSection *osec) { 82 StringRef segname = osec->parent->name; 83 // Sections are uniquely identified by their segment + section name. 84 if (segname == segment_names::text) { 85 return StringSwitch<int>(osec->name) 86 .Case(section_names::header, -4) 87 .Case(section_names::text, -3) 88 .Case(section_names::stubs, -2) 89 .Case(section_names::stubHelper, -1) 90 .Case(section_names::unwindInfo, std::numeric_limits<int>::max() - 1) 91 .Case(section_names::ehFrame, std::numeric_limits<int>::max()) 92 .Default(osec->inputOrder); 93 } else if (segname == segment_names::data || 94 segname == segment_names::dataConst) { 95 // For each thread spawned, dyld will initialize its TLVs by copying the 96 // address range from the start of the first thread-local data section to 97 // the end of the last one. We therefore arrange these sections contiguously 98 // to minimize the amount of memory used. Additionally, since zerofill 99 // sections must be at the end of their segments, and since TLV data 100 // sections can be zerofills, we end up putting all TLV data sections at the 101 // end of the segment. 102 switch (sectionType(osec->flags)) { 103 case S_THREAD_LOCAL_REGULAR: 104 return std::numeric_limits<int>::max() - 2; 105 case S_THREAD_LOCAL_ZEROFILL: 106 return std::numeric_limits<int>::max() - 1; 107 case S_ZEROFILL: 108 return std::numeric_limits<int>::max(); 109 default: 110 return StringSwitch<int>(osec->name) 111 .Case(section_names::got, -3) 112 .Case(section_names::lazySymbolPtr, -2) 113 .Case(section_names::const_, -1) 114 .Default(osec->inputOrder); 115 } 116 } else if (segname == segment_names::linkEdit) { 117 return StringSwitch<int>(osec->name) 118 .Case(section_names::rebase, -9) 119 .Case(section_names::binding, -8) 120 .Case(section_names::weakBinding, -7) 121 .Case(section_names::lazyBinding, -6) 122 .Case(section_names::export_, -5) 123 .Case(section_names::functionStarts, -4) 124 .Case(section_names::symbolTable, -3) 125 .Case(section_names::indirectSymbolTable, -2) 126 .Case(section_names::stringTable, -1) 127 .Case(section_names::codeSignature, std::numeric_limits<int>::max()) 128 .Default(osec->inputOrder); 129 } 130 // ZeroFill sections must always be the at the end of their segments, 131 // otherwise subsequent sections may get overwritten with zeroes at runtime. 132 if (sectionType(osec->flags) == S_ZEROFILL) 133 return std::numeric_limits<int>::max(); 134 return osec->inputOrder; 135 } 136 137 void OutputSegment::sortOutputSections() { 138 llvm::sort(sections, compareByOrder<OutputSection *>(sectionOrder)); 139 } 140 141 void macho::sortOutputSegments() { 142 llvm::sort(outputSegments, compareByOrder<OutputSegment *>(segmentOrder)); 143 } 144 145 static DenseMap<StringRef, OutputSegment *> nameToOutputSegment; 146 std::vector<OutputSegment *> macho::outputSegments; 147 148 OutputSegment *macho::getOrCreateOutputSegment(StringRef name) { 149 OutputSegment *&segRef = nameToOutputSegment[name]; 150 if (segRef) 151 return segRef; 152 153 segRef = make<OutputSegment>(); 154 segRef->name = name; 155 segRef->maxProt = maxProt(name); 156 segRef->initProt = initProt(name); 157 158 outputSegments.push_back(segRef); 159 return segRef; 160 } 161