1*5ffd83dbSDimitry Andric //===- OutputSegment.cpp --------------------------------------------------===// 2*5ffd83dbSDimitry Andric // 3*5ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*5ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*5ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*5ffd83dbSDimitry Andric // 7*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 8*5ffd83dbSDimitry Andric 9*5ffd83dbSDimitry Andric #include "OutputSegment.h" 10*5ffd83dbSDimitry Andric #include "InputSection.h" 11*5ffd83dbSDimitry Andric #include "MergedOutputSection.h" 12*5ffd83dbSDimitry Andric #include "SyntheticSections.h" 13*5ffd83dbSDimitry Andric 14*5ffd83dbSDimitry Andric #include "lld/Common/ErrorHandler.h" 15*5ffd83dbSDimitry Andric #include "lld/Common/Memory.h" 16*5ffd83dbSDimitry Andric #include "llvm/BinaryFormat/MachO.h" 17*5ffd83dbSDimitry Andric 18*5ffd83dbSDimitry Andric using namespace llvm; 19*5ffd83dbSDimitry Andric using namespace llvm::MachO; 20*5ffd83dbSDimitry Andric using namespace lld; 21*5ffd83dbSDimitry Andric using namespace lld::macho; 22*5ffd83dbSDimitry Andric 23*5ffd83dbSDimitry Andric static uint32_t initProt(StringRef name) { 24*5ffd83dbSDimitry Andric if (name == segment_names::text) 25*5ffd83dbSDimitry Andric return VM_PROT_READ | VM_PROT_EXECUTE; 26*5ffd83dbSDimitry Andric if (name == segment_names::pageZero) 27*5ffd83dbSDimitry Andric return 0; 28*5ffd83dbSDimitry Andric if (name == segment_names::linkEdit) 29*5ffd83dbSDimitry Andric return VM_PROT_READ; 30*5ffd83dbSDimitry Andric return VM_PROT_READ | VM_PROT_WRITE; 31*5ffd83dbSDimitry Andric } 32*5ffd83dbSDimitry Andric 33*5ffd83dbSDimitry Andric static uint32_t maxProt(StringRef name) { 34*5ffd83dbSDimitry Andric if (name == segment_names::pageZero) 35*5ffd83dbSDimitry Andric return 0; 36*5ffd83dbSDimitry Andric return VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE; 37*5ffd83dbSDimitry Andric } 38*5ffd83dbSDimitry Andric 39*5ffd83dbSDimitry Andric size_t OutputSegment::numNonHiddenSections() const { 40*5ffd83dbSDimitry Andric size_t count = 0; 41*5ffd83dbSDimitry Andric for (const OutputSection *osec : sections) { 42*5ffd83dbSDimitry Andric count += (!osec->isHidden() ? 1 : 0); 43*5ffd83dbSDimitry Andric } 44*5ffd83dbSDimitry Andric return count; 45*5ffd83dbSDimitry Andric } 46*5ffd83dbSDimitry Andric 47*5ffd83dbSDimitry Andric void OutputSegment::addOutputSection(OutputSection *osec) { 48*5ffd83dbSDimitry Andric osec->parent = this; 49*5ffd83dbSDimitry Andric sections.push_back(osec); 50*5ffd83dbSDimitry Andric } 51*5ffd83dbSDimitry Andric 52*5ffd83dbSDimitry Andric static llvm::DenseMap<StringRef, OutputSegment *> nameToOutputSegment; 53*5ffd83dbSDimitry Andric std::vector<OutputSegment *> macho::outputSegments; 54*5ffd83dbSDimitry Andric 55*5ffd83dbSDimitry Andric OutputSegment *macho::getOrCreateOutputSegment(StringRef name) { 56*5ffd83dbSDimitry Andric OutputSegment *&segRef = nameToOutputSegment[name]; 57*5ffd83dbSDimitry Andric if (segRef != nullptr) 58*5ffd83dbSDimitry Andric return segRef; 59*5ffd83dbSDimitry Andric 60*5ffd83dbSDimitry Andric segRef = make<OutputSegment>(); 61*5ffd83dbSDimitry Andric segRef->name = name; 62*5ffd83dbSDimitry Andric segRef->maxProt = maxProt(name); 63*5ffd83dbSDimitry Andric segRef->initProt = initProt(name); 64*5ffd83dbSDimitry Andric 65*5ffd83dbSDimitry Andric outputSegments.push_back(segRef); 66*5ffd83dbSDimitry Andric return segRef; 67*5ffd83dbSDimitry Andric } 68