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 "InputSection.h" 11 #include "MergedOutputSection.h" 12 #include "SyntheticSections.h" 13 14 #include "lld/Common/ErrorHandler.h" 15 #include "lld/Common/Memory.h" 16 #include "llvm/BinaryFormat/MachO.h" 17 18 using namespace llvm; 19 using namespace llvm::MachO; 20 using namespace lld; 21 using namespace lld::macho; 22 23 static uint32_t initProt(StringRef name) { 24 auto it = find_if( 25 config->segmentProtections, 26 [&](const SegmentProtection &segprot) { return segprot.name == name; }); 27 if (it != config->segmentProtections.end()) 28 return it->initProt; 29 30 if (name == segment_names::text) 31 return VM_PROT_READ | VM_PROT_EXECUTE; 32 if (name == segment_names::pageZero) 33 return 0; 34 if (name == segment_names::linkEdit) 35 return VM_PROT_READ; 36 return VM_PROT_READ | VM_PROT_WRITE; 37 } 38 39 static uint32_t maxProt(StringRef name) { 40 assert(config->target.Arch != AK_i386 && 41 "TODO: i386 has different maxProt requirements"); 42 return initProt(name); 43 } 44 45 size_t OutputSegment::numNonHiddenSections() const { 46 size_t count = 0; 47 for (const OutputSection *osec : sections) 48 count += (!osec->isHidden() ? 1 : 0); 49 return count; 50 } 51 52 void OutputSegment::addOutputSection(OutputSection *osec) { 53 osec->parent = this; 54 sections.push_back(osec); 55 } 56 57 static DenseMap<StringRef, OutputSegment *> nameToOutputSegment; 58 std::vector<OutputSegment *> macho::outputSegments; 59 60 OutputSegment *macho::getOrCreateOutputSegment(StringRef name) { 61 OutputSegment *&segRef = nameToOutputSegment[name]; 62 if (segRef) 63 return segRef; 64 65 segRef = make<OutputSegment>(); 66 segRef->name = name; 67 segRef->maxProt = maxProt(name); 68 segRef->initProt = initProt(name); 69 70 outputSegments.push_back(segRef); 71 return segRef; 72 } 73