xref: /freebsd-src/contrib/llvm-project/llvm/lib/Object/TapiFile.cpp (revision 8bcb0991864975618c09697b1aca10683346d9f0)
1*8bcb0991SDimitry Andric //===- TapiFile.cpp -------------------------------------------------------===//
2*8bcb0991SDimitry Andric //
3*8bcb0991SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*8bcb0991SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*8bcb0991SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*8bcb0991SDimitry Andric //
7*8bcb0991SDimitry Andric //===----------------------------------------------------------------------===//
8*8bcb0991SDimitry Andric //
9*8bcb0991SDimitry Andric // This file defines the Text-based Dynamcic Library Stub format.
10*8bcb0991SDimitry Andric //
11*8bcb0991SDimitry Andric //===----------------------------------------------------------------------===//
12*8bcb0991SDimitry Andric 
13*8bcb0991SDimitry Andric #include "llvm/Object/TapiFile.h"
14*8bcb0991SDimitry Andric #include "llvm/ADT/StringRef.h"
15*8bcb0991SDimitry Andric #include "llvm/Object/Error.h"
16*8bcb0991SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
17*8bcb0991SDimitry Andric 
18*8bcb0991SDimitry Andric using namespace llvm;
19*8bcb0991SDimitry Andric using namespace MachO;
20*8bcb0991SDimitry Andric using namespace object;
21*8bcb0991SDimitry Andric 
22*8bcb0991SDimitry Andric static constexpr StringLiteral ObjC1ClassNamePrefix = ".objc_class_name_";
23*8bcb0991SDimitry Andric static constexpr StringLiteral ObjC2ClassNamePrefix = "_OBJC_CLASS_$_";
24*8bcb0991SDimitry Andric static constexpr StringLiteral ObjC2MetaClassNamePrefix = "_OBJC_METACLASS_$_";
25*8bcb0991SDimitry Andric static constexpr StringLiteral ObjC2EHTypePrefix = "_OBJC_EHTYPE_$_";
26*8bcb0991SDimitry Andric static constexpr StringLiteral ObjC2IVarPrefix = "_OBJC_IVAR_$_";
27*8bcb0991SDimitry Andric 
28*8bcb0991SDimitry Andric static uint32_t getFlags(const Symbol *Sym) {
29*8bcb0991SDimitry Andric   uint32_t Flags = BasicSymbolRef::SF_Global;
30*8bcb0991SDimitry Andric   if (Sym->isUndefined())
31*8bcb0991SDimitry Andric     Flags |= BasicSymbolRef::SF_Undefined;
32*8bcb0991SDimitry Andric   else
33*8bcb0991SDimitry Andric     Flags |= BasicSymbolRef::SF_Exported;
34*8bcb0991SDimitry Andric 
35*8bcb0991SDimitry Andric   if (Sym->isWeakDefined() || Sym->isWeakReferenced())
36*8bcb0991SDimitry Andric     Flags |= BasicSymbolRef::SF_Weak;
37*8bcb0991SDimitry Andric 
38*8bcb0991SDimitry Andric   return Flags;
39*8bcb0991SDimitry Andric }
40*8bcb0991SDimitry Andric 
41*8bcb0991SDimitry Andric TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &interface,
42*8bcb0991SDimitry Andric                    Architecture Arch)
43*8bcb0991SDimitry Andric     : SymbolicFile(ID_TapiFile, Source) {
44*8bcb0991SDimitry Andric   for (const auto *Symbol : interface.symbols()) {
45*8bcb0991SDimitry Andric     if (!Symbol->getArchitectures().has(Arch))
46*8bcb0991SDimitry Andric       continue;
47*8bcb0991SDimitry Andric 
48*8bcb0991SDimitry Andric     switch (Symbol->getKind()) {
49*8bcb0991SDimitry Andric     case SymbolKind::GlobalSymbol:
50*8bcb0991SDimitry Andric       Symbols.emplace_back(StringRef(), Symbol->getName(), getFlags(Symbol));
51*8bcb0991SDimitry Andric       break;
52*8bcb0991SDimitry Andric     case SymbolKind::ObjectiveCClass:
53*8bcb0991SDimitry Andric       if (interface.getPlatforms().count(PlatformKind::macOS) &&
54*8bcb0991SDimitry Andric           Arch == AK_i386) {
55*8bcb0991SDimitry Andric         Symbols.emplace_back(ObjC1ClassNamePrefix, Symbol->getName(),
56*8bcb0991SDimitry Andric                              getFlags(Symbol));
57*8bcb0991SDimitry Andric       } else {
58*8bcb0991SDimitry Andric         Symbols.emplace_back(ObjC2ClassNamePrefix, Symbol->getName(),
59*8bcb0991SDimitry Andric                              getFlags(Symbol));
60*8bcb0991SDimitry Andric         Symbols.emplace_back(ObjC2MetaClassNamePrefix, Symbol->getName(),
61*8bcb0991SDimitry Andric                              getFlags(Symbol));
62*8bcb0991SDimitry Andric       }
63*8bcb0991SDimitry Andric       break;
64*8bcb0991SDimitry Andric     case SymbolKind::ObjectiveCClassEHType:
65*8bcb0991SDimitry Andric       Symbols.emplace_back(ObjC2EHTypePrefix, Symbol->getName(),
66*8bcb0991SDimitry Andric                            getFlags(Symbol));
67*8bcb0991SDimitry Andric       break;
68*8bcb0991SDimitry Andric     case SymbolKind::ObjectiveCInstanceVariable:
69*8bcb0991SDimitry Andric       Symbols.emplace_back(ObjC2IVarPrefix, Symbol->getName(),
70*8bcb0991SDimitry Andric                            getFlags(Symbol));
71*8bcb0991SDimitry Andric       break;
72*8bcb0991SDimitry Andric     }
73*8bcb0991SDimitry Andric   }
74*8bcb0991SDimitry Andric }
75*8bcb0991SDimitry Andric 
76*8bcb0991SDimitry Andric TapiFile::~TapiFile() = default;
77*8bcb0991SDimitry Andric 
78*8bcb0991SDimitry Andric void TapiFile::moveSymbolNext(DataRefImpl &DRI) const {
79*8bcb0991SDimitry Andric   const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p);
80*8bcb0991SDimitry Andric   DRI.p = reinterpret_cast<uintptr_t>(++Sym);
81*8bcb0991SDimitry Andric }
82*8bcb0991SDimitry Andric 
83*8bcb0991SDimitry Andric Error TapiFile::printSymbolName(raw_ostream &OS, DataRefImpl DRI) const {
84*8bcb0991SDimitry Andric   const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p);
85*8bcb0991SDimitry Andric   OS << Sym->Prefix << Sym->Name;
86*8bcb0991SDimitry Andric   return Error::success();
87*8bcb0991SDimitry Andric }
88*8bcb0991SDimitry Andric 
89*8bcb0991SDimitry Andric uint32_t TapiFile::getSymbolFlags(DataRefImpl DRI) const {
90*8bcb0991SDimitry Andric   const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p);
91*8bcb0991SDimitry Andric   return Sym->Flags;
92*8bcb0991SDimitry Andric }
93*8bcb0991SDimitry Andric 
94*8bcb0991SDimitry Andric basic_symbol_iterator TapiFile::symbol_begin() const {
95*8bcb0991SDimitry Andric   DataRefImpl DRI;
96*8bcb0991SDimitry Andric   DRI.p = reinterpret_cast<uintptr_t>(&*Symbols.begin());
97*8bcb0991SDimitry Andric   return BasicSymbolRef{DRI, this};
98*8bcb0991SDimitry Andric }
99*8bcb0991SDimitry Andric 
100*8bcb0991SDimitry Andric basic_symbol_iterator TapiFile::symbol_end() const {
101*8bcb0991SDimitry Andric   DataRefImpl DRI;
102*8bcb0991SDimitry Andric   DRI.p = reinterpret_cast<uintptr_t>(&*Symbols.end());
103*8bcb0991SDimitry Andric   return BasicSymbolRef{DRI, this};
104*8bcb0991SDimitry Andric }
105