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" 15e72c195fSserge-sans-paille #include "llvm/BinaryFormat/MachO.h" 16e72c195fSserge-sans-paille #include "llvm/Support/MemoryBufferRef.h" 17e72c195fSserge-sans-paille #include "llvm/TextAPI/ArchitectureSet.h" 18e72c195fSserge-sans-paille #include "llvm/TextAPI/InterfaceFile.h" 19e72c195fSserge-sans-paille #include "llvm/TextAPI/Platform.h" 2056709b86SCyndy Ishida #include "llvm/TextAPI/Symbol.h" 21c20d1f90SCyndy Ishida 22c20d1f90SCyndy Ishida using namespace llvm; 23c20d1f90SCyndy Ishida using namespace MachO; 24c20d1f90SCyndy Ishida using namespace object; 25c20d1f90SCyndy Ishida 26c20d1f90SCyndy Ishida static uint32_t getFlags(const Symbol *Sym) { 27c20d1f90SCyndy Ishida uint32_t Flags = BasicSymbolRef::SF_Global; 28c20d1f90SCyndy Ishida if (Sym->isUndefined()) 29c20d1f90SCyndy Ishida Flags |= BasicSymbolRef::SF_Undefined; 30c20d1f90SCyndy Ishida else 31c20d1f90SCyndy Ishida Flags |= BasicSymbolRef::SF_Exported; 32c20d1f90SCyndy Ishida 33c20d1f90SCyndy Ishida if (Sym->isWeakDefined() || Sym->isWeakReferenced()) 34c20d1f90SCyndy Ishida Flags |= BasicSymbolRef::SF_Weak; 35c20d1f90SCyndy Ishida 36c20d1f90SCyndy Ishida return Flags; 37c20d1f90SCyndy Ishida } 38c20d1f90SCyndy Ishida 39bc85cf16SCyndy Ishida static SymbolRef::Type getType(const Symbol *Sym) { 40bc85cf16SCyndy Ishida SymbolRef::Type Type = SymbolRef::ST_Unknown; 41bc85cf16SCyndy Ishida if (Sym->isData()) 42bc85cf16SCyndy Ishida Type = SymbolRef::ST_Data; 43bc85cf16SCyndy Ishida else if (Sym->isText()) 44bc85cf16SCyndy Ishida Type = SymbolRef::ST_Function; 45bc85cf16SCyndy Ishida 46bc85cf16SCyndy Ishida return Type; 47bc85cf16SCyndy Ishida } 48bc85cf16SCyndy Ishida 49bc85cf16SCyndy Ishida TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &Interface, 50c20d1f90SCyndy Ishida Architecture Arch) 51455bf3d1SCyndy Ishida : SymbolicFile(ID_TapiFile, Source), Arch(Arch), 52455bf3d1SCyndy Ishida FileKind(Interface.getFileType()) { 53bc85cf16SCyndy Ishida for (const auto *Symbol : Interface.symbols()) { 54c20d1f90SCyndy Ishida if (!Symbol->getArchitectures().has(Arch)) 55c20d1f90SCyndy Ishida continue; 56c20d1f90SCyndy Ishida 57c20d1f90SCyndy Ishida switch (Symbol->getKind()) { 58*d9a9872eSCyndy Ishida case EncodeKind::GlobalSymbol: 59bc85cf16SCyndy Ishida Symbols.emplace_back(StringRef(), Symbol->getName(), getFlags(Symbol), 60bc85cf16SCyndy Ishida ::getType(Symbol)); 61c20d1f90SCyndy Ishida break; 62*d9a9872eSCyndy Ishida case EncodeKind::ObjectiveCClass: 63bc85cf16SCyndy Ishida if (Interface.getPlatforms().count(PLATFORM_MACOS) && Arch == AK_i386) { 64c20d1f90SCyndy Ishida Symbols.emplace_back(ObjC1ClassNamePrefix, Symbol->getName(), 65bc85cf16SCyndy Ishida getFlags(Symbol), ::getType(Symbol)); 66c20d1f90SCyndy Ishida } else { 67c20d1f90SCyndy Ishida Symbols.emplace_back(ObjC2ClassNamePrefix, Symbol->getName(), 68bc85cf16SCyndy Ishida getFlags(Symbol), ::getType(Symbol)); 69c20d1f90SCyndy Ishida Symbols.emplace_back(ObjC2MetaClassNamePrefix, Symbol->getName(), 70bc85cf16SCyndy Ishida getFlags(Symbol), ::getType(Symbol)); 71c20d1f90SCyndy Ishida } 72c20d1f90SCyndy Ishida break; 73*d9a9872eSCyndy Ishida case EncodeKind::ObjectiveCClassEHType: 74c20d1f90SCyndy Ishida Symbols.emplace_back(ObjC2EHTypePrefix, Symbol->getName(), 75bc85cf16SCyndy Ishida getFlags(Symbol), ::getType(Symbol)); 76c20d1f90SCyndy Ishida break; 77*d9a9872eSCyndy Ishida case EncodeKind::ObjectiveCInstanceVariable: 78bc85cf16SCyndy Ishida Symbols.emplace_back(ObjC2IVarPrefix, Symbol->getName(), getFlags(Symbol), 79bc85cf16SCyndy Ishida ::getType(Symbol)); 80c20d1f90SCyndy Ishida break; 81c20d1f90SCyndy Ishida } 82c20d1f90SCyndy Ishida } 83c20d1f90SCyndy Ishida } 84c20d1f90SCyndy Ishida 85c20d1f90SCyndy Ishida TapiFile::~TapiFile() = default; 86c20d1f90SCyndy Ishida 87425c6f07SJonas Devlieghere void TapiFile::moveSymbolNext(DataRefImpl &DRI) const { DRI.d.a++; } 88c20d1f90SCyndy Ishida 89c20d1f90SCyndy Ishida Error TapiFile::printSymbolName(raw_ostream &OS, DataRefImpl DRI) const { 90425c6f07SJonas Devlieghere assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds"); 91425c6f07SJonas Devlieghere const Symbol &Sym = Symbols[DRI.d.a]; 92425c6f07SJonas Devlieghere OS << Sym.Prefix << Sym.Name; 93c20d1f90SCyndy Ishida return Error::success(); 94c20d1f90SCyndy Ishida } 95c20d1f90SCyndy Ishida 96bc85cf16SCyndy Ishida Expected<SymbolRef::Type> TapiFile::getSymbolType(DataRefImpl DRI) const { 97bc85cf16SCyndy Ishida assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds"); 98bc85cf16SCyndy Ishida return Symbols[DRI.d.a].Type; 99bc85cf16SCyndy Ishida } 100bc85cf16SCyndy Ishida 101ac00376aSvgxbj Expected<uint32_t> TapiFile::getSymbolFlags(DataRefImpl DRI) const { 102425c6f07SJonas Devlieghere assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds"); 103425c6f07SJonas Devlieghere return Symbols[DRI.d.a].Flags; 104c20d1f90SCyndy Ishida } 105c20d1f90SCyndy Ishida 106c20d1f90SCyndy Ishida basic_symbol_iterator TapiFile::symbol_begin() const { 107c20d1f90SCyndy Ishida DataRefImpl DRI; 108425c6f07SJonas Devlieghere DRI.d.a = 0; 109c20d1f90SCyndy Ishida return BasicSymbolRef{DRI, this}; 110c20d1f90SCyndy Ishida } 111c20d1f90SCyndy Ishida 112c20d1f90SCyndy Ishida basic_symbol_iterator TapiFile::symbol_end() const { 113c20d1f90SCyndy Ishida DataRefImpl DRI; 114425c6f07SJonas Devlieghere DRI.d.a = Symbols.size(); 115c20d1f90SCyndy Ishida return BasicSymbolRef{DRI, this}; 116c20d1f90SCyndy Ishida } 117