Index: llvm/test/tools/llvm-elfabi/read-tbe-as-elf.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-elfabi/read-tbe-as-elf.test @@ -0,0 +1,16 @@ +# RUN: not llvm-elfabi --elf %s --emit-tbe=%t 2>&1 | FileCheck %s + +--- !tapi-tbe +SoName: somelib.so +TbeVersion: 1.0 +Arch: x86_64 +Symbols: + foo: { Type: Func } + bar: { Type: Object, Size: 42 } + baz: { Type: Object, Size: 8 } + not: { Type: Object, Undefined: true, Size: 128 } + nor: { Type: Func, Undefined: true } +... + +# CHECK: The file was not recognized as a valid object file +# CHECK: No file readers succeeded reading `{{.*}}read-tbe-as-elf.test` (unsupported/malformed file?) Index: llvm/test/tools/llvm-elfabi/read-tbe-as-tbe.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-elfabi/read-tbe-as-tbe.test @@ -0,0 +1,13 @@ +# RUN: llvm-elfabi --tbe %s --emit-tbe=- | FileCheck %s + +--- !tapi-tbe +TbeVersion: 1.0 +Arch: AArch64 +Symbols: {} +... + +# CHECK: --- !tapi-tbe +# CHECK-NEXT: TbeVersion: {{[1-9]\d*\.(0|([1-9]\d*))}} +# CHECK-NEXT: Arch: AArch64 +# CHECK-NEXT: Symbols: {} +# CHECK-NEXT: ... Index: llvm/tools/llvm-elfabi/llvm-elfabi.cpp =================================================================== --- llvm/tools/llvm-elfabi/llvm-elfabi.cpp +++ llvm/tools/llvm-elfabi/llvm-elfabi.cpp @@ -19,10 +19,27 @@ #include "llvm/TextAPI/ELF/TBEHandler.h" #include +namespace llvm { +namespace elfabi { + +enum class FileFormat { + TBE, + ELF +}; + +} // end namespace elfabi +} // end namespace llvm + using namespace llvm; using namespace llvm::elfabi; // Command line flags: +cl::opt InputFileFormat( + cl::desc("Force input file format:"), + cl::values(clEnumValN(FileFormat::TBE, + "tbe", "Read `input` as text-based ELF stub"), + clEnumValN(FileFormat::ELF, + "elf", "Read `input` as ELF binary"))); cl::opt InputFilePath(cl::Positional, cl::desc("input"), cl::Required); cl::opt @@ -67,20 +84,26 @@ ErrorCollector EC(/*UseFatalErrors=*/false); // First try to read as a binary (fails fast if not binary). - Expected> StubFromELF = - readELFFile(FileReadBuffer->getMemBufferRef()); - if (StubFromELF) { - return std::move(*StubFromELF); + if (InputFileFormat.getNumOccurrences() == 0 || + InputFileFormat == FileFormat::ELF) { + Expected> StubFromELF = + readELFFile(FileReadBuffer->getMemBufferRef()); + if (StubFromELF) { + return std::move(*StubFromELF); + } + EC.addError(StubFromELF.takeError(), "BinaryRead"); } - EC.addError(StubFromELF.takeError(), "BinaryRead"); // Fall back to reading as a tbe. - Expected> StubFromTBE = - readTBEFromBuffer(FileReadBuffer->getBuffer()); - if (StubFromTBE) { - return std::move(*StubFromTBE); + if (InputFileFormat.getNumOccurrences() == 0 || + InputFileFormat == FileFormat::TBE) { + Expected> StubFromTBE = + readTBEFromBuffer(FileReadBuffer->getBuffer()); + if (StubFromTBE) { + return std::move(*StubFromTBE); + } + EC.addError(StubFromTBE.takeError(), "YamlParse"); } - EC.addError(StubFromTBE.takeError(), "YamlParse"); // If both readers fail, build a new error that includes all information. EC.addError(createStringError(errc::not_supported,