diff --git a/llvm/test/tools/llvm-ifs/func.ifs b/llvm/test/tools/llvm-ifs/func.ifs --- a/llvm/test/tools/llvm-ifs/func.ifs +++ b/llvm/test/tools/llvm-ifs/func.ifs @@ -4,6 +4,9 @@ # RUN: llvm-ifs -action write-bin -o - %s %S/object.ifs | \ # RUN: llvm-readelf --all - | FileCheck %s --check-prefixes=CHECK-ELF +# RUN: llvm-ifs -action write-bin -o - %s %S/object.ifs -use-interfacestub | \ +# RUN: llvm-readelf --all - | FileCheck %s --check-prefixes=CHECK-ELF + # RUN: llvm-ifs -action write-bin -force-format TBD -o - %s %S/object.ifs | \ # RUN: FileCheck %s --check-prefixes=CHECK-DARWIN-TBD3 diff --git a/llvm/tools/llvm-ifs/CMakeLists.txt b/llvm/tools/llvm-ifs/CMakeLists.txt --- a/llvm/tools/llvm-ifs/CMakeLists.txt +++ b/llvm/tools/llvm-ifs/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + InterfaceStub Object Support TextAPI diff --git a/llvm/tools/llvm-ifs/llvm-ifs.cpp b/llvm/tools/llvm-ifs/llvm-ifs.cpp --- 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,10 @@ static cl::opt OutputFilename("o", cl::desc(""), cl::value_desc("path")); +static cl::opt UseInterfaceStub( + "use-interfacestub", + cl::desc("Write output ELF file using InterfaceStub backend")); + enum class IFSSymbolType { NoType = 0, Object, @@ -342,6 +347,50 @@ return convertYAML(YIn, Out, ErrHandler) ? 0 : 1; } +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, raw_ostream &Out) { if (IsWriteIfs) { yaml::Output YamlOut(Out, NULL, /*WrapColumn =*/0); @@ -500,6 +549,17 @@ std::error_code SysErr; + if (UseInterfaceStub && (Action == "write-bin")) { + 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. raw_fd_ostream Out(OutputFilename, SysErr); if (SysErr) { @@ -507,6 +567,5 @@ << " for writing.\n"; return -1; } - return writeIfso(Stub, (Action == "write-ifs"), Out); }