]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/lib/ReaderWriter/MachO/ExecutableAtoms.h
MFV r337195: 9454 ::zfs_blkstats should count embedded blocks
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / lib / ReaderWriter / MachO / ExecutableAtoms.h
1 //===- lib/ReaderWriter/MachO/ExecutableAtoms.h ---------------------------===//
2 //
3 //                             The LLVM Linker
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef LLD_READER_WRITER_MACHO_EXECUTABLE_ATOMS_H
11 #define LLD_READER_WRITER_MACHO_EXECUTABLE_ATOMS_H
12
13 #include "Atoms.h"
14 #include "File.h"
15
16 #include "llvm/BinaryFormat/MachO.h"
17
18 #include "lld/Core/DefinedAtom.h"
19 #include "lld/Core/File.h"
20 #include "lld/Core/LinkingContext.h"
21 #include "lld/Core/Reference.h"
22 #include "lld/Core/Simple.h"
23 #include "lld/Core/UndefinedAtom.h"
24 #include "lld/ReaderWriter/MachOLinkingContext.h"
25
26 namespace lld {
27 namespace mach_o {
28
29
30 //
31 // CEntryFile adds an UndefinedAtom for "_main" so that the Resolving
32 // phase will fail if "_main" is undefined.
33 //
34 class CEntryFile : public SimpleFile {
35 public:
36   CEntryFile(const MachOLinkingContext &context)
37       : SimpleFile("C entry", kindCEntryObject),
38        _undefMain(*this, context.entrySymbolName()) {
39     this->addAtom(_undefMain);
40   }
41
42 private:
43   SimpleUndefinedAtom   _undefMain;
44 };
45
46
47 //
48 // StubHelperFile adds an UndefinedAtom for "dyld_stub_binder" so that
49 // the Resolveing phase will fail if "dyld_stub_binder" is undefined.
50 //
51 class StubHelperFile : public SimpleFile {
52 public:
53   StubHelperFile(const MachOLinkingContext &context)
54       : SimpleFile("stub runtime", kindStubHelperObject),
55         _undefBinder(*this, context.binderSymbolName()) {
56     this->addAtom(_undefBinder);
57   }
58
59 private:
60   SimpleUndefinedAtom   _undefBinder;
61 };
62
63
64 //
65 // MachHeaderAliasFile lazily instantiates the magic symbols that mark the start
66 // of the mach_header for final linked images.
67 //
68 class MachHeaderAliasFile : public SimpleFile {
69 public:
70   MachHeaderAliasFile(const MachOLinkingContext &context)
71     : SimpleFile("mach_header symbols", kindHeaderObject) {
72     StringRef machHeaderSymbolName;
73     DefinedAtom::Scope symbolScope = DefinedAtom::scopeLinkageUnit;
74     StringRef dsoHandleName;
75     switch (context.outputMachOType()) {
76     case llvm::MachO::MH_OBJECT:
77       machHeaderSymbolName = "__mh_object_header";
78       break;
79     case llvm::MachO::MH_EXECUTE:
80       machHeaderSymbolName = "__mh_execute_header";
81       symbolScope = DefinedAtom::scopeGlobal;
82       dsoHandleName = "___dso_handle";
83       break;
84     case llvm::MachO::MH_FVMLIB:
85       llvm_unreachable("no mach_header symbol for file type");
86     case llvm::MachO::MH_CORE:
87       llvm_unreachable("no mach_header symbol for file type");
88     case llvm::MachO::MH_PRELOAD:
89       llvm_unreachable("no mach_header symbol for file type");
90     case llvm::MachO::MH_DYLIB:
91       machHeaderSymbolName = "__mh_dylib_header";
92       dsoHandleName = "___dso_handle";
93       break;
94     case llvm::MachO::MH_DYLINKER:
95       machHeaderSymbolName = "__mh_dylinker_header";
96       dsoHandleName = "___dso_handle";
97       break;
98     case llvm::MachO::MH_BUNDLE:
99       machHeaderSymbolName = "__mh_bundle_header";
100       dsoHandleName = "___dso_handle";
101       break;
102     case llvm::MachO::MH_DYLIB_STUB:
103       llvm_unreachable("no mach_header symbol for file type");
104     case llvm::MachO::MH_DSYM:
105       llvm_unreachable("no mach_header symbol for file type");
106     case llvm::MachO::MH_KEXT_BUNDLE:
107       dsoHandleName = "___dso_handle";
108       break;
109     }
110     if (!machHeaderSymbolName.empty())
111       _definedAtoms.push_back(new (allocator()) MachODefinedAtom(
112           *this, machHeaderSymbolName, symbolScope,
113           DefinedAtom::typeMachHeader, DefinedAtom::mergeNo, false,
114           true /* noDeadStrip */,
115           ArrayRef<uint8_t>(), DefinedAtom::Alignment(4096)));
116
117     if (!dsoHandleName.empty())
118       _definedAtoms.push_back(new (allocator()) MachODefinedAtom(
119           *this, dsoHandleName, DefinedAtom::scopeLinkageUnit,
120           DefinedAtom::typeDSOHandle, DefinedAtom::mergeNo, false,
121           true /* noDeadStrip */,
122           ArrayRef<uint8_t>(), DefinedAtom::Alignment(1)));
123   }
124
125   const AtomRange<DefinedAtom> defined() const override {
126     return _definedAtoms;
127   }
128   const AtomRange<UndefinedAtom> undefined() const override {
129     return _noUndefinedAtoms;
130   }
131
132   const AtomRange<SharedLibraryAtom> sharedLibrary() const override {
133     return _noSharedLibraryAtoms;
134   }
135
136   const AtomRange<AbsoluteAtom> absolute() const override {
137     return _noAbsoluteAtoms;
138   }
139
140   void clearAtoms() override {
141     _definedAtoms.clear();
142     _noUndefinedAtoms.clear();
143     _noSharedLibraryAtoms.clear();
144     _noAbsoluteAtoms.clear();
145   }
146
147
148 private:
149   mutable AtomVector<DefinedAtom> _definedAtoms;
150 };
151
152 } // namespace mach_o
153 } // namespace lld
154
155 #endif // LLD_READER_WRITER_MACHO_EXECUTABLE_ATOMS_H