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" 15*81ad6265SDimitry Andric #include "llvm/BinaryFormat/MachO.h" 168bcb0991SDimitry Andric #include "llvm/Object/Error.h" 17*81ad6265SDimitry Andric #include "llvm/Support/MemoryBufferRef.h" 18*81ad6265SDimitry Andric #include "llvm/TextAPI/ArchitectureSet.h" 19*81ad6265SDimitry Andric #include "llvm/TextAPI/InterfaceFile.h" 20*81ad6265SDimitry 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 408bcb0991SDimitry Andric TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &interface, 418bcb0991SDimitry Andric Architecture Arch) 425ffd83dbSDimitry Andric : SymbolicFile(ID_TapiFile, Source), Arch(Arch) { 438bcb0991SDimitry Andric for (const auto *Symbol : interface.symbols()) { 448bcb0991SDimitry Andric if (!Symbol->getArchitectures().has(Arch)) 458bcb0991SDimitry Andric continue; 468bcb0991SDimitry Andric 478bcb0991SDimitry Andric switch (Symbol->getKind()) { 488bcb0991SDimitry Andric case SymbolKind::GlobalSymbol: 498bcb0991SDimitry Andric Symbols.emplace_back(StringRef(), Symbol->getName(), getFlags(Symbol)); 508bcb0991SDimitry Andric break; 518bcb0991SDimitry Andric case SymbolKind::ObjectiveCClass: 5204eeddc0SDimitry Andric if (interface.getPlatforms().count(PLATFORM_MACOS) && Arch == AK_i386) { 538bcb0991SDimitry Andric Symbols.emplace_back(ObjC1ClassNamePrefix, Symbol->getName(), 548bcb0991SDimitry Andric getFlags(Symbol)); 558bcb0991SDimitry Andric } else { 568bcb0991SDimitry Andric Symbols.emplace_back(ObjC2ClassNamePrefix, Symbol->getName(), 578bcb0991SDimitry Andric getFlags(Symbol)); 588bcb0991SDimitry Andric Symbols.emplace_back(ObjC2MetaClassNamePrefix, Symbol->getName(), 598bcb0991SDimitry Andric getFlags(Symbol)); 608bcb0991SDimitry Andric } 618bcb0991SDimitry Andric break; 628bcb0991SDimitry Andric case SymbolKind::ObjectiveCClassEHType: 638bcb0991SDimitry Andric Symbols.emplace_back(ObjC2EHTypePrefix, Symbol->getName(), 648bcb0991SDimitry Andric getFlags(Symbol)); 658bcb0991SDimitry Andric break; 668bcb0991SDimitry Andric case SymbolKind::ObjectiveCInstanceVariable: 678bcb0991SDimitry Andric Symbols.emplace_back(ObjC2IVarPrefix, Symbol->getName(), 688bcb0991SDimitry Andric getFlags(Symbol)); 698bcb0991SDimitry Andric break; 708bcb0991SDimitry Andric } 718bcb0991SDimitry Andric } 728bcb0991SDimitry Andric } 738bcb0991SDimitry Andric 748bcb0991SDimitry Andric TapiFile::~TapiFile() = default; 758bcb0991SDimitry Andric 765ffd83dbSDimitry Andric void TapiFile::moveSymbolNext(DataRefImpl &DRI) const { DRI.d.a++; } 778bcb0991SDimitry Andric 788bcb0991SDimitry Andric Error TapiFile::printSymbolName(raw_ostream &OS, DataRefImpl DRI) const { 795ffd83dbSDimitry Andric assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds"); 805ffd83dbSDimitry Andric const Symbol &Sym = Symbols[DRI.d.a]; 815ffd83dbSDimitry Andric OS << Sym.Prefix << Sym.Name; 828bcb0991SDimitry Andric return Error::success(); 838bcb0991SDimitry Andric } 848bcb0991SDimitry Andric 855ffd83dbSDimitry Andric Expected<uint32_t> TapiFile::getSymbolFlags(DataRefImpl DRI) const { 865ffd83dbSDimitry Andric assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds"); 875ffd83dbSDimitry Andric return Symbols[DRI.d.a].Flags; 888bcb0991SDimitry Andric } 898bcb0991SDimitry Andric 908bcb0991SDimitry Andric basic_symbol_iterator TapiFile::symbol_begin() const { 918bcb0991SDimitry Andric DataRefImpl DRI; 925ffd83dbSDimitry Andric DRI.d.a = 0; 938bcb0991SDimitry Andric return BasicSymbolRef{DRI, this}; 948bcb0991SDimitry Andric } 958bcb0991SDimitry Andric 968bcb0991SDimitry Andric basic_symbol_iterator TapiFile::symbol_end() const { 978bcb0991SDimitry Andric DataRefImpl DRI; 985ffd83dbSDimitry Andric DRI.d.a = Symbols.size(); 998bcb0991SDimitry Andric return BasicSymbolRef{DRI, this}; 1008bcb0991SDimitry Andric } 101