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: CEntryFile(const MachOLinkingContext & context)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: StubHelperFile(const MachOLinkingContext & context)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: MachHeaderAliasFile(const MachOLinkingContext & context)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 defined()125 const AtomRange<DefinedAtom> defined() const override { 126 return _definedAtoms; 127 } undefined()128 const AtomRange<UndefinedAtom> undefined() const override { 129 return _noUndefinedAtoms; 130 } 131 sharedLibrary()132 const AtomRange<SharedLibraryAtom> sharedLibrary() const override { 133 return _noSharedLibraryAtoms; 134 } 135 absolute()136 const AtomRange<AbsoluteAtom> absolute() const override { 137 return _noAbsoluteAtoms; 138 } 139 clearAtoms()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 156