18bcb0991SDimitry Andric //===- TapiFile.cpp -------------------------------------------------------===// 28bcb0991SDimitry Andric // 38bcb0991SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 48bcb0991SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 58bcb0991SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 68bcb0991SDimitry Andric // 78bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 88bcb0991SDimitry Andric // 98bcb0991SDimitry Andric // This file defines the Text-based Dynamcic Library Stub format. 108bcb0991SDimitry Andric // 118bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 128bcb0991SDimitry Andric 138bcb0991SDimitry Andric #include "llvm/Object/TapiFile.h" 148bcb0991SDimitry Andric #include "llvm/ADT/StringRef.h" 1581ad6265SDimitry Andric #include "llvm/BinaryFormat/MachO.h" 168bcb0991SDimitry Andric #include "llvm/Object/Error.h" 1781ad6265SDimitry Andric #include "llvm/Support/MemoryBufferRef.h" 1881ad6265SDimitry Andric #include "llvm/TextAPI/ArchitectureSet.h" 1981ad6265SDimitry Andric #include "llvm/TextAPI/InterfaceFile.h" 2081ad6265SDimitry Andric #include "llvm/TextAPI/Platform.h" 21fe6060f1SDimitry Andric #include "llvm/TextAPI/Symbol.h" 228bcb0991SDimitry Andric 238bcb0991SDimitry Andric using namespace llvm; 248bcb0991SDimitry Andric using namespace MachO; 258bcb0991SDimitry Andric using namespace object; 268bcb0991SDimitry Andric 278bcb0991SDimitry Andric static uint32_t getFlags(const Symbol *Sym) { 288bcb0991SDimitry Andric uint32_t Flags = BasicSymbolRef::SF_Global; 298bcb0991SDimitry Andric if (Sym->isUndefined()) 308bcb0991SDimitry Andric Flags |= BasicSymbolRef::SF_Undefined; 318bcb0991SDimitry Andric else 328bcb0991SDimitry Andric Flags |= BasicSymbolRef::SF_Exported; 338bcb0991SDimitry Andric 348bcb0991SDimitry Andric if (Sym->isWeakDefined() || Sym->isWeakReferenced()) 358bcb0991SDimitry Andric Flags |= BasicSymbolRef::SF_Weak; 368bcb0991SDimitry Andric 378bcb0991SDimitry Andric return Flags; 388bcb0991SDimitry Andric } 398bcb0991SDimitry Andric 4006c3fb27SDimitry Andric static SymbolRef::Type getType(const Symbol *Sym) { 4106c3fb27SDimitry Andric SymbolRef::Type Type = SymbolRef::ST_Unknown; 4206c3fb27SDimitry Andric if (Sym->isData()) 4306c3fb27SDimitry Andric Type = SymbolRef::ST_Data; 4406c3fb27SDimitry Andric else if (Sym->isText()) 4506c3fb27SDimitry Andric Type = SymbolRef::ST_Function; 4606c3fb27SDimitry Andric 4706c3fb27SDimitry Andric return Type; 4806c3fb27SDimitry Andric } 4906c3fb27SDimitry Andric 5006c3fb27SDimitry Andric TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &Interface, 518bcb0991SDimitry Andric Architecture Arch) 525f757f3fSDimitry Andric : SymbolicFile(ID_TapiFile, Source), Arch(Arch), 535f757f3fSDimitry Andric FileKind(Interface.getFileType()) { 5406c3fb27SDimitry Andric for (const auto *Symbol : Interface.symbols()) { 558bcb0991SDimitry Andric if (!Symbol->getArchitectures().has(Arch)) 568bcb0991SDimitry Andric continue; 578bcb0991SDimitry Andric 588bcb0991SDimitry Andric switch (Symbol->getKind()) { 59*0fca6ea1SDimitry Andric case EncodeKind::GlobalSymbol: 6006c3fb27SDimitry Andric Symbols.emplace_back(StringRef(), Symbol->getName(), getFlags(Symbol), 6106c3fb27SDimitry Andric ::getType(Symbol)); 628bcb0991SDimitry Andric break; 63*0fca6ea1SDimitry Andric case EncodeKind::ObjectiveCClass: 6406c3fb27SDimitry Andric if (Interface.getPlatforms().count(PLATFORM_MACOS) && Arch == AK_i386) { 658bcb0991SDimitry Andric Symbols.emplace_back(ObjC1ClassNamePrefix, Symbol->getName(), 6606c3fb27SDimitry Andric getFlags(Symbol), ::getType(Symbol)); 678bcb0991SDimitry Andric } else { 688bcb0991SDimitry Andric Symbols.emplace_back(ObjC2ClassNamePrefix, Symbol->getName(), 6906c3fb27SDimitry Andric getFlags(Symbol), ::getType(Symbol)); 708bcb0991SDimitry Andric Symbols.emplace_back(ObjC2MetaClassNamePrefix, Symbol->getName(), 7106c3fb27SDimitry Andric getFlags(Symbol), ::getType(Symbol)); 728bcb0991SDimitry Andric } 738bcb0991SDimitry Andric break; 74*0fca6ea1SDimitry Andric case EncodeKind::ObjectiveCClassEHType: 758bcb0991SDimitry Andric Symbols.emplace_back(ObjC2EHTypePrefix, Symbol->getName(), 7606c3fb27SDimitry Andric getFlags(Symbol), ::getType(Symbol)); 778bcb0991SDimitry Andric break; 78*0fca6ea1SDimitry Andric case EncodeKind::ObjectiveCInstanceVariable: 7906c3fb27SDimitry Andric Symbols.emplace_back(ObjC2IVarPrefix, Symbol->getName(), getFlags(Symbol), 8006c3fb27SDimitry Andric ::getType(Symbol)); 818bcb0991SDimitry Andric break; 828bcb0991SDimitry Andric } 838bcb0991SDimitry Andric } 848bcb0991SDimitry Andric } 858bcb0991SDimitry Andric 868bcb0991SDimitry Andric TapiFile::~TapiFile() = default; 878bcb0991SDimitry Andric 885ffd83dbSDimitry Andric void TapiFile::moveSymbolNext(DataRefImpl &DRI) const { DRI.d.a++; } 898bcb0991SDimitry Andric 908bcb0991SDimitry Andric Error TapiFile::printSymbolName(raw_ostream &OS, DataRefImpl DRI) const { 915ffd83dbSDimitry Andric assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds"); 925ffd83dbSDimitry Andric const Symbol &Sym = Symbols[DRI.d.a]; 935ffd83dbSDimitry Andric OS << Sym.Prefix << Sym.Name; 948bcb0991SDimitry Andric return Error::success(); 958bcb0991SDimitry Andric } 968bcb0991SDimitry Andric 9706c3fb27SDimitry Andric Expected<SymbolRef::Type> TapiFile::getSymbolType(DataRefImpl DRI) const { 9806c3fb27SDimitry Andric assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds"); 9906c3fb27SDimitry Andric return Symbols[DRI.d.a].Type; 10006c3fb27SDimitry Andric } 10106c3fb27SDimitry Andric 1025ffd83dbSDimitry Andric Expected<uint32_t> TapiFile::getSymbolFlags(DataRefImpl DRI) const { 1035ffd83dbSDimitry Andric assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds"); 1045ffd83dbSDimitry Andric return Symbols[DRI.d.a].Flags; 1058bcb0991SDimitry Andric } 1068bcb0991SDimitry Andric 1078bcb0991SDimitry Andric basic_symbol_iterator TapiFile::symbol_begin() const { 1088bcb0991SDimitry Andric DataRefImpl DRI; 1095ffd83dbSDimitry Andric DRI.d.a = 0; 1108bcb0991SDimitry Andric return BasicSymbolRef{DRI, this}; 1118bcb0991SDimitry Andric } 1128bcb0991SDimitry Andric 1138bcb0991SDimitry Andric basic_symbol_iterator TapiFile::symbol_end() const { 1148bcb0991SDimitry Andric DataRefImpl DRI; 1155ffd83dbSDimitry Andric DRI.d.a = Symbols.size(); 1168bcb0991SDimitry Andric return BasicSymbolRef{DRI, this}; 1178bcb0991SDimitry Andric } 118