LLVM: lib/Object/OffloadBinary.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
10
25
26using namespace llvm;
28
29namespace {
30
31
32
33
37
39 std::unique_ptr Buffer =
41 false);
43 Buffer->getBufferStart()))
45 Buffer->getBufferIdentifier());
47 if (!BinaryOrErr)
48 return BinaryOrErr.takeError();
50
51
56 if (!NewBinaryOrErr)
57 return NewBinaryOrErr.takeError();
58 Binaries.emplace_back(std::move(*NewBinaryOrErr), std::move(BufferCopy));
59
61 }
62
64}
65
66
69 assert((Obj.isELF() || Obj.isCOFF()) && "Invalid file type");
70
72
73 if (Obj.isELF() &&
75 continue;
76
77
78 if (Obj.isCOFF()) {
80 if (!NameOrErr)
82
83 if (!NameOrErr->starts_with(".llvm.offloading"))
84 continue;
85 }
86
88 if (!Buffer)
90
92 if (Error Err = extractOffloadFiles(Contents, Binaries))
93 return Err;
94 }
95
97}
98
105 Context);
106 if (!M)
108 "Failed to create module");
109
110
111
112 auto *MD = M->getNamedMetadata("llvm.embedded.objects");
113 if (!MD)
115
116 for (const MDNode *Op : MD->operands()) {
117 if (Op->getNumOperands() < 2)
118 continue;
119
121 if (!SectionID || SectionID->getString() != ".llvm.offloading")
122 continue;
123
126 if (!GV)
127 continue;
128
130 if (!CDS)
131 continue;
132
133 MemoryBufferRef Contents(CDS->getAsString(), M->getName());
134 if (Error Err = extractOffloadFiles(Contents, Binaries))
135 return Err;
136 }
137
139}
140
141Error extractFromArchive(const Archive &Library,
143
145 for (auto Child : Library.children(Err)) {
146 auto ChildBufferOrErr = Child.getMemoryBufferRef();
147 if (!ChildBufferOrErr)
148 return ChildBufferOrErr.takeError();
149 std::unique_ptr ChildBuffer =
151
152
154 ChildBuffer->getBufferStart()))
156 ChildBufferOrErr->getBuffer(),
157 ChildBufferOrErr->getBufferIdentifier());
158
160 return Err;
161 }
162
163 if (Err)
164 return Err;
166}
167
168}
169
174
175
178
179
182
184 const Header *TheHeader = reinterpret_cast<const Header *>(Start);
187
189 TheHeader->Size < sizeof(Entry) || TheHeader->Size < sizeof(Header))
191
192 if (TheHeader->EntryOffset > TheHeader->Size - sizeof(Entry) ||
193 TheHeader->EntrySize > TheHeader->Size - sizeof(Header))
195
196 const Entry *TheEntry =
197 reinterpret_cast<const Entry *>(&Start[TheHeader->EntryOffset]);
198
199 if (TheEntry->ImageOffset > Buf.getBufferSize() ||
202
203 return std::unique_ptr(
204 new OffloadBinary(Buf, TheHeader, TheEntry));
205}
206
208
210 for (auto &KeyAndValue : OffloadingData.StringData) {
211 StrTab.add(KeyAndValue.first);
212 StrTab.add(KeyAndValue.second);
213 }
215
218
219
221 StringEntrySize + StrTab.getSize(),
223
224
225
226
229 BinaryDataSize + OffloadingData.Image->getBufferSize(), getAlignment());
230 TheHeader.EntryOffset = sizeof(Header);
231 TheHeader.EntrySize = sizeof(Entry);
232
233
234
237 TheEntry.TheOffloadKind = OffloadingData.TheOffloadKind;
238 TheEntry.Flags = OffloadingData.Flags;
239 TheEntry.StringOffset = sizeof(Header) + sizeof(Entry);
240 TheEntry.NumStrings = OffloadingData.StringData.size();
241
242 TheEntry.ImageOffset = BinaryDataSize;
243 TheEntry.ImageSize = OffloadingData.Image->getBufferSize();
244
246 Data.reserve(TheHeader.Size);
248 OS << StringRef(reinterpret_cast<char *>(&TheHeader), sizeof(Header));
249 OS << StringRef(reinterpret_cast<char *>(&TheEntry), sizeof(Entry));
250 for (auto &KeyAndValue : OffloadingData.StringData) {
254 OS << StringRef(reinterpret_cast<char *>(&Map), sizeof(StringEntry));
255 }
256 StrTab.write(OS);
257
259 OS << OffloadingData.Image->getBuffer();
260
261
262 assert(TheHeader.Size >= OS.tell() && "Too much data written?");
264 assert(TheHeader.Size == OS.tell() && "Size mismatch");
265
267}
268
272 switch (Type) {
274 return extractFromBitcode(Buffer, Binaries);
281 if (!ObjFile)
283 return extractFromObject(*ObjFile->get(), Binaries);
284 }
288 if (!LibFile)
290 return extractFromArchive(*LibFile->get(), Binaries);
291 }
293 return extractOffloadFiles(Buffer, Binaries);
294 default:
296 }
297}
298
307
309 switch (Kind) {
311 return "openmp";
313 return "cuda";
315 return "hip";
317 return "sycl";
318 default:
319 return "none";
320 }
321}
322
332
334 switch (Kind) {
336 return "o";
338 return "bc";
340 return "cubin";
342 return "fatbin";
344 return "s";
345 default:
346 return "";
347 }
348}
349
352
353
354 if (LHS == RHS)
355 return false;
356
357
358 if (LHS.first != RHS.first)
359 return false;
360
361
362 if (LHS.second == "generic" || RHS.second == "generic")
363 return true;
364
365
367 if (.isAMDGPU())
368 return false;
369
370
371 if (LHS.second.split(":").first != RHS.second.split(":").first)
372 return false;
373
374
375 if (LHS.second.contains("xnack+") && RHS.second.contains("xnack-"))
376 return false;
377 if (LHS.second.contains("xnack-") && RHS.second.contains("xnack+"))
378 return false;
379 if (LHS.second.contains("sramecc-") && RHS.second.contains("sramecc+"))
380 return false;
381 if (LHS.second.contains("sramecc+") && RHS.second.contains("sramecc-"))
382 return false;
383 return true;
384}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
This is an important class for using LLVM in a threaded context.
LLVM_ABI StringRef getString() const
size_t getBufferSize() const
StringRef getBufferIdentifier() const
const char * getBufferStart() const
StringRef getBuffer() const
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
StringRef - Represent a constant reference to a string, i.e.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
constexpr size_t size() const
size - Get the string size.
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Utility for building string tables with deduplicated suffixes.
LLVM_ABI size_t getOffset(CachedHashStringRef S) const
Get the offest of a string in the string table.
LLVM_ABI size_t add(CachedHashStringRef S, uint8_t Priority=0)
Add a string to the builder.
LLVM_ABI void write(raw_ostream &OS) const
LLVM_ABI void finalize()
Analyze the strings and build the final table.
Triple - Helper class for working with autoconf configuration names.
The instances of the Type class are immutable: once they are created, they are never changed.
iterator_range< child_iterator > children(Error &Err, bool SkipInternal=true) const
static Expected< std::unique_ptr< Archive > > create(MemoryBufferRef Source)
StringRef getData() const
This class is the base class for all object file types.
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
A simple binary serialization of an offloading file.
static uint64_t getAlignment()
static LLVM_ABI SmallString< 0 > write(const OffloadingImage &)
Serialize the contents of File to a binary buffer to be read later.
Definition OffloadBinary.cpp:207
static LLVM_ABI Expected< std::unique_ptr< OffloadBinary > > create(MemoryBufferRef)
Attempt to parse the offloading binary stored in Data.
Definition OffloadBinary.cpp:171
static const uint32_t Version
The current version of the binary used for backwards compatibility.
std::pair< StringRef, StringRef > TargetID
This is a value type class that represents a single section in the list of sections in the object fil...
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
uint64_t tell() const
tell - Return the current offset with the file.
A raw_ostream that writes to an SmallVector or SmallString.
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract_or_null(Y &&MD)
Extract a Value from Metadata, if any, allowing null.
LLVM_ABI Error extractOffloadBinaries(MemoryBufferRef Buffer, SmallVectorImpl< OffloadFile > &Binaries)
Extracts embedded device offloading code from a memory Buffer to a list of Binaries.
Definition OffloadBinary.cpp:269
LLVM_ABI ImageKind getImageKind(StringRef Name)
Convert a string Name to an image kind.
Definition OffloadBinary.cpp:323
LLVM_ABI bool areTargetsCompatible(const OffloadFile::TargetID &LHS, const OffloadFile::TargetID &RHS)
If the target is AMD we check the target IDs for mutual compatibility.
Definition OffloadBinary.cpp:350
OffloadKind
The producer of the associated offloading image.
LLVM_ABI OffloadKind getOffloadKind(StringRef Name)
Convert a string Name to an offload kind.
Definition OffloadBinary.cpp:299
LLVM_ABI StringRef getImageKindName(ImageKind Name)
Convert an image kind to its string representation.
Definition OffloadBinary.cpp:333
ImageKind
The type of contents the offloading image contains.
LLVM_ABI StringRef getOffloadKindName(OffloadKind Name)
Convert an offload kind to its string representation.
Definition OffloadBinary.cpp:308
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
bool isAddrAligned(Align Lhs, const void *Addr)
Checks that Addr is a multiple of the alignment.
LLVM_ABI std::unique_ptr< Module > getLazyIRModule(std::unique_ptr< MemoryBuffer > Buffer, SMDiagnostic &Err, LLVMContext &Context, bool ShouldLazyLoadMetadata=false)
If the given MemoryBuffer holds a bitcode image, return a Module for it which does lazy deserializati...
This struct is a compact representation of a valid (non-zero power of two) alignment.
file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...
@ elf_relocatable
ELF Relocatable object file.
@ archive
ar style archive file
@ elf_shared_object
ELF dynamically linked shared lib.
@ elf_executable
ELF Executable image.
@ offload_binary
LLVM offload object file.
@ coff_object
COFF object file.
The offloading metadata that will be serialized to a memory buffer.
OffloadKind TheOffloadKind
std::unique_ptr< MemoryBuffer > Image
MapVector< StringRef, StringRef > StringData