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 "Sections.h" 13 #include "Symbols.h" 14 #include "SyntheticSections.h" 15 16 #include "lld/Common/ErrorHandler.h" 17 #include "lld/Common/Memory.h" 18 #include "llvm/ADT/StringSwitch.h" 19 #include "llvm/BinaryFormat/MachO.h" 20 21 using namespace llvm; 22 using namespace llvm::MachO; 23 using namespace lld; 24 using namespace lld::macho; 25 26 static uint32_t initProt(StringRef name) { 27 auto it = find_if( 28 config->segmentProtections, 29 [&](const SegmentProtection &segprot) { return segprot.name == name; }); 30 if (it != config->segmentProtections.end()) 31 return it->initProt; 32 33 if (name == segment_names::text) 34 return VM_PROT_READ | VM_PROT_EXECUTE; 35 if (name == segment_names::pageZero) 36 return 0; 37 if (name == segment_names::linkEdit) 38 return VM_PROT_READ; 39 return VM_PROT_READ | VM_PROT_WRITE; 40 } 41 42 static uint32_t maxProt(StringRef name) { 43 assert(config->arch() != AK_i386 && 44 "TODO: i386 has different maxProt requirements"); 45 auto it = find_if( 46 config->segmentProtections, 47 [&](const SegmentProtection &segprot) { return segprot.name == name; }); 48 if (it != config->segmentProtections.end()) 49 return it->maxProt; 50 51 return initProt(name); 52 } 53 54 static uint32_t flags(StringRef name) { 55 // If we ever implement shared cache output support, SG_READ_ONLY should not 56 // be used for dylibs that can be placed in it. 57 return name == segment_names::dataConst ? (uint32_t)SG_READ_ONLY : 0; 58 } 59 60 size_t OutputSegment::numNonHiddenSections() const { 61 size_t count = 0; 62 for (const OutputSection *osec : sections) 63 count += (!osec->isHidden() ? 1 : 0); 64 return count; 65 } 66 67 void OutputSegment::addOutputSection(OutputSection *osec) { 68 inputOrder = std::min(inputOrder, osec->inputOrder); 69 70 osec->parent = this; 71 sections.push_back(osec); 72 73 for (const SectionAlign §Align : config->sectionAlignments) 74 if (sectAlign.segName == name && sectAlign.sectName == osec->name) 75 osec->align = sectAlign.align; 76 } 77 78 template <typename T, typename F> static auto compareByOrder(F ord) { 79 return [=](T a, T b) { return ord(a) < ord(b); }; 80 } 81 82 static int segmentOrder(OutputSegment *seg) { 83 return StringSwitch<int>(seg->name) 84 .Case(segment_names::pageZero, -4) 85 .Case(segment_names::text, -3) 86 .Case(segment_names::dataConst, -2) 87 .Case(segment_names::data, -1) 88 .Case(segment_names::llvm, std::numeric_limits<int>::max() - 1) 89 // Make sure __LINKEDIT is the last segment (i.e. all its hidden 90 // sections must be ordered after other sections). 91 .Case(segment_names::linkEdit, std::numeric_limits<int>::max()) 92 .Default(seg->inputOrder); 93 } 94 95 static int sectionOrder(OutputSection *osec) { 96 StringRef segname = osec->parent->name; 97 // Sections are uniquely identified by their segment + section name. 98 if (segname == segment_names::text) { 99 if (osec->name == section_names::header) 100 return -7; 101 // `__text` needs to precede the other code sections since its 102 // expected to be the largest. This means in effect that it will 103 // be the section that determines whether we need thunks or not. 104 if (osec->name == section_names::text) 105 return -6; 106 // Ensure all code sections are contiguous with `__text` for thunk 107 // calculations. 108 if (sections::isCodeSection(osec->name, segment_names::text, osec->flags) && 109 osec->name != section_names::stubHelper) { 110 return -5; 111 } 112 return StringSwitch<int>(osec->name) 113 .Case(section_names::stubs, -4) 114 .Case(section_names::stubHelper, -3) 115 .Case(section_names::objcStubs, -2) 116 .Case(section_names::initOffsets, -1) 117 .Case(section_names::unwindInfo, std::numeric_limits<int>::max() - 1) 118 .Case(section_names::ehFrame, std::numeric_limits<int>::max()) 119 .Default(osec->inputOrder); 120 } else if (segname == segment_names::data || 121 segname == segment_names::dataConst) { 122 // For each thread spawned, dyld will initialize its TLVs by copying the 123 // address range from the start of the first thread-local data section to 124 // the end of the last one. We therefore arrange these sections contiguously 125 // to minimize the amount of memory used. Additionally, since zerofill 126 // sections must be at the end of their segments, and since TLV data 127 // sections can be zerofills, we end up putting all TLV data sections at the 128 // end of the segment. 129 switch (sectionType(osec->flags)) { 130 case S_THREAD_LOCAL_VARIABLE_POINTERS: 131 return std::numeric_limits<int>::max() - 3; 132 case S_THREAD_LOCAL_REGULAR: 133 return std::numeric_limits<int>::max() - 2; 134 case S_THREAD_LOCAL_ZEROFILL: 135 return std::numeric_limits<int>::max() - 1; 136 case S_ZEROFILL: 137 return std::numeric_limits<int>::max(); 138 default: 139 return StringSwitch<int>(osec->name) 140 .Case(section_names::got, -3) 141 .Case(section_names::lazySymbolPtr, -2) 142 .Case(section_names::const_, -1) 143 .Default(osec->inputOrder); 144 } 145 } else if (segname == segment_names::linkEdit) { 146 return StringSwitch<int>(osec->name) 147 .Case(section_names::chainFixups, -11) 148 .Case(section_names::rebase, -10) 149 .Case(section_names::binding, -9) 150 .Case(section_names::weakBinding, -8) 151 .Case(section_names::lazyBinding, -7) 152 .Case(section_names::export_, -6) 153 .Case(section_names::functionStarts, -5) 154 .Case(section_names::dataInCode, -4) 155 .Case(section_names::symbolTable, -3) 156 .Case(section_names::indirectSymbolTable, -2) 157 .Case(section_names::stringTable, -1) 158 .Case(section_names::codeSignature, std::numeric_limits<int>::max()) 159 .Default(osec->inputOrder); 160 } 161 // ZeroFill sections must always be the at the end of their segments: 162 // dyld checks if a segment's file size is smaller than its in-memory 163 // size to detect if a segment has zerofill sections, and if so it maps 164 // the missing tail as zerofill. 165 if (sectionType(osec->flags) == S_ZEROFILL) 166 return std::numeric_limits<int>::max(); 167 return osec->inputOrder; 168 } 169 170 void OutputSegment::sortOutputSections() { 171 // Must be stable_sort() to keep special sections such as 172 // S_THREAD_LOCAL_REGULAR in input order. 173 llvm::stable_sort(sections, compareByOrder<OutputSection *>(sectionOrder)); 174 } 175 176 void OutputSegment::assignAddressesToStartEndSymbols() { 177 for (Defined *d : segmentStartSymbols) 178 d->value = addr; 179 for (Defined *d : segmentEndSymbols) 180 d->value = addr + vmSize; 181 } 182 183 void macho::sortOutputSegments() { 184 llvm::stable_sort(outputSegments, 185 compareByOrder<OutputSegment *>(segmentOrder)); 186 } 187 188 static DenseMap<StringRef, OutputSegment *> nameToOutputSegment; 189 std::vector<OutputSegment *> macho::outputSegments; 190 191 void macho::resetOutputSegments() { 192 outputSegments.clear(); 193 nameToOutputSegment.clear(); 194 } 195 196 static StringRef maybeRenameSegment(StringRef name) { 197 auto newName = config->segmentRenameMap.find(name); 198 if (newName != config->segmentRenameMap.end()) 199 return newName->second; 200 return name; 201 } 202 203 OutputSegment *macho::getOrCreateOutputSegment(StringRef name) { 204 name = maybeRenameSegment(name); 205 206 OutputSegment *&segRef = nameToOutputSegment[name]; 207 if (segRef) 208 return segRef; 209 210 segRef = make<OutputSegment>(); 211 segRef->name = name; 212 segRef->maxProt = maxProt(name); 213 segRef->initProt = initProt(name); 214 segRef->flags = flags(name); 215 216 outputSegments.push_back(segRef); 217 return segRef; 218 } 219