xref: /llvm-project/llvm/lib/Object/TapiFile.cpp (revision e9c8106a90d49e75bac87341ade57c6049357a97)
1c20d1f90SCyndy Ishida //===- TapiFile.cpp -------------------------------------------------------===//
2c20d1f90SCyndy Ishida //
3c20d1f90SCyndy Ishida // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c20d1f90SCyndy Ishida // See https://llvm.org/LICENSE.txt for license information.
5c20d1f90SCyndy Ishida // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c20d1f90SCyndy Ishida //
7c20d1f90SCyndy Ishida //===----------------------------------------------------------------------===//
8c20d1f90SCyndy Ishida //
9c20d1f90SCyndy Ishida // This file defines the Text-based Dynamcic Library Stub format.
10c20d1f90SCyndy Ishida //
11c20d1f90SCyndy Ishida //===----------------------------------------------------------------------===//
12c20d1f90SCyndy Ishida 
13c20d1f90SCyndy Ishida #include "llvm/Object/TapiFile.h"
14c20d1f90SCyndy Ishida #include "llvm/ADT/StringRef.h"
15e72c195fSserge-sans-paille #include "llvm/BinaryFormat/MachO.h"
16e72c195fSserge-sans-paille #include "llvm/Support/MemoryBufferRef.h"
17e72c195fSserge-sans-paille #include "llvm/TextAPI/ArchitectureSet.h"
18e72c195fSserge-sans-paille #include "llvm/TextAPI/InterfaceFile.h"
19e72c195fSserge-sans-paille #include "llvm/TextAPI/Platform.h"
2056709b86SCyndy Ishida #include "llvm/TextAPI/Symbol.h"
21c20d1f90SCyndy Ishida 
22c20d1f90SCyndy Ishida using namespace llvm;
23c20d1f90SCyndy Ishida using namespace MachO;
24c20d1f90SCyndy Ishida using namespace object;
25c20d1f90SCyndy Ishida 
26c20d1f90SCyndy Ishida static uint32_t getFlags(const Symbol *Sym) {
27c20d1f90SCyndy Ishida   uint32_t Flags = BasicSymbolRef::SF_Global;
28c20d1f90SCyndy Ishida   if (Sym->isUndefined())
29c20d1f90SCyndy Ishida     Flags |= BasicSymbolRef::SF_Undefined;
30c20d1f90SCyndy Ishida   else
31c20d1f90SCyndy Ishida     Flags |= BasicSymbolRef::SF_Exported;
32c20d1f90SCyndy Ishida 
33c20d1f90SCyndy Ishida   if (Sym->isWeakDefined() || Sym->isWeakReferenced())
34c20d1f90SCyndy Ishida     Flags |= BasicSymbolRef::SF_Weak;
35c20d1f90SCyndy Ishida 
36c20d1f90SCyndy Ishida   return Flags;
37c20d1f90SCyndy Ishida }
38c20d1f90SCyndy Ishida 
39bc85cf16SCyndy Ishida static SymbolRef::Type getType(const Symbol *Sym) {
40bc85cf16SCyndy Ishida   SymbolRef::Type Type = SymbolRef::ST_Unknown;
41bc85cf16SCyndy Ishida   if (Sym->isData())
42bc85cf16SCyndy Ishida     Type = SymbolRef::ST_Data;
43bc85cf16SCyndy Ishida   else if (Sym->isText())
44bc85cf16SCyndy Ishida     Type = SymbolRef::ST_Function;
45bc85cf16SCyndy Ishida 
46bc85cf16SCyndy Ishida   return Type;
47bc85cf16SCyndy Ishida }
48bc85cf16SCyndy Ishida 
49bc85cf16SCyndy Ishida TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &Interface,
50c20d1f90SCyndy Ishida                    Architecture Arch)
51455bf3d1SCyndy Ishida     : SymbolicFile(ID_TapiFile, Source), Arch(Arch),
52455bf3d1SCyndy Ishida       FileKind(Interface.getFileType()) {
53bc85cf16SCyndy Ishida   for (const auto *Symbol : Interface.symbols()) {
54c20d1f90SCyndy Ishida     if (!Symbol->getArchitectures().has(Arch))
55c20d1f90SCyndy Ishida       continue;
56c20d1f90SCyndy Ishida 
57c20d1f90SCyndy Ishida     switch (Symbol->getKind()) {
58*d9a9872eSCyndy Ishida     case EncodeKind::GlobalSymbol:
59bc85cf16SCyndy Ishida       Symbols.emplace_back(StringRef(), Symbol->getName(), getFlags(Symbol),
60bc85cf16SCyndy Ishida                            ::getType(Symbol));
61c20d1f90SCyndy Ishida       break;
62*d9a9872eSCyndy Ishida     case EncodeKind::ObjectiveCClass:
63bc85cf16SCyndy Ishida       if (Interface.getPlatforms().count(PLATFORM_MACOS) && Arch == AK_i386) {
64c20d1f90SCyndy Ishida         Symbols.emplace_back(ObjC1ClassNamePrefix, Symbol->getName(),
65bc85cf16SCyndy Ishida                              getFlags(Symbol), ::getType(Symbol));
66c20d1f90SCyndy Ishida       } else {
67c20d1f90SCyndy Ishida         Symbols.emplace_back(ObjC2ClassNamePrefix, Symbol->getName(),
68bc85cf16SCyndy Ishida                              getFlags(Symbol), ::getType(Symbol));
69c20d1f90SCyndy Ishida         Symbols.emplace_back(ObjC2MetaClassNamePrefix, Symbol->getName(),
70bc85cf16SCyndy Ishida                              getFlags(Symbol), ::getType(Symbol));
71c20d1f90SCyndy Ishida       }
72c20d1f90SCyndy Ishida       break;
73*d9a9872eSCyndy Ishida     case EncodeKind::ObjectiveCClassEHType:
74c20d1f90SCyndy Ishida       Symbols.emplace_back(ObjC2EHTypePrefix, Symbol->getName(),
75bc85cf16SCyndy Ishida                            getFlags(Symbol), ::getType(Symbol));
76c20d1f90SCyndy Ishida       break;
77*d9a9872eSCyndy Ishida     case EncodeKind::ObjectiveCInstanceVariable:
78bc85cf16SCyndy Ishida       Symbols.emplace_back(ObjC2IVarPrefix, Symbol->getName(), getFlags(Symbol),
79bc85cf16SCyndy Ishida                            ::getType(Symbol));
80c20d1f90SCyndy Ishida       break;
81c20d1f90SCyndy Ishida     }
82c20d1f90SCyndy Ishida   }
83c20d1f90SCyndy Ishida }
84c20d1f90SCyndy Ishida 
85c20d1f90SCyndy Ishida TapiFile::~TapiFile() = default;
86c20d1f90SCyndy Ishida 
87425c6f07SJonas Devlieghere void TapiFile::moveSymbolNext(DataRefImpl &DRI) const { DRI.d.a++; }
88c20d1f90SCyndy Ishida 
89c20d1f90SCyndy Ishida Error TapiFile::printSymbolName(raw_ostream &OS, DataRefImpl DRI) const {
90425c6f07SJonas Devlieghere   assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds");
91425c6f07SJonas Devlieghere   const Symbol &Sym = Symbols[DRI.d.a];
92425c6f07SJonas Devlieghere   OS << Sym.Prefix << Sym.Name;
93c20d1f90SCyndy Ishida   return Error::success();
94c20d1f90SCyndy Ishida }
95c20d1f90SCyndy Ishida 
96bc85cf16SCyndy Ishida Expected<SymbolRef::Type> TapiFile::getSymbolType(DataRefImpl DRI) const {
97bc85cf16SCyndy Ishida   assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds");
98bc85cf16SCyndy Ishida   return Symbols[DRI.d.a].Type;
99bc85cf16SCyndy Ishida }
100bc85cf16SCyndy Ishida 
101ac00376aSvgxbj Expected<uint32_t> TapiFile::getSymbolFlags(DataRefImpl DRI) const {
102425c6f07SJonas Devlieghere   assert(DRI.d.a < Symbols.size() && "Attempt to access symbol out of bounds");
103425c6f07SJonas Devlieghere   return Symbols[DRI.d.a].Flags;
104c20d1f90SCyndy Ishida }
105c20d1f90SCyndy Ishida 
106c20d1f90SCyndy Ishida basic_symbol_iterator TapiFile::symbol_begin() const {
107c20d1f90SCyndy Ishida   DataRefImpl DRI;
108425c6f07SJonas Devlieghere   DRI.d.a = 0;
109c20d1f90SCyndy Ishida   return BasicSymbolRef{DRI, this};
110c20d1f90SCyndy Ishida }
111c20d1f90SCyndy Ishida 
112c20d1f90SCyndy Ishida basic_symbol_iterator TapiFile::symbol_end() const {
113c20d1f90SCyndy Ishida   DataRefImpl DRI;
114425c6f07SJonas Devlieghere   DRI.d.a = Symbols.size();
115c20d1f90SCyndy Ishida   return BasicSymbolRef{DRI, this};
116c20d1f90SCyndy Ishida }
117