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 21namespace lld { 22 23class File; 24 25namespace mach_o { 26 27class MachODefinedAtom : public SimpleDefinedAtom { 28public: 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 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 47 uint64_t size() const override { return _content.size(); } 48 49 ContentType contentType() const override { return _contentType; } 50 51 Alignment alignment() const override { return _align; } 52 53 StringRef name() const override { return _name; } 54 55 Scope scope() const override { return _scope; } 56 57 Merge merge() const override { return _merge; } 58 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 69 ArrayRef<uint8_t> rawContent() const override { 70 // Note: Zerofill atoms have a content pointer which is null. 71 return _content; 72 } 73 74 bool isThumb() const { return _thumb; } 75 76private: 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 87class MachODefinedCustomSectionAtom : public MachODefinedAtom { 88public: 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 100 SectionChoice sectionChoice() const override { 101 return DefinedAtom::sectionCustomRequired; 102 } 103 104 StringRef customSectionName() const override { 105 return _sectionName; 106 } 107private: 108 StringRef _sectionName; 109}; 110 111class MachOTentativeDefAtom : public SimpleDefinedAtom { 112public: 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 120 uint64_t size() const override { return _size; } 121 122 Merge merge() const override { return DefinedAtom::mergeAsTentative; } 123 124 ContentType contentType() const override { return DefinedAtom::typeZeroFill; } 125 126 Alignment alignment() const override { return _align; } 127 128 StringRef name() const override { return _name; } 129 130 Scope scope() const override { return _scope; } 131 132 ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); } 133 134private: 135 const std::string _name; 136 const Scope _scope; 137 const uint64_t _size; 138 const DefinedAtom::Alignment _align; 139}; 140 141class MachOSharedLibraryAtom : public SharedLibraryAtom { 142public: 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 149 StringRef loadName() const override { return _dylibInstallName; } 150 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 157 const File &file() const override { return _file; } 158 159 StringRef name() const override { return _name; } 160 161 Type type() const override { 162 // Unused in MachO (I think). 163 return Type::Unknown; 164 } 165 166 uint64_t size() const override { 167 // Unused in MachO (I think) 168 return 0; 169 } 170 171private: 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