1*8bcb0991SDimitry Andric //===- TapiFile.cpp -------------------------------------------------------===// 2*8bcb0991SDimitry Andric // 3*8bcb0991SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*8bcb0991SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*8bcb0991SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*8bcb0991SDimitry Andric // 7*8bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 8*8bcb0991SDimitry Andric // 9*8bcb0991SDimitry Andric // This file defines the Text-based Dynamcic Library Stub format. 10*8bcb0991SDimitry Andric // 11*8bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 12*8bcb0991SDimitry Andric 13*8bcb0991SDimitry Andric #include "llvm/Object/TapiFile.h" 14*8bcb0991SDimitry Andric #include "llvm/ADT/StringRef.h" 15*8bcb0991SDimitry Andric #include "llvm/Object/Error.h" 16*8bcb0991SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 17*8bcb0991SDimitry Andric 18*8bcb0991SDimitry Andric using namespace llvm; 19*8bcb0991SDimitry Andric using namespace MachO; 20*8bcb0991SDimitry Andric using namespace object; 21*8bcb0991SDimitry Andric 22*8bcb0991SDimitry Andric static constexpr StringLiteral ObjC1ClassNamePrefix = ".objc_class_name_"; 23*8bcb0991SDimitry Andric static constexpr StringLiteral ObjC2ClassNamePrefix = "_OBJC_CLASS_$_"; 24*8bcb0991SDimitry Andric static constexpr StringLiteral ObjC2MetaClassNamePrefix = "_OBJC_METACLASS_$_"; 25*8bcb0991SDimitry Andric static constexpr StringLiteral ObjC2EHTypePrefix = "_OBJC_EHTYPE_$_"; 26*8bcb0991SDimitry Andric static constexpr StringLiteral ObjC2IVarPrefix = "_OBJC_IVAR_$_"; 27*8bcb0991SDimitry Andric 28*8bcb0991SDimitry Andric static uint32_t getFlags(const Symbol *Sym) { 29*8bcb0991SDimitry Andric uint32_t Flags = BasicSymbolRef::SF_Global; 30*8bcb0991SDimitry Andric if (Sym->isUndefined()) 31*8bcb0991SDimitry Andric Flags |= BasicSymbolRef::SF_Undefined; 32*8bcb0991SDimitry Andric else 33*8bcb0991SDimitry Andric Flags |= BasicSymbolRef::SF_Exported; 34*8bcb0991SDimitry Andric 35*8bcb0991SDimitry Andric if (Sym->isWeakDefined() || Sym->isWeakReferenced()) 36*8bcb0991SDimitry Andric Flags |= BasicSymbolRef::SF_Weak; 37*8bcb0991SDimitry Andric 38*8bcb0991SDimitry Andric return Flags; 39*8bcb0991SDimitry Andric } 40*8bcb0991SDimitry Andric 41*8bcb0991SDimitry Andric TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &interface, 42*8bcb0991SDimitry Andric Architecture Arch) 43*8bcb0991SDimitry Andric : SymbolicFile(ID_TapiFile, Source) { 44*8bcb0991SDimitry Andric for (const auto *Symbol : interface.symbols()) { 45*8bcb0991SDimitry Andric if (!Symbol->getArchitectures().has(Arch)) 46*8bcb0991SDimitry Andric continue; 47*8bcb0991SDimitry Andric 48*8bcb0991SDimitry Andric switch (Symbol->getKind()) { 49*8bcb0991SDimitry Andric case SymbolKind::GlobalSymbol: 50*8bcb0991SDimitry Andric Symbols.emplace_back(StringRef(), Symbol->getName(), getFlags(Symbol)); 51*8bcb0991SDimitry Andric break; 52*8bcb0991SDimitry Andric case SymbolKind::ObjectiveCClass: 53*8bcb0991SDimitry Andric if (interface.getPlatforms().count(PlatformKind::macOS) && 54*8bcb0991SDimitry Andric Arch == AK_i386) { 55*8bcb0991SDimitry Andric Symbols.emplace_back(ObjC1ClassNamePrefix, Symbol->getName(), 56*8bcb0991SDimitry Andric getFlags(Symbol)); 57*8bcb0991SDimitry Andric } else { 58*8bcb0991SDimitry Andric Symbols.emplace_back(ObjC2ClassNamePrefix, Symbol->getName(), 59*8bcb0991SDimitry Andric getFlags(Symbol)); 60*8bcb0991SDimitry Andric Symbols.emplace_back(ObjC2MetaClassNamePrefix, Symbol->getName(), 61*8bcb0991SDimitry Andric getFlags(Symbol)); 62*8bcb0991SDimitry Andric } 63*8bcb0991SDimitry Andric break; 64*8bcb0991SDimitry Andric case SymbolKind::ObjectiveCClassEHType: 65*8bcb0991SDimitry Andric Symbols.emplace_back(ObjC2EHTypePrefix, Symbol->getName(), 66*8bcb0991SDimitry Andric getFlags(Symbol)); 67*8bcb0991SDimitry Andric break; 68*8bcb0991SDimitry Andric case SymbolKind::ObjectiveCInstanceVariable: 69*8bcb0991SDimitry Andric Symbols.emplace_back(ObjC2IVarPrefix, Symbol->getName(), 70*8bcb0991SDimitry Andric getFlags(Symbol)); 71*8bcb0991SDimitry Andric break; 72*8bcb0991SDimitry Andric } 73*8bcb0991SDimitry Andric } 74*8bcb0991SDimitry Andric } 75*8bcb0991SDimitry Andric 76*8bcb0991SDimitry Andric TapiFile::~TapiFile() = default; 77*8bcb0991SDimitry Andric 78*8bcb0991SDimitry Andric void TapiFile::moveSymbolNext(DataRefImpl &DRI) const { 79*8bcb0991SDimitry Andric const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p); 80*8bcb0991SDimitry Andric DRI.p = reinterpret_cast<uintptr_t>(++Sym); 81*8bcb0991SDimitry Andric } 82*8bcb0991SDimitry Andric 83*8bcb0991SDimitry Andric Error TapiFile::printSymbolName(raw_ostream &OS, DataRefImpl DRI) const { 84*8bcb0991SDimitry Andric const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p); 85*8bcb0991SDimitry Andric OS << Sym->Prefix << Sym->Name; 86*8bcb0991SDimitry Andric return Error::success(); 87*8bcb0991SDimitry Andric } 88*8bcb0991SDimitry Andric 89*8bcb0991SDimitry Andric uint32_t TapiFile::getSymbolFlags(DataRefImpl DRI) const { 90*8bcb0991SDimitry Andric const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p); 91*8bcb0991SDimitry Andric return Sym->Flags; 92*8bcb0991SDimitry Andric } 93*8bcb0991SDimitry Andric 94*8bcb0991SDimitry Andric basic_symbol_iterator TapiFile::symbol_begin() const { 95*8bcb0991SDimitry Andric DataRefImpl DRI; 96*8bcb0991SDimitry Andric DRI.p = reinterpret_cast<uintptr_t>(&*Symbols.begin()); 97*8bcb0991SDimitry Andric return BasicSymbolRef{DRI, this}; 98*8bcb0991SDimitry Andric } 99*8bcb0991SDimitry Andric 100*8bcb0991SDimitry Andric basic_symbol_iterator TapiFile::symbol_end() const { 101*8bcb0991SDimitry Andric DataRefImpl DRI; 102*8bcb0991SDimitry Andric DRI.p = reinterpret_cast<uintptr_t>(&*Symbols.end()); 103*8bcb0991SDimitry Andric return BasicSymbolRef{DRI, this}; 104*8bcb0991SDimitry Andric } 105