diff options
author | Haowei Wu <haowei@google.com> | 2021-01-08 16:26:32 -0800 |
---|---|---|
committer | Haowei Wu <haowei@google.com> | 2021-03-04 11:28:49 -0800 |
commit | db06088d63f823e5a4894eea291baf5a449ed406 (patch) | |
tree | 958d87660db51fd72c0d43c4709eeedda88b8205 /llvm/tools/llvm-ifs/llvm-ifs.cpp | |
parent | 9550f8ba9a3a697f28a7920c8aeb5cba1e8003a6 (diff) | |
download | llvm-db06088d63f823e5a4894eea291baf5a449ed406.zip llvm-db06088d63f823e5a4894eea291baf5a449ed406.tar.gz llvm-db06088d63f823e5a4894eea291baf5a449ed406.tar.bz2 |
[llvm-ifs] Add option to use InterfaceStub library
This change adds '-use-interfacestub' option to allow llvm-ifs
to use InterfaceStub lib when generating ELF binary.
Differential Revision: https://reviews.llvm.org/D94461
Diffstat (limited to 'llvm/tools/llvm-ifs/llvm-ifs.cpp')
-rw-r--r-- | llvm/tools/llvm-ifs/llvm-ifs.cpp | 92 |
1 files changed, 77 insertions, 15 deletions
diff --git a/llvm/tools/llvm-ifs/llvm-ifs.cpp b/llvm/tools/llvm-ifs/llvm-ifs.cpp index 4d9a5c3..5eda708 100644 --- a/llvm/tools/llvm-ifs/llvm-ifs.cpp +++ b/llvm/tools/llvm-ifs/llvm-ifs.cpp @@ -9,6 +9,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" +#include "llvm/InterfaceStub/ELFObjHandler.h" #include "llvm/ObjectYAML/yaml2obj.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -54,6 +55,11 @@ static cl::list<std::string> InputFilenames(cl::Positional, static cl::opt<std::string> OutputFilename("o", cl::desc("<output file>"), cl::value_desc("path")); +static cl::opt<bool> UseInterfaceStub( + "use-interfacestub", + cl::desc("Write output ELF file using latest InterfaceStub backend"), + cl::init(false)); + enum class IFSSymbolType { NoType = 0, Object, @@ -342,16 +348,82 @@ static int writeElfStub(const Triple &T, const std::vector<IFSSymbol> &Symbols, return convertYAML(YIn, Out, ErrHandler) ? 0 : 1; } -static int writeIfso(const IFSStub &Stub, bool IsWriteIfs, raw_ostream &Out) { +static elfabi::ELFTarget convertIFSStub(const IFSStub &IfsStub, + elfabi::ELFStub &ElfStub) { + ElfStub.TbeVersion = IfsStub.IfsVersion; + ElfStub.SoName = IfsStub.SOName; + // TODO: Support more archs and targets. + Triple IFSTriple(IfsStub.Triple); + elfabi::ELFTarget Target = elfabi::ELFTarget::ELF64LE; + switch (IFSTriple.getArch()) { + case Triple::ArchType::aarch64: + ElfStub.Arch = (elfabi::ELFArch)ELF::EM_AARCH64; + break; + case Triple::ArchType::x86_64: + ElfStub.Arch = (elfabi::ELFArch)ELF::EM_X86_64; + break; + default: + ElfStub.Arch = (elfabi::ELFArch)ELF::EM_NONE; + } + ElfStub.NeededLibs = IfsStub.NeededLibs; + for (const IFSSymbol &IfsSymbol : IfsStub.Symbols) { + elfabi::ELFSymbol ElfSymbol(IfsSymbol.Name); + switch (IfsSymbol.Type) { + case IFSSymbolType::Func: + ElfSymbol.Type = elfabi::ELFSymbolType::Func; + break; + case IFSSymbolType::NoType: + ElfSymbol.Type = elfabi::ELFSymbolType::NoType; + break; + case IFSSymbolType::Object: + ElfSymbol.Type = elfabi::ELFSymbolType::Object; + break; + default: + ElfSymbol.Type = elfabi::ELFSymbolType::Unknown; + break; + // TODO: Add support for TLS? + } + ElfSymbol.Size = IfsSymbol.Size; + ElfSymbol.Undefined = false; + ElfSymbol.Weak = IfsSymbol.Weak; + ElfSymbol.Warning = IfsSymbol.Warning; + ElfStub.Symbols.insert(ElfSymbol); + } + return Target; +} + +static int writeIfso(const IFSStub &Stub, bool IsWriteIfs) { + std::string ObjectFileFormat = + ForceFormat.empty() ? Stub.ObjectFileFormat : ForceFormat; + + // Use InterfaceStub library if the option is enabled and output + // format is ELF. + if (UseInterfaceStub && (!IsWriteIfs) && ObjectFileFormat != "TBD") { + elfabi::ELFStub ElfStub; + elfabi::ELFTarget Target = convertIFSStub(Stub, ElfStub); + Error BinaryWriteError = + elfabi::writeBinaryStub(OutputFilename, ElfStub, Target); + if (BinaryWriteError) { + return -1; + } + return 0; + } + + // Open file for writing. + std::error_code SysErr; + raw_fd_ostream Out(OutputFilename, SysErr); + if (SysErr) { + WithColor::error() << "Couldn't open " << OutputFilename + << " for writing.\n"; + return -1; + } + if (IsWriteIfs) { yaml::Output YamlOut(Out, NULL, /*WrapColumn =*/0); YamlOut << const_cast<IFSStub &>(Stub); return 0; } - std::string ObjectFileFormat = - ForceFormat.empty() ? Stub.ObjectFileFormat : ForceFormat; - if (ObjectFileFormat == "ELF" || ForceFormat == "ELFOBJYAML") return writeElfStub(llvm::Triple(Stub.Triple), Stub.Symbols, Stub.ObjectFileFormat, Out); @@ -498,15 +570,5 @@ int main(int argc, char *argv[]) { for (auto &Entry : SymbolMap) Stub.Symbols.push_back(Entry.second); - std::error_code SysErr; - - // Open file for writing. - raw_fd_ostream Out(OutputFilename, SysErr); - if (SysErr) { - WithColor::error() << "Couldn't open " << OutputFilename - << " for writing.\n"; - return -1; - } - - return writeIfso(Stub, (Action == "write-ifs"), Out); + return writeIfso(Stub, (Action == "write-ifs")); } |