1 //===- TapiFile.cpp -------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the Text-based Dynamcic Library Stub format.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/Object/TapiFile.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/BinaryFormat/MachO.h"
16 #include "llvm/Object/Error.h"
17 #include "llvm/Support/MemoryBufferRef.h"
18 #include "llvm/TextAPI/ArchitectureSet.h"
19 #include "llvm/TextAPI/InterfaceFile.h"
20 #include "llvm/TextAPI/Platform.h"
21 #include "llvm/TextAPI/Symbol.h"
24 using namespace MachO
;
25 using namespace object
;
27 static uint32_t getFlags(const Symbol
*Sym
) {
28 uint32_t Flags
= BasicSymbolRef::SF_Global
;
29 if (Sym
->isUndefined())
30 Flags
|= BasicSymbolRef::SF_Undefined
;
32 Flags
|= BasicSymbolRef::SF_Exported
;
34 if (Sym
->isWeakDefined() || Sym
->isWeakReferenced())
35 Flags
|= BasicSymbolRef::SF_Weak
;
40 static SymbolRef::Type
getType(const Symbol
*Sym
) {
41 SymbolRef::Type Type
= SymbolRef::ST_Unknown
;
43 Type
= SymbolRef::ST_Data
;
44 else if (Sym
->isText())
45 Type
= SymbolRef::ST_Function
;
50 TapiFile::TapiFile(MemoryBufferRef Source
, const InterfaceFile
&Interface
,
52 : SymbolicFile(ID_TapiFile
, Source
), Arch(Arch
),
53 FileKind(Interface
.getFileType()) {
54 for (const auto *Symbol
: Interface
.symbols()) {
55 if (!Symbol
->getArchitectures().has(Arch
))
58 switch (Symbol
->getKind()) {
59 case SymbolKind::GlobalSymbol
:
60 Symbols
.emplace_back(StringRef(), Symbol
->getName(), getFlags(Symbol
),
63 case SymbolKind::ObjectiveCClass
:
64 if (Interface
.getPlatforms().count(PLATFORM_MACOS
) && Arch
== AK_i386
) {
65 Symbols
.emplace_back(ObjC1ClassNamePrefix
, Symbol
->getName(),
66 getFlags(Symbol
), ::getType(Symbol
));
68 Symbols
.emplace_back(ObjC2ClassNamePrefix
, Symbol
->getName(),
69 getFlags(Symbol
), ::getType(Symbol
));
70 Symbols
.emplace_back(ObjC2MetaClassNamePrefix
, Symbol
->getName(),
71 getFlags(Symbol
), ::getType(Symbol
));
74 case SymbolKind::ObjectiveCClassEHType
:
75 Symbols
.emplace_back(ObjC2EHTypePrefix
, Symbol
->getName(),
76 getFlags(Symbol
), ::getType(Symbol
));
78 case SymbolKind::ObjectiveCInstanceVariable
:
79 Symbols
.emplace_back(ObjC2IVarPrefix
, Symbol
->getName(), getFlags(Symbol
),
86 TapiFile::~TapiFile() = default;
88 void TapiFile::moveSymbolNext(DataRefImpl
&DRI
) const { DRI
.d
.a
++; }
90 Error
TapiFile::printSymbolName(raw_ostream
&OS
, DataRefImpl DRI
) const {
91 assert(DRI
.d
.a
< Symbols
.size() && "Attempt to access symbol out of bounds");
92 const Symbol
&Sym
= Symbols
[DRI
.d
.a
];
93 OS
<< Sym
.Prefix
<< Sym
.Name
;
94 return Error::success();
97 Expected
<SymbolRef::Type
> TapiFile::getSymbolType(DataRefImpl DRI
) const {
98 assert(DRI
.d
.a
< Symbols
.size() && "Attempt to access symbol out of bounds");
99 return Symbols
[DRI
.d
.a
].Type
;
102 Expected
<uint32_t> TapiFile::getSymbolFlags(DataRefImpl DRI
) const {
103 assert(DRI
.d
.a
< Symbols
.size() && "Attempt to access symbol out of bounds");
104 return Symbols
[DRI
.d
.a
].Flags
;
107 basic_symbol_iterator
TapiFile::symbol_begin() const {
110 return BasicSymbolRef
{DRI
, this};
113 basic_symbol_iterator
TapiFile::symbol_end() const {
115 DRI
.d
.a
= Symbols
.size();
116 return BasicSymbolRef
{DRI
, this};