[clang] 3384f05 - [llvm-objdump][Offload] Use common offload extraction method

Joseph Huber via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 3 14:19:25 PDT 2022


Author: Joseph Huber
Date: 2022-11-03T16:19:13-05:00
New Revision: 3384f05a2cdb96a2f106c234ae8a9d0e306717a4

URL: https://github.com/llvm/llvm-project/commit/3384f05a2cdb96a2f106c234ae8a9d0e306717a4
DIFF: https://github.com/llvm/llvm-project/commit/3384f05a2cdb96a2f106c234ae8a9d0e306717a4.diff

LOG: [llvm-objdump][Offload] Use common offload extraction method

A previous patch introduced a common function used to extract offloading
binaries from an image. Therefore we no longer need to duplicate the
functionality in the `llvm-objdump` implementation. Functionally, this
removes the old warning behaviour when given malformed input. This has
been changed to a hard error, which is effectively the same.

This required a slight tweak in the linker wrapper to filter out the
user passing shared objects directly.

Reviewed By: tra

Differential Revision: https://reviews.llvm.org/D136796

Added: 
    llvm/test/tools/llvm-objdump/Offloading/elf.test

Modified: 
    clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
    llvm/lib/Object/OffloadBinary.cpp
    llvm/test/tools/llvm-objdump/Offloading/content-failure.test
    llvm/tools/llvm-objdump/OffloadDump.cpp

Removed: 
    llvm/test/tools/llvm-objdump/Offloading/binary.test
    llvm/test/tools/llvm-objdump/Offloading/warning.test


################################################################################
diff  --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index 3ad22be755f3c..6a12b64f7d7dd 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -1259,6 +1259,10 @@ Expected<SmallVector<OffloadFile>> getDeviceInput(const ArgList &Args) {
     if (std::error_code EC = BufferOrErr.getError())
       return createFileError(Filename, EC);
 
+    if (identify_magic((*BufferOrErr)->getBuffer()) ==
+        file_magic::elf_shared_object)
+      continue;
+
     bool IsLazy =
         identify_magic((*BufferOrErr)->getBuffer()) == file_magic::archive;
     if (Error Err = extractOffloadBinaries(

diff  --git a/llvm/lib/Object/OffloadBinary.cpp b/llvm/lib/Object/OffloadBinary.cpp
index 8f62d692d050a..3f7a60d89c27d 100644
--- a/llvm/lib/Object/OffloadBinary.cpp
+++ b/llvm/lib/Object/OffloadBinary.cpp
@@ -41,6 +41,10 @@ Error extractOffloadFiles(MemoryBufferRef Contents,
     std::unique_ptr<MemoryBuffer> Buffer =
         MemoryBuffer::getMemBuffer(Contents.getBuffer().drop_front(Offset), "",
                                    /*RequiresNullTerminator*/ false);
+    if (!isAddrAligned(Align(OffloadBinary::getAlignment()),
+                       Buffer->getBufferStart()))
+      Buffer = MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(),
+                                              Buffer->getBufferIdentifier());
     auto BinaryOrErr = OffloadBinary::create(*Buffer);
     if (!BinaryOrErr)
       return BinaryOrErr.takeError();
@@ -254,7 +258,9 @@ Error object::extractOffloadBinaries(MemoryBufferRef Buffer,
   switch (Type) {
   case file_magic::bitcode:
     return extractFromBitcode(Buffer, Binaries);
-  case file_magic::elf_relocatable: {
+  case file_magic::elf_relocatable:
+  case file_magic::elf_executable:
+  case file_magic::elf_shared_object: {
     Expected<std::unique_ptr<ObjectFile>> ObjFile =
         ObjectFile::createObjectFile(Buffer, Type);
     if (!ObjFile)

diff  --git a/llvm/test/tools/llvm-objdump/Offloading/content-failure.test b/llvm/test/tools/llvm-objdump/Offloading/content-failure.test
index 5089edae04502..40ff6785f2d38 100644
--- a/llvm/test/tools/llvm-objdump/Offloading/content-failure.test
+++ b/llvm/test/tools/llvm-objdump/Offloading/content-failure.test
@@ -15,4 +15,4 @@ Sections:
     ShOffset:        0x99999
     AddressAlign:    0x0000000000000008
 
-# CHECK: error: '[[FILENAME]]': The end of the file was unexpectedly encountered
+# CHECK: error: '[[FILENAME]]': while extracting offloading files: The end of the file was unexpectedly encountered

diff  --git a/llvm/test/tools/llvm-objdump/Offloading/binary.test b/llvm/test/tools/llvm-objdump/Offloading/elf.test
similarity index 67%
rename from llvm/test/tools/llvm-objdump/Offloading/binary.test
rename to llvm/test/tools/llvm-objdump/Offloading/elf.test
index 880bab2ec5337..10182aeb856cd 100644
--- a/llvm/test/tools/llvm-objdump/Offloading/binary.test
+++ b/llvm/test/tools/llvm-objdump/Offloading/elf.test
@@ -3,15 +3,21 @@
 # RUN: llvm-objdump --offloading %t.bin | FileCheck %s --match-full-lines --strict-whitespace --implicit-check-not={{.}}
 
 ## Check that we can dump an offloading binary inside of an ELF section.
-# RUN: yaml2obj %s -o %t.elf
-# RUN: llvm-objcopy --update-section .llvm.offloading=%t.bin %t.elf
-# RUN: llvm-objdump --offloading %t.elf | FileCheck %s --check-prefixes=CHECK,ELF --match-full-lines --strict-whitespace --implicit-check-not={{.}}
+# RUN: yaml2obj %s -o %t -DTYPE=ET_EXEC
+# RUN: yaml2obj %s -o %t.so -DTYPE=ET_DYN
+# RUN: yaml2obj %s -o %t.o -DTYPE=ET_REL
+# RUN: llvm-objcopy --update-section .llvm.offloading=%t.bin %t
+# RUN: llvm-objcopy --update-section .llvm.offloading=%t.bin %t.so
+# RUN: llvm-objcopy --update-section .llvm.offloading=%t.bin %t.o
+# RUN: llvm-objdump --offloading %t | FileCheck %s --check-prefixes=CHECK,ELF --match-full-lines --strict-whitespace --implicit-check-not={{.}}
+# RUN: llvm-objdump --offloading %t.so | FileCheck %s --check-prefixes=CHECK,ELF --match-full-lines --strict-whitespace --implicit-check-not={{.}}
+# RUN: llvm-objdump --offloading %t.o | FileCheck %s --check-prefixes=CHECK,ELF --match-full-lines --strict-whitespace --implicit-check-not={{.}}
 
 !ELF
 FileHeader:
   Class:           ELFCLASS64
   Data:            ELFDATA2LSB
-  Type:            ET_EXEC
+  Type:            [[TYPE]]
 Sections:
   - Name:            .llvm.offloading
     Type:            SHT_LLVM_OFFLOADING

diff  --git a/llvm/test/tools/llvm-objdump/Offloading/warning.test b/llvm/test/tools/llvm-objdump/Offloading/warning.test
deleted file mode 100644
index a4be54ebf6dc3..0000000000000
--- a/llvm/test/tools/llvm-objdump/Offloading/warning.test
+++ /dev/null
@@ -1,21 +0,0 @@
-## Ensure we give a warning on bad input following good input.
-# RUN: yaml2obj %S/Inputs/binary.yaml -o %t-good.bin
-# RUN: yaml2obj %S/Inputs/malformed.yaml -o %t-bad.bin
-# RUN: cat %t-bad.bin >> %t-good.bin
-# RUN: yaml2obj %s -o %t.elf
-# RUN: llvm-objcopy --update-section .llvm.offloading=%t-good.bin %t.elf
-# RUN: llvm-objdump --offloading %t.elf 2>&1 | FileCheck %s -DFILENAME=%t.elf
-
-!ELF
-FileHeader:
-  Class:           ELFCLASS64
-  Data:            ELFDATA2LSB
-  Type:            ET_EXEC
-Sections:
-  - Name:            .llvm.offloading
-    Type:            SHT_LLVM_OFFLOADING
-    Flags:           [ SHF_EXCLUDE ]
-    AddressAlign:    0x0000000000000008
-
-# CHECK: OFFLOADING IMAGE [0]:
-# CHECK: warning: '[[FILENAME]]': while parsing offloading files: The end of the file was unexpectedly encountered

diff  --git a/llvm/tools/llvm-objdump/OffloadDump.cpp b/llvm/tools/llvm-objdump/OffloadDump.cpp
index 46334c249070d..fdef373279b39 100644
--- a/llvm/tools/llvm-objdump/OffloadDump.cpp
+++ b/llvm/tools/llvm-objdump/OffloadDump.cpp
@@ -10,6 +10,7 @@
 /// This file implements the offloading-specific dumper for llvm-objdump.
 ///
 //===----------------------------------------------------------------------===//
+
 #include "OffloadDump.h"
 #include "llvm-objdump.h"
 #include "llvm/Object/ELFObjectFile.h"
@@ -46,24 +47,6 @@ static void printBinary(const OffloadBinary &OB, uint64_t Index) {
          << getOffloadKindName(OB.getOffloadKind()) << "\n";
 }
 
-static Error visitAllBinaries(const OffloadBinary &OB) {
-  uint64_t Offset = 0;
-  uint64_t Index = 0;
-  while (Offset < OB.getMemoryBufferRef().getBufferSize()) {
-    MemoryBufferRef Buffer =
-        MemoryBufferRef(OB.getData().drop_front(Offset), OB.getFileName());
-    auto BinaryOrErr = OffloadBinary::create(Buffer);
-    if (!BinaryOrErr)
-      return BinaryOrErr.takeError();
-
-    OffloadBinary &Binary = **BinaryOrErr;
-    printBinary(Binary, Index++);
-
-    Offset += Binary.getSize();
-  }
-  return Error::success();
-}
-
 /// Print the embedded offloading contents of an ObjectFile \p O.
 void llvm::dumpOffloadBinary(const ObjectFile &O) {
   if (!O.isELF()) {
@@ -72,41 +55,25 @@ void llvm::dumpOffloadBinary(const ObjectFile &O) {
     return;
   }
 
-  for (ELFSectionRef Sec : O.sections()) {
-    if (Sec.getType() != ELF::SHT_LLVM_OFFLOADING)
-      continue;
-
-    Expected<StringRef> Contents = Sec.getContents();
-    if (!Contents)
-      reportError(Contents.takeError(), O.getFileName());
-
-    std::unique_ptr<MemoryBuffer> Buffer =
-        MemoryBuffer::getMemBuffer(*Contents, O.getFileName(), false);
-    if (!isAddrAligned(Align(OffloadBinary::getAlignment()),
-                       Buffer->getBufferStart()))
-      Buffer = MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(),
-                                              Buffer->getBufferIdentifier());
-    auto BinaryOrErr = OffloadBinary::create(*Buffer);
-    if (!BinaryOrErr)
-      reportError(O.getFileName(), "while extracting offloading files: " +
-                                       toString(BinaryOrErr.takeError()));
-    OffloadBinary &Binary = **BinaryOrErr;
+  SmallVector<OffloadFile> Binaries;
+  if (Error Err = extractOffloadBinaries(O.getMemoryBufferRef(), Binaries))
+    reportError(O.getFileName(), "while extracting offloading files: " +
+                                     toString(std::move(Err)));
 
-    // Print out all the binaries that are contained in this buffer. If we fail
-    // to parse a binary before reaching the end of the buffer emit a warning.
-    if (Error Err = visitAllBinaries(Binary))
-      reportWarning("while parsing offloading files: " +
-                        toString(std::move(Err)),
-                    O.getFileName());
-  }
+  // Print out all the binaries that are contained in this buffer.
+  for (uint64_t I = 0, E = Binaries.size(); I != E; ++I)
+    printBinary(*Binaries[I].getBinary(), I);
 }
 
 /// Print the contents of an offload binary file \p OB. This may contain
 /// multiple binaries stored in the same buffer.
 void llvm::dumpOffloadSections(const OffloadBinary &OB) {
-  // Print out all the binaries that are contained at this buffer. If we fail to
-  // parse a binary before reaching the end of the buffer emit a warning.
-  if (Error Err = visitAllBinaries(OB))
-    reportWarning("while parsing offloading files: " + toString(std::move(Err)),
-                  OB.getFileName());
+  SmallVector<OffloadFile> Binaries;
+  if (Error Err = extractOffloadBinaries(OB.getMemoryBufferRef(), Binaries))
+    reportError(OB.getFileName(), "while extracting offloading files: " +
+                                      toString(std::move(Err)));
+
+  // Print out all the binaries that are contained in this buffer.
+  for (uint64_t I = 0, E = Binaries.size(); I != E; ++I)
+    printBinary(*Binaries[I].getBinary(), I);
 }


        


More information about the cfe-commits mailing list