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/LoadLinkableFile.cpp
213799 views
1
//===------- LoadLinkableFile.cpp -- Load relocatables and archives -------===//
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/LoadLinkableFile.h"
10
11
#include "llvm/ADT/ScopeExit.h"
12
#include "llvm/BinaryFormat/Magic.h"
13
#include "llvm/ExecutionEngine/Orc/MachO.h"
14
#include "llvm/Support/FileSystem.h"
15
16
#define DEBUG_TYPE "orc"
17
18
namespace llvm {
19
namespace orc {
20
21
static Expected<std::unique_ptr<MemoryBuffer>>
22
checkCOFFRelocatableObject(std::unique_ptr<MemoryBuffer> Obj,
23
const Triple &TT) {
24
// TODO: Actually check the architecture of the file.
25
return std::move(Obj);
26
}
27
28
static Expected<std::unique_ptr<MemoryBuffer>>
29
checkXCOFFRelocatableObject(std::unique_ptr<MemoryBuffer> Obj,
30
const Triple &TT) {
31
// TODO: Actually check the architecture of the file.
32
return std::move(Obj);
33
}
34
35
static Expected<std::unique_ptr<MemoryBuffer>>
36
checkELFRelocatableObject(std::unique_ptr<MemoryBuffer> Obj, const Triple &TT) {
37
// TODO: Actually check the architecture of the file.
38
return std::move(Obj);
39
}
40
41
Expected<std::pair<std::unique_ptr<MemoryBuffer>, LinkableFileKind>>
42
loadLinkableFile(StringRef Path, const Triple &TT, LoadArchives LA,
43
std::optional<StringRef> IdentifierOverride) {
44
if (!IdentifierOverride)
45
IdentifierOverride = Path;
46
47
Expected<sys::fs::file_t> FDOrErr =
48
sys::fs::openNativeFileForRead(Path, sys::fs::OF_None);
49
if (!FDOrErr)
50
return createFileError(Path, FDOrErr.takeError());
51
sys::fs::file_t FD = *FDOrErr;
52
auto CloseFile = make_scope_exit([&]() { sys::fs::closeFile(FD); });
53
54
auto Buf =
55
MemoryBuffer::getOpenFile(FD, *IdentifierOverride, /*FileSize=*/-1);
56
if (!Buf)
57
return make_error<StringError>(
58
StringRef("Could not load object at path ") + Path, Buf.getError());
59
60
std::optional<Triple::ObjectFormatType> RequireFormat;
61
if (TT.getObjectFormat() != Triple::UnknownObjectFormat)
62
RequireFormat = TT.getObjectFormat();
63
64
switch (identify_magic((*Buf)->getBuffer())) {
65
case file_magic::archive:
66
if (LA != LoadArchives::Never)
67
return std::make_pair(std::move(*Buf), LinkableFileKind::Archive);
68
return make_error<StringError>(
69
Path + " does not contain a relocatable object file",
70
inconvertibleErrorCode());
71
case file_magic::coff_object:
72
if (LA == LoadArchives::Required)
73
return make_error<StringError>(Path + " does not contain an archive",
74
inconvertibleErrorCode());
75
76
if (!RequireFormat || *RequireFormat == Triple::COFF) {
77
auto CheckedBuf = checkCOFFRelocatableObject(std::move(*Buf), TT);
78
if (!CheckedBuf)
79
return CheckedBuf.takeError();
80
return std::make_pair(std::move(*CheckedBuf),
81
LinkableFileKind::RelocatableObject);
82
}
83
break;
84
case file_magic::elf_relocatable:
85
if (LA == LoadArchives::Required)
86
return make_error<StringError>(Path + " does not contain an archive",
87
inconvertibleErrorCode());
88
89
if (!RequireFormat || *RequireFormat == Triple::ELF) {
90
auto CheckedBuf = checkELFRelocatableObject(std::move(*Buf), TT);
91
if (!CheckedBuf)
92
return CheckedBuf.takeError();
93
return std::make_pair(std::move(*CheckedBuf),
94
LinkableFileKind::RelocatableObject);
95
}
96
break;
97
case file_magic::macho_object:
98
if (LA == LoadArchives::Required)
99
return make_error<StringError>(Path + " does not contain an archive",
100
inconvertibleErrorCode());
101
102
if (!RequireFormat || *RequireFormat == Triple::MachO) {
103
auto CheckedBuf = checkMachORelocatableObject(std::move(*Buf), TT, false);
104
if (!CheckedBuf)
105
return CheckedBuf.takeError();
106
return std::make_pair(std::move(*CheckedBuf),
107
LinkableFileKind::RelocatableObject);
108
}
109
break;
110
case file_magic::macho_universal_binary:
111
if (!RequireFormat || *RequireFormat == Triple::MachO)
112
return loadLinkableSliceFromMachOUniversalBinary(
113
FD, std::move(*Buf), TT, LA, Path, *IdentifierOverride);
114
break;
115
case file_magic::xcoff_object_64:
116
if (!RequireFormat || *RequireFormat == Triple::XCOFF) {
117
auto CheckedBuf = checkXCOFFRelocatableObject(std::move(*Buf), TT);
118
if (!CheckedBuf)
119
return CheckedBuf.takeError();
120
return std::make_pair(std::move(*CheckedBuf),
121
LinkableFileKind::RelocatableObject);
122
}
123
break;
124
default:
125
break;
126
}
127
128
return make_error<StringError>(
129
Path +
130
" does not contain a relocatable object file or archive compatible "
131
"with " +
132
TT.str(),
133
inconvertibleErrorCode());
134
}
135
136
} // End namespace orc.
137
} // End namespace llvm.
138
139