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