diff --git a/llvm/test/tools/llvm-readobj/basic.test b/llvm/test/tools/llvm-readobj/basic.test --- a/llvm/test/tools/llvm-readobj/basic.test +++ b/llvm/test/tools/llvm-readobj/basic.test @@ -20,6 +20,22 @@ RUN: llvm-readobj --all %t.a 2>&1 | FileCheck --check-prefix=NO-OUTPUT --allow-empty %s NO-OUTPUT-NOT: {{.}} +## Test we report a meaningful warning for bitcode files. +## Check we try to continue dumping other files. + +## Note: 'echo -e -n "\x42\x43\xc0\xde" > %t.bc.1' simply doesn't work properly on windows. +## It has an issue with writing of the 2 last bytes and emits different data instead. +## echo.exe from GnuWin32 works properly though, but using of python is a more stable way. +RUN: %python -c "import os; open(r'%t.bc.1', 'wb').write(b'\x42\x43\xC0\xDE')" +RUN: %python -c "import os; open(r'%t.bc.2', 'wb').write(b'\xDE\xC0\x17\x0B')" +RUN: llvm-readelf %t.bc.1 %t.bc.2 2>&1 | \ +RUN: FileCheck --check-prefix=BITCODE -DFILE1=%t.bc.1 -DFILE2=%t.bc.2 %s +RUN: llvm-readobj %t.bc.1 %t.bc.2 2>&1 | \ +RUN: FileCheck --check-prefix=BITCODE -DFILE1=%t.bc.1 -DFILE2=%t.bc.2 %s + +# BITCODE: warning: '[[FILE1]]': bitcode files are not supported{{$}} +# BITCODE: warning: '[[FILE2]]': bitcode files are not supported{{$}} + # Test case where switch it not recognised. RUN: not llvm-readobj --unknown-switch 2>&1 | FileCheck --check-prefix=UNKNOWN %s UNKNOWN: Unknown command line argument '--unknown-switch' diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp --- a/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -646,28 +646,43 @@ /// Opens \a File and dumps it. static void dumpInput(StringRef File, ScopedPrinter &Writer) { - // Attempt to open the binary. - Expected> BinaryOrErr = - createBinary(File, /*Context=*/nullptr, /*InitContent=*/false); + ErrorOr> FileOrErr = + MemoryBuffer::getFileOrSTDIN(File, /*FileSize=*/-1, + /*RequiresNullTerminator=*/false); + if (std::error_code EC = FileOrErr.getError()) + return reportError(errorCodeToError(EC), File); + + std::unique_ptr &Buffer = FileOrErr.get(); + file_magic Type = identify_magic(Buffer->getBuffer()); + if (Type == file_magic::bitcode) { + reportWarning(createStringError(errc::invalid_argument, + "bitcode files are not supported"), + File); + return; + } + + Expected> BinaryOrErr = createBinary( + Buffer->getMemBufferRef(), /*Context=*/nullptr, /*InitContent=*/false); if (!BinaryOrErr) reportError(BinaryOrErr.takeError(), File); - Binary &Binary = *BinaryOrErr.get().getBinary(); - if (Archive *Arc = dyn_cast(&Binary)) + std::unique_ptr Bin = std::move(*BinaryOrErr); + if (Archive *Arc = dyn_cast(Bin.get())) dumpArchive(Arc, Writer); else if (MachOUniversalBinary *UBinary = - dyn_cast(&Binary)) + dyn_cast(Bin.get())) dumpMachOUniversalBinary(UBinary, Writer); - else if (ObjectFile *Obj = dyn_cast(&Binary)) + else if (ObjectFile *Obj = dyn_cast(Bin.get())) dumpObject(*Obj, Writer); - else if (COFFImportFile *Import = dyn_cast(&Binary)) + else if (COFFImportFile *Import = dyn_cast(Bin.get())) dumpCOFFImportFile(Import, Writer); - else if (WindowsResource *WinRes = dyn_cast(&Binary)) + else if (WindowsResource *WinRes = dyn_cast(Bin.get())) dumpWindowsResourceFile(WinRes, Writer); else llvm_unreachable("unrecognized file type"); - CVTypes.Binaries.push_back(std::move(*BinaryOrErr)); + CVTypes.Binaries.push_back( + OwningBinary(std::move(Bin), std::move(Buffer))); } /// Registers aliases that should only be allowed by readobj.