[llvm] Extend llvm objdump fatbin (PR #114834)

Joseph Huber via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 28 17:55:52 PST 2025


================
@@ -183,11 +210,159 @@ class OffloadFile : public OwningBinary<OffloadBinary> {
   }
 };
 
+/// Bundle entry in binary clang-offload-bundler format.
+struct OffloadBundleEntry {
+  uint64_t Offset = 0u;
+  uint64_t Size = 0u;
+  uint64_t IDLength = 0u;
+  StringRef ID;
+  OffloadBundleEntry(uint64_t O, uint64_t S, uint64_t I, StringRef T)
+      : Offset(O), Size(S), IDLength(I), ID(T) {}
+  void dumpInfo(raw_ostream &OS) {
+    OS << "Offset = " << Offset << ", Size = " << Size
+       << ", ID Length = " << IDLength << ", ID = " << ID;
+  }
+  void dumpURI(raw_ostream &OS, StringRef filePath) {
+    OS << ID.data() << "\tfile://" << filePath << "#offset=" << Offset
+       << "&size=" << Size << "\n";
+  }
+};
+
+/// Fat binary embedded in object files in clang-offload-bundler format
+class OffloadBundleFatBin {
+
+private:
+  uint64_t Size = 0u;
+  StringRef FileName;
+  uint64_t NumberOfEntries;
+  SmallVector<OffloadBundleEntry> Entries;
+
+public:
+  SmallVector<OffloadBundleEntry> getEntries() { return Entries; }
+  uint64_t getSize() const { return Size; }
+  StringRef getFileName() const { return FileName; }
+  uint64_t getNumEntries() const { return NumberOfEntries; }
+
+  static Expected<std::unique_ptr<OffloadBundleFatBin>>
+  create(MemoryBufferRef, uint64_t SectionOffset, StringRef fileName);
+  Error extractBundle(const ObjectFile &Source);
+
+  Error dumpEntryToCodeObject();
+
+  Error ReadEntries(StringRef Section, uint64_t SectionOffset);
+  void DumpEntries() {
+    SmallVectorImpl<OffloadBundleEntry>::iterator it = Entries.begin();
+    for (uint64_t I = 0; I < Entries.size(); I++) {
+      it->dumpInfo(outs());
+      ++it;
+    }
+  }
+
+  void PrintEntriesAsURI() {
+    SmallVectorImpl<OffloadBundleEntry>::iterator it = Entries.begin();
+    for (uint64_t I = 0; I < Entries.size(); I++) {
+      it->dumpURI(outs(), FileName);
+      ++it;
+    }
+  }
+
+  OffloadBundleFatBin(MemoryBufferRef Source, StringRef file)
+      : FileName(file), NumberOfEntries(0),
+        Entries(SmallVector<OffloadBundleEntry>()) {}
+
+  SmallVector<OffloadBundleEntry> EntryIDContains(StringRef str) {
+    SmallVector<OffloadBundleEntry> found = SmallVector<OffloadBundleEntry>();
+    SmallVectorImpl<OffloadBundleEntry>::iterator it = Entries.begin();
+    for (uint64_t I = 0; I < Entries.size(); I++) {
+      if (it->ID.contains(str)) {
+        found.push_back(*it);
+      }
+
+      ++it;
+    }
+    return found;
+  }
+};
+
+enum uri_type_t { FILE_URI, MEMORY_URI };
+
+struct OffloadBundleURI {
+  int64_t Offset = 0;
+  int64_t Size = 0;
+  uint64_t ProcessID = 0;
+  StringRef FileName;
+  uri_type_t URIType;
+
+  // Constructors
+  // TODO: add a Copy ctor ?
+  OffloadBundleURI(StringRef file, int64_t off, int64_t size)
+      : Offset(off), Size(size), ProcessID(0), FileName(file),
+        URIType(FILE_URI) {}
+
+  OffloadBundleURI(StringRef str, uri_type_t type) {
+    URIType = type;
+    switch (URIType) {
+    case FILE_URI:
+      parseFileName(str);
+      break;
+    case MEMORY_URI:
+      parseMemoryURI(str);
+      break;
+    default:
+      report_fatal_error("Unrecognized URI type.");
+    }
+  }
+
+  void parseFileName(StringRef str) {
+    ProcessID = 0;
+    URIType = FILE_URI;
+    if (str.consume_front("file://")) {
+      StringRef FilePathname =
+          str.take_until([](char c) { return (c == '#') || (c == '?'); });
+      FileName = FilePathname;
+      str = str.drop_front(FilePathname.size());
+
+      if (str.consume_front("#offset=")) {
+        StringRef OffsetStr = str.take_until([](char c) { return c == '&'; });
+        OffsetStr.getAsInteger(10, Offset);
+        str = str.drop_front(OffsetStr.size());
+
+        if (str.consume_front("&size=")) {
+          // Size;
+          str.getAsInteger(10, Size);
+        } else
+          report_fatal_error("Reading 'size' in URI.");
----------------
jhuber6 wrote:

API functions like this should never fatally error like this. Return an `llvm::Error` and let the user decide if it's fatal.

https://github.com/llvm/llvm-project/pull/114834


More information about the llvm-commits mailing list