1//===- lib/ReaderWriter/MachO/TLVPass.cpp -----------------------*- 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/// \file 10/// This linker pass transforms all TLV references to real references. 11/// 12//===----------------------------------------------------------------------===// 13 14#include "ArchHandler.h" 15#include "File.h" 16#include "MachOPasses.h" 17#include "lld/Core/Simple.h" 18#include "llvm/ADT/STLExtras.h" 19#include "llvm/Support/Debug.h" 20 21namespace lld { 22namespace mach_o { 23 24// 25// TLVP Entry Atom created by the TLV pass. 26// 27class TLVPEntryAtom : public SimpleDefinedAtom { 28public: 29 TLVPEntryAtom(const File &file, bool is64, StringRef name) 30 : SimpleDefinedAtom(file), _is64(is64), _name(name) {} 31 32 ~TLVPEntryAtom() override = default; 33 34 ContentType contentType() const override { 35 return DefinedAtom::typeTLVInitializerPtr; 36 } 37 38 Alignment alignment() const override { 39 return _is64 ? 8 : 4; 40 } 41 42 uint64_t size() const override { 43 return _is64 ? 8 : 4; 44 } 45 46 ContentPermissions permissions() const override { 47 return DefinedAtom::permRW_; 48 } 49 50 ArrayRef<uint8_t> rawContent() const override { 51 static const uint8_t zeros[] = 52 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 53 return llvm::makeArrayRef(zeros, size()); 54 } 55 56 StringRef slotName() const { 57 return _name; 58 } 59 60private: 61 const bool _is64; 62 StringRef _name; 63}; 64 65class TLVPass : public Pass { 66public: 67 TLVPass(const MachOLinkingContext &context) 68 : _ctx(context), _archHandler(_ctx.archHandler()), 69 _file(*_ctx.make_file<MachOFile>("<mach-o TLV pass>")) { 70 _file.setOrdinal(_ctx.getNextOrdinalAndIncrement()); 71 } 72 73private: 74 llvm::Error perform(SimpleFile &mergedFile) override { 75 bool allowTLV = _ctx.minOS("10.7", "1.0"); 76 77 for (const DefinedAtom *atom : mergedFile.defined()) { 78 for (const Reference *ref : *atom) { 79 if (!_archHandler.isTLVAccess(*ref)) 80 continue; 81 82 if (!allowTLV) 83 return llvm::make_error<GenericError>( 84 "targeted OS version does not support use of thread local " 85 "variables in " + atom->name() + " for architecture " + 86 _ctx.archName()); 87 88 const Atom *target = ref->target(); 89 assert(target != nullptr); 90 91 const DefinedAtom *tlvpEntry = makeTLVPEntry(target); 92 const_cast<Reference*>(ref)->setTarget(tlvpEntry); 93 _archHandler.updateReferenceToTLV(ref); 94 } 95 } 96 97 std::vector<const TLVPEntryAtom*> entries; 98 entries.reserve(_targetToTLVP.size()); 99 for (auto &it : _targetToTLVP) 100 entries.push_back(it.second); 101 std::sort(entries.begin(), entries.end(), 102 [](const TLVPEntryAtom *lhs, const TLVPEntryAtom *rhs) { 103 return (lhs->slotName().compare(rhs->slotName()) < 0); 104 }); 105 106 for (const TLVPEntryAtom *slot : entries) 107 mergedFile.addAtom(*slot); 108 109 return llvm::Error::success(); 110 } 111 112 const DefinedAtom *makeTLVPEntry(const Atom *target) { 113 auto pos = _targetToTLVP.find(target); 114 115 if (pos != _targetToTLVP.end()) 116 return pos->second; 117 118 auto *tlvpEntry = new (_file.allocator()) 119 TLVPEntryAtom(_file, _ctx.is64Bit(), target->name()); 120 _targetToTLVP[target] = tlvpEntry; 121 const ArchHandler::ReferenceInfo &nlInfo = 122 _archHandler.stubInfo().nonLazyPointerReferenceToBinder; 123 tlvpEntry->addReference(Reference::KindNamespace::mach_o, nlInfo.arch, 124 nlInfo.kind, 0, target, 0); 125 return tlvpEntry; 126 } 127 128 const MachOLinkingContext &_ctx; 129 mach_o::ArchHandler &_archHandler; 130 MachOFile &_file; 131 llvm::DenseMap<const Atom*, const TLVPEntryAtom*> _targetToTLVP; 132}; 133 134void addTLVPass(PassManager &pm, const MachOLinkingContext &ctx) { 135 assert(ctx.needsTLVPass()); 136 pm.add(std::make_unique<TLVPass>(ctx)); 137} 138 139} // end namesapce mach_o 140} // end namesapce lld 141