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