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 
12 #include "lld/Common/Memory.h"
13 #include "llvm/BinaryFormat/MachO.h"
14 
15 using namespace llvm;
16 using namespace llvm::MachO;
17 using namespace lld;
18 using namespace lld::macho;
19 
20 static uint32_t initProt(StringRef name) {
21   if (name == segment_names::text)
22     return VM_PROT_READ | VM_PROT_EXECUTE;
23   if (name == segment_names::pageZero)
24     return 0;
25   if (name == segment_names::linkEdit)
26     return VM_PROT_READ;
27   return VM_PROT_READ | VM_PROT_WRITE;
28 }
29 
30 static uint32_t maxProt(StringRef name) {
31   if (name == segment_names::pageZero)
32     return 0;
33   return VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
34 }
35 
36 void OutputSegment::addSection(InputSection *isec) {
37   isec->parent = this;
38   std::vector<InputSection *> &vec = sections[isec->name];
39   if (vec.empty() && !isec->isHidden()) {
40     ++numNonHiddenSections;
41   }
42   vec.push_back(isec);
43 }
44 
45 static llvm::DenseMap<StringRef, OutputSegment *> nameToOutputSegment;
46 std::vector<OutputSegment *> macho::outputSegments;
47 
48 OutputSegment *macho::getOutputSegment(StringRef name) {
49   return nameToOutputSegment.lookup(name);
50 }
51 
52 OutputSegment *macho::getOrCreateOutputSegment(StringRef name) {
53   OutputSegment *&segRef = nameToOutputSegment[name];
54   if (segRef != nullptr)
55     return segRef;
56 
57   segRef = make<OutputSegment>();
58   segRef->name = name;
59   segRef->maxProt = maxProt(name);
60   segRef->initProt = initProt(name);
61 
62   outputSegments.push_back(segRef);
63   return segRef;
64 }
65