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