1 //===- TapiFile.cpp -------------------------------------------------------===// 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 // This file defines the Text-based Dynamcic Library Stub format. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/Object/TapiFile.h" 14 #include "llvm/ADT/StringRef.h" 15 #include "llvm/Object/Error.h" 16 #include "llvm/Support/MemoryBuffer.h" 17 #include "llvm/TextAPI/Symbol.h" 18 19 using namespace llvm; 20 using namespace MachO; 21 using namespace object; 22 23 static uint32_t getFlags(const Symbol *Sym) { 24 uint32_t Flags = BasicSymbolRef::SF_Global; 25 if (Sym->isUndefined()) 26 Flags |= BasicSymbolRef::SF_Undefined; 27 else 28 Flags |= BasicSymbolRef::SF_Exported; 29 30 if (Sym->isWeakDefined() || Sym->isWeakReferenced()) 31 Flags |= BasicSymbolRef::SF_Weak; 32 33 return Flags; 34 } 35 36 TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &interface, 37 Architecture Arch) 38 : SymbolicFile(ID_TapiFile, Source), Arch(Arch) { 39 for (const auto *Symbol : interface.symbols()) { 40 if (!Symbol->getArchitectures().has(Arch)) 41 continue; 42 43 switch (Symbol->getKind()) { 44 case SymbolKind::GlobalSymbol: 45 Symbols.emplace_back(StringRef(), Symbol->getName(), getFlags(Symbol)); 46 break; 47 case SymbolKind::ObjectiveCClass: 48 if (interface.getPlatforms().count(PlatformKind::macOS) && 49 Arch == AK_i386) { 50 Symbols.emplace_back(ObjC1ClassNamePrefix, Symbol->getName(), 51 getFlags(Symbol)); 52 } else { 53 Symbols.emplace_back(ObjC2ClassNamePrefix, Symbol->getName(), 54 getFlags(Symbol)); 55 Symbols.emplace_back(ObjC2MetaClassNamePrefix, Symbol->getName(), 56 getFlags(Symbol)); 57 } 58 break; 59 case SymbolKind::ObjectiveCClassEHType: 60 Symbols.emplace_back(ObjC2EHTypePrefix, Symbol->getName(), 61 getFlags(Symbol)); 62 break; 63 case SymbolKind::ObjectiveCInstanceVariable: 64 Symbols.emplace_back(ObjC2IVarPrefix, Symbol->getName(), 65 getFlags(Symbol)); 66 break; 67 } 68 } 69 } 70 71 TapiFile::~TapiFile() = default; 72 73 void TapiFile::moveSymbolNext(DataRefImpl &DRI) const { DRI.d.a++; } 74 75 Error TapiFile::printSymbolName(raw_ostream &OS, DataRefImpl DRI) const { 76 assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds"); 77 const Symbol &Sym = Symbols[DRI.d.a]; 78 OS << Sym.Prefix << Sym.Name; 79 return Error::success(); 80 } 81 82 Expected<uint32_t> TapiFile::getSymbolFlags(DataRefImpl DRI) const { 83 assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds"); 84 return Symbols[DRI.d.a].Flags; 85 } 86 87 basic_symbol_iterator TapiFile::symbol_begin() const { 88 DataRefImpl DRI; 89 DRI.d.a = 0; 90 return BasicSymbolRef{DRI, this}; 91 } 92 93 basic_symbol_iterator TapiFile::symbol_end() const { 94 DataRefImpl DRI; 95 DRI.d.a = Symbols.size(); 96 return BasicSymbolRef{DRI, this}; 97 } 98