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