[elfabi] Add option to manually specify file read format

Although llvm-elfabi will attempt to read input files without needing the format to be manually specified, doing so has the potential to introduce extraneous errors that can hinder debugging (since multiple readers may fail in attempts to read the file). This change allows the input file format to be manually specified to force elfabi to use a single reader. This makes it easier to test and debug errors specific to a given reader.

llvm-svn: 350545
This commit is contained in:
Armando Montanez 2019-01-07 17:33:10 +00:00
parent 1f66672515
commit 488545ef15
3 changed files with 62 additions and 10 deletions

View File

@ -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?)

View File

@ -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: ...

View File

@ -19,10 +19,27 @@
#include "llvm/TextAPI/ELF/TBEHandler.h"
#include <string>
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<FileFormat> 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<std::string> InputFilePath(cl::Positional, cl::desc("input"),
cl::Required);
cl::opt<std::string>
@ -67,20 +84,26 @@ static Expected<std::unique_ptr<ELFStub>> readInputFile(StringRef FilePath) {
ErrorCollector EC(/*UseFatalErrors=*/false);
// First try to read as a binary (fails fast if not binary).
Expected<std::unique_ptr<ELFStub>> StubFromELF =
readELFFile(FileReadBuffer->getMemBufferRef());
if (StubFromELF) {
return std::move(*StubFromELF);
if (InputFileFormat.getNumOccurrences() == 0 ||
InputFileFormat == FileFormat::ELF) {
Expected<std::unique_ptr<ELFStub>> 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<std::unique_ptr<ELFStub>> StubFromTBE =
readTBEFromBuffer(FileReadBuffer->getBuffer());
if (StubFromTBE) {
return std::move(*StubFromTBE);
if (InputFileFormat.getNumOccurrences() == 0 ||
InputFileFormat == FileFormat::TBE) {
Expected<std::unique_ptr<ELFStub>> 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,