xref: /freebsd-src/contrib/llvm-project/llvm/lib/Object/TapiFile.cpp (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
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