diff options
Diffstat (limited to 'lld/lib/ReaderWriter/MachO/ObjCPass.cpp')
-rw-r--r-- | lld/lib/ReaderWriter/MachO/ObjCPass.cpp | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/lld/lib/ReaderWriter/MachO/ObjCPass.cpp b/lld/lib/ReaderWriter/MachO/ObjCPass.cpp new file mode 100644 index 00000000000..023019111a8 --- /dev/null +++ b/lld/lib/ReaderWriter/MachO/ObjCPass.cpp @@ -0,0 +1,126 @@ +//===- lib/ReaderWriter/MachO/ObjCPass.cpp -------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#include "ArchHandler.h" +#include "File.h" +#include "MachOPasses.h" +#include "lld/Core/DefinedAtom.h" +#include "lld/Core/File.h" +#include "lld/Core/LLVM.h" +#include "lld/Core/Reference.h" +#include "lld/Core/Simple.h" +#include "lld/ReaderWriter/MachOLinkingContext.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/STLExtras.h" + +namespace lld { +namespace mach_o { + +// +// ObjC Image Info Atom created by the ObjC pass. +// +class ObjCImageInfoAtom : public SimpleDefinedAtom { +public: + ObjCImageInfoAtom(const File &file, + MachOLinkingContext::ObjCConstraint objCConstraint, + uint32_t swiftVersion) + : SimpleDefinedAtom(file) { + + Data.info.version = 0; + + switch (objCConstraint) { + case MachOLinkingContext::objc_unknown: + llvm_unreachable("Shouldn't run the objc pass without a constraint"); + case MachOLinkingContext::objc_supports_gc: + case MachOLinkingContext::objc_gc_only: + llvm_unreachable("GC is not supported"); + case MachOLinkingContext::objc_retainReleaseForSimulator: + // The retain/release for simulator flag is already the correct + // encoded value for the data so just set it here. + Data.info.flags = (uint32_t)objCConstraint; + break; + case MachOLinkingContext::objc_retainRelease: + // We don't need to encode this flag, so just leave the flags as 0. + Data.info.flags = 0; + break; + } + + Data.info.flags |= (swiftVersion << 8); + } + + ContentType contentType() const override { + return DefinedAtom::typeObjCImageInfo; + } + + Alignment alignment() const override { + return 4; + } + + uint64_t size() const override { + return 8; + } + + ContentPermissions permissions() const override { + return DefinedAtom::permR__; + } + + ArrayRef<uint8_t> rawContent() const override { + return llvm::makeArrayRef(Data.bytes, size()); + } + +private: + + struct objc_image_info { + uint32_t version; + uint32_t flags; + }; + + union { + objc_image_info info; + uint8_t bytes[8]; + } Data; +}; + +class ObjCPass : public Pass { +public: + ObjCPass(const MachOLinkingContext &context) + : _ctx(context), + _file("<mach-o objc pass>") { + _file.setOrdinal(_ctx.getNextOrdinalAndIncrement()); + } + + std::error_code perform(SimpleFile &mergedFile) override { + // Add the image info. + mergedFile.addAtom(*getImageInfo()); + + return std::error_code(); + } + +private: + + const DefinedAtom* getImageInfo() { + return new (_file.allocator()) ObjCImageInfoAtom(_file, + _ctx.objcConstraint(), + _ctx.swiftVersion()); + } + + const MachOLinkingContext &_ctx; + MachOFile _file; +}; + + + +void addObjCPass(PassManager &pm, const MachOLinkingContext &ctx) { + pm.add(llvm::make_unique<ObjCPass>(ctx)); +} + +} // end namespace mach_o +} // end namespace lld |