49 std::unique_ptr<MemoryBuffer> Buffer =
53 Buffer->getBufferStart()))
55 Buffer->getBufferIdentifier());
59 return HeaderOrErr.takeError();
66 return BinariesOrErr.takeError();
68 for (
auto &
Binary : *BinariesOrErr)
80 assert((
Obj.isELF() ||
Obj.isCOFF()) &&
"Invalid file type");
94 if (!NameOrErr->starts_with(
".llvm.offloading"))
103 if (
Error Err = extractOffloadFiles(Contents, Binaries))
119 "Failed to create module");
123 auto *MD = M->getNamedMetadata(
"llvm.embedded.objects");
127 for (
const MDNode *
Op : MD->operands()) {
128 if (
Op->getNumOperands() < 2)
132 if (!SectionID || SectionID->
getString() !=
".llvm.offloading")
145 if (
Error Err = extractOffloadFiles(Contents, Binaries))
156 for (
auto Child : Library.
children(Err)) {
157 auto ChildBufferOrErr = Child.getMemoryBufferRef();
158 if (!ChildBufferOrErr)
159 return ChildBufferOrErr.takeError();
160 std::unique_ptr<MemoryBuffer> ChildBuffer =
165 ChildBuffer->getBufferStart()))
167 ChildBufferOrErr->getBuffer(),
168 ChildBufferOrErr->getBufferIdentifier());
184 Header->EntriesOffset > Header->Size ||
185 Header->InflatedSize < Header->EntriesOffset)
192 uint64_t BodySize = Header->InflatedSize - Header->EntriesOffset;
197 return std::move(Err);
208 Out.append(
StringRef(
reinterpret_cast<const char *
>(&Restored),
223 return Hdr->
Version >= 3 && Hdr->InflatedSize != 0;
240 const Header *TheHeader =
reinterpret_cast<const Header *
>(Start);
250 if (TheHeader->Size <
sizeof(
Entry))
253 uint64_t EntriesCount =
254 (TheHeader->Version == 1) ? 1 : TheHeader->EntriesCount;
255 uint64_t EntriesSize =
sizeof(
Entry) * EntriesCount;
256 if (TheHeader->EntriesOffset > TheHeader->Size - EntriesSize ||
268 return HeaderOrErr.takeError();
269 const Header *OnDisk = *HeaderOrErr;
272 std::shared_ptr<MemoryBuffer>
Binary;
274 auto DecompressedOrErr = decompressOffloadBinary(Buf);
275 if (!DecompressedOrErr)
276 return DecompressedOrErr.takeError();
277 Binary = std::shared_ptr<MemoryBuffer>(std::move(*DecompressedOrErr));
287 return HeaderOrErr.takeError();
288 const Header *TheHeader = *HeaderOrErr;
291 const Entry *Entries =
292 reinterpret_cast<const Entry *
>(&Start[TheHeader->EntriesOffset]);
294 auto validateEntry = [&](
const Entry *TheEntry) ->
Error {
296 if (TheEntry->ImageOffset > BufSize ||
297 TheEntry->ImageSize > BufSize - TheEntry->ImageOffset)
300 const size_t StringEntrySize =
302 if (TheEntry->StringOffset > BufSize ||
303 TheEntry->NumStrings >
304 (BufSize - TheEntry->StringOffset) / StringEntrySize)
310 if (TheHeader->Version > 1 && Index.has_value()) {
311 if (*Index >= TheHeader->EntriesCount)
313 const Entry *TheEntry = &Entries[*Index];
314 if (
auto Err = validateEntry(TheEntry))
315 return std::move(Err);
318 new OffloadBinary(
Binary, TheHeader, TheEntry, *Index));
319 return std::move(Binaries);
322 uint64_t EntriesCount = TheHeader->Version == 1 ? 1 : TheHeader->EntriesCount;
323 for (uint64_t
I = 0;
I < EntriesCount; ++
I) {
324 const Entry *TheEntry = &Entries[
I];
325 if (
auto Err = validateEntry(TheEntry))
326 return std::move(Err);
331 return std::move(Binaries);
335 uint64_t EntriesCount = OffloadingData.
size();
336 assert(EntriesCount > 0 &&
"At least one offloading image is required");
341 uint64_t TotalStringEntries = 0;
342 uint64_t TotalImagesSize = 0;
344 for (
auto &KeyAndValue : Img.StringData) {
345 StrTab.
add(KeyAndValue.first);
346 StrTab.
add(KeyAndValue.second);
348 TotalStringEntries += Img.StringData.size();
349 TotalImagesSize += Img.Image->getBufferSize();
353 uint64_t StringEntrySize =
sizeof(
StringEntry) * TotalStringEntries;
354 uint64_t EntriesSize =
sizeof(
Entry) * EntriesCount;
355 uint64_t StrTabOffset =
sizeof(
Header) + EntriesSize + StringEntrySize;
358 uint64_t BinaryDataSize =
366 TheHeader.EntriesOffset =
sizeof(
Header);
367 TheHeader.EntriesCount = EntriesCount;
370 Data.reserve(TheHeader.Size);
372 OS << StringRef(reinterpret_cast<char *>(&TheHeader),
sizeof(
Header));
377 uint64_t StringEntryOffset =
sizeof(
Header) + EntriesSize;
378 uint64_t ImageOffset = BinaryDataSize;
383 TheEntry.TheOffloadKind = Img.TheOffloadKind;
384 TheEntry.Flags = Img.Flags;
386 TheEntry.StringOffset = StringEntryOffset;
387 StringEntryOffset +=
sizeof(
StringEntry) * Img.StringData.size();
388 TheEntry.NumStrings = Img.StringData.size();
390 TheEntry.ImageOffset = ImageOffset;
391 ImageOffset += Img.Image->getBufferSize();
392 TheEntry.ImageSize = Img.Image->getBufferSize();
394 OS << StringRef(reinterpret_cast<char *>(&TheEntry),
sizeof(
Entry));
399 for (
auto &KeyAndValue : Img.StringData) {
401 StrTabOffset + StrTab.
getOffset(KeyAndValue.second),
402 KeyAndValue.second.size()};
403 OS << StringRef(reinterpret_cast<char *>(&Map),
sizeof(
StringEntry));
412 OS << Img.Image->getBuffer();
415 assert(TheHeader.Size >= OS.
tell() &&
"Too much data written?");
417 assert(TheHeader.Size == OS.
tell() &&
"Size mismatch");
446 OS << StringRef(reinterpret_cast<const char *>(&
Header),
459 return extractFromBitcode(Buffer, Binaries);
468 return extractFromObject(*ObjFile->
get(), Binaries);
475 return extractFromArchive(*LibFile->
get(), Binaries);
478 return extractOffloadFiles(Buffer, Binaries);
572 if (Provided.second ==
"generic" || Requested.second ==
"generic")
575 return Provided.second == Requested.second;
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.
#define offsetof(TYPE, MEMBER)
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
bool isEquivalent(const TargetID &Other) const
Returns true if Other denotes the same target as *this, i.e.
bool providesFor(const TargetID &Other) const
Returns true if a device image for *this can provide the device code for a request for Other.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
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)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
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.
LLVM_ABI bool isCompatibleWith(const Triple &Other) const
Test whether target triples are compatible.
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)
Binary(unsigned int Type, MemoryBufferRef Source)
This class is the base class for all object file types.
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
static uint64_t getAlignment()
static LLVM_ABI Expected< SmallVector< std::unique_ptr< OffloadBinary > > > create(MemoryBufferRef Buf, std::optional< uint64_t > Index=std::nullopt)
Attempt to parse the offloading binary stored in Buf.
static LLVM_ABI SmallString< 0 > write(ArrayRef< OffloadingImage > OffloadingData)
Serialize the contents of OffloadingData to a binary buffer to be read later.
static LLVM_ABI bool isCompressed(MemoryBufferRef Buf)
True if Buf is a compressed offload package, false otherwise.
static LLVM_ABI Expected< const Header * > extractHeader(MemoryBufferRef Buf)
Attempt to extract and validate the header from the offloading binary in Buf.
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.
LLVM_ABI const char * getReasonIfUnsupported(Format F)
LLVM_ABI Error decompress(DebugCompressionType T, ArrayRef< uint8_t > Input, uint8_t *Output, size_t UncompressedSize)
LLVM_ABI void compress(Params P, ArrayRef< uint8_t > Input, SmallVectorImpl< uint8_t > &Output)
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 bool areTargetsEquivalent(const OffloadFile::TargetID &LHS, const OffloadFile::TargetID &RHS)
Returns true if LHS and RHS denote the same logical target, i.e.
LLVM_ABI bool areTargetsCompatible(const OffloadFile::TargetID &Provided, const OffloadFile::TargetID &Requested)
Returns true if an image built for target Provided can provide the device code for a request for targ...
LLVM_ABI Error extractOffloadBinaries(MemoryBufferRef Buffer, SmallVectorImpl< OffloadFile > &Binaries)
Extracts embedded device offloading code from a memory Buffer to a list of Binaries.
LLVM_ABI ImageKind getImageKind(StringRef Name)
Convert a string Name to an image kind.
OffloadKind
The producer of the associated offloading image.
LLVM_ABI OffloadKind getOffloadKind(StringRef Name)
Convert a string Name to an offload kind.
LLVM_ABI StringRef getImageKindName(ImageKind Name)
Convert an image kind to its string representation.
ImageKind
The type of contents the offloading image contains.
LLVM_ABI StringRef getOffloadKindName(OffloadKind Name)
Convert an offload kind to its string representation.
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.
ArrayRef< CharT > arrayRefFromStringRef(StringRef Input)
Construct an array ref of bytes from a string ref.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - 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.
constexpr 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.
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
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.