|  | //===- TapiFile.cpp -------------------------------------------------------===// | 
|  | // | 
|  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | // See https://llvm.org/LICENSE.txt for license information. | 
|  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // This file defines the Text-based Dynamcic Library Stub format. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "llvm/Object/TapiFile.h" | 
|  | #include "llvm/ADT/StringRef.h" | 
|  | #include "llvm/Object/Error.h" | 
|  | #include "llvm/Support/MemoryBuffer.h" | 
|  |  | 
|  | using namespace llvm; | 
|  | using namespace MachO; | 
|  | using namespace object; | 
|  |  | 
|  | static constexpr StringLiteral ObjC1ClassNamePrefix = ".objc_class_name_"; | 
|  | static constexpr StringLiteral ObjC2ClassNamePrefix = "_OBJC_CLASS_$_"; | 
|  | static constexpr StringLiteral ObjC2MetaClassNamePrefix = "_OBJC_METACLASS_$_"; | 
|  | static constexpr StringLiteral ObjC2EHTypePrefix = "_OBJC_EHTYPE_$_"; | 
|  | static constexpr StringLiteral ObjC2IVarPrefix = "_OBJC_IVAR_$_"; | 
|  |  | 
|  | static uint32_t getFlags(const Symbol *Sym) { | 
|  | uint32_t Flags = BasicSymbolRef::SF_Global; | 
|  | if (Sym->isUndefined()) | 
|  | Flags |= BasicSymbolRef::SF_Undefined; | 
|  | else | 
|  | Flags |= BasicSymbolRef::SF_Exported; | 
|  |  | 
|  | if (Sym->isWeakDefined() || Sym->isWeakReferenced()) | 
|  | Flags |= BasicSymbolRef::SF_Weak; | 
|  |  | 
|  | return Flags; | 
|  | } | 
|  |  | 
|  | TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &interface, | 
|  | Architecture Arch) | 
|  | : SymbolicFile(ID_TapiFile, Source) { | 
|  | for (const auto *Symbol : interface.symbols()) { | 
|  | if (!Symbol->getArchitectures().has(Arch)) | 
|  | continue; | 
|  |  | 
|  | switch (Symbol->getKind()) { | 
|  | case SymbolKind::GlobalSymbol: | 
|  | Symbols.emplace_back(StringRef(), Symbol->getName(), getFlags(Symbol)); | 
|  | break; | 
|  | case SymbolKind::ObjectiveCClass: | 
|  | if (interface.getPlatforms().count(PlatformKind::macOS) && | 
|  | Arch == AK_i386) { | 
|  | Symbols.emplace_back(ObjC1ClassNamePrefix, Symbol->getName(), | 
|  | getFlags(Symbol)); | 
|  | } else { | 
|  | Symbols.emplace_back(ObjC2ClassNamePrefix, Symbol->getName(), | 
|  | getFlags(Symbol)); | 
|  | Symbols.emplace_back(ObjC2MetaClassNamePrefix, Symbol->getName(), | 
|  | getFlags(Symbol)); | 
|  | } | 
|  | break; | 
|  | case SymbolKind::ObjectiveCClassEHType: | 
|  | Symbols.emplace_back(ObjC2EHTypePrefix, Symbol->getName(), | 
|  | getFlags(Symbol)); | 
|  | break; | 
|  | case SymbolKind::ObjectiveCInstanceVariable: | 
|  | Symbols.emplace_back(ObjC2IVarPrefix, Symbol->getName(), | 
|  | getFlags(Symbol)); | 
|  | break; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | TapiFile::~TapiFile() = default; | 
|  |  | 
|  | void TapiFile::moveSymbolNext(DataRefImpl &DRI) const { | 
|  | const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p); | 
|  | DRI.p = reinterpret_cast<uintptr_t>(++Sym); | 
|  | } | 
|  |  | 
|  | Error TapiFile::printSymbolName(raw_ostream &OS, DataRefImpl DRI) const { | 
|  | const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p); | 
|  | OS << Sym->Prefix << Sym->Name; | 
|  | return Error::success(); | 
|  | } | 
|  |  | 
|  | uint32_t TapiFile::getSymbolFlags(DataRefImpl DRI) const { | 
|  | const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p); | 
|  | return Sym->Flags; | 
|  | } | 
|  |  | 
|  | basic_symbol_iterator TapiFile::symbol_begin() const { | 
|  | DataRefImpl DRI; | 
|  | DRI.p = reinterpret_cast<uintptr_t>(&*Symbols.begin()); | 
|  | return BasicSymbolRef{DRI, this}; | 
|  | } | 
|  |  | 
|  | basic_symbol_iterator TapiFile::symbol_end() const { | 
|  | DataRefImpl DRI; | 
|  | DRI.p = reinterpret_cast<uintptr_t>(&*Symbols.end()); | 
|  | return BasicSymbolRef{DRI, this}; | 
|  | } |