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" 158bcb0991SDimitry Andric #include "llvm/Object/Error.h" 168bcb0991SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 178bcb0991SDimitry Andric 188bcb0991SDimitry Andric using namespace llvm; 198bcb0991SDimitry Andric using namespace MachO; 208bcb0991SDimitry Andric using namespace object; 218bcb0991SDimitry Andric 228bcb0991SDimitry Andric static constexpr StringLiteral ObjC1ClassNamePrefix = ".objc_class_name_"; 238bcb0991SDimitry Andric static constexpr StringLiteral ObjC2ClassNamePrefix = "_OBJC_CLASS_$_"; 248bcb0991SDimitry Andric static constexpr StringLiteral ObjC2MetaClassNamePrefix = "_OBJC_METACLASS_$_"; 258bcb0991SDimitry Andric static constexpr StringLiteral ObjC2EHTypePrefix = "_OBJC_EHTYPE_$_"; 268bcb0991SDimitry Andric static constexpr StringLiteral ObjC2IVarPrefix = "_OBJC_IVAR_$_"; 278bcb0991SDimitry Andric 288bcb0991SDimitry Andric static uint32_t getFlags(const Symbol *Sym) { 298bcb0991SDimitry Andric uint32_t Flags = BasicSymbolRef::SF_Global; 308bcb0991SDimitry Andric if (Sym->isUndefined()) 318bcb0991SDimitry Andric Flags |= BasicSymbolRef::SF_Undefined; 328bcb0991SDimitry Andric else 338bcb0991SDimitry Andric Flags |= BasicSymbolRef::SF_Exported; 348bcb0991SDimitry Andric 358bcb0991SDimitry Andric if (Sym->isWeakDefined() || Sym->isWeakReferenced()) 368bcb0991SDimitry Andric Flags |= BasicSymbolRef::SF_Weak; 378bcb0991SDimitry Andric 388bcb0991SDimitry Andric return Flags; 398bcb0991SDimitry Andric } 408bcb0991SDimitry Andric 418bcb0991SDimitry Andric TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &interface, 428bcb0991SDimitry Andric Architecture Arch) 43*5ffd83dbSDimitry Andric : SymbolicFile(ID_TapiFile, Source), Arch(Arch) { 448bcb0991SDimitry Andric for (const auto *Symbol : interface.symbols()) { 458bcb0991SDimitry Andric if (!Symbol->getArchitectures().has(Arch)) 468bcb0991SDimitry Andric continue; 478bcb0991SDimitry Andric 488bcb0991SDimitry Andric switch (Symbol->getKind()) { 498bcb0991SDimitry Andric case SymbolKind::GlobalSymbol: 508bcb0991SDimitry Andric Symbols.emplace_back(StringRef(), Symbol->getName(), getFlags(Symbol)); 518bcb0991SDimitry Andric break; 528bcb0991SDimitry Andric case SymbolKind::ObjectiveCClass: 538bcb0991SDimitry Andric if (interface.getPlatforms().count(PlatformKind::macOS) && 548bcb0991SDimitry Andric Arch == AK_i386) { 558bcb0991SDimitry Andric Symbols.emplace_back(ObjC1ClassNamePrefix, Symbol->getName(), 568bcb0991SDimitry Andric getFlags(Symbol)); 578bcb0991SDimitry Andric } else { 588bcb0991SDimitry Andric Symbols.emplace_back(ObjC2ClassNamePrefix, Symbol->getName(), 598bcb0991SDimitry Andric getFlags(Symbol)); 608bcb0991SDimitry Andric Symbols.emplace_back(ObjC2MetaClassNamePrefix, Symbol->getName(), 618bcb0991SDimitry Andric getFlags(Symbol)); 628bcb0991SDimitry Andric } 638bcb0991SDimitry Andric break; 648bcb0991SDimitry Andric case SymbolKind::ObjectiveCClassEHType: 658bcb0991SDimitry Andric Symbols.emplace_back(ObjC2EHTypePrefix, Symbol->getName(), 668bcb0991SDimitry Andric getFlags(Symbol)); 678bcb0991SDimitry Andric break; 688bcb0991SDimitry Andric case SymbolKind::ObjectiveCInstanceVariable: 698bcb0991SDimitry Andric Symbols.emplace_back(ObjC2IVarPrefix, Symbol->getName(), 708bcb0991SDimitry Andric getFlags(Symbol)); 718bcb0991SDimitry Andric break; 728bcb0991SDimitry Andric } 738bcb0991SDimitry Andric } 748bcb0991SDimitry Andric } 758bcb0991SDimitry Andric 768bcb0991SDimitry Andric TapiFile::~TapiFile() = default; 778bcb0991SDimitry Andric 78*5ffd83dbSDimitry Andric void TapiFile::moveSymbolNext(DataRefImpl &DRI) const { DRI.d.a++; } 798bcb0991SDimitry Andric 808bcb0991SDimitry Andric Error TapiFile::printSymbolName(raw_ostream &OS, DataRefImpl DRI) const { 81*5ffd83dbSDimitry Andric assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds"); 82*5ffd83dbSDimitry Andric const Symbol &Sym = Symbols[DRI.d.a]; 83*5ffd83dbSDimitry Andric OS << Sym.Prefix << Sym.Name; 848bcb0991SDimitry Andric return Error::success(); 858bcb0991SDimitry Andric } 868bcb0991SDimitry Andric 87*5ffd83dbSDimitry Andric Expected<uint32_t> TapiFile::getSymbolFlags(DataRefImpl DRI) const { 88*5ffd83dbSDimitry Andric assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds"); 89*5ffd83dbSDimitry Andric return Symbols[DRI.d.a].Flags; 908bcb0991SDimitry Andric } 918bcb0991SDimitry Andric 928bcb0991SDimitry Andric basic_symbol_iterator TapiFile::symbol_begin() const { 938bcb0991SDimitry Andric DataRefImpl DRI; 94*5ffd83dbSDimitry Andric DRI.d.a = 0; 958bcb0991SDimitry Andric return BasicSymbolRef{DRI, this}; 968bcb0991SDimitry Andric } 978bcb0991SDimitry Andric 988bcb0991SDimitry Andric basic_symbol_iterator TapiFile::symbol_end() const { 998bcb0991SDimitry Andric DataRefImpl DRI; 100*5ffd83dbSDimitry Andric DRI.d.a = Symbols.size(); 1018bcb0991SDimitry Andric return BasicSymbolRef{DRI, this}; 1028bcb0991SDimitry Andric } 103