Skip to content

Commit 247da2c

Browse files
david-salinasdsalinas
authored andcommitted
Extend llvm objdump fatbin (llvm#140286)
Utilize the new extensions to the LLVM Offloading API to extend to llvm-objdump to handle dumping fatbin offload bundles generated by HIP. This extension to llvm-objdump adds the option --offload-fatbin. Specifying this option will take the input object/executable and extract all offload fatbin bundle entries into distinct code object files with names reflecting the source file name combined with the Bundle Entry ID. Users can also use the --arch-name option to filter offload fatbin bundle entries by their target triple. --------- Co-authored-by: dsalinas <[email protected]>
1 parent b8f69ab commit 247da2c

File tree

10 files changed

+654
-656
lines changed

10 files changed

+654
-656
lines changed

llvm/include/llvm/Object/OffloadBinary.h

Lines changed: 0 additions & 171 deletions
Original file line numberDiff line numberDiff line change
@@ -52,31 +52,6 @@ enum ImageKind : uint16_t {
5252
IMG_LAST,
5353
};
5454

55-
class CompressedOffloadBundle {
56-
private:
57-
static inline const size_t MagicSize = 4;
58-
static inline const size_t VersionFieldSize = sizeof(uint16_t);
59-
static inline const size_t MethodFieldSize = sizeof(uint16_t);
60-
static inline const size_t FileSizeFieldSize = sizeof(uint32_t);
61-
static inline const size_t UncompressedSizeFieldSize = sizeof(uint32_t);
62-
static inline const size_t HashFieldSize = sizeof(uint64_t);
63-
static inline const size_t V1HeaderSize =
64-
MagicSize + VersionFieldSize + MethodFieldSize +
65-
UncompressedSizeFieldSize + HashFieldSize;
66-
static inline const size_t V2HeaderSize =
67-
MagicSize + VersionFieldSize + FileSizeFieldSize + MethodFieldSize +
68-
UncompressedSizeFieldSize + HashFieldSize;
69-
static inline const llvm::StringRef MagicNumber = "CCOB";
70-
static inline const uint16_t Version = 2;
71-
72-
public:
73-
static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
74-
compress(llvm::compression::Params P, const llvm::MemoryBuffer &Input,
75-
bool Verbose = false);
76-
static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
77-
decompress(llvm::MemoryBufferRef &Input, bool Verbose = false);
78-
};
79-
8055
/// A simple binary serialization of an offloading file. We use this format to
8156
/// embed the offloading image into the host executable so it can be extracted
8257
/// and used by the linker.
@@ -211,157 +186,11 @@ class OffloadFile : public OwningBinary<OffloadBinary> {
211186
}
212187
};
213188

214-
/// Bundle entry in binary clang-offload-bundler format.
215-
struct OffloadBundleEntry {
216-
uint64_t Offset = 0u;
217-
uint64_t Size = 0u;
218-
uint64_t IDLength = 0u;
219-
StringRef ID;
220-
OffloadBundleEntry(uint64_t O, uint64_t S, uint64_t I, StringRef T)
221-
: Offset(O), Size(S), IDLength(I), ID(T) {}
222-
void dumpInfo(raw_ostream &OS) {
223-
OS << "Offset = " << Offset << ", Size = " << Size
224-
<< ", ID Length = " << IDLength << ", ID = " << ID;
225-
}
226-
void dumpURI(raw_ostream &OS, StringRef filePath) {
227-
OS << ID.data() << "\tfile://" << filePath << "#offset=" << Offset
228-
<< "&size=" << Size << "\n";
229-
}
230-
};
231-
232-
/// Fat binary embedded in object files in clang-offload-bundler format
233-
class OffloadBundleFatBin {
234-
235-
private:
236-
uint64_t Size = 0u;
237-
StringRef FileName;
238-
uint64_t NumberOfEntries;
239-
SmallVector<OffloadBundleEntry> Entries;
240-
241-
public:
242-
SmallVector<OffloadBundleEntry> getEntries() { return Entries; }
243-
uint64_t getSize() const { return Size; }
244-
StringRef getFileName() const { return FileName; }
245-
uint64_t getNumEntries() const { return NumberOfEntries; }
246-
247-
static Expected<std::unique_ptr<OffloadBundleFatBin>>
248-
create(MemoryBufferRef, uint64_t SectionOffset, StringRef fileName);
249-
Error extractBundle(const ObjectFile &Source);
250-
251-
Error DumpEntryToCodeObject();
252-
253-
Error ReadEntries(StringRef Section, uint64_t SectionOffset);
254-
void DumpEntries() {
255-
SmallVectorImpl<OffloadBundleEntry>::iterator it = Entries.begin();
256-
for (uint64_t I = 0; I < Entries.size(); I++) {
257-
it->dumpInfo(outs());
258-
++it;
259-
}
260-
}
261-
262-
void PrintEntriesAsURI() {
263-
SmallVectorImpl<OffloadBundleEntry>::iterator it = Entries.begin();
264-
for (uint64_t I = 0; I < NumberOfEntries; I++) {
265-
it->dumpURI(outs(), FileName);
266-
++it;
267-
}
268-
}
269-
270-
OffloadBundleFatBin(MemoryBufferRef Source, StringRef file) : FileName(file) {
271-
NumberOfEntries = 0;
272-
Entries = SmallVector<OffloadBundleEntry>();
273-
}
274-
275-
SmallVector<OffloadBundleEntry> EntryIDContains(StringRef str) {
276-
SmallVector<OffloadBundleEntry> found = SmallVector<OffloadBundleEntry>();
277-
SmallVectorImpl<OffloadBundleEntry>::iterator it = Entries.begin();
278-
for (uint64_t I = 0; I < NumberOfEntries; I++) {
279-
if (it->ID.contains(str)) {
280-
found.push_back(*it);
281-
}
282-
283-
++it;
284-
}
285-
return found;
286-
}
287-
};
288-
289-
enum uri_type_t { FILE_URI, MEMORY_URI };
290-
291-
struct OffloadBundleURI {
292-
int64_t Offset = 0;
293-
int64_t Size = 0;
294-
uint64_t ProcessID = 0;
295-
StringRef FileName;
296-
uri_type_t URIType;
297-
298-
// Constructors
299-
// TODO: add a Copy ctor ?
300-
OffloadBundleURI(StringRef file, int64_t off, int64_t size)
301-
: Offset(off), Size(size), ProcessID(0), FileName(file),
302-
URIType(FILE_URI) {}
303-
304-
OffloadBundleURI(StringRef str, uri_type_t type) {
305-
URIType = type;
306-
switch (URIType) {
307-
case FILE_URI:
308-
parseFileName(str);
309-
break;
310-
case MEMORY_URI:
311-
parseMemoryURI(str);
312-
break;
313-
}
314-
}
315-
316-
void parseFileName(StringRef str) {
317-
ProcessID = 0;
318-
URIType = FILE_URI;
319-
if (str.consume_front("file://")) {
320-
StringRef FilePathname =
321-
str.take_until([](char c) { return (c == '#') || (c == '?'); });
322-
FileName = FilePathname;
323-
str = str.drop_front(FilePathname.size());
324-
325-
if (str.consume_front("#offset=")) {
326-
StringRef OffsetStr = str.take_until([](char c) { return c == '&'; });
327-
OffsetStr.getAsInteger(10, Offset);
328-
str = str.drop_front(OffsetStr.size());
329-
330-
if (str.consume_front("&size=")) {
331-
str.getAsInteger(10, Size);
332-
} else
333-
report_fatal_error("Reading 'size' in URI.");
334-
} else
335-
report_fatal_error("Reading 'offset' in URI.");
336-
} else
337-
report_fatal_error("Reading type of URI.");
338-
}
339-
340-
void parseMemoryURI(StringRef str) {
341-
// TODO: add parseMemoryURI type
342-
}
343-
344-
StringRef getFileName() const { return FileName; }
345-
};
346-
347189
/// Extracts embedded device offloading code from a memory \p Buffer to a list
348190
/// of \p Binaries.
349191
Error extractOffloadBinaries(MemoryBufferRef Buffer,
350192
SmallVectorImpl<OffloadFile> &Binaries);
351193

352-
/// Extracts fat binary in binary clang-offload-bundler format from object \p
353-
/// Obj and return it in \p Bundles
354-
Error extractOffloadBundleFatBinary(
355-
const ObjectFile &Obj, SmallVectorImpl<OffloadBundleFatBin> &Bundles);
356-
357-
/// Extract code object memory from the given \p Source object file at \p Offset
358-
/// and of \p Size, and copy into \p OutputFileName.
359-
Error extractCodeObject(const ObjectFile &Source, int64_t Offset, int64_t Size,
360-
StringRef OutputFileName);
361-
362-
/// Extracts an Offload Bundle Entry given by URI
363-
Error extractOffloadBundleByURI(StringRef URIstr);
364-
365194
/// Convert a string \p Name to an image kind.
366195
ImageKind getImageKind(StringRef Name);
367196

llvm/lib/Object/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ add_llvm_component_library(LLVMObject
2222
Object.cpp
2323
ObjectFile.cpp
2424
OffloadBinary.cpp
25+
OffloadBundle.cpp
2526
RecordStreamer.cpp
2627
RelocationResolver.cpp
2728
SymbolicFile.cpp

0 commit comments

Comments
 (0)