xref: /freebsd-src/contrib/llvm-project/lld/MachO/OutputSegment.cpp (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
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