diff options
author | Haowei Wu <haowei@google.com> | 2021-12-02 23:25:38 -0800 |
---|---|---|
committer | Haowei Wu <haowei@google.com> | 2021-12-09 12:25:51 -0800 |
commit | 5e171cebd3bafbf39cdad6294fe26c3952aedbc3 (patch) | |
tree | 4cfe1684f6e26c5716bdd541dfcc51f60b3ccbbb /llvm/tools/llvm-ifs/llvm-ifs.cpp | |
parent | 2d6dfce4aa078d18db29e451d761a9d1dcd308b6 (diff) | |
download | llvm-5e171cebd3bafbf39cdad6294fe26c3952aedbc3.zip llvm-5e171cebd3bafbf39cdad6294fe26c3952aedbc3.tar.gz llvm-5e171cebd3bafbf39cdad6294fe26c3952aedbc3.tar.bz2 |
[ifs] Add options to allow llvm-ifs to generate multiple outputs
This change adds options to llvm-ifs to allow it to generate multiple
types of stub files at a single invocation.
Differential Revision: https://reviews.llvm.org/D115024
Diffstat (limited to 'llvm/tools/llvm-ifs/llvm-ifs.cpp')
-rw-r--r-- | llvm/tools/llvm-ifs/llvm-ifs.cpp | 198 |
1 files changed, 140 insertions, 58 deletions
diff --git a/llvm/tools/llvm-ifs/llvm-ifs.cpp b/llvm/tools/llvm-ifs/llvm-ifs.cpp index d034793..0792066 100644 --- a/llvm/tools/llvm-ifs/llvm-ifs.cpp +++ b/llvm/tools/llvm-ifs/llvm-ifs.cpp @@ -57,11 +57,11 @@ cl::opt<FileFormat> InputFormat( clEnumValN(FileFormat::ELF, "ELF", "ELF object file")), cl::cat(IfsCategory)); cl::opt<FileFormat> OutputFormat( - "output-format", cl::desc("Specify the output file format"), + "output-format", cl::desc("Specify the output file format **DEPRECATED**"), cl::values(clEnumValN(FileFormat::IFS, "IFS", "Text based ELF stub file"), clEnumValN(FileFormat::ELF, "ELF", "ELF stub file"), clEnumValN(FileFormat::TBD, "TBD", "Apple TBD text stub file")), - cl::Required, cl::cat(IfsCategory)); + cl::cat(IfsCategory)); cl::opt<std::string> OptArch("arch", cl::desc("Specify the architecture, e.g. x86_64"), cl::cat(IfsCategory)); @@ -108,10 +108,21 @@ cl::opt<std::string> SoName("soname", cl::desc("Manually set the DT_SONAME entry of any emitted files"), cl::value_desc("name"), cl::cat(IfsCategory)); -cl::opt<std::string> OutputFilePath("output", cl::desc("Output file"), +cl::opt<std::string> OutputFilePath("output", + cl::desc("Output file **DEPRECATED**"), cl::cat(IfsCategory)); cl::alias OutputFilePathA("o", cl::desc("Alias for --output"), cl::aliasopt(OutputFilePath), cl::cat(IfsCategory)); +cl::opt<std::string> OutputELFFilePath("output-elf", + cl::desc("Output path for ELF file"), + cl::cat(IfsCategory)); +cl::opt<std::string> OutputIFSFilePath("output-ifs", + cl::desc("Output path for IFS file"), + cl::cat(IfsCategory)); +cl::opt<std::string> OutputTBDFilePath("output-tbd", + cl::desc("Output path for TBD file"), + cl::cat(IfsCategory)); + cl::opt<bool> WriteIfChanged( "write-if-changed", cl::desc("Write the output file only if it is new or has changed."), @@ -320,8 +331,6 @@ int main(int argc, char *argv[]) { WithColor::error() << "Interface Stub: Target Mismatch." << "\nFilenames: " << PreviousInputFilePath << " " << InputFilePath; - // << "\nTriple Values: " << Stub.Triple << " " - // << TargetStub->Triple << "\n"; return -1; } if (Stub.SoName != TargetStub->SoName) { @@ -408,63 +417,136 @@ int main(int argc, char *argv[]) { if (OverrideError) fatalError(std::move(OverrideError)); - switch (OutputFormat.getValue()) { - case FileFormat::TBD: { - std::error_code SysErr; - raw_fd_ostream Out(OutputFilePath, SysErr); - if (SysErr) { - WithColor::error() << "Couldn't open " << OutputFilePath - << " for writing.\n"; - return -1; - } - if (!Stub.Target.Triple) { - WithColor::error() - << "Triple should be defined when output format is TBD"; + if (OutputELFFilePath.getNumOccurrences() == 0 && + OutputIFSFilePath.getNumOccurrences() == 0 && + OutputTBDFilePath.getNumOccurrences() == 0) { + if (OutputFormat.getNumOccurrences() == 0) { + WithColor::error() << "at least one output should be specified."; return -1; } - return writeTbdStub(llvm::Triple(Stub.Target.Triple.getValue()), - Stub.Symbols, "TBD", Out); + } else if (OutputFormat.getNumOccurrences() == 1) { + WithColor::error() << "'--output-format' cannot be used with " + "'--output-{FILE_FORMAT}' options at the same time"; + return -1; } - case FileFormat::IFS: { - Stub.IfsVersion = IfsVersionCurrent; - if (InputFormat.getValue() == FileFormat::ELF && - OptTargetTripleHint.getNumOccurrences() == 1) { - std::error_code HintEC(1, std::generic_category()); - IFSTarget HintTarget = parseTriple(OptTargetTripleHint); - if (Stub.Target.Arch.getValue() != HintTarget.Arch.getValue()) - fatalError(make_error<StringError>( - "Triple hint does not match the actual architecture", HintEC)); - if (Stub.Target.Endianness.getValue() != - HintTarget.Endianness.getValue()) - fatalError(make_error<StringError>( - "Triple hint does not match the actual endianness", HintEC)); - if (Stub.Target.BitWidth.getValue() != HintTarget.BitWidth.getValue()) - fatalError(make_error<StringError>( - "Triple hint does not match the actual bit width", HintEC)); - - stripIFSTarget(Stub, true, false, false, false); - Stub.Target.Triple = OptTargetTripleHint.getValue(); - } else { - stripIFSTarget(Stub, StripIFSTarget, StripIFSArch, - StripIFSEndiannessWidth, StripIFSBitWidth); + if (OutputFormat.getNumOccurrences() == 1) { + // TODO: Remove OutputFormat flag in the next revision. + WithColor::warning() << "--output-format option is deprecated, please use " + "--output-{FILE_FORMAT} options instead\n"; + switch (OutputFormat.getValue()) { + case FileFormat::TBD: { + std::error_code SysErr; + raw_fd_ostream Out(OutputFilePath, SysErr); + if (SysErr) { + WithColor::error() << "Couldn't open " << OutputFilePath + << " for writing.\n"; + return -1; + } + if (!Stub.Target.Triple) { + WithColor::error() + << "Triple should be defined when output format is TBD"; + return -1; + } + return writeTbdStub(llvm::Triple(Stub.Target.Triple.getValue()), + Stub.Symbols, "TBD", Out); + } + case FileFormat::IFS: { + Stub.IfsVersion = IfsVersionCurrent; + if (InputFormat.getValue() == FileFormat::ELF && + OptTargetTripleHint.getNumOccurrences() == 1) { + std::error_code HintEC(1, std::generic_category()); + IFSTarget HintTarget = parseTriple(OptTargetTripleHint); + if (Stub.Target.Arch.getValue() != HintTarget.Arch.getValue()) + fatalError(make_error<StringError>( + "Triple hint does not match the actual architecture", HintEC)); + if (Stub.Target.Endianness.getValue() != + HintTarget.Endianness.getValue()) + fatalError(make_error<StringError>( + "Triple hint does not match the actual endianness", HintEC)); + if (Stub.Target.BitWidth.getValue() != HintTarget.BitWidth.getValue()) + fatalError(make_error<StringError>( + "Triple hint does not match the actual bit width", HintEC)); + + stripIFSTarget(Stub, true, false, false, false); + Stub.Target.Triple = OptTargetTripleHint.getValue(); + } else { + stripIFSTarget(Stub, StripIFSTarget, StripIFSArch, + StripIFSEndiannessWidth, StripIFSBitWidth); + } + if (StripUndefined) + stripIFSUndefinedSymbols(Stub); + Error IFSWriteError = writeIFS(OutputFilePath.getValue(), Stub); + if (IFSWriteError) + fatalError(std::move(IFSWriteError)); + break; + } + case FileFormat::ELF: { + Error TargetError = validateIFSTarget(Stub, true); + if (TargetError) + fatalError(std::move(TargetError)); + Error BinaryWriteError = + writeBinaryStub(OutputFilePath, Stub, WriteIfChanged); + if (BinaryWriteError) + fatalError(std::move(BinaryWriteError)); + break; + } + } + } else { + // Check if output path for individual format. + if (OutputELFFilePath.getNumOccurrences() == 1) { + Error TargetError = validateIFSTarget(Stub, true); + if (TargetError) + fatalError(std::move(TargetError)); + Error BinaryWriteError = + writeBinaryStub(OutputELFFilePath, Stub, WriteIfChanged); + if (BinaryWriteError) + fatalError(std::move(BinaryWriteError)); + } + if (OutputIFSFilePath.getNumOccurrences() == 1) { + Stub.IfsVersion = IfsVersionCurrent; + if (InputFormat.getValue() == FileFormat::ELF && + OptTargetTripleHint.getNumOccurrences() == 1) { + std::error_code HintEC(1, std::generic_category()); + IFSTarget HintTarget = parseTriple(OptTargetTripleHint); + if (Stub.Target.Arch.getValue() != HintTarget.Arch.getValue()) + fatalError(make_error<StringError>( + "Triple hint does not match the actual architecture", HintEC)); + if (Stub.Target.Endianness.getValue() != + HintTarget.Endianness.getValue()) + fatalError(make_error<StringError>( + "Triple hint does not match the actual endianness", HintEC)); + if (Stub.Target.BitWidth.getValue() != HintTarget.BitWidth.getValue()) + fatalError(make_error<StringError>( + "Triple hint does not match the actual bit width", HintEC)); + + stripIFSTarget(Stub, true, false, false, false); + Stub.Target.Triple = OptTargetTripleHint.getValue(); + } else { + stripIFSTarget(Stub, StripIFSTarget, StripIFSArch, + StripIFSEndiannessWidth, StripIFSBitWidth); + } + if (StripUndefined) + stripIFSUndefinedSymbols(Stub); + Error IFSWriteError = writeIFS(OutputIFSFilePath.getValue(), Stub); + if (IFSWriteError) + fatalError(std::move(IFSWriteError)); + } + if (OutputTBDFilePath.getNumOccurrences() == 1) { + std::error_code SysErr; + raw_fd_ostream Out(OutputTBDFilePath, SysErr); + if (SysErr) { + WithColor::error() << "Couldn't open " << OutputTBDFilePath + << " for writing.\n"; + return -1; + } + if (!Stub.Target.Triple) { + WithColor::error() + << "Triple should be defined when output format is TBD"; + return -1; + } + return writeTbdStub(llvm::Triple(Stub.Target.Triple.getValue()), + Stub.Symbols, "TBD", Out); } - if (StripUndefined) - stripIFSUndefinedSymbols(Stub); - Error IFSWriteError = writeIFS(OutputFilePath.getValue(), Stub); - if (IFSWriteError) - fatalError(std::move(IFSWriteError)); - break; - } - case FileFormat::ELF: { - Error TargetError = validateIFSTarget(Stub, true); - if (TargetError) - fatalError(std::move(TargetError)); - Error BinaryWriteError = - writeBinaryStub(OutputFilePath, Stub, WriteIfChanged); - if (BinaryWriteError) - fatalError(std::move(BinaryWriteError)); - break; - } } return 0; } |