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