Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/GetDylibInterface.cpp
213799 views
1
//===-------- GetDylibInterface.cpp - Get interface for real dylib --------===//
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
#include "llvm/ExecutionEngine/Orc/GetDylibInterface.h"
10
11
#include "llvm/BinaryFormat/Magic.h"
12
#include "llvm/Object/MachO.h"
13
#include "llvm/Object/MachOUniversal.h"
14
#include "llvm/Object/TapiUniversal.h"
15
16
#define DEBUG_TYPE "orc"
17
18
namespace llvm::orc {
19
20
Expected<SymbolNameSet> getDylibInterfaceFromDylib(ExecutionSession &ES,
21
Twine Path) {
22
auto CPUType = MachO::getCPUType(ES.getTargetTriple());
23
if (!CPUType)
24
return CPUType.takeError();
25
26
auto CPUSubType = MachO::getCPUSubType(ES.getTargetTriple());
27
if (!CPUSubType)
28
return CPUSubType.takeError();
29
30
auto Buf = MemoryBuffer::getFile(Path);
31
if (!Buf)
32
return createFileError(Path, Buf.getError());
33
34
auto BinFile = object::createBinary((*Buf)->getMemBufferRef());
35
if (!BinFile)
36
return BinFile.takeError();
37
38
std::unique_ptr<object::MachOObjectFile> MachOFile;
39
if (isa<object::MachOObjectFile>(**BinFile))
40
MachOFile.reset(dyn_cast<object::MachOObjectFile>(BinFile->release()));
41
else if (auto *MachOUni =
42
dyn_cast<object::MachOUniversalBinary>(BinFile->get())) {
43
for (auto &O : MachOUni->objects()) {
44
if (O.getCPUType() == *CPUType &&
45
(O.getCPUSubType() & ~MachO::CPU_SUBTYPE_MASK) == *CPUSubType) {
46
if (auto Obj = O.getAsObjectFile())
47
MachOFile = std::move(*Obj);
48
else
49
return Obj.takeError();
50
break;
51
}
52
}
53
if (!MachOFile)
54
return make_error<StringError>("MachO universal binary at " + Path +
55
" does not contain a slice for " +
56
ES.getTargetTriple().str(),
57
inconvertibleErrorCode());
58
} else
59
return make_error<StringError>("File at " + Path + " is not a MachO",
60
inconvertibleErrorCode());
61
62
if (MachOFile->getHeader().filetype != MachO::MH_DYLIB)
63
return make_error<StringError>("MachO at " + Path + " is not a dylib",
64
inconvertibleErrorCode());
65
66
SymbolNameSet Symbols;
67
for (auto &Sym : MachOFile->symbols()) {
68
if (auto Name = Sym.getName())
69
Symbols.insert(ES.intern(*Name));
70
else
71
return Name.takeError();
72
}
73
74
return std::move(Symbols);
75
}
76
77
Expected<SymbolNameSet> getDylibInterfaceFromTapiFile(ExecutionSession &ES,
78
Twine Path) {
79
SymbolNameSet Symbols;
80
81
auto TapiFileBuffer = MemoryBuffer::getFile(Path);
82
if (!TapiFileBuffer)
83
return createFileError(Path, TapiFileBuffer.getError());
84
85
auto Tapi =
86
object::TapiUniversal::create((*TapiFileBuffer)->getMemBufferRef());
87
if (!Tapi)
88
return Tapi.takeError();
89
90
auto CPUType = MachO::getCPUType(ES.getTargetTriple());
91
if (!CPUType)
92
return CPUType.takeError();
93
94
auto CPUSubType = MachO::getCPUSubType(ES.getTargetTriple());
95
if (!CPUSubType)
96
return CPUSubType.takeError();
97
98
auto &IF = (*Tapi)->getInterfaceFile();
99
auto Interface =
100
IF.extract(MachO::getArchitectureFromCpuType(*CPUType, *CPUSubType));
101
if (!Interface)
102
return Interface.takeError();
103
104
for (auto *Sym : (*Interface)->exports())
105
Symbols.insert(ES.intern(Sym->getName()));
106
107
return Symbols;
108
}
109
110
Expected<SymbolNameSet> getDylibInterface(ExecutionSession &ES, Twine Path) {
111
file_magic Magic;
112
if (auto EC = identify_magic(Path, Magic))
113
return createFileError(Path, EC);
114
115
switch (Magic) {
116
case file_magic::macho_universal_binary:
117
case file_magic::macho_dynamically_linked_shared_lib:
118
return getDylibInterfaceFromDylib(ES, Path);
119
case file_magic::tapi_file:
120
return getDylibInterfaceFromTapiFile(ES, Path);
121
default:
122
return make_error<StringError>("Cannot get interface for " + Path +
123
" unrecognized file type",
124
inconvertibleErrorCode());
125
}
126
}
127
128
} // namespace llvm::orc
129
130