1 //===- lib/ReaderWriter/MachO/Atoms.h ---------------------------*- C++ -*-===// 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_ATOMS_H 11 #define LLD_READER_WRITER_MACHO_ATOMS_H 12 13 #include "lld/Core/Atom.h" 14 #include "lld/Core/DefinedAtom.h" 15 #include "lld/Core/SharedLibraryAtom.h" 16 #include "lld/Core/Simple.h" 17 #include "llvm/ADT/ArrayRef.h" 18 #include "llvm/ADT/StringRef.h" 19 #include <cstdint> 20 #include <string> 21 22 namespace lld { 23 24 class File; 25 26 namespace mach_o { 27 28 class MachODefinedAtom : public SimpleDefinedAtom { 29 public: MachODefinedAtom(const File & f,const StringRef name,Scope scope,ContentType type,Merge merge,bool thumb,bool noDeadStrip,const ArrayRef<uint8_t> content,Alignment align)30 MachODefinedAtom(const File &f, const StringRef name, Scope scope, 31 ContentType type, Merge merge, bool thumb, bool noDeadStrip, 32 const ArrayRef<uint8_t> content, Alignment align) 33 : SimpleDefinedAtom(f), _name(name), _content(content), 34 _align(align), _contentType(type), _scope(scope), _merge(merge), 35 _thumb(thumb), _noDeadStrip(noDeadStrip) {} 36 37 // Constructor for zero-fill content MachODefinedAtom(const File & f,const StringRef name,Scope scope,ContentType type,uint64_t size,bool noDeadStrip,Alignment align)38 MachODefinedAtom(const File &f, const StringRef name, Scope scope, 39 ContentType type, uint64_t size, bool noDeadStrip, 40 Alignment align) 41 : SimpleDefinedAtom(f), _name(name), 42 _content(ArrayRef<uint8_t>(nullptr, size)), _align(align), 43 _contentType(type), _scope(scope), _merge(mergeNo), _thumb(false), 44 _noDeadStrip(noDeadStrip) {} 45 46 ~MachODefinedAtom() override = default; 47 size()48 uint64_t size() const override { return _content.size(); } 49 contentType()50 ContentType contentType() const override { return _contentType; } 51 alignment()52 Alignment alignment() const override { return _align; } 53 name()54 StringRef name() const override { return _name; } 55 scope()56 Scope scope() const override { return _scope; } 57 merge()58 Merge merge() const override { return _merge; } 59 deadStrip()60 DeadStripKind deadStrip() const override { 61 if (_contentType == DefinedAtom::typeInitializerPtr) 62 return deadStripNever; 63 if (_contentType == DefinedAtom::typeTerminatorPtr) 64 return deadStripNever; 65 if (_noDeadStrip) 66 return deadStripNever; 67 return deadStripNormal; 68 } 69 rawContent()70 ArrayRef<uint8_t> rawContent() const override { 71 // Note: Zerofill atoms have a content pointer which is null. 72 return _content; 73 } 74 isThumb()75 bool isThumb() const { return _thumb; } 76 77 private: 78 const StringRef _name; 79 const ArrayRef<uint8_t> _content; 80 const DefinedAtom::Alignment _align; 81 const ContentType _contentType; 82 const Scope _scope; 83 const Merge _merge; 84 const bool _thumb; 85 const bool _noDeadStrip; 86 }; 87 88 class MachODefinedCustomSectionAtom : public MachODefinedAtom { 89 public: MachODefinedCustomSectionAtom(const File & f,const StringRef name,Scope scope,ContentType type,Merge merge,bool thumb,bool noDeadStrip,const ArrayRef<uint8_t> content,StringRef sectionName,Alignment align)90 MachODefinedCustomSectionAtom(const File &f, const StringRef name, 91 Scope scope, ContentType type, Merge merge, 92 bool thumb, bool noDeadStrip, 93 const ArrayRef<uint8_t> content, 94 StringRef sectionName, Alignment align) 95 : MachODefinedAtom(f, name, scope, type, merge, thumb, noDeadStrip, 96 content, align), 97 _sectionName(sectionName) {} 98 99 ~MachODefinedCustomSectionAtom() override = default; 100 sectionChoice()101 SectionChoice sectionChoice() const override { 102 return DefinedAtom::sectionCustomRequired; 103 } 104 customSectionName()105 StringRef customSectionName() const override { 106 return _sectionName; 107 } 108 private: 109 StringRef _sectionName; 110 }; 111 112 class MachOTentativeDefAtom : public SimpleDefinedAtom { 113 public: MachOTentativeDefAtom(const File & f,const StringRef name,Scope scope,uint64_t size,DefinedAtom::Alignment align)114 MachOTentativeDefAtom(const File &f, const StringRef name, Scope scope, 115 uint64_t size, DefinedAtom::Alignment align) 116 : SimpleDefinedAtom(f), _name(name), _scope(scope), _size(size), 117 _align(align) {} 118 119 ~MachOTentativeDefAtom() override = default; 120 size()121 uint64_t size() const override { return _size; } 122 merge()123 Merge merge() const override { return DefinedAtom::mergeAsTentative; } 124 contentType()125 ContentType contentType() const override { return DefinedAtom::typeZeroFill; } 126 alignment()127 Alignment alignment() const override { return _align; } 128 name()129 StringRef name() const override { return _name; } 130 scope()131 Scope scope() const override { return _scope; } 132 rawContent()133 ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); } 134 135 private: 136 const std::string _name; 137 const Scope _scope; 138 const uint64_t _size; 139 const DefinedAtom::Alignment _align; 140 }; 141 142 class MachOSharedLibraryAtom : public SharedLibraryAtom { 143 public: MachOSharedLibraryAtom(const File & file,StringRef name,StringRef dylibInstallName,bool weakDef)144 MachOSharedLibraryAtom(const File &file, StringRef name, 145 StringRef dylibInstallName, bool weakDef) 146 : SharedLibraryAtom(), _file(file), _name(name), 147 _dylibInstallName(dylibInstallName) {} 148 ~MachOSharedLibraryAtom() override = default; 149 loadName()150 StringRef loadName() const override { return _dylibInstallName; } 151 canBeNullAtRuntime()152 bool canBeNullAtRuntime() const override { 153 // FIXME: this may actually be changeable. For now, all symbols are strongly 154 // defined though. 155 return false; 156 } 157 file()158 const File &file() const override { return _file; } 159 name()160 StringRef name() const override { return _name; } 161 type()162 Type type() const override { 163 // Unused in MachO (I think). 164 return Type::Unknown; 165 } 166 size()167 uint64_t size() const override { 168 // Unused in MachO (I think) 169 return 0; 170 } 171 172 private: 173 const File &_file; 174 StringRef _name; 175 StringRef _dylibInstallName; 176 }; 177 178 } // end namespace mach_o 179 } // end namespace lld 180 181 #endif // LLD_READER_WRITER_MACHO_ATOMS_H 182