xref: /src/contrib/llvm-project/llvm/lib/Object/TapiFile.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
11d5ae102SDimitry Andric //===- TapiFile.cpp -------------------------------------------------------===//
21d5ae102SDimitry Andric //
31d5ae102SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41d5ae102SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
51d5ae102SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61d5ae102SDimitry Andric //
71d5ae102SDimitry Andric //===----------------------------------------------------------------------===//
81d5ae102SDimitry Andric //
91d5ae102SDimitry Andric // This file defines the Text-based Dynamcic Library Stub format.
101d5ae102SDimitry Andric //
111d5ae102SDimitry Andric //===----------------------------------------------------------------------===//
121d5ae102SDimitry Andric 
131d5ae102SDimitry Andric #include "llvm/Object/TapiFile.h"
141d5ae102SDimitry Andric #include "llvm/ADT/StringRef.h"
15145449b1SDimitry Andric #include "llvm/BinaryFormat/MachO.h"
161d5ae102SDimitry Andric #include "llvm/Object/Error.h"
17145449b1SDimitry Andric #include "llvm/Support/MemoryBufferRef.h"
18145449b1SDimitry Andric #include "llvm/TextAPI/ArchitectureSet.h"
19145449b1SDimitry Andric #include "llvm/TextAPI/InterfaceFile.h"
20145449b1SDimitry Andric #include "llvm/TextAPI/Platform.h"
21344a3780SDimitry Andric #include "llvm/TextAPI/Symbol.h"
221d5ae102SDimitry Andric 
231d5ae102SDimitry Andric using namespace llvm;
241d5ae102SDimitry Andric using namespace MachO;
251d5ae102SDimitry Andric using namespace object;
261d5ae102SDimitry Andric 
getFlags(const Symbol * Sym)271d5ae102SDimitry Andric static uint32_t getFlags(const Symbol *Sym) {
281d5ae102SDimitry Andric   uint32_t Flags = BasicSymbolRef::SF_Global;
291d5ae102SDimitry Andric   if (Sym->isUndefined())
301d5ae102SDimitry Andric     Flags |= BasicSymbolRef::SF_Undefined;
311d5ae102SDimitry Andric   else
321d5ae102SDimitry Andric     Flags |= BasicSymbolRef::SF_Exported;
331d5ae102SDimitry Andric 
341d5ae102SDimitry Andric   if (Sym->isWeakDefined() || Sym->isWeakReferenced())
351d5ae102SDimitry Andric     Flags |= BasicSymbolRef::SF_Weak;
361d5ae102SDimitry Andric 
371d5ae102SDimitry Andric   return Flags;
381d5ae102SDimitry Andric }
391d5ae102SDimitry Andric 
getType(const Symbol * Sym)407fa27ce4SDimitry Andric static SymbolRef::Type getType(const Symbol *Sym) {
417fa27ce4SDimitry Andric   SymbolRef::Type Type = SymbolRef::ST_Unknown;
427fa27ce4SDimitry Andric   if (Sym->isData())
437fa27ce4SDimitry Andric     Type = SymbolRef::ST_Data;
447fa27ce4SDimitry Andric   else if (Sym->isText())
457fa27ce4SDimitry Andric     Type = SymbolRef::ST_Function;
467fa27ce4SDimitry Andric 
477fa27ce4SDimitry Andric   return Type;
487fa27ce4SDimitry Andric }
497fa27ce4SDimitry Andric 
TapiFile(MemoryBufferRef Source,const InterfaceFile & Interface,Architecture Arch)507fa27ce4SDimitry Andric TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &Interface,
511d5ae102SDimitry Andric                    Architecture Arch)
52b1c73532SDimitry Andric     : SymbolicFile(ID_TapiFile, Source), Arch(Arch),
53b1c73532SDimitry Andric       FileKind(Interface.getFileType()) {
547fa27ce4SDimitry Andric   for (const auto *Symbol : Interface.symbols()) {
551d5ae102SDimitry Andric     if (!Symbol->getArchitectures().has(Arch))
561d5ae102SDimitry Andric       continue;
571d5ae102SDimitry Andric 
581d5ae102SDimitry Andric     switch (Symbol->getKind()) {
59ac9a064cSDimitry Andric     case EncodeKind::GlobalSymbol:
607fa27ce4SDimitry Andric       Symbols.emplace_back(StringRef(), Symbol->getName(), getFlags(Symbol),
617fa27ce4SDimitry Andric                            ::getType(Symbol));
621d5ae102SDimitry Andric       break;
63ac9a064cSDimitry Andric     case EncodeKind::ObjectiveCClass:
647fa27ce4SDimitry Andric       if (Interface.getPlatforms().count(PLATFORM_MACOS) && Arch == AK_i386) {
651d5ae102SDimitry Andric         Symbols.emplace_back(ObjC1ClassNamePrefix, Symbol->getName(),
667fa27ce4SDimitry Andric                              getFlags(Symbol), ::getType(Symbol));
671d5ae102SDimitry Andric       } else {
681d5ae102SDimitry Andric         Symbols.emplace_back(ObjC2ClassNamePrefix, Symbol->getName(),
697fa27ce4SDimitry Andric                              getFlags(Symbol), ::getType(Symbol));
701d5ae102SDimitry Andric         Symbols.emplace_back(ObjC2MetaClassNamePrefix, Symbol->getName(),
717fa27ce4SDimitry Andric                              getFlags(Symbol), ::getType(Symbol));
721d5ae102SDimitry Andric       }
731d5ae102SDimitry Andric       break;
74ac9a064cSDimitry Andric     case EncodeKind::ObjectiveCClassEHType:
751d5ae102SDimitry Andric       Symbols.emplace_back(ObjC2EHTypePrefix, Symbol->getName(),
767fa27ce4SDimitry Andric                            getFlags(Symbol), ::getType(Symbol));
771d5ae102SDimitry Andric       break;
78ac9a064cSDimitry Andric     case EncodeKind::ObjectiveCInstanceVariable:
797fa27ce4SDimitry Andric       Symbols.emplace_back(ObjC2IVarPrefix, Symbol->getName(), getFlags(Symbol),
807fa27ce4SDimitry Andric                            ::getType(Symbol));
811d5ae102SDimitry Andric       break;
821d5ae102SDimitry Andric     }
831d5ae102SDimitry Andric   }
841d5ae102SDimitry Andric }
851d5ae102SDimitry Andric 
861d5ae102SDimitry Andric TapiFile::~TapiFile() = default;
871d5ae102SDimitry Andric 
moveSymbolNext(DataRefImpl & DRI) const88cfca06d7SDimitry Andric void TapiFile::moveSymbolNext(DataRefImpl &DRI) const { DRI.d.a++; }
891d5ae102SDimitry Andric 
printSymbolName(raw_ostream & OS,DataRefImpl DRI) const901d5ae102SDimitry Andric Error TapiFile::printSymbolName(raw_ostream &OS, DataRefImpl DRI) const {
91cfca06d7SDimitry Andric   assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds");
92cfca06d7SDimitry Andric   const Symbol &Sym = Symbols[DRI.d.a];
93cfca06d7SDimitry Andric   OS << Sym.Prefix << Sym.Name;
941d5ae102SDimitry Andric   return Error::success();
951d5ae102SDimitry Andric }
961d5ae102SDimitry Andric 
getSymbolType(DataRefImpl DRI) const977fa27ce4SDimitry Andric Expected<SymbolRef::Type> TapiFile::getSymbolType(DataRefImpl DRI) const {
987fa27ce4SDimitry Andric   assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds");
997fa27ce4SDimitry Andric   return Symbols[DRI.d.a].Type;
1007fa27ce4SDimitry Andric }
1017fa27ce4SDimitry Andric 
getSymbolFlags(DataRefImpl DRI) const102cfca06d7SDimitry Andric Expected<uint32_t> TapiFile::getSymbolFlags(DataRefImpl DRI) const {
103cfca06d7SDimitry Andric   assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds");
104cfca06d7SDimitry Andric   return Symbols[DRI.d.a].Flags;
1051d5ae102SDimitry Andric }
1061d5ae102SDimitry Andric 
symbol_begin() const1071d5ae102SDimitry Andric basic_symbol_iterator TapiFile::symbol_begin() const {
1081d5ae102SDimitry Andric   DataRefImpl DRI;
109cfca06d7SDimitry Andric   DRI.d.a = 0;
1101d5ae102SDimitry Andric   return BasicSymbolRef{DRI, this};
1111d5ae102SDimitry Andric }
1121d5ae102SDimitry Andric 
symbol_end() const1131d5ae102SDimitry Andric basic_symbol_iterator TapiFile::symbol_end() const {
1141d5ae102SDimitry Andric   DataRefImpl DRI;
115cfca06d7SDimitry Andric   DRI.d.a = Symbols.size();
1161d5ae102SDimitry Andric   return BasicSymbolRef{DRI, this};
1171d5ae102SDimitry Andric }
118