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) 4328fefcc8SCyndy 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 78*425c6f07SJonas Devlieghere void TapiFile::moveSymbolNext(DataRefImpl &DRI) const { DRI.d.a++; } 79c20d1f90SCyndy Ishida 80c20d1f90SCyndy Ishida Error TapiFile::printSymbolName(raw_ostream &OS, DataRefImpl DRI) const { 81*425c6f07SJonas Devlieghere assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds"); 82*425c6f07SJonas Devlieghere const Symbol &Sym = Symbols[DRI.d.a]; 83*425c6f07SJonas Devlieghere OS << Sym.Prefix << Sym.Name; 84c20d1f90SCyndy Ishida return Error::success(); 85c20d1f90SCyndy Ishida } 86c20d1f90SCyndy Ishida 87ac00376aSvgxbj Expected<uint32_t> TapiFile::getSymbolFlags(DataRefImpl DRI) const { 88*425c6f07SJonas Devlieghere assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds"); 89*425c6f07SJonas Devlieghere return Symbols[DRI.d.a].Flags; 90c20d1f90SCyndy Ishida } 91c20d1f90SCyndy Ishida 92c20d1f90SCyndy Ishida basic_symbol_iterator TapiFile::symbol_begin() const { 93c20d1f90SCyndy Ishida DataRefImpl DRI; 94*425c6f07SJonas Devlieghere DRI.d.a = 0; 95c20d1f90SCyndy Ishida return BasicSymbolRef{DRI, this}; 96c20d1f90SCyndy Ishida } 97c20d1f90SCyndy Ishida 98c20d1f90SCyndy Ishida basic_symbol_iterator TapiFile::symbol_end() const { 99c20d1f90SCyndy Ishida DataRefImpl DRI; 100*425c6f07SJonas Devlieghere DRI.d.a = Symbols.size(); 101c20d1f90SCyndy Ishida return BasicSymbolRef{DRI, this}; 102c20d1f90SCyndy Ishida } 103