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 25namespace lld { 26namespace 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// 33class CEntryFile : public SimpleFile { 34public: 35 CEntryFile(const MachOLinkingContext &context) 36 : SimpleFile("C entry", kindCEntryObject), 37 _undefMain(*this, context.entrySymbolName()) { 38 this->addAtom(_undefMain); 39 } 40 41private: 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// 50class StubHelperFile : public SimpleFile { 51public: 52 StubHelperFile(const MachOLinkingContext &context) 53 : SimpleFile("stub runtime", kindStubHelperObject), 54 _undefBinder(*this, context.binderSymbolName()) { 55 this->addAtom(_undefBinder); 56 } 57 58private: 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// 67class MachHeaderAliasFile : public SimpleFile { 68public: 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 124 const AtomRange<DefinedAtom> defined() const override { 125 return _definedAtoms; 126 } 127 const AtomRange<UndefinedAtom> undefined() const override { 128 return _noUndefinedAtoms; 129 } 130 131 const AtomRange<SharedLibraryAtom> sharedLibrary() const override { 132 return _noSharedLibraryAtoms; 133 } 134 135 const AtomRange<AbsoluteAtom> absolute() const override { 136 return _noAbsoluteAtoms; 137 } 138 139 void clearAtoms() override { 140 _definedAtoms.clear(); 141 _noUndefinedAtoms.clear(); 142 _noSharedLibraryAtoms.clear(); 143 _noAbsoluteAtoms.clear(); 144 } 145 146 147private: 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