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