LLVM 23.0.0git
OffloadBundle.cpp
Go to the documentation of this file.
1//===- OffloadBundle.cpp - Utilities for offload bundles---*- C++ -*-===//
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
11#include "llvm/IR/Module.h"
14#include "llvm/Object/Archive.h"
15#include "llvm/Object/Binary.h"
16#include "llvm/Object/COFF.h"
18#include "llvm/Object/Error.h"
23#include "llvm/Support/Timer.h"
24
25using namespace llvm;
26using namespace llvm::object;
27
28static TimerGroup OffloadBundlerTimerGroup("Offload Bundler Timer Group",
29 "Timer group for offload bundler");
30
31// Returns the on-disk size recorded in the compressed offload bundle header at
32// the start of \p Blob, or std::nullopt if the header carries no size field.
33static std::optional<size_t> getCompressedBundleSize(StringRef Blob) {
36 if (!HeaderOrErr) {
37 consumeError(HeaderOrErr.takeError());
38 return std::nullopt;
39 }
40 return HeaderOrErr->FileSize;
41}
42
43// Extract an Offload bundle (usually a Offload Bundle) from a fat_bin
44// section.
46 StringRef FileName,
48
49 size_t Offset = 0;
50 size_t NextbundleStart = 0;
51 StringRef Magic;
52 std::unique_ptr<MemoryBuffer> Buffer;
53
54 // There could be multiple offloading bundles stored at this section.
55 while ((NextbundleStart != StringRef::npos) &&
56 (Offset < Contents.getBuffer().size())) {
57 Buffer =
59 /*RequiresNullTerminator=*/false);
60
61 if (identify_magic((*Buffer).getBuffer()) ==
63 Magic = "CCOB";
64 // Locate this bundle's end and the next bundle from the header size.
65 size_t CurBundleEnd;
66 if (std::optional<size_t> Size =
67 getCompressedBundleSize((*Buffer).getBuffer())) {
68 CurBundleEnd = *Size;
69 NextbundleStart = (*Buffer).getBuffer().find(Magic, *Size);
70 } else {
71 // Legacy bundle without a recorded size: fall back to magic scanning.
72 NextbundleStart = (*Buffer).getBuffer().find(Magic, Magic.size());
73 CurBundleEnd = NextbundleStart;
74 }
75 if (NextbundleStart == StringRef::npos) {
76 NextbundleStart = (*Buffer).getBuffer().size();
77 if (CurBundleEnd == StringRef::npos)
78 CurBundleEnd = (*Buffer).getBuffer().size();
79 }
80
83 (*Buffer).getBuffer().take_front(CurBundleEnd), FileName, false);
84 if (std::error_code EC = CodeOrErr.getError())
85 return createFileError(FileName, EC);
86
87 Expected<std::unique_ptr<MemoryBuffer>> DecompressedBufferOrErr =
88 CompressedOffloadBundle::decompress(**CodeOrErr, nullptr);
89 if (!DecompressedBufferOrErr)
90 return createStringError("failed to decompress input: " +
91 toString(DecompressedBufferOrErr.takeError()));
92
93 auto FatBundleOrErr = OffloadBundleFatBin::create(
94 **DecompressedBufferOrErr, Offset, FileName, true);
95 if (!FatBundleOrErr)
96 return FatBundleOrErr.takeError();
97
98 // Add current Bundle to list.
99 Bundles.emplace_back(std::move(**FatBundleOrErr));
100
101 } else if (identify_magic((*Buffer).getBuffer()) ==
103 // Create the OffloadBundleFatBin object. This will also create the Bundle
104 // Entry list info.
105 auto FatBundleOrErr = OffloadBundleFatBin::create(
106 *Buffer, SectionOffset + Offset, FileName);
107 if (!FatBundleOrErr)
108 return FatBundleOrErr.takeError();
109
110 // Add current Bundle to list.
111 Bundles.emplace_back(std::move(**FatBundleOrErr));
112
113 Magic = "__CLANG_OFFLOAD_BUNDLE__";
114 NextbundleStart = (*Buffer).getBuffer().find(Magic, Magic.size());
115 }
116
117 if (NextbundleStart != StringRef::npos)
118 Offset += NextbundleStart;
119 }
120
121 return Error::success();
122}
123
125 uint64_t SectionOffset) {
126 uint64_t NumOfEntries = 0;
127
129
130 // Read the Magic String first.
131 StringRef Magic;
132 if (auto EC = Reader.readFixedString(Magic, 24))
134
135 // Read the number of Code Objects (Entries) in the current Bundle.
136 if (auto EC = Reader.readInteger(NumOfEntries))
138
139 NumberOfEntries = NumOfEntries;
140
141 // For each Bundle Entry (code object).
142 for (uint64_t I = 0; I < NumOfEntries; I++) {
143 uint64_t EntrySize;
144 uint64_t EntryOffset;
145 uint64_t EntryIDSize;
146 StringRef EntryID;
147
148 if (Error Err = Reader.readInteger(EntryOffset))
149 return Err;
150
151 if (Error Err = Reader.readInteger(EntrySize))
152 return Err;
153
154 if (Error Err = Reader.readInteger(EntryIDSize))
155 return Err;
156
157 if (Error Err = Reader.readFixedString(EntryID, EntryIDSize))
158 return Err;
159
160 auto Entry = std::make_unique<OffloadBundleEntry>(
161 EntryOffset + SectionOffset, EntrySize, EntryIDSize, EntryID);
162
163 Entries.push_back(*Entry);
164 }
165
166 return Error::success();
167}
168
171 StringRef FileName, bool Decompress) {
172 if (Buf.getBufferSize() < 24)
174
175 // Check for magic bytes.
177 (identify_magic(Buf.getBuffer()) !=
180
181 std::unique_ptr<OffloadBundleFatBin> TheBundle(
182 new OffloadBundleFatBin(Buf, FileName, Decompress));
183
184 // Read the Bundle Entries.
185 Error Err =
186 TheBundle->readEntries(Buf.getBuffer(), Decompress ? 0 : SectionOffset);
187 if (Err)
188 return Err;
189
190 return std::move(TheBundle);
191}
192
194 // This will extract all entries in the Bundle.
195 for (OffloadBundleEntry &Entry : Entries) {
196
197 if (Entry.Size == 0)
198 continue;
199
200 // create output file name. Which should be
201 // <fileName>-offset<Offset>-size<Size>.co"
202 std::string Str = getFileName().str() + "-offset" + itostr(Entry.Offset) +
203 "-size" + itostr(Entry.Size) + ".co";
204 if (Error Err = object::extractCodeObject(Source, Entry.Offset, Entry.Size,
205 StringRef(Str)))
206 return Err;
207 }
208
209 return Error::success();
210}
211
214 // Ignore unsupported object formats.
215 if (!Obj.isELF() && !Obj.isCOFF())
216 return Error::success();
217
218 // Iterate through Sections until we find an offload_bundle section.
219 for (SectionRef Sec : Obj.sections()) {
220 Expected<StringRef> Buffer = Sec.getContents();
221 if (!Buffer)
222 return Buffer.takeError();
223
224 // If it does not start with the reserved suffix, just skip this section.
226 (llvm::identify_magic(*Buffer) ==
228
229 uint64_t SectionOffset = 0;
230 if (Obj.isELF()) {
231 SectionOffset = ELFSectionRef(Sec).getOffset();
232 } else if (Obj.isCOFF()) {
235 COFF.getSection(COFF.getSectionID(Sec));
236 if (!SecOrErr)
237 return SecOrErr.takeError();
238 SectionOffset = (*SecOrErr)->PointerToRawData;
239 }
240
241 MemoryBufferRef Contents(*Buffer, Obj.getFileName());
242 if (Error Err = extractOffloadBundle(Contents, SectionOffset,
243 Obj.getFileName(), Bundles))
244 return Err;
245 }
246 }
247 return Error::success();
248}
249
251 size_t Size, StringRef OutputFileName) {
253 FileOutputBuffer::create(OutputFileName, Size);
254
255 if (!BufferOrErr)
256 return BufferOrErr.takeError();
257
258 Expected<MemoryBufferRef> InputBuffOrErr = Source.getMemoryBufferRef();
259 if (Error Err = InputBuffOrErr.takeError())
260 return createFileError(Source.getFileName(), std::move(Err));
261
262 if (Size > InputBuffOrErr->getBufferSize())
263 return createStringError("size in URI (%zu) is larger than source (%zu)",
264 Size, InputBuffOrErr->getBufferSize());
265
266 if (Offset > InputBuffOrErr->getBufferSize())
267 return createStringError(
268 "offset in URI (%zu) is beyond the end of the source (%zu)", Offset,
269 InputBuffOrErr->getBufferSize());
270
271 if (Offset + Size > InputBuffOrErr->getBufferSize())
272 return createStringError(
273 "offset + size (%zu) in URI is beyond the end of the source (%zu)",
274 Offset + Size, InputBuffOrErr->getBufferSize());
275
276 std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr);
277 std::copy(InputBuffOrErr->getBufferStart() + Offset,
278 InputBuffOrErr->getBufferStart() + Offset + Size,
279 Buf->getBufferStart());
280 if (Error E = Buf->commit())
281 return createFileError(OutputFileName, std::move(E));
282
283 return Error::success();
284}
285
287 int64_t Size, StringRef OutputFileName) {
289 FileOutputBuffer::create(OutputFileName, Size);
290 if (!BufferOrErr)
291 return BufferOrErr.takeError();
292
293 std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr);
294 std::copy(Buffer.getBufferStart() + Offset,
295 Buffer.getBufferStart() + Offset + Size, Buf->getBufferStart());
296
297 return Buf->commit();
298}
299
300// given a file name, offset, and size, extract data into a code object file,
301// into file "<SourceFile>-offset<Offset>-size<Size>.co".
303 // create a URI object
306
307 if (!UriOrErr)
308 return UriOrErr.takeError();
309
310 OffloadBundleURI &Uri = **UriOrErr;
311 std::string OutputFile = Uri.FileName.str();
312 OutputFile +=
313 "-offset" + itostr(Uri.Offset) + "-size" + itostr(Uri.Size) + ".co";
314
315 // Create an ObjectFile object from uri.file_uri.
316 auto ObjOrErr = ObjectFile::createObjectFile(Uri.FileName);
317 if (!ObjOrErr)
318 return ObjOrErr.takeError();
319
320 auto Obj = ObjOrErr->getBinary();
321 if (Error Err =
322 object::extractCodeObject(*Obj, Uri.Offset, Uri.Size, OutputFile))
323 return createFileError(Uri.FileName, std::move(Err));
324
325 return Error::success();
326}
327
328// Utility function to format numbers with commas.
329static std::string formatWithCommas(unsigned long long Value) {
330 std::string Num = std::to_string(Value);
331 int InsertPosition = Num.length() - 3;
332 while (InsertPosition > 0) {
333 Num.insert(InsertPosition, ",");
334 InsertPosition -= 3;
335 }
336 return Num;
337}
338
339Expected<std::unique_ptr<MemoryBuffer>>
342 raw_ostream *VerboseStream) {
344 return createStringError("compression not supported.");
345 Timer HashTimer("Hash Calculation Timer", "Hash calculation time",
347 if (VerboseStream)
348 HashTimer.startTimer();
349 MD5 Hash;
350 MD5::MD5Result Result;
351 Hash.update(Input.getBuffer());
352 Hash.final(Result);
353 uint64_t TruncatedHash = Result.low();
354 if (VerboseStream)
355 HashTimer.stopTimer();
356
357 SmallVector<uint8_t, 0> CompressedBuffer;
358 auto BufferUint8 = ArrayRef<uint8_t>(
359 reinterpret_cast<const uint8_t *>(Input.getBuffer().data()),
360 Input.getBuffer().size());
361 Timer CompressTimer("Compression Timer", "Compression time",
363 if (VerboseStream)
364 CompressTimer.startTimer();
365 compression::compress(P, BufferUint8, CompressedBuffer);
366 if (VerboseStream)
367 CompressTimer.stopTimer();
368
369 uint16_t CompressionMethod = static_cast<uint16_t>(P.format);
370
371 // Store sizes in 64-bit variables first.
372 uint64_t UncompressedSize64 = Input.getBuffer().size();
373 uint64_t TotalFileSize64;
374
375 // Calculate total file size based on version.
376 if (Version == 2) {
377 // For V2, ensure the sizes don't exceed 32-bit limit.
378 if (UncompressedSize64 > std::numeric_limits<uint32_t>::max())
379 return createStringError("uncompressed size (%llu) exceeds version 2 "
380 "unsigned 32-bit integer limit",
381 UncompressedSize64);
382 TotalFileSize64 = MagicNumber.size() + sizeof(uint32_t) + sizeof(Version) +
383 sizeof(CompressionMethod) + sizeof(uint32_t) +
384 sizeof(TruncatedHash) + CompressedBuffer.size();
385 if (TotalFileSize64 > std::numeric_limits<uint32_t>::max())
386 return createStringError("total file size (%llu) exceeds version 2 "
387 "unsigned 32-bit integer limit",
388 TotalFileSize64);
389
390 } else { // Version 3.
391 TotalFileSize64 = MagicNumber.size() + sizeof(uint64_t) + sizeof(Version) +
392 sizeof(CompressionMethod) + sizeof(uint64_t) +
393 sizeof(TruncatedHash) + CompressedBuffer.size();
394 }
395
396 SmallVector<char, 0> FinalBuffer;
397 raw_svector_ostream OS(FinalBuffer);
398 OS << MagicNumber;
399 OS.write(reinterpret_cast<const char *>(&Version), sizeof(Version));
400 OS.write(reinterpret_cast<const char *>(&CompressionMethod),
401 sizeof(CompressionMethod));
402
403 // Write size fields according to version.
404 if (Version == 2) {
405 uint32_t TotalFileSize32 = static_cast<uint32_t>(TotalFileSize64);
406 uint32_t UncompressedSize32 = static_cast<uint32_t>(UncompressedSize64);
407 OS.write(reinterpret_cast<const char *>(&TotalFileSize32),
408 sizeof(TotalFileSize32));
409 OS.write(reinterpret_cast<const char *>(&UncompressedSize32),
410 sizeof(UncompressedSize32));
411 } else { // Version 3.
412 OS.write(reinterpret_cast<const char *>(&TotalFileSize64),
413 sizeof(TotalFileSize64));
414 OS.write(reinterpret_cast<const char *>(&UncompressedSize64),
415 sizeof(UncompressedSize64));
416 }
417
418 OS.write(reinterpret_cast<const char *>(&TruncatedHash),
419 sizeof(TruncatedHash));
420 OS.write(reinterpret_cast<const char *>(CompressedBuffer.data()),
421 CompressedBuffer.size());
422
423 if (VerboseStream) {
424 auto MethodUsed = P.format == compression::Format::Zstd ? "zstd" : "zlib";
425 double CompressionRate =
426 static_cast<double>(UncompressedSize64) / CompressedBuffer.size();
427 double CompressionTimeSeconds = CompressTimer.getTotalTime().getWallTime();
428 double CompressionSpeedMBs =
429 (UncompressedSize64 / (1024.0 * 1024.0)) / CompressionTimeSeconds;
430 *VerboseStream << "Compressed bundle format version: " << Version << "\n"
431 << "Total file size (including headers): "
432 << formatWithCommas(TotalFileSize64) << " bytes\n"
433 << "Compression method used: " << MethodUsed << "\n"
434 << "Compression level: " << P.level << "\n"
435 << "Binary size before compression: "
436 << formatWithCommas(UncompressedSize64) << " bytes\n"
437 << "Binary size after compression: "
438 << formatWithCommas(CompressedBuffer.size()) << " bytes\n"
439 << "Compression rate: " << format("%.2lf", CompressionRate)
440 << "\n"
441 << "Compression ratio: "
442 << format("%.2lf%%", 100.0 / CompressionRate) << "\n"
443 << "Compression speed: "
444 << format("%.2lf MB/s", CompressionSpeedMBs) << "\n"
445 << "Truncated MD5 hash: " << format_hex(TruncatedHash, 16)
446 << "\n";
447 }
448
450 StringRef(FinalBuffer.data(), FinalBuffer.size()));
451}
452
453// Use packed structs to avoid padding, such that the structs map the serialized
454// format.
489
490// Helper method to get header size based on version.
491static size_t getHeaderSize(uint16_t Version) {
492 switch (Version) {
493 case 1:
495 case 2:
497 case 3:
499 default:
500 llvm_unreachable("Unsupported version");
501 }
502}
503
504Expected<CompressedOffloadBundle::CompressedBundleHeader>
508
510 std::memcpy(&Header, Blob.data(), std::min(Blob.size(), sizeof(Header)));
511
512 CompressedBundleHeader Normalized;
513 Normalized.Version = Header.Common.Version;
514
515 size_t RequiredSize = getHeaderSize(Normalized.Version);
516
517 if (Blob.size() < RequiredSize)
518 return createStringError("compressed bundle header size too small");
519
520 switch (Normalized.Version) {
521 case 1:
522 Normalized.UncompressedFileSize = Header.V1.UncompressedFileSize;
523 Normalized.Hash = Header.V1.Hash;
524 break;
525 case 2:
526 Normalized.FileSize = Header.V2.FileSize;
527 Normalized.UncompressedFileSize = Header.V2.UncompressedFileSize;
528 Normalized.Hash = Header.V2.Hash;
529 break;
530 case 3:
531 Normalized.FileSize = Header.V3.FileSize;
532 Normalized.UncompressedFileSize = Header.V3.UncompressedFileSize;
533 Normalized.Hash = Header.V3.Hash;
534 break;
535 default:
536 return createStringError("unknown compressed bundle version");
537 }
538
539 // Determine compression format.
540 switch (Header.Common.Method) {
541 case static_cast<uint16_t>(compression::Format::Zlib):
542 case static_cast<uint16_t>(compression::Format::Zstd):
543 Normalized.CompressionFormat =
544 static_cast<compression::Format>(Header.Common.Method);
545 break;
546 default:
547 return createStringError("unknown compressing method");
548 }
549
550 return Normalized;
551}
552
555 raw_ostream *VerboseStream) {
556 StringRef Blob = Input.getBuffer();
557
558 // Check minimum header size (using V1 as it's the smallest).
561
563 if (VerboseStream)
564 *VerboseStream << "Uncompressed bundle\n";
566 }
567
570 if (!HeaderOrErr)
571 return HeaderOrErr.takeError();
572
573 const CompressedBundleHeader &Normalized = *HeaderOrErr;
574 unsigned ThisVersion = Normalized.Version;
575 size_t HeaderSize = getHeaderSize(ThisVersion);
576
577 compression::Format CompressionFormat = Normalized.CompressionFormat;
578
579 size_t TotalFileSize = Normalized.FileSize.value_or(0);
580 size_t UncompressedSize = Normalized.UncompressedFileSize;
581 auto StoredHash = Normalized.Hash;
582
583 Timer DecompressTimer("Decompression Timer", "Decompression time",
585 if (VerboseStream)
586 DecompressTimer.startTimer();
587
588 SmallVector<uint8_t, 0> DecompressedData;
589 StringRef CompressedData =
590 Blob.substr(HeaderSize, TotalFileSize - HeaderSize);
591
592 if (Error DecompressionError = compression::decompress(
593 CompressionFormat, arrayRefFromStringRef(CompressedData),
594 DecompressedData, UncompressedSize))
595 return createStringError("could not decompress embedded file contents: " +
596 toString(std::move(DecompressionError)));
597
598 if (VerboseStream) {
599 DecompressTimer.stopTimer();
600
601 double DecompressionTimeSeconds =
602 DecompressTimer.getTotalTime().getWallTime();
603
604 // Recalculate MD5 hash for integrity check.
605 Timer HashRecalcTimer("Hash Recalculation Timer", "Hash recalculation time",
607 HashRecalcTimer.startTimer();
608 MD5 Hash;
609 MD5::MD5Result Result;
610 Hash.update(ArrayRef<uint8_t>(DecompressedData));
611 Hash.final(Result);
612 uint64_t RecalculatedHash = Result.low();
613 HashRecalcTimer.stopTimer();
614 bool HashMatch = (StoredHash == RecalculatedHash);
615
616 double CompressionRate =
617 static_cast<double>(UncompressedSize) / CompressedData.size();
618 double DecompressionSpeedMBs =
619 (UncompressedSize / (1024.0 * 1024.0)) / DecompressionTimeSeconds;
620
621 *VerboseStream << "Compressed bundle format version: " << ThisVersion
622 << "\n";
623 if (ThisVersion >= 2)
624 *VerboseStream << "Total file size (from header): "
625 << formatWithCommas(TotalFileSize) << " bytes\n";
626 *VerboseStream
627 << "Decompression method: "
628 << (CompressionFormat == compression::Format::Zlib ? "zlib" : "zstd")
629 << "\n"
630 << "Size before decompression: "
631 << formatWithCommas(CompressedData.size()) << " bytes\n"
632 << "Size after decompression: " << formatWithCommas(UncompressedSize)
633 << " bytes\n"
634 << "Compression rate: " << format("%.2lf", CompressionRate) << "\n"
635 << "Compression ratio: " << format("%.2lf%%", 100.0 / CompressionRate)
636 << "\n"
637 << "Decompression speed: "
638 << format("%.2lf MB/s", DecompressionSpeedMBs) << "\n"
639 << "Stored hash: " << format_hex(StoredHash, 16) << "\n"
640 << "Recalculated hash: " << format_hex(RecalculatedHash, 16) << "\n"
641 << "Hashes match: " << (HashMatch ? "Yes" : "No") << "\n";
642 }
643
644 return MemoryBuffer::getMemBufferCopy(toStringRef(DecompressedData));
645}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_PACKED_END
Definition Compiler.h:557
#define LLVM_PACKED_START
Definition Compiler.h:556
Module.h This file contains the declarations for the Module class.
#define I(x, y, z)
Definition MD5.cpp:57
static LLVM_PACKED_END size_t getHeaderSize(uint16_t Version)
Error extractOffloadBundle(MemoryBufferRef Contents, uint64_t SectionOffset, StringRef FileName, SmallVectorImpl< OffloadBundleFatBin > &Bundles)
static std::string formatWithCommas(unsigned long long Value)
static TimerGroup OffloadBundlerTimerGroup("Offload Bundler Timer Group", "Timer group for offload bundler")
static std::optional< size_t > getCompressedBundleSize(StringRef Blob)
#define P(N)
The Input class is used to parse a yaml document into in-memory structs and vectors.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Provides read only access to a subclass of BinaryStream.
Error readInteger(T &Dest)
Read an integer of the specified endianness into Dest and update the stream's offset.
LLVM_ABI Error readFixedString(StringRef &Dest, uint32_t Length)
Read a Length byte string into Dest.
Represents either an error or a value T.
Definition ErrorOr.h:56
std::error_code getError() const
Definition ErrorOr.h:152
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Error takeError()
Take ownership of the stored error.
Definition Error.h:612
static LLVM_ABI Expected< std::unique_ptr< FileOutputBuffer > > create(StringRef FilePath, size_t Size, unsigned Flags=0)
Factory method to create an OutputBuffer object which manages a read/write buffer of the specified si...
LLVM_ABI void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
Definition MD5.cpp:188
LLVM_ABI void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
Definition MD5.cpp:233
size_t getBufferSize() const
const char * getBufferStart() const
StringRef getBuffer() const
This interface provides simple read-only access to a block of memory, and provides simple methods for...
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.
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.
Definition StringRef.h:56
static constexpr size_t npos
Definition StringRef.h:58
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:597
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition StringRef.h:635
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Definition StringRef.h:138
double getWallTime() const
Definition Timer.h:45
The TimerGroup class is used to group together related timers into a single report that is printed wh...
Definition Timer.h:191
This class is used to track the amount of time spent between invocations of its startTimer()/stopTime...
Definition Timer.h:87
LLVM_ABI void stopTimer()
Stop the timer.
Definition Timer.cpp:159
LLVM_ABI void startTimer()
Start the timer running.
Definition Timer.cpp:150
TimeRecord getTotalTime() const
Return the duration for which this timer has been running.
Definition Timer.h:145
LLVM Value Representation.
Definition Value.h:75
static LLVM_ABI llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > decompress(const llvm::MemoryBuffer &Input, raw_ostream *VerboseStream=nullptr)
static LLVM_ABI llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > compress(llvm::compression::Params P, const llvm::MemoryBuffer &Input, uint16_t Version, raw_ostream *VerboseStream=nullptr)
This class is the base class for all object file types.
Definition ObjectFile.h:231
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
LLVM_ABI Error readEntries(StringRef Section, uint64_t SectionOffset)
OffloadBundleFatBin(MemoryBufferRef Source, StringRef File, bool Decompress=false)
LLVM_ABI Error extractBundle(const ObjectFile &Source)
static LLVM_ABI Expected< std::unique_ptr< OffloadBundleFatBin > > create(MemoryBufferRef, uint64_t SectionOffset, StringRef FileName, bool Decompress=false)
This is a value type class that represents a single section in the list of sections in the object fil...
Definition ObjectFile.h:83
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
raw_ostream & write(unsigned char C)
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI bool isAvailable()
LLVM_ABI bool isAvailable()
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)
LLVM_ABI Error extractOffloadBundleByURI(StringRef URIstr)
Extracts an Offload Bundle Entry given by URI.
LLVM_ABI Error extractOffloadBundleFatBinary(const ObjectFile &Obj, SmallVectorImpl< OffloadBundleFatBin > &Bundles)
Extracts fat binary in binary clang-offload-bundler format from object Obj and return it in Bundles.
LLVM_ABI Error extractCodeObject(const ObjectFile &Source, size_t Offset, size_t Size, StringRef OutputFileName)
Extract code object memory from the given Source object file at Offset and of Size,...
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.
Definition Magic.cpp:33
@ Offset
Definition DWP.cpp:558
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Definition Error.h:1415
ArrayRef< CharT > arrayRefFromStringRef(StringRef Input)
Construct an array ref of bytes from a string ref.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
FunctionAddr VTableAddr uintptr_t uintptr_t Version
Definition InstrProf.h:334
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
Definition Format.h:191
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:129
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition Error.cpp:107
void consumeError(Error Err)
Consume a Error without doing anything.
Definition Error.h:1106
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
std::string itostr(int64_t X)
@ offload_bundle
Clang offload bundle file.
Definition Magic.h:60
@ offload_bundle_compressed
Compressed clang offload bundle file.
Definition Magic.h:61
static LLVM_ABI llvm::Expected< CompressedBundleHeader > tryParse(llvm::StringRef)
Bundle entry in binary clang-offload-bundler format.
static Expected< std::unique_ptr< OffloadBundleURI > > createOffloadBundleURI(StringRef Str, UriTypeT Type)