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());
180 return Header.Version >= 3 && Header.InflatedSize != 0;
188 Header->EntriesOffset > Header->Size ||
189 Header->InflatedSize < Header->EntriesOffset)
196 uint64_t BodySize = Header->InflatedSize - Header->EntriesOffset;
201 return std::move(Err);
212 Out.append(
StringRef(
reinterpret_cast<const char *
>(&Restored),
234 const Header *TheHeader =
reinterpret_cast<const Header *
>(Start);
241 if (isCompressed(*TheHeader))
244 if (TheHeader->Size <
sizeof(
Entry))
247 uint64_t EntriesCount =
248 (TheHeader->Version == 1) ? 1 : TheHeader->EntriesCount;
249 uint64_t EntriesSize =
sizeof(
Entry) * EntriesCount;
250 if (TheHeader->EntriesOffset > TheHeader->Size - EntriesSize ||
262 return HeaderOrErr.takeError();
263 const Header *OnDisk = *HeaderOrErr;
266 std::shared_ptr<MemoryBuffer>
Binary;
267 if (isCompressed(*OnDisk)) {
268 auto DecompressedOrErr = decompressOffloadBinary(Buf);
269 if (!DecompressedOrErr)
270 return DecompressedOrErr.takeError();
271 Binary = std::shared_ptr<MemoryBuffer>(std::move(*DecompressedOrErr));
281 return HeaderOrErr.takeError();
282 const Header *TheHeader = *HeaderOrErr;
285 const Entry *Entries =
286 reinterpret_cast<const Entry *
>(&Start[TheHeader->EntriesOffset]);
288 auto validateEntry = [&](
const Entry *TheEntry) ->
Error {
290 if (TheEntry->ImageOffset > BufSize ||
291 TheEntry->ImageSize > BufSize - TheEntry->ImageOffset)
294 const size_t StringEntrySize =
296 if (TheEntry->StringOffset > BufSize ||
297 TheEntry->NumStrings >
298 (BufSize - TheEntry->StringOffset) / StringEntrySize)
304 if (TheHeader->Version > 1 && Index.has_value()) {
305 if (*Index >= TheHeader->EntriesCount)
307 const Entry *TheEntry = &Entries[*Index];
308 if (
auto Err = validateEntry(TheEntry))
309 return std::move(Err);
312 new OffloadBinary(
Binary, TheHeader, TheEntry, *Index));
313 return std::move(Binaries);
316 uint64_t EntriesCount = TheHeader->Version == 1 ? 1 : TheHeader->EntriesCount;
317 for (uint64_t
I = 0;
I < EntriesCount; ++
I) {
318 const Entry *TheEntry = &Entries[
I];
319 if (
auto Err = validateEntry(TheEntry))
320 return std::move(Err);
325 return std::move(Binaries);
329 uint64_t EntriesCount = OffloadingData.
size();
330 assert(EntriesCount > 0 &&
"At least one offloading image is required");
335 uint64_t TotalStringEntries = 0;
336 uint64_t TotalImagesSize = 0;
338 for (
auto &KeyAndValue : Img.StringData) {
339 StrTab.
add(KeyAndValue.first);
340 StrTab.
add(KeyAndValue.second);
342 TotalStringEntries += Img.StringData.size();
343 TotalImagesSize += Img.Image->getBufferSize();
347 uint64_t StringEntrySize =
sizeof(
StringEntry) * TotalStringEntries;
348 uint64_t EntriesSize =
sizeof(
Entry) * EntriesCount;
349 uint64_t StrTabOffset =
sizeof(
Header) + EntriesSize + StringEntrySize;
352 uint64_t BinaryDataSize =
360 TheHeader.EntriesOffset =
sizeof(
Header);
361 TheHeader.EntriesCount = EntriesCount;
364 Data.reserve(TheHeader.Size);
366 OS << StringRef(reinterpret_cast<char *>(&TheHeader),
sizeof(
Header));
371 uint64_t StringEntryOffset =
sizeof(
Header) + EntriesSize;
372 uint64_t ImageOffset = BinaryDataSize;
377 TheEntry.TheOffloadKind = Img.TheOffloadKind;
378 TheEntry.Flags = Img.Flags;
380 TheEntry.StringOffset = StringEntryOffset;
381 StringEntryOffset +=
sizeof(
StringEntry) * Img.StringData.size();
382 TheEntry.NumStrings = Img.StringData.size();
384 TheEntry.ImageOffset = ImageOffset;
385 ImageOffset += Img.Image->getBufferSize();
386 TheEntry.ImageSize = Img.Image->getBufferSize();
388 OS << StringRef(reinterpret_cast<char *>(&TheEntry),
sizeof(
Entry));
393 for (
auto &KeyAndValue : Img.StringData) {
395 StrTabOffset + StrTab.
getOffset(KeyAndValue.second),
396 KeyAndValue.second.size()};
397 OS << StringRef(reinterpret_cast<char *>(&Map),
sizeof(
StringEntry));
406 OS << Img.Image->getBuffer();
409 assert(TheHeader.Size >= OS.
tell() &&
"Too much data written?");
411 assert(TheHeader.Size == OS.
tell() &&
"Size mismatch");
440 OS << StringRef(reinterpret_cast<const char *>(&
Header),
453 return extractFromBitcode(Buffer, Binaries);
462 return extractFromObject(*ObjFile->
get(), Binaries);
469 return extractFromArchive(*LibFile->
get(), Binaries);
472 return extractOffloadFiles(Buffer, Binaries);
566 if (Provided.second ==
"generic" || Requested.second ==
"generic")
569 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 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.