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 18 using namespace llvm; 19 using namespace MachO; 20 using namespace object; 21 22 static constexpr StringLiteral ObjC1ClassNamePrefix = ".objc_class_name_"; 23 static constexpr StringLiteral ObjC2ClassNamePrefix = "_OBJC_CLASS_$_"; 24 static constexpr StringLiteral ObjC2MetaClassNamePrefix = "_OBJC_METACLASS_$_"; 25 static constexpr StringLiteral ObjC2EHTypePrefix = "_OBJC_EHTYPE_$_"; 26 static constexpr StringLiteral ObjC2IVarPrefix = "_OBJC_IVAR_$_"; 27 28 static uint32_t getFlags(const Symbol *Sym) { 29 uint32_t Flags = BasicSymbolRef::SF_Global; 30 if (Sym->isUndefined()) 31 Flags |= BasicSymbolRef::SF_Undefined; 32 else 33 Flags |= BasicSymbolRef::SF_Exported; 34 35 if (Sym->isWeakDefined() || Sym->isWeakReferenced()) 36 Flags |= BasicSymbolRef::SF_Weak; 37 38 return Flags; 39 } 40 41 TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &interface, 42 Architecture Arch) 43 : SymbolicFile(ID_TapiFile, Source) { 44 for (const auto *Symbol : interface.symbols()) { 45 if (!Symbol->getArchitectures().has(Arch)) 46 continue; 47 48 switch (Symbol->getKind()) { 49 case SymbolKind::GlobalSymbol: 50 Symbols.emplace_back(StringRef(), Symbol->getName(), getFlags(Symbol)); 51 break; 52 case SymbolKind::ObjectiveCClass: 53 if (interface.getPlatforms().count(PlatformKind::macOS) && 54 Arch == AK_i386) { 55 Symbols.emplace_back(ObjC1ClassNamePrefix, Symbol->getName(), 56 getFlags(Symbol)); 57 } else { 58 Symbols.emplace_back(ObjC2ClassNamePrefix, Symbol->getName(), 59 getFlags(Symbol)); 60 Symbols.emplace_back(ObjC2MetaClassNamePrefix, Symbol->getName(), 61 getFlags(Symbol)); 62 } 63 break; 64 case SymbolKind::ObjectiveCClassEHType: 65 Symbols.emplace_back(ObjC2EHTypePrefix, Symbol->getName(), 66 getFlags(Symbol)); 67 break; 68 case SymbolKind::ObjectiveCInstanceVariable: 69 Symbols.emplace_back(ObjC2IVarPrefix, Symbol->getName(), 70 getFlags(Symbol)); 71 break; 72 } 73 } 74 } 75 76 TapiFile::~TapiFile() = default; 77 78 void TapiFile::moveSymbolNext(DataRefImpl &DRI) const { 79 const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p); 80 DRI.p = reinterpret_cast<uintptr_t>(++Sym); 81 } 82 83 Error TapiFile::printSymbolName(raw_ostream &OS, DataRefImpl DRI) const { 84 const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p); 85 OS << Sym->Prefix << Sym->Name; 86 return Error::success(); 87 } 88 89 uint32_t TapiFile::getSymbolFlags(DataRefImpl DRI) const { 90 const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p); 91 return Sym->Flags; 92 } 93 94 basic_symbol_iterator TapiFile::symbol_begin() const { 95 DataRefImpl DRI; 96 DRI.p = reinterpret_cast<uintptr_t>(&*Symbols.begin()); 97 return BasicSymbolRef{DRI, this}; 98 } 99 100 basic_symbol_iterator TapiFile::symbol_end() const { 101 DataRefImpl DRI; 102 DRI.p = reinterpret_cast<uintptr_t>(&*Symbols.end()); 103 return BasicSymbolRef{DRI, this}; 104 } 105