diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -1259,6 +1259,10 @@ 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 --- a/llvm/lib/Object/OffloadBinary.cpp +++ b/llvm/lib/Object/OffloadBinary.cpp @@ -41,6 +41,10 @@ std::unique_ptr 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 @@ 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> 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 --- a/llvm/test/tools/llvm-objdump/Offloading/content-failure.test +++ b/llvm/test/tools/llvm-objdump/Offloading/content-failure.test @@ -15,4 +15,4 @@ 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 rename from llvm/test/tools/llvm-objdump/Offloading/binary.test rename to llvm/test/tools/llvm-objdump/Offloading/elf.test --- 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 --- 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 --- 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 @@ << 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 @@ return; } - for (ELFSectionRef Sec : O.sections()) { - if (Sec.getType() != ELF::SHT_LLVM_OFFLOADING) - continue; - - Expected Contents = Sec.getContents(); - if (!Contents) - reportError(Contents.takeError(), O.getFileName()); - - std::unique_ptr 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 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 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); }