8 changes: 4 additions & 4 deletions clang/test/InterfaceStubs/ppc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
// RUN: -emit-interface-stubs -emit-merged-ifs -S | \
// RUN: FileCheck -check-prefix=CHECK-IFS %s

// CHECK-IFS: --- !experimental-ifs-v2
// CHECK-IFS: IfsVersion: 2.0
// CHECK-IFS: Triple: powerpc64le
// CHECK-IFS: --- !ifs-v1
// CHECK-IFS: IfsVersion: 3.0
// CHECK-IFS: Target: powerpc64le
// CHECK-IFS: Symbols:
// CHECK-IFS: - { Name: _Z8helloPPCv, Type: Func }
// CHECK-IFS: ...

int helloPPC();
int helloPPC();
7 changes: 3 additions & 4 deletions clang/test/InterfaceStubs/template-constexpr.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// RUN: %clang_cc1 -o - -emit-interface-stubs %s | FileCheck %s

// CHECK: --- !experimental-ifs-v2
// CHECK-NEXT: IfsVersion: 2.0
// CHECK-NEXT: Triple:
// CHECK-NEXT: ObjectFileFormat: ELF
// CHECK: --- !ifs-v1
// CHECK-NEXT: IfsVersion: 3.0
// CHECK-NEXT: Target:
// CHECK-NEXT: Symbols:
// CHECK-NEXT: ...

Expand Down
7 changes: 3 additions & 4 deletions clang/test/InterfaceStubs/template-template-parm-decl.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// RUN: %clang_cc1 -o - -emit-interface-stubs %s | FileCheck %s

// CHECK: --- !experimental-ifs-v2
// CHECK-NEXT: IfsVersion: 2.0
// CHECK-NEXT: Triple:
// CHECK-NEXT: ObjectFileFormat: ELF
// CHECK: --- !ifs-v1
// CHECK-NEXT: IfsVersion: 3.0
// CHECK-NEXT: Target:
// CHECK-NEXT: Symbols:
// CHECK-NEXT: ...

Expand Down
7 changes: 3 additions & 4 deletions clang/test/InterfaceStubs/trycatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -o - -emit-interface-stubs %s | FileCheck %s

// CHECK: --- !experimental-ifs-v2
// CHECK-NEXT: IfsVersion: 2.0
// CHECK-NEXT: Triple: x86_64-unknown-linux-gnu
// CHECK-NEXT: ObjectFileFormat: ELF
// CHECK: --- !ifs-v1
// CHECK-NEXT: IfsVersion: 3.0
// CHECK-NEXT: Target: x86_64-unknown-linux-gnu
// CHECK-NEXT: Symbols:
// CHECK-NEXT: - { Name: "_Z1fv", Type: Func }
// CHECK-NEXT: ...
Expand Down
7 changes: 3 additions & 4 deletions clang/test/InterfaceStubs/unresolved-using-typename.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// RUN: %clang_cc1 -o - -emit-interface-stubs %s | FileCheck %s

// CHECK: --- !experimental-ifs-v2
// CHECK-NEXT: IfsVersion: 2.0
// CHECK-NEXT: Triple:
// CHECK-NEXT: ObjectFileFormat: ELF
// CHECK: --- !ifs-v1
// CHECK-NEXT: IfsVersion: 3.0
// CHECK-NEXT: Target:
// CHECK-NEXT: Symbols:
// CHECK-NEXT: ...

Expand Down
7 changes: 3 additions & 4 deletions clang/test/InterfaceStubs/usings.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// RUN: %clang_cc1 -o - -emit-interface-stubs %s | FileCheck %s

// CHECK: --- !experimental-ifs-v2
// CHECK-NEXT: IfsVersion: 2.0
// CHECK-NEXT: Triple:
// CHECK-NEXT: ObjectFileFormat: ELF
// CHECK: --- !ifs-v1
// CHECK-NEXT: IfsVersion: 3.0
// CHECK-NEXT: Target:
// CHECK-NEXT: Symbols:
// CHECK-NEXT: ...

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// REQUIRES: x86-registered-target
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -o - -emit-interface-stubs %s | FileCheck %s

// CHECK: --- !experimental-ifs-v2
// CHECK-NEXT: IfsVersion: 2.0
// CHECK-NEXT: Triple: x86_64-unknown-linux-gnu
// CHECK-NEXT: ObjectFileFormat: ELF
// CHECK: --- !ifs-v1
// CHECK-NEXT: IfsVersion: 3.0
// CHECK-NEXT: Target: x86_64-unknown-linux-gnu
// CHECK-NEXT: Symbols:
// CHECK-NEXT: - { Name: "a", Type: Object, Size: 4 }
// CHECK-NEXT: ...
Expand Down
2 changes: 1 addition & 1 deletion clang/test/InterfaceStubs/weak.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// REQUIRES: x86-registered-target
// RUN: %clang_cc1 -triple x86_64-linux-gnu -o - -emit-interface-stubs \
// RUN: -interface-stub-version=experimental-ifs-v2 %s | \
// RUN: -interface-stub-version=ifs-v1 %s | \
// RUN: FileCheck %s

// RUN: %clang -target x86_64-unknown-linux-gnu -o - -c %s | llvm-nm - 2>&1 | \
Expand Down
6 changes: 3 additions & 3 deletions clang/test/InterfaceStubs/windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
// CHECK-CC1: Symbols:
// CHECK-CC1-NEXT: ?helloWindowsMsvc@@YAHXZ

// CHECK-IFS: --- !experimental-ifs-v2
// CHECK-IFS: IfsVersion: 2.0
// CHECK-IFS: Triple:
// CHECK-IFS: --- !ifs-v1
// CHECK-IFS: IfsVersion: 3.0
// CHECK-IFS: Target:
// CHECK-IFS: Symbols:
// CHECK-IFS: - { Name: '?helloWindowsMsvc@@YAHXZ', Type: Func }
// CHECK-IFS: ...
Expand Down
8 changes: 8 additions & 0 deletions llvm/include/llvm/BinaryFormat/ELF.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
#ifndef LLVM_BINARYFORMAT_ELF_H
#define LLVM_BINARYFORMAT_ELF_H

#include "llvm/ADT/StringRef.h"
#include <cstdint>
#include <cstring>
#include <string>

namespace llvm {
namespace ELF {
Expand Down Expand Up @@ -1673,6 +1675,12 @@ enum {
ELFCOMPRESS_HIPROC = 0x7fffffff // End of processor-specific.
};

/// Convert an architecture name into ELF's e_machine value.
uint16_t convertArchNameToEMachine(StringRef Arch);

/// Convert an ELF's e_machine value into an architecture name.
StringRef convertEMachineToArchName(uint16_t EMachine);

} // end namespace ELF
} // end namespace llvm

Expand Down
15 changes: 6 additions & 9 deletions llvm/include/llvm/InterfaceStub/ELFObjHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#ifndef LLVM_INTERFACESTUB_ELFOBJHANDLER_H
#define LLVM_INTERFACESTUB_ELFOBJHANDLER_H

#include "llvm/InterfaceStub/ELFStub.h"
#include "llvm/InterfaceStub/IFSStub.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/ELFTypes.h"
#include "llvm/Support/FileSystem.h"
Expand All @@ -22,26 +22,23 @@ namespace llvm {

class MemoryBuffer;

namespace elfabi {

enum class ELFTarget { ELF32LE, ELF32BE, ELF64LE, ELF64BE };
namespace ifs {

/// Attempt to read a binary ELF file from a MemoryBuffer.
Expected<std::unique_ptr<ELFStub>> readELFFile(MemoryBufferRef Buf);
Expected<std::unique_ptr<IFSStub>> readELFFile(MemoryBufferRef Buf);

/// Attempt to write a binary ELF stub.
/// This function determines appropriate ELFType using the passed ELFTarget and
/// then writes a binary ELF stub to a specified file path.
///
/// @param FilePath File path for writing the ELF binary.
/// @param Stub Source ELFStub to generate a binary ELF stub from.
/// @param OutputFormat Target ELFType to write binary as.
/// @param WriteIfChanged Whether or not to preserve timestamp if
/// the output stays the same.
Error writeBinaryStub(StringRef FilePath, const ELFStub &Stub,
ELFTarget OutputFormat, bool WriteIfChanged = false);
Error writeBinaryStub(StringRef FilePath, const IFSStub &Stub,
bool WriteIfChanged = false);

} // end namespace elfabi
} // end namespace ifs
} // end namespace llvm

#endif // LLVM_INTERFACESTUB_ELFOBJHANDLER_H
66 changes: 0 additions & 66 deletions llvm/include/llvm/InterfaceStub/ELFStub.h

This file was deleted.

60 changes: 60 additions & 0 deletions llvm/include/llvm/InterfaceStub/IFSHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//===- IFSHandler.h ---------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===-----------------------------------------------------------------------===/
///
/// \file
/// This file declares an interface for reading and writing .ifs (text-based
/// InterFace Stub) files.
///
//===-----------------------------------------------------------------------===/

#ifndef LLVM_INTERFACESTUB_IFSHANDLER_H
#define LLVM_INTERFACESTUB_IFSHANDLER_H

#include "IFSStub.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/VersionTuple.h"
#include <memory>

namespace llvm {

class raw_ostream;
class Error;
class StringRef;

namespace ifs {

struct IFSStub;

const VersionTuple IFSVersionCurrent(3, 0);

/// Attempts to read an IFS interface file from a StringRef buffer.
Expected<std::unique_ptr<IFSStub>> readIFSFromBuffer(StringRef Buf);

/// Attempts to write an IFS interface file to a raw_ostream.
Error writeIFSToOutputStream(raw_ostream &OS, const IFSStub &Stub);

/// Override the target platform inforation in the text stub.
Error overrideIFSTarget(IFSStub &Stub, Optional<IFSArch> OverrideArch,
Optional<IFSEndiannessType> OverrideEndianness,
Optional<IFSBitWidthType> OverrideBitWidth,
Optional<std::string> OverrideTriple);

/// Validate the target platform inforation in the text stub.
Error validateIFSTarget(IFSStub &Stub, bool ParseTriple);

/// Strips target platform information from the text stub.
void stripIFSTarget(IFSStub &Stub, bool StripTriple, bool StripArch,
bool StripEndianness, bool StripBitWidth);

/// Parse llvm triple string into a IFSTarget struct.
IFSTarget parseTriple(StringRef TripleStr);

} // end namespace ifs
} // end namespace llvm

#endif // LLVM_INTERFACESTUB_IFSHANDLER_H
157 changes: 157 additions & 0 deletions llvm/include/llvm/InterfaceStub/IFSStub.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
//===- IFSStub.h ------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===-----------------------------------------------------------------------===/
///
/// \file
/// This file defines an internal representation of an InterFace Stub.
///
//===-----------------------------------------------------------------------===/

#ifndef LLVM_INTERFACESTUB_IFSSTUB_H
#define LLVM_INTERFACESTUB_IFSSTUB_H

#include "llvm/Support/Error.h"
#include "llvm/Support/VersionTuple.h"
#include <set>
#include <vector>

namespace llvm {
namespace ifs {

typedef uint16_t IFSArch;

enum class IFSSymbolType {
NoType,
Object,
Func,
TLS,

// Type information is 4 bits, so 16 is safely out of range.
Unknown = 16,
};

enum class IFSEndiannessType {
Little,
Big,

// Endianness info is 1 bytes, 256 is safely out of range.
Unknown = 256,
};

enum class IFSBitWidthType {
IFS32,
IFS64,

// Bit width info is 1 bytes, 256 is safely out of range.
Unknown = 256,
};

struct IFSSymbol {
IFSSymbol() = default;
explicit IFSSymbol(std::string SymbolName) : Name(std::move(SymbolName)) {}
std::string Name;
uint64_t Size;
IFSSymbolType Type;
bool Undefined;
bool Weak;
Optional<std::string> Warning;
bool operator<(const IFSSymbol &RHS) const { return Name < RHS.Name; }
};

struct IFSTarget {
Optional<std::string> Triple;
Optional<std::string> ObjectFormat;
Optional<IFSArch> Arch;
Optional<std::string> ArchString;
Optional<IFSEndiannessType> Endianness;
Optional<IFSBitWidthType> BitWidth;

bool empty();
};

inline bool operator==(const IFSTarget &Lhs, const IFSTarget &Rhs) {
if (Lhs.Arch != Rhs.Arch || Lhs.BitWidth != Rhs.BitWidth ||
Lhs.Endianness != Rhs.Endianness ||
Lhs.ObjectFormat != Rhs.ObjectFormat || Lhs.Triple != Rhs.Triple)
return false;
return true;
}

inline bool operator!=(const IFSTarget &Lhs, const IFSTarget &Rhs) {
return !(Lhs == Rhs);
}

// A cumulative representation of InterFace stubs.
// Both textual and binary stubs will read into and write from this object.
struct IFSStub {
// TODO: Add support for symbol versioning.
VersionTuple IfsVersion;
Optional<std::string> SoName;
IFSTarget Target;
std::vector<std::string> NeededLibs;
std::vector<IFSSymbol> Symbols;

IFSStub() {}
IFSStub(const IFSStub &Stub);
IFSStub(IFSStub &&Stub);
};

// Create a alias class for IFSStub.
// LLVM's YAML library does not allow mapping a class with 2 traits,
// which prevents us using 'Target:' field with different definitions.
// This class makes it possible to map a second traits so the same data
// structure can be used for 2 different yaml schema.
struct IFSStubTriple : IFSStub {
IFSStubTriple() {}
IFSStubTriple(const IFSStub &Stub);
IFSStubTriple(const IFSStubTriple &Stub);
IFSStubTriple(IFSStubTriple &&Stub);
};

/// This function convert bit width type from IFS enum to ELF format
/// Currently, ELFCLASS32 and ELFCLASS64 are supported.
///
/// @param BitWidth IFS bit width type.
uint8_t convertIFSBitWidthToELF(IFSBitWidthType BitWidth);

/// This function convert endianness type from IFS enum to ELF format
/// Currently, ELFDATA2LSB and ELFDATA2MSB are supported.
///
/// @param Endianness IFS endianness type.
uint8_t convertIFSEndiannessToELF(IFSEndiannessType Endianness);

/// This function convert symbol type from IFS enum to ELF format
/// Currently, STT_NOTYPE, STT_OBJECT, STT_FUNC, and STT_TLS are supported.
///
/// @param SymbolType IFS symbol type.
uint8_t convertIFSSymbolTypeToELF(IFSSymbolType SymbolType);

/// This function extracts ELF bit width from e_ident[EI_CLASS] of an ELF file
/// Currently, ELFCLASS32 and ELFCLASS64 are supported.
/// Other endianness types are mapped to IFSBitWidthType::Unknown.
///
/// @param BitWidth e_ident[EI_CLASS] value to extract bit width from.
IFSBitWidthType convertELFBitWidthToIFS(uint8_t BitWidth);

/// This function extracts ELF endianness from e_ident[EI_DATA] of an ELF file
/// Currently, ELFDATA2LSB and ELFDATA2MSB are supported.
/// Other endianness types are mapped to IFSEndiannessType::Unknown.
///
/// @param Endianness e_ident[EI_DATA] value to extract endianness type from.
IFSEndiannessType convertELFEndiannessToIFS(uint8_t Endianness);

/// This function extracts symbol type from a symbol's st_info member and
/// maps it to an IFSSymbolType enum.
/// Currently, STT_NOTYPE, STT_OBJECT, STT_FUNC, and STT_TLS are supported.
/// Other symbol types are mapped to IFSSymbolType::Unknown.
///
/// @param SymbolType Binary symbol st_info to extract symbol type from.
IFSSymbolType convertELFSymbolTypeToIFS(uint8_t SymbolType);
} // namespace ifs
} // end namespace llvm

#endif // LLVM_INTERFACESTUB_IFSSTUB_H
43 changes: 0 additions & 43 deletions llvm/include/llvm/InterfaceStub/TBEHandler.h

This file was deleted.

1 change: 1 addition & 0 deletions llvm/lib/BinaryFormat/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
add_llvm_component_library(LLVMBinaryFormat
AMDGPUMetadataVerifier.cpp
Dwarf.cpp
ELF.cpp
MachO.cpp
Magic.cpp
Minidump.cpp
Expand Down
568 changes: 568 additions & 0 deletions llvm/lib/BinaryFormat/ELF.cpp

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions llvm/lib/InterfaceStub/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
add_llvm_component_library(LLVMInterfaceStub
ELFObjHandler.cpp
ELFStub.cpp
TBEHandler.cpp
IFSHandler.cpp
IFSStub.cpp

LINK_COMPONENTS
BinaryFormat
MC
Object
Support
Expand Down
110 changes: 51 additions & 59 deletions llvm/lib/InterfaceStub/ELFObjHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//===-----------------------------------------------------------------------===/

#include "llvm/InterfaceStub/ELFObjHandler.h"
#include "llvm/InterfaceStub/ELFStub.h"
#include "llvm/InterfaceStub/IFSStub.h"
#include "llvm/MC/StringTableBuilder.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/ELFObjectFile.h"
Expand All @@ -27,7 +27,7 @@ using namespace llvm::object;
using namespace llvm::ELF;

namespace llvm {
namespace elfabi {
namespace ifs {

// Simple struct to hold relevant .dynamic entries.
struct DynamicEntries {
Expand Down Expand Up @@ -180,7 +180,7 @@ template <class ELFT> class ELFStubBuilder {
ELFStubBuilder(const ELFStubBuilder &) = delete;
ELFStubBuilder(ELFStubBuilder &&) = default;

explicit ELFStubBuilder(const ELFStub &Stub) {
explicit ELFStubBuilder(const IFSStub &Stub) {
DynSym.Name = ".dynsym";
DynSym.Align = sizeof(Elf_Addr);
DynStr.Name = ".dynstr";
Expand All @@ -191,7 +191,7 @@ template <class ELFT> class ELFStubBuilder {
ShStrTab.Align = 1;

// Populate string tables.
for (const ELFSymbol &Sym : Stub.Symbols)
for (const IFSSymbol &Sym : Stub.Symbols)
DynStr.Content.add(Sym.Name);
for (const std::string &Lib : Stub.NeededLibs)
DynStr.Content.add(Lib);
Expand All @@ -213,14 +213,14 @@ template <class ELFT> class ELFStubBuilder {
DynStr.Size = DynStr.Content.getSize();

// Populate dynamic symbol table.
for (const ELFSymbol &Sym : Stub.Symbols) {
for (const IFSSymbol &Sym : Stub.Symbols) {
uint8_t Bind = Sym.Weak ? STB_WEAK : STB_GLOBAL;
// For non-undefined symbols, value of the shndx is not relevant at link
// time as long as it is not SHN_UNDEF. Set shndx to 1, which
// points to ".dynsym".
uint16_t Shndx = Sym.Undefined ? SHN_UNDEF : 1;
DynSym.Content.add(DynStr.Content.getOffset(Sym.Name), Sym.Size, Bind,
(uint8_t)Sym.Type, 0, Shndx);
convertIFSSymbolTypeToELF(Sym.Type), 0, Shndx);
}
DynSym.Size = DynSym.Content.getSize();

Expand Down Expand Up @@ -250,7 +250,8 @@ template <class ELFT> class ELFStubBuilder {
fillStrTabShdr(ShStrTab);

// Finish initializing the ELF header.
initELFHeader<ELFT>(ElfHeader, Stub.Arch);
initELFHeader<ELFT>(ElfHeader,
static_cast<uint16_t>(Stub.Target.Arch.getValue()));
ElfHeader.e_shstrndx = ShStrTab.Index;
ElfHeader.e_shnum = LastSection->Index + 1;
ElfHeader.e_shoff =
Expand Down Expand Up @@ -443,62 +444,40 @@ static Error populateDynamic(DynamicEntries &Dyn,
return Error::success();
}

/// This function extracts symbol type from a symbol's st_info member and
/// maps it to an ELFSymbolType enum.
/// Currently, STT_NOTYPE, STT_OBJECT, STT_FUNC, and STT_TLS are supported.
/// Other symbol types are mapped to ELFSymbolType::Unknown.
///
/// @param Info Binary symbol st_info to extract symbol type from.
static ELFSymbolType convertInfoToType(uint8_t Info) {
Info = Info & 0xf;
switch (Info) {
case ELF::STT_NOTYPE:
return ELFSymbolType::NoType;
case ELF::STT_OBJECT:
return ELFSymbolType::Object;
case ELF::STT_FUNC:
return ELFSymbolType::Func;
case ELF::STT_TLS:
return ELFSymbolType::TLS;
default:
return ELFSymbolType::Unknown;
}
}

/// This function creates an ELFSymbol and populates all members using
/// This function creates an IFSSymbol and populates all members using
/// information from a binary ELFT::Sym.
///
/// @param SymName The desired name of the ELFSymbol.
/// @param SymName The desired name of the IFSSymbol.
/// @param RawSym ELFT::Sym to extract symbol information from.
template <class ELFT>
static ELFSymbol createELFSym(StringRef SymName,
static IFSSymbol createELFSym(StringRef SymName,
const typename ELFT::Sym &RawSym) {
ELFSymbol TargetSym{std::string(SymName)};
IFSSymbol TargetSym{std::string(SymName)};
uint8_t Binding = RawSym.getBinding();
if (Binding == STB_WEAK)
TargetSym.Weak = true;
else
TargetSym.Weak = false;

TargetSym.Undefined = RawSym.isUndefined();
TargetSym.Type = convertInfoToType(RawSym.st_info);
TargetSym.Type = convertELFSymbolTypeToIFS(RawSym.st_info);

if (TargetSym.Type == ELFSymbolType::Func) {
if (TargetSym.Type == IFSSymbolType::Func) {
TargetSym.Size = 0;
} else {
TargetSym.Size = RawSym.st_size;
}
return TargetSym;
}

/// This function populates an ELFStub with symbols using information read
/// This function populates an IFSStub with symbols using information read
/// from an ELF binary.
///
/// @param TargetStub ELFStub to add symbols to.
/// @param TargetStub IFSStub to add symbols to.
/// @param DynSym Range of dynamic symbols to add to TargetStub.
/// @param DynStr StringRef to the dynamic string table.
template <class ELFT>
static Error populateSymbols(ELFStub &TargetStub,
static Error populateSymbols(IFSStub &TargetStub,
const typename ELFT::SymRange DynSym,
StringRef DynStr) {
// Skips the first symbol since it's the NULL symbol.
Expand All @@ -511,28 +490,28 @@ static Error populateSymbols(ELFStub &TargetStub,
uint8_t Visibility = RawSym.getVisibility();
if (!(Visibility == STV_DEFAULT || Visibility == STV_PROTECTED))
continue;
// Create an ELFSymbol and populate it with information from the symbol
// Create an IFSSymbol and populate it with information from the symbol
// table entry.
Expected<StringRef> SymName = terminatedSubstr(DynStr, RawSym.st_name);
if (!SymName)
return SymName.takeError();
ELFSymbol Sym = createELFSym<ELFT>(*SymName, RawSym);
TargetStub.Symbols.insert(std::move(Sym));
IFSSymbol Sym = createELFSym<ELFT>(*SymName, RawSym);
TargetStub.Symbols.push_back(std::move(Sym));
// TODO: Populate symbol warning.
}
return Error::success();
}

/// Returns a new ELFStub with all members populated from an ELFObjectFile.
/// Returns a new IFSStub with all members populated from an ELFObjectFile.
/// @param ElfObj Source ELFObjectFile.
template <class ELFT>
static Expected<std::unique_ptr<ELFStub>>
static Expected<std::unique_ptr<IFSStub>>
buildStub(const ELFObjectFile<ELFT> &ElfObj) {
using Elf_Dyn_Range = typename ELFT::DynRange;
using Elf_Phdr_Range = typename ELFT::PhdrRange;
using Elf_Sym_Range = typename ELFT::SymRange;
using Elf_Sym = typename ELFT::Sym;
std::unique_ptr<ELFStub> DestStub = std::make_unique<ELFStub>();
std::unique_ptr<IFSStub> DestStub = std::make_unique<IFSStub>();
const ELFFile<ELFT> &ElfFile = ElfObj.getELFFile();
// Fetch .dynamic table.
Expected<Elf_Dyn_Range> DynTable = ElfFile.dynamicEntries();
Expand Down Expand Up @@ -561,7 +540,12 @@ buildStub(const ELFObjectFile<ELFT> &ElfObj) {
DynEnt.StrSize);

// Populate Arch from ELF header.
DestStub->Arch = ElfFile.getHeader().e_machine;
DestStub->Target.Arch = static_cast<IFSArch>(ElfFile.getHeader().e_machine);
DestStub->Target.BitWidth =
convertELFBitWidthToIFS(ElfFile.getHeader().e_ident[EI_CLASS]);
DestStub->Target.Endianness =
convertELFEndiannessToIFS(ElfFile.getHeader().e_ident[EI_DATA]);
DestStub->Target.ObjectFormat = "ELF";

// Populate SoName from .dynamic entries and dynamic string table.
if (DynEnt.SONameOffset.hasValue()) {
Expand Down Expand Up @@ -609,9 +593,9 @@ buildStub(const ELFObjectFile<ELFT> &ElfObj) {
/// the file.
///
/// @param FilePath File path for writing the ELF binary.
/// @param Stub Source ELFStub to generate a binary ELF stub from.
/// @param Stub Source InterFace Stub to generate a binary ELF stub from.
template <class ELFT>
static Error writeELFBinaryToFile(StringRef FilePath, const ELFStub &Stub,
static Error writeELFBinaryToFile(StringRef FilePath, const IFSStub &Stub,
bool WriteIfChanged) {
ELFStubBuilder<ELFT> Builder{Stub};
// Write Stub to memory first.
Expand Down Expand Up @@ -645,7 +629,7 @@ static Error writeELFBinaryToFile(StringRef FilePath, const ELFStub &Stub,
return FileBuf->commit();
}

Expected<std::unique_ptr<ELFStub>> readELFFile(MemoryBufferRef Buf) {
Expected<std::unique_ptr<IFSStub>> readELFFile(MemoryBufferRef Buf) {
Expected<std::unique_ptr<Binary>> BinOrErr = createBinary(Buf);
if (!BinOrErr) {
return BinOrErr.takeError();
Expand All @@ -666,18 +650,26 @@ Expected<std::unique_ptr<ELFStub>> readELFFile(MemoryBufferRef Buf) {

// This function wraps the ELFT writeELFBinaryToFile() so writeBinaryStub()
// can be called without having to use ELFType templates directly.
Error writeBinaryStub(StringRef FilePath, const ELFStub &Stub,
ELFTarget OutputFormat, bool WriteIfChanged) {
if (OutputFormat == ELFTarget::ELF32LE)
return writeELFBinaryToFile<ELF32LE>(FilePath, Stub, WriteIfChanged);
if (OutputFormat == ELFTarget::ELF32BE)
return writeELFBinaryToFile<ELF32BE>(FilePath, Stub, WriteIfChanged);
if (OutputFormat == ELFTarget::ELF64LE)
return writeELFBinaryToFile<ELF64LE>(FilePath, Stub, WriteIfChanged);
if (OutputFormat == ELFTarget::ELF64BE)
return writeELFBinaryToFile<ELF64BE>(FilePath, Stub, WriteIfChanged);
Error writeBinaryStub(StringRef FilePath, const IFSStub &Stub,
bool WriteIfChanged) {
assert(Stub.Target.Arch);
assert(Stub.Target.BitWidth);
assert(Stub.Target.Endianness);
if (Stub.Target.BitWidth == IFSBitWidthType::IFS32) {
if (Stub.Target.Endianness == IFSEndiannessType::Little) {
return writeELFBinaryToFile<ELF32LE>(FilePath, Stub, WriteIfChanged);
} else {
return writeELFBinaryToFile<ELF32BE>(FilePath, Stub, WriteIfChanged);
}
} else {
if (Stub.Target.Endianness == IFSEndiannessType::Little) {
return writeELFBinaryToFile<ELF64LE>(FilePath, Stub, WriteIfChanged);
} else {
return writeELFBinaryToFile<ELF64BE>(FilePath, Stub, WriteIfChanged);
}
}
llvm_unreachable("invalid binary output target");
}

} // end namespace elfabi
} // end namespace ifs
} // end namespace llvm
28 changes: 0 additions & 28 deletions llvm/lib/InterfaceStub/ELFStub.cpp

This file was deleted.

329 changes: 329 additions & 0 deletions llvm/lib/InterfaceStub/IFSHandler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,329 @@
//===- IFSHandler.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===-----------------------------------------------------------------------===/

#include "llvm/InterfaceStub/IFSHandler.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/InterfaceStub/IFSStub.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/YAMLTraits.h"

using namespace llvm;
using namespace llvm::ifs;

LLVM_YAML_IS_SEQUENCE_VECTOR(IFSSymbol)

namespace llvm {
namespace yaml {

/// YAML traits for ELFSymbolType.
template <> struct ScalarEnumerationTraits<IFSSymbolType> {
static void enumeration(IO &IO, IFSSymbolType &SymbolType) {
IO.enumCase(SymbolType, "NoType", IFSSymbolType::NoType);
IO.enumCase(SymbolType, "Func", IFSSymbolType::Func);
IO.enumCase(SymbolType, "Object", IFSSymbolType::Object);
IO.enumCase(SymbolType, "TLS", IFSSymbolType::TLS);
IO.enumCase(SymbolType, "Unknown", IFSSymbolType::Unknown);
// Treat other symbol types as noise, and map to Unknown.
if (!IO.outputting() && IO.matchEnumFallback())
SymbolType = IFSSymbolType::Unknown;
}
};

template <> struct ScalarTraits<IFSEndiannessType> {
static void output(const IFSEndiannessType &Value, void *,
llvm::raw_ostream &Out) {
switch (Value) {
case IFSEndiannessType::Big:
Out << "big";
break;
case IFSEndiannessType::Little:
Out << "little";
break;
default:
llvm_unreachable("Unsupported endianness");
}
}

static StringRef input(StringRef Scalar, void *, IFSEndiannessType &Value) {
Value = StringSwitch<IFSEndiannessType>(Scalar)
.Case("big", IFSEndiannessType::Big)
.Case("little", IFSEndiannessType::Little)
.Default(IFSEndiannessType::Unknown);
if (Value == IFSEndiannessType::Unknown) {
return "Unsupported endianness";
}
return StringRef();
}

static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};

template <> struct ScalarTraits<IFSBitWidthType> {
static void output(const IFSBitWidthType &Value, void *,
llvm::raw_ostream &Out) {
switch (Value) {
case IFSBitWidthType::IFS32:
Out << "32";
break;
case IFSBitWidthType::IFS64:
Out << "64";
break;
default:
llvm_unreachable("Unsupported bit width");
}
}

static StringRef input(StringRef Scalar, void *, IFSBitWidthType &Value) {
Value = StringSwitch<IFSBitWidthType>(Scalar)
.Case("32", IFSBitWidthType::IFS32)
.Case("64", IFSBitWidthType::IFS64)
.Default(IFSBitWidthType::Unknown);
if (Value == IFSBitWidthType::Unknown) {
return "Unsupported bit width";
}
return StringRef();
}

static QuotingType mustQuote(StringRef) { return QuotingType::None; }
};

template <> struct MappingTraits<IFSTarget> {
static void mapping(IO &IO, IFSTarget &Target) {
IO.mapOptional("ObjectFormat", Target.ObjectFormat);
IO.mapOptional("Arch", Target.ArchString);
IO.mapOptional("Endianness", Target.Endianness);
IO.mapOptional("BitWidth", Target.BitWidth);
}

// Compacts symbol information into a single line.
static const bool flow = true; // NOLINT(readability-identifier-naming)
};

/// YAML traits for ELFSymbol.
template <> struct MappingTraits<IFSSymbol> {
static void mapping(IO &IO, IFSSymbol &Symbol) {
IO.mapRequired("Name", Symbol.Name);
IO.mapRequired("Type", Symbol.Type);
// The need for symbol size depends on the symbol type.
if (Symbol.Type == IFSSymbolType::NoType) {
IO.mapOptional("Size", Symbol.Size, (uint64_t)0);
} else if (Symbol.Type == IFSSymbolType::Func) {
Symbol.Size = 0;
} else {
IO.mapRequired("Size", Symbol.Size);
}
IO.mapOptional("Undefined", Symbol.Undefined, false);
IO.mapOptional("Weak", Symbol.Weak, false);
IO.mapOptional("Warning", Symbol.Warning);
}

// Compacts symbol information into a single line.
static const bool flow = true; // NOLINT(readability-identifier-naming)
};

/// YAML traits for ELFStub objects.
template <> struct MappingTraits<IFSStub> {
static void mapping(IO &IO, IFSStub &Stub) {
if (!IO.mapTag("!ifs-v1", true))
IO.setError("Not a .tbe YAML file.");
IO.mapRequired("IfsVersion", Stub.IfsVersion);
IO.mapOptional("SoName", Stub.SoName);
IO.mapOptional("Target", Stub.Target);
IO.mapOptional("NeededLibs", Stub.NeededLibs);
IO.mapRequired("Symbols", Stub.Symbols);
}
};

/// YAML traits for ELFStubTriple objects.
template <> struct MappingTraits<IFSStubTriple> {
static void mapping(IO &IO, IFSStubTriple &Stub) {
if (!IO.mapTag("!ifs-v1", true))
IO.setError("Not a .tbe YAML file.");
IO.mapRequired("IfsVersion", Stub.IfsVersion);
IO.mapOptional("SoName", Stub.SoName);
IO.mapOptional("Target", Stub.Target.Triple);
IO.mapOptional("NeededLibs", Stub.NeededLibs);
IO.mapRequired("Symbols", Stub.Symbols);
}
};
} // end namespace yaml
} // end namespace llvm

/// Attempt to determine if a Text stub uses target triple.
bool usesTriple(StringRef Buf) {
for (line_iterator I(MemoryBufferRef(Buf, "ELFStub")); !I.is_at_eof(); ++I) {
StringRef Line = (*I).trim();
if (Line.startswith("Target:")) {
if (Line == "Target:" || (Line.find("{") != Line.npos)) {
return false;
}
}
}
return true;
}

Expected<std::unique_ptr<IFSStub>> ifs::readIFSFromBuffer(StringRef Buf) {
yaml::Input YamlIn(Buf);
std::unique_ptr<IFSStubTriple> Stub(new IFSStubTriple());
if (usesTriple(Buf)) {
YamlIn >> *Stub;
} else {
YamlIn >> *static_cast<IFSStub *>(Stub.get());
}
if (std::error_code Err = YamlIn.error()) {
return createStringError(Err, "YAML failed reading as IFS");
}

if (Stub->IfsVersion > IFSVersionCurrent)
return make_error<StringError>(
"IFS version " + Stub->IfsVersion.getAsString() + " is unsupported.",
std::make_error_code(std::errc::invalid_argument));
if (Stub->Target.ArchString) {
Stub->Target.Arch =
ELF::convertArchNameToEMachine(Stub->Target.ArchString.getValue());
}
return std::move(Stub);
}

Error ifs::writeIFSToOutputStream(raw_ostream &OS, const IFSStub &Stub) {
yaml::Output YamlOut(OS, NULL, /*WrapColumn =*/0);
std::unique_ptr<IFSStubTriple> CopyStub(new IFSStubTriple(Stub));
if (Stub.Target.Arch) {
CopyStub->Target.ArchString = std::string(
ELF::convertEMachineToArchName(Stub.Target.Arch.getValue()));
}
IFSTarget Target = Stub.Target;

if (CopyStub->Target.Triple ||
(!CopyStub->Target.ArchString && !CopyStub->Target.Endianness &&
!CopyStub->Target.BitWidth))
YamlOut << *CopyStub;
else
YamlOut << *static_cast<IFSStub *>(CopyStub.get());
return Error::success();
}

Error ifs::overrideIFSTarget(IFSStub &Stub, Optional<IFSArch> OverrideArch,
Optional<IFSEndiannessType> OverrideEndianness,
Optional<IFSBitWidthType> OverrideBitWidth,
Optional<std::string> OverrideTriple) {
std::error_code OverrideEC(1, std::generic_category());
if (OverrideArch) {
if (Stub.Target.Arch &&
Stub.Target.Arch.getValue() != OverrideArch.getValue()) {
return make_error<StringError>(
"Supplied Arch conflicts with the text stub", OverrideEC);
}
Stub.Target.Arch = OverrideArch.getValue();
}
if (OverrideEndianness) {
if (Stub.Target.Endianness &&
Stub.Target.Endianness.getValue() != OverrideEndianness.getValue()) {
return make_error<StringError>(
"Supplied Endianness conflicts with the text stub", OverrideEC);
}
Stub.Target.Endianness = OverrideEndianness.getValue();
}
if (OverrideBitWidth) {
if (Stub.Target.BitWidth &&
Stub.Target.BitWidth.getValue() != OverrideBitWidth.getValue()) {
return make_error<StringError>(
"Supplied BitWidth conflicts with the text stub", OverrideEC);
}
Stub.Target.BitWidth = OverrideBitWidth.getValue();
}
if (OverrideTriple) {
if (Stub.Target.Triple &&
Stub.Target.Triple.getValue() != OverrideTriple.getValue()) {
return make_error<StringError>(
"Supplied Triple conflicts with the text stub", OverrideEC);
}
Stub.Target.Triple = OverrideTriple.getValue();
}
return Error::success();
}

Error ifs::validateIFSTarget(IFSStub &Stub, bool ParseTriple) {
std::error_code ValidationEC(1, std::generic_category());
if (Stub.Target.Triple) {
if (Stub.Target.Arch || Stub.Target.BitWidth || Stub.Target.Endianness ||
Stub.Target.ObjectFormat) {
return make_error<StringError>(
"Target triple cannot be used simultaneously with ELF target format",
ValidationEC);
}
if (ParseTriple) {
IFSTarget TargetFromTriple = parseTriple(Stub.Target.Triple.getValue());
Stub.Target.Arch = TargetFromTriple.Arch;
Stub.Target.BitWidth = TargetFromTriple.BitWidth;
Stub.Target.Endianness = TargetFromTriple.Endianness;
}
return Error::success();
}
if (!Stub.Target.Arch || !Stub.Target.BitWidth || !Stub.Target.Endianness) {
// TODO: unify the error message.
if (!Stub.Target.Arch) {
return make_error<StringError>("Arch is not defined in the text stub",
ValidationEC);
}
if (!Stub.Target.BitWidth) {
return make_error<StringError>("BitWidth is not defined in the text stub",
ValidationEC);
}
if (!Stub.Target.Endianness) {
return make_error<StringError>(
"Endianness is not defined in the text stub", ValidationEC);
}
}
return Error::success();
}

IFSTarget ifs::parseTriple(StringRef TripleStr) {
Triple IFSTriple(TripleStr);
IFSTarget RetTarget;
// TODO: Implement a Triple Arch enum to e_machine map.
switch (IFSTriple.getArch()) {
case Triple::ArchType::aarch64:
RetTarget.Arch = (IFSArch)ELF::EM_AARCH64;
break;
case Triple::ArchType::x86_64:
RetTarget.Arch = (IFSArch)ELF::EM_X86_64;
break;
default:
RetTarget.Arch = (IFSArch)ELF::EM_NONE;
}
RetTarget.Endianness = IFSTriple.isLittleEndian() ? IFSEndiannessType::Little
: IFSEndiannessType::Big;
RetTarget.BitWidth =
IFSTriple.isArch64Bit() ? IFSBitWidthType::IFS64 : IFSBitWidthType::IFS32;
return RetTarget;
}

void ifs::stripIFSTarget(IFSStub &Stub, bool StripTriple, bool StripArch,
bool StripEndianness, bool StripBitWidth) {
if (StripTriple || StripArch) {
Stub.Target.Arch.reset();
Stub.Target.ArchString.reset();
}
if (StripTriple || StripEndianness) {
Stub.Target.Endianness.reset();
}
if (StripTriple || StripBitWidth) {
Stub.Target.BitWidth.reset();
}
if (StripTriple) {
Stub.Target.Triple.reset();
}
if (!Stub.Target.Arch && !Stub.Target.BitWidth && !Stub.Target.Endianness) {
Stub.Target.ObjectFormat.reset();
}
}
133 changes: 133 additions & 0 deletions llvm/lib/InterfaceStub/IFSStub.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
//===- IFSStub.cpp --------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===-----------------------------------------------------------------------===/

#include "llvm/InterfaceStub/IFSStub.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Support/Error.h"

using namespace llvm;
using namespace llvm::ifs;

IFSStub::IFSStub(IFSStub const &Stub) {
IfsVersion = Stub.IfsVersion;
Target = Stub.Target;
SoName = Stub.SoName;
NeededLibs = Stub.NeededLibs;
Symbols = Stub.Symbols;
}

IFSStub::IFSStub(IFSStub &&Stub) {
IfsVersion = std::move(Stub.IfsVersion);
Target = std::move(Stub.Target);
SoName = std::move(Stub.SoName);
NeededLibs = std::move(Stub.NeededLibs);
Symbols = std::move(Stub.Symbols);
}

IFSStubTriple::IFSStubTriple(IFSStubTriple const &Stub) {
IfsVersion = Stub.IfsVersion;
Target = Stub.Target;
SoName = Stub.SoName;
NeededLibs = Stub.NeededLibs;
Symbols = Stub.Symbols;
}

IFSStubTriple::IFSStubTriple(IFSStub const &Stub) {
IfsVersion = Stub.IfsVersion;
Target = Stub.Target;
SoName = Stub.SoName;
NeededLibs = Stub.NeededLibs;
Symbols = Stub.Symbols;
}

IFSStubTriple::IFSStubTriple(IFSStubTriple &&Stub) {
IfsVersion = std::move(Stub.IfsVersion);
Target = std::move(Stub.Target);
SoName = std::move(Stub.SoName);
NeededLibs = std::move(Stub.NeededLibs);
Symbols = std::move(Stub.Symbols);
}

bool IFSTarget::empty() {
return !Triple && !ObjectFormat && !Arch && !ArchString && !Endianness &&
!BitWidth;
}

uint8_t ifs::convertIFSBitWidthToELF(IFSBitWidthType BitWidth) {
switch (BitWidth) {
case IFSBitWidthType::IFS32:
return ELF::ELFCLASS32;
case IFSBitWidthType::IFS64:
return ELF::ELFCLASS64;
case IFSBitWidthType::Unknown:
llvm_unreachable("unkown bitwidth");
}
}

uint8_t ifs::convertIFSEndiannessToELF(IFSEndiannessType Endianness) {
switch (Endianness) {
case IFSEndiannessType::Little:
return ELF::ELFDATA2LSB;
case IFSEndiannessType::Big:
return ELF::ELFDATA2MSB;
case IFSEndiannessType::Unknown:
llvm_unreachable("unknown endianness");
}
}

uint8_t ifs::convertIFSSymbolTypeToELF(IFSSymbolType SymbolType) {
switch (SymbolType) {
case IFSSymbolType::Object:
return ELF::STT_OBJECT;
case IFSSymbolType::Func:
return ELF::STT_FUNC;
case IFSSymbolType::TLS:
return ELF::STT_TLS;
case IFSSymbolType::NoType:
default:
return ELF::STT_NOTYPE;
}
}

IFSBitWidthType ifs::convertELFBitWidthToIFS(uint8_t BitWidth) {
switch (BitWidth) {
case ELF::ELFCLASS32:
return IFSBitWidthType::IFS32;
case ELF::ELFCLASS64:
return IFSBitWidthType::IFS64;
default:
return IFSBitWidthType::Unknown;
}
}

IFSEndiannessType ifs::convertELFEndiannessToIFS(uint8_t Endianness) {
switch (Endianness) {
case ELF::ELFDATA2LSB:
return IFSEndiannessType::Little;
case ELF::ELFDATA2MSB:
return IFSEndiannessType::Big;
default:
return IFSEndiannessType::Unknown;
}
}

IFSSymbolType ifs::convertELFSymbolTypeToIFS(uint8_t SymbolType) {
SymbolType = SymbolType & 0xf;
switch (SymbolType) {
case ELF::STT_OBJECT:
return IFSSymbolType::Object;
case ELF::STT_FUNC:
return IFSSymbolType::Func;
case ELF::STT_TLS:
return IFSSymbolType::TLS;
case ELF::STT_NOTYPE:
return IFSSymbolType::NoType;
default:
return IFSSymbolType::Unknown;
}
}
143 changes: 0 additions & 143 deletions llvm/lib/InterfaceStub/TBEHandler.cpp

This file was deleted.

1 change: 0 additions & 1 deletion llvm/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ set(LLVM_TEST_DEPENDS
dsymutil
llvm-dwarfdump
llvm-dwp
llvm-elfabi
llvm-exegesis
llvm-extract
llvm-gsymutil
Expand Down
49 changes: 0 additions & 49 deletions llvm/test/tools/llvm-elfabi/binary-read-arch.test

This file was deleted.

22 changes: 0 additions & 22 deletions llvm/test/tools/llvm-elfabi/binary-read-syms-gnu-hash.test

This file was deleted.

22 changes: 0 additions & 22 deletions llvm/test/tools/llvm-elfabi/binary-read-syms-sysv-hash.test

This file was deleted.

16 changes: 0 additions & 16 deletions llvm/test/tools/llvm-elfabi/fail-file-write-windows.test

This file was deleted.

15 changes: 0 additions & 15 deletions llvm/test/tools/llvm-elfabi/output-target-error.test

This file was deleted.

19 changes: 0 additions & 19 deletions llvm/test/tools/llvm-elfabi/preserve-dates-stub.test

This file was deleted.

8 changes: 0 additions & 8 deletions llvm/test/tools/llvm-elfabi/preserve-dates-tbe.test

This file was deleted.

16 changes: 0 additions & 16 deletions llvm/test/tools/llvm-elfabi/read-tbe-as-elf.test

This file was deleted.

13 changes: 0 additions & 13 deletions llvm/test/tools/llvm-elfabi/read-tbe-as-tbe.test

This file was deleted.

7 changes: 0 additions & 7 deletions llvm/test/tools/llvm-elfabi/read-unsupported-file.test

This file was deleted.

13 changes: 0 additions & 13 deletions llvm/test/tools/llvm-elfabi/tbe-emits-current-version.test

This file was deleted.

25 changes: 0 additions & 25 deletions llvm/test/tools/llvm-elfabi/tbe-read-basic.test

This file was deleted.

File renamed without changes.
7 changes: 3 additions & 4 deletions llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-size.ifs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# NOTE: Used by weak-mismatch.ifs
--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
--- !ifs-v1
IfsVersion: 3.0
Target: x86_64-unknown-linux-gnu
Symbols:
- { Name: foobar, Type: Object, Size: 2 }
...
7 changes: 3 additions & 4 deletions llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-type.ifs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# NOTE: Used by weak-mismatch.ifs
--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
--- !ifs-v1
IfsVersion: 3.0
Target: x86_64-unknown-linux-gnu
Symbols:
- { Name: foobar, Type: Func }
...
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# RUN: yaml2obj %s -o %t
# RUN: llvm-elfabi --elf %t --emit-tbe=- --soname=best.so | FileCheck %s
# RUN: llvm-ifs --input-format=ELF --output-format=IFS --output=- --soname=best.so %t | FileCheck %s

!ELF
FileHeader:
Expand Down Expand Up @@ -42,9 +42,9 @@ ProgramHeaders:
FirstSec: .dynamic
LastSec: .dynamic

# CHECK: --- !tapi-tbe
# CHECK-NEXT: TbeVersion: {{[1-9]\d*\.(0|([1-9]\d*))}}
# CHECK: --- !ifs-v1
# CHECK-NEXT: IfsVersion: {{[1-9]\d*\.(0|([1-9]\d*))}}
# CHECK-NEXT: SoName: best.so{{$}}
# CHECK-NEXT: Arch: AArch64
# CHECK-NEXT: Symbols: {}
# CHECK-NEXT: Target: { ObjectFormat: ELF, Arch: AArch64, Endianness: little, BitWidth: 64 }
# CHECK-NEXT: Symbols: []
# CHECK-NEXT: ...
143 changes: 143 additions & 0 deletions llvm/test/tools/llvm-ifs/binary-read-arch.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# RUN: yaml2obj --docnum=1 %s -o %t
# RUN: llvm-ifs --input-format=ELF --output-format=IFS --output=- %t | FileCheck %s -DTARGET="{ ObjectFormat: ELF, Arch: x86_64, Endianness: little, BitWidth: 64 }"
# RUN: llvm-ifs --input-format=ELF --output-format=IFS --output=- --hint-ifs-target="x86_64-linux-gnu" %t | FileCheck %s -DTARGET="x86_64-linux-gnu"

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .dynstr
Type: SHT_STRTAB
Flags: [ SHF_ALLOC ]
Address: 0x0000
Content: "00"
- Name: .dynamic
Type: SHT_DYNAMIC
Flags: [ SHF_ALLOC ]
Address: 0x0000000000000008
Link: .dynstr
AddressAlign: 0x0000000000000008
EntSize: 0x0000000000000010
Entries:
- Tag: DT_STRSZ
Value: 0x0000000000000001
- Tag: DT_STRTAB
Value: 0x0000000000000000
- Tag: DT_SYMTAB
Value: 0x0000000000000000
- Tag: DT_NULL
Value: 0x0000000000000000
ProgramHeaders:
- Type: PT_LOAD
Flags: [ PF_R ]
VAddr: 0x0000
Align: 8
FirstSec: .dynstr
LastSec: .dynamic
- Type: PT_DYNAMIC
Flags: [ PF_X, PF_R ]
VAddr: 0x0008
FirstSec: .dynamic
LastSec: .dynamic

# CHECK: --- !ifs-v1
# CHECK-NEXT: IfsVersion: {{[1-9]\d*\.(0|([1-9]\d*))}}
# CHECK-NEXT: Target: [[TARGET]]
# CHECK-NEXT: Symbols: []
# CHECK-NEXT: ...

# HINTERR: error: Triple hint does not match the actual [[MSG]]

# RUN: yaml2obj --docnum=1 %s -o %t
# RUN: not llvm-ifs --input-format=ELF --output-format=IFS --output=%t.tbe --hint-ifs-target="aarch64-linux-gnu" %t 2>&1 | FileCheck %s -DMSG=architecture --check-prefix=HINTERR

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2MSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .dynstr
Type: SHT_STRTAB
Flags: [ SHF_ALLOC ]
Address: 0x0000
Content: "00"
- Name: .dynamic
Type: SHT_DYNAMIC
Flags: [ SHF_ALLOC ]
Address: 0x0000000000000008
Link: .dynstr
AddressAlign: 0x0000000000000008
EntSize: 0x0000000000000010
Entries:
- Tag: DT_STRSZ
Value: 0x0000000000000001
- Tag: DT_STRTAB
Value: 0x0000000000000000
- Tag: DT_SYMTAB
Value: 0x0000000000000000
- Tag: DT_NULL
Value: 0x0000000000000000
ProgramHeaders:
- Type: PT_LOAD
Flags: [ PF_R ]
VAddr: 0x0000
Align: 8
FirstSec: .dynstr
LastSec: .dynamic
- Type: PT_DYNAMIC
Flags: [ PF_X, PF_R ]
VAddr: 0x0008
FirstSec: .dynamic
LastSec: .dynamic

# RUN: yaml2obj --docnum=2 %s -o %t
# RUN: not llvm-ifs --input-format=ELF --output-format=IFS --output=%t.tbe --hint-ifs-target="x86_64-unknown-linux-gnu" %t 2>&1 | FileCheck %s -DMSG="endianness" --check-prefix=HINTERR

--- !ELF
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
Type: ET_DYN
Machine: EM_X86_64
Sections:
- Name: .dynstr
Type: SHT_STRTAB
Flags: [ SHF_ALLOC ]
Address: 0x0000
Content: "00"
- Name: .dynamic
Type: SHT_DYNAMIC
Flags: [ SHF_ALLOC ]
Address: 0x0000000000000008
Link: .dynstr
AddressAlign: 0x0000000000000008
EntSize: 0x0000000000000010
Entries:
- Tag: DT_STRSZ
Value: 0x0000000000000001
- Tag: DT_STRTAB
Value: 0x0000000000000000
- Tag: DT_SYMTAB
Value: 0x0000000000000000
- Tag: DT_NULL
Value: 0x0000000000000000
ProgramHeaders:
- Type: PT_LOAD
Flags: [ PF_R ]
VAddr: 0x0000
Align: 8
FirstSec: .dynstr
LastSec: .dynamic
- Type: PT_DYNAMIC
Flags: [ PF_X, PF_R ]
VAddr: 0x0008
FirstSec: .dynamic
LastSec: .dynamic

# RUN: yaml2obj --docnum=3 %s -o %t
# RUN: not llvm-ifs --input-format=ELF --output-format=IFS --output=%t.tbe --hint-ifs-target="x86_64-unknown-linux-gnu" %t 2>&1 | FileCheck %s -DMSG="bit width" --check-prefix=HINTERR
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# RUN: yaml2obj %s -o %t
# RUN: not llvm-elfabi --elf %t --emit-tbe=%t.tbe 2>&1 | FileCheck %s
# RUN: not llvm-ifs --input-format=ELF --output-format=IFS --output=%t.tbe %t 2>&1 | FileCheck %s

!ELF
FileHeader:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# RUN: yaml2obj %s -o %t
# RUN: not llvm-elfabi --elf %t --emit-tbe=%t.tbe 2>&1 | FileCheck %s
# RUN: not llvm-ifs --input-format=ELF --output-format=IFS --output=%t.tbe %t 2>&1 | FileCheck %s

!ELF
FileHeader:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# RUN: yaml2obj %s -o %t
# RUN: not llvm-elfabi --elf %t --emit-tbe=%t.tbe 2>&1 | FileCheck %s
# RUN: not llvm-ifs --input-format=ELF --output-format=IFS --output=%t.tbe %t 2>&1 | FileCheck %s

!ELF
FileHeader:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# RUN: yaml2obj %s -o %t
# RUN: llvm-elfabi --elf %t --emit-tbe=- | FileCheck %s
# RUN: llvm-ifs --input-format=ELF --output-format=IFS --output=- %t | FileCheck %s

!ELF
FileHeader:
Expand Down Expand Up @@ -48,4 +48,4 @@ ProgramHeaders:
# CHECK: NeededLibs:
# CHECK-NEXT: - libfoo.so{{$}}
# CHECK-NEXT: - libbar.so{{$}}
# CHECK-NEXT: Symbols: {}
# CHECK-NEXT: Symbols: []
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# RUN: yaml2obj %s -o %t
# RUN: not llvm-elfabi --elf %t --emit-tbe=%t.tbe 2>&1 | FileCheck %s
# RUN: not llvm-ifs --input-format=ELF --output-format=IFS --output=%t.tbe %t 2>&1 | FileCheck %s

!ELF
FileHeader:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# RUN: yaml2obj %s -o %t
# RUN: not llvm-elfabi --elf %t --emit-tbe=%t.tbe 2>&1 | FileCheck %s
# RUN: not llvm-ifs --input-format=ELF --output-format=IFS --output=%t.tbe %t 2>&1 | FileCheck %s

!ELF
FileHeader:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# RUN: yaml2obj %s -o %t
# RUN: not llvm-elfabi --elf %t --emit-tbe=%t.tbe 2>&1 | FileCheck %s
# RUN: not llvm-ifs --input-format=ELF --output-format=IFS --output=%t.tbe %t 2>&1 | FileCheck %s

!ELF
FileHeader:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# RUN: yaml2obj %s -o %t
# RUN: llvm-elfabi --elf %t --emit-tbe=- | FileCheck %s --check-prefix=ORIGINAL
# RUN: llvm-elfabi --elf %t --emit-tbe=- --soname=libbest.so | FileCheck %s --check-prefix=REPLACED
# RUN: llvm-ifs --input-format=ELF --output-format=IFS --output=- %t | FileCheck %s --check-prefix=ORIGINAL
# RUN: llvm-ifs --input-format=ELF --output-format=IFS --soname=libbest.so --output=- %t | FileCheck %s --check-prefix=REPLACED

!ELF
FileHeader:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# RUN: yaml2obj %s -o %t
# RUN: not llvm-elfabi --elf %t --emit-tbe=%t.tbe 2>&1 | FileCheck %s
# RUN: not llvm-ifs --input-format=ELF --output-format=IFS --output=%t.tbe %t 2>&1 | FileCheck %s

!ELF
FileHeader:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# RUN: yaml2obj %s -o %t
# RUN: llvm-elfabi --elf %t --emit-tbe=- | FileCheck %s
# RUN: llvm-ifs --input-format=ELF --output-format=IFS --output=- %t | FileCheck %s

!ELF
FileHeader:
Expand Down Expand Up @@ -45,9 +45,9 @@ ProgramHeaders:
FirstSec: .dynamic
LastSec: .dynamic

# CHECK: --- !tapi-tbe
# CHECK-NEXT: TbeVersion: {{[1-9]\d*\.(0|([1-9]\d*))}}
# CHECK: --- !ifs-v1
# CHECK-NEXT: IfsVersion: {{[1-9]\d*\.(0|([1-9]\d*))}}
# CHECK-NEXT: SoName: somelib.so{{$}}
# CHECK-NEXT: Arch: x86_64
# CHECK-NEXT: Symbols: {}
# CHECK-NEXT: Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: little, BitWidth: 64 }
# CHECK-NEXT: Symbols: []
# CHECK-NEXT: ...
22 changes: 22 additions & 0 deletions llvm/test/tools/llvm-ifs/binary-read-syms-gnu-hash.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# RUN: llvm-ifs --input-format=ELF --output-format=IFS --output=- %p/Inputs/gnu_hash.so | FileCheck %s

# CHECK: --- !ifs-v1
# CHECK-NEXT: IfsVersion: 3.0
# CHECK-NEXT: SoName: libsomething.so
# CHECK-NEXT: Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: little, BitWidth: 64 }
# CHECK-NEXT: NeededLibs:
# CHECK-NEXT: - libm.so.6
# CHECK-NEXT: - libc.so.6
# CHECK-NEXT: - ld-linux-x86-64.so.2
# CHECK-NEXT: Symbols:
# CHECK-NEXT: - { Name: AGlobalInteger, Type: Object, Size: 4 }
# CHECK-NEXT: - { Name: AThreadLocalLongInteger, Type: TLS, Size: 8 }
# CHECK-NEXT: - { Name: _ITM_deregisterTMCloneTable, Type: NoType, Undefined: true, Weak: true }
# CHECK-NEXT: - { Name: _ITM_registerTMCloneTable, Type: NoType, Undefined: true, Weak: true }
# CHECK-NEXT: - { Name: _Z11rotateArrayPii, Type: Func }
# CHECK-NEXT: - { Name: __cxa_finalize, Type: Func, Undefined: true, Weak: true }
# CHECK-NEXT: - { Name: __gmon_start__, Type: NoType, Undefined: true, Weak: true }
# CHECK-NEXT: - { Name: __tls_get_addr, Type: Func, Undefined: true }
# CHECK-NEXT: - { Name: _fini, Type: Func }
# CHECK-NEXT: - { Name: _init, Type: Func }
# CHECK-NEXT: ...
22 changes: 22 additions & 0 deletions llvm/test/tools/llvm-ifs/binary-read-syms-sysv-hash.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# RUN: llvm-ifs --input-format=ELF --output-format=IFS --output=- %p/Inputs/sysv_hash.so | FileCheck %s

# CHECK: --- !ifs-v1
# CHECK-NEXT: IfsVersion: 3.0
# CHECK-NEXT: SoName: libsomething.so
# CHECK-NEXT: Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: little, BitWidth: 64 }
# CHECK-NEXT: NeededLibs:
# CHECK-NEXT: - libm.so.6
# CHECK-NEXT: - libc.so.6
# CHECK-NEXT: - ld-linux-x86-64.so.2
# CHECK-NEXT: Symbols:
# CHECK-NEXT: - { Name: AGlobalInteger, Type: Object, Size: 4 }
# CHECK-NEXT: - { Name: AThreadLocalLongInteger, Type: TLS, Size: 8 }
# CHECK-NEXT: - { Name: _ITM_deregisterTMCloneTable, Type: NoType, Undefined: true, Weak: true }
# CHECK-NEXT: - { Name: _ITM_registerTMCloneTable, Type: NoType, Undefined: true, Weak: true }
# CHECK-NEXT: - { Name: _Z11rotateArrayPii, Type: Func }
# CHECK-NEXT: - { Name: __cxa_finalize, Type: Func, Undefined: true, Weak: true }
# CHECK-NEXT: - { Name: __gmon_start__, Type: NoType, Undefined: true, Weak: true }
# CHECK-NEXT: - { Name: __tls_get_addr, Type: Func, Undefined: true }
# CHECK-NEXT: - { Name: _fini, Type: Func }
# CHECK-NEXT: - { Name: _init, Type: Func }
# CHECK-NEXT: ...
14 changes: 0 additions & 14 deletions llvm/test/tools/llvm-ifs/conflict-header-format.ifs

This file was deleted.

12 changes: 5 additions & 7 deletions llvm/test/tools/llvm-ifs/conflict-header-triple.ifs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
# RUN: not llvm-ifs -action write-ifs -o - %s %S/object.ifs 2>&1 | \
# RUN: not llvm-ifs --input-format=IFS --output-format=IFS -o - %s %S/object.ifs 2>&1 | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS

# CHECK-IFS: error: Interface Stub: Triple Mismatch.
# CHECK-IFS: error: Interface Stub: Target Mismatch.
# CHECK-IFS-NEXT: Filenames:
# CHECK-IFS-NEXT: Triple Values: mips-unknown-linux x86_64-unknown-linux-gnu

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: mips-unknown-linux
ObjectFileFormat: ELF
--- !ifs-v1
IfsVersion: 3.0
Target: mips-unknown-linux
Symbols:
- { Name: a, Type: Func }
...
11 changes: 5 additions & 6 deletions llvm/test/tools/llvm-ifs/conflict-header-version.ifs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
# RUN: not llvm-ifs -action write-ifs -o - %s %S/object.ifs 2>&1 | \
# RUN: not llvm-ifs --input-format=IFS --output-format=IFS -o - %s %S/object.ifs 2>&1 | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS

# RUN: not llvm-ifs -action write-ifs -o - %s 2>&1 | \
# RUN: not llvm-ifs --input-format=IFS --output-format=IFS -o - %s 2>&1 | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS2

# CHECK-IFS: error: Interface Stub: IfsVersion Mismatch.
# CHECK-IFS2: error: Interface Stub: Bad IfsVersion: 0.0, llvm-ifs supported version: 2.0.
# CHECK-IFS2: error: Interface Stub: Bad IfsVersion: 0.0, llvm-ifs supported version: 3.0.

--- !experimental-ifs-v2
--- !ifs-v1
IfsVersion: 0.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
Target: x86_64-unknown-linux-gnu
Symbols:
- { Name: a, Type: Func }
...
9 changes: 4 additions & 5 deletions llvm/test/tools/llvm-ifs/conflict-size.ifs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# RUN: not llvm-ifs -action write-ifs -o - %s %S/object.ifs 2>&1 | \
# RUN: not llvm-ifs --input-format=IFS --output-format=IFS -o - %s %S/object.ifs 2>&1 | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS

# Here we are testing to see if two symbols with identical names will fail to
Expand All @@ -7,10 +7,9 @@
# CHECK-IFS-NEXT: Filename:
# CHECK-IFS-NEXT: Size Values: 1 4

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
--- !ifs-v1
IfsVersion: 3.0
Target: x86_64-unknown-linux-gnu
Symbols:
- { Name: b, Type: Object, Size: 1 }
...
9 changes: 4 additions & 5 deletions llvm/test/tools/llvm-ifs/conflict-type.ifs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# RUN: not llvm-ifs -action write-ifs -o - %s %S/func.ifs 2>&1 | \
# RUN: not llvm-ifs --input-format=IFS --output-format=IFS -o - %s %S/func.ifs 2>&1 | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS

# Here we are testing to see if two symbols with identical names will fail to
Expand All @@ -7,10 +7,9 @@
# CHECK-IFS-NEXT: Filename:
# CHECK-IFS-NEXT: Type Values: Object Func

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
--- !ifs-v1
IfsVersion: 3.0
Target: x86_64-unknown-linux-gnu
Symbols:
- { Name: a, Type: Object, Size: 1 }
...
9 changes: 4 additions & 5 deletions llvm/test/tools/llvm-ifs/conflict-weak.ifs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# RUN: llvm-ifs -action write-ifs -o - %s %S/func.ifs 2>&1 | \
# RUN: llvm-ifs --input-format=IFS --output-format=IFS -o - %s %S/func.ifs 2>&1 | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS

# CHECK-IFS: Symbols:
# CHECK-IFS-NEXT: - { Name: a, Type: Func, Weak: true }

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
--- !ifs-v1
IfsVersion: 3.0
Target: x86_64-unknown-linux-gnu
Symbols:
- { Name: a, Type: Func, Weak: true }
...
23 changes: 9 additions & 14 deletions llvm/test/tools/llvm-ifs/default-empty.ifs
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
# RUN: llvm-ifs -action write-ifs -o - %s | FileCheck --check-prefixes=CHECK-DEFAULT %s
# RUN: llvm-ifs -action write-ifs -o - %s %S/weak.ifs | FileCheck --check-prefixes=CHECK-MERGE %s
# RUN: llvm-ifs --input-format=IFS --output-format=IFS -o - %s | FileCheck --check-prefixes=CHECK-DEFAULT %s
# RUN: llvm-ifs --input-format=IFS --output-format=IFS -o - %S/weak.ifs %s | FileCheck --check-prefixes=CHECK-MERGE %s

# CHECK-DEFAULT: --- !experimental-ifs-v2
# CHECK-DEFAULT-NEXT: IfsVersion: 2.0
# CHECK-DEFAULT-NEXT: Triple: ''
# CHECK-DEFAULT-NEXT: ObjectFileFormat: ELF
# CHECK-DEFAULT: --- !ifs-v1
# CHECK-DEFAULT-NEXT: IfsVersion: 3.0
# CHECK-DEFAULT-NEXT: Symbols: []
# CHECK-DEFAULT-NEXT: ...

# CHECK-MERGE: --- !experimental-ifs-v2
# CHECK-MERGE-NEXT: IfsVersion: 2.0
# CHECK-MERGE-NEXT: Triple: x86_64-unknown-linux-gnu
# CHECK-MERGE-NEXT: ObjectFileFormat: ELF
# CHECK-MERGE: --- !ifs-v1
# CHECK-MERGE-NEXT: IfsVersion: 3.0
# CHECK-MERGE-NEXT: Target: x86_64-unknown-linux-gnu
# CHECK-MERGE-NEXT: Symbols:
# CHECK-MERGE-DAG: - { Name: _Z8weakFuncv, Type: Func, Weak: true }
# CHECK-MERGE-DAG: - { Name: _Z10strongFuncv, Type: Func }
# CHECK-MERGE: ...

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: ''
ObjectFileFormat: ELF
--- !ifs-v1
IfsVersion: 3.0
Symbols: []
...
16 changes: 7 additions & 9 deletions llvm/test/tools/llvm-ifs/empty1.ifs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
# RUN: llvm-ifs -action write-ifs -o - %s | FileCheck %s
# RUN: llvm-ifs --input-format=IFS --output-format=IFS -o - %s | FileCheck %s

# CHECK: --- !experimental-ifs-v2
# CHECK-NEXT: IfsVersion: 2.0
# CHECK-NEXT: Triple: x86_64-unknown-linux-gnu
# CHECK-NEXT: ObjectFileFormat: ELF
# CHECK: --- !ifs-v1
# CHECK-NEXT: IfsVersion: 3.0
# CHECK-NEXT: Target: x86_64-unknown-linux-gnu
# CHECK-NEXT: Symbols: []
# CHECK: ...

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
--- !ifs-v1
IfsVersion: 3.0
Target: x86_64-unknown-linux-gnu
Symbols: []
...
16 changes: 7 additions & 9 deletions llvm/test/tools/llvm-ifs/empty2.ifs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
# RUN: llvm-ifs -action write-ifs -o - %s | FileCheck %s
# RUN: llvm-ifs --input-format=IFS --output-format=IFS -o - %s | FileCheck %s

# CHECK: --- !experimental-ifs-v2
# CHECK-NEXT: IfsVersion: 2.0
# CHECK-NEXT: Triple: x86_64-unknown-linux-gnu
# CHECK-NEXT: ObjectFileFormat: ELF
# CHECK: --- !ifs-v1
# CHECK-NEXT: IfsVersion: 3.0
# CHECK-NEXT: Target: x86_64-unknown-linux-gnu
# CHECK-NEXT: Symbols: []
# CHECK: ...

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
--- !ifs-v1
IfsVersion: 3.0
Target: x86_64-unknown-linux-gnu
Symbols:
...
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# RUN: not llvm-elfabi %s.NotAFileInTestingDir --emit-tbe=%t 2>&1 | FileCheck %s
# RUN: not llvm-ifs --output-format=IFS --output=%t.tbe %s.NotAFileInTestingDir 2>&1 | FileCheck %s

This file will not be read. An invalid file path is fed to llvm-elfabi.
This file will not be read. An invalid file path is fed to llvm-ifs.

# CHECK: error: Could not open `{{.*}}.NotAFileInTestingDir`
16 changes: 16 additions & 0 deletions llvm/test/tools/llvm-ifs/fail-file-write-windows.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## Test failing to write output file on windows platform.

# REQUIRES: system-windows
# RUN: touch %t.TestFile
# RUN: chmod 400 %t.TestFile
# RUN: not llvm-ifs --output-format=ELF --output=%t.TestFile %s 2>&1 | FileCheck -DMSG=%errc_EACCES %s --check-prefix=ERR
# RUN: chmod 777 %t.TestFile
# RUN: rm -rf %t.TestFile

--- !ifs-v1
IfsVersion: 3.0
Target: { ObjectFormat: ELF, Arch: AArch64, Endianness: little, BitWidth: 64 }
Symbols: []
...

# ERR: error: [[MSG]]
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
# RUN: mkdir %t.TestDir
# RUN: touch %t.TestDir/Output.TestFile
# RUN: chmod 400 %t.TestDir
# RUN: not llvm-elfabi %s --output-target=elf64-little %t.TestDir/Output.TestFile 2>&1 | FileCheck -DMSG=%errc_EACCES %s --check-prefix=ERR
# RUN: not llvm-ifs --output-format=ELF --output=%t.TestDir/Output.TestFile %s 2>&1 | FileCheck -DMSG=%errc_EACCES %s --check-prefix=ERR
# RUN: chmod 777 %t.TestDir
# RUN: rm -rf %t.TestDir

--- !tapi-tbe
TbeVersion: 1.0
Arch: AArch64
Symbols: {}
--- !ifs-v1
IfsVersion: 3.0
Target: { ObjectFormat: ELF, Arch: AArch64, Endianness: little, BitWidth: 64 }
Symbols: []
...

# ERR: [[MSG]] when trying to open `{{.*}}.TestDir/Output.TestFile` for writing
33 changes: 14 additions & 19 deletions llvm/test/tools/llvm-ifs/func.ifs
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
# RUN: llvm-ifs -action write-ifs -o - %s %S/object.ifs | \
# RUN: llvm-ifs --input-format=IFS --output-format=IFS -o - %s %S/object.ifs | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS

# RUN: llvm-ifs -action write-bin -o - %s %S/object.ifs | \
# RUN: llvm-ifs --input-format=IFS --output-format=ELF -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: llvm-ifs --input-format=IFS --output-format=IFS --strip-ifs-target -o %t.tbd %s %S/object.ifs
# RUN: llvm-ifs --input-format=IFS --output-format=TBD --target=x86_64-apple-darwin -o - %t.tbd | \
# RUN: FileCheck %s --check-prefixes=CHECK-DARWIN-TBD3

# RUN: llvm-ifs -action write-ifs -o - %s %s | \
# RUN: llvm-ifs --input-format=IFS --output-format=IFS -o - %s %s | \
# RUN: FileCheck %s --check-prefixes=CHECK-MERGE-IFS

# CHECK-IFS: --- !experimental-ifs-v2
# CHECK-IFS-NEXT: IfsVersion: 2.0
# CHECK-IFS-NEXT: Triple: x86_64-unknown-linux-gnu
# CHECK-IFS-NEXT: ObjectFileFormat: ELF
# CHECK-IFS: --- !ifs-v1
# CHECK-IFS-NEXT: IfsVersion: 3.0
# CHECK-IFS-NEXT: Target: x86_64-unknown-linux-gnu
# CHECK-IFS-NEXT: Symbols:
# CHECK-IFS-DAG: - { Name: a, Type: Func }
# CHECK-IFS-DAG: - { Name: b, Type: Object, Size: 4 }
Expand All @@ -42,18 +39,16 @@
# CHECK-DARWIN-TBD3-NEXT: ...

# Here we are testing to see if two identical symbols will merge.
# CHECK-MERGE-IFS: --- !experimental-ifs-v2
# CHECK-MERGE-IFS-NEXT: IfsVersion: 2.0
# CHECK-MERGE-IFS-NEXT: Triple: x86_64-unknown-linux-gnu
# CHECK-MERGE-IFS-NEXT: ObjectFileFormat: ELF
# CHECK-MERGE-IFS: --- !ifs-v1
# CHECK-MERGE-IFS-NEXT: IfsVersion: 3.0
# CHECK-MERGE-IFS-NEXT: Target: x86_64-unknown-linux-gnu
# CHECK-MERGE-IFS-NEXT: Symbols:
# CHECK-MERGE-IFS-NEXT: - { Name: a, Type: Func }
# CHECK-MERGE-IFS-NEXT: ...

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
--- !ifs-v1
IfsVersion: 3.0
Target: x86_64-unknown-linux-gnu
Symbols:
- { Name: a, Type: Func }
...
13 changes: 13 additions & 0 deletions llvm/test/tools/llvm-ifs/ifs-emits-current-version.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# RUN: llvm-ifs --output-format=IFS --output=- %s | FileCheck %s

--- !ifs-v1
IfsVersion: 3.0
Target: { ObjectFormat: ELF, Arch: AArch64, Endianness: little, BitWidth: 64 }
Symbols: []
...

# As the tbe reader/writer is updated, update this check to ensure --emit-tbe
# uses the latest tbe writer by default.

# CHECK: --- !ifs-v1
# CHECK-NEXT: IfsVersion: 3.0
25 changes: 25 additions & 0 deletions llvm/test/tools/llvm-ifs/ifs-read-basic.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# RUN: llvm-ifs --output-format=IFS --output=- %s | FileCheck %s

--- !ifs-v1
SoName: somelib.so
IfsVersion: 3.0
Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: little, BitWidth: 64 }
Symbols:
- { Name: foo, Type: Func }
- { Name: bar, Type: Object, Size: 42 }
- { Name: baz, Type: Object, Size: 8 }
- { Name: not, Type: Object, Size: 128, Undefined: true }
- { Name: nor, Type: Func, Undefined: true }
...

# CHECK: --- !ifs-v1
# CHECK-NEXT: IfsVersion: {{[1-9]\d*\.(0|([1-9]\d*))}}
# CHECK-NEXT: SoName: somelib.so
# CHECK-NEXT: Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: little, BitWidth: 64 }
# CHECK-NEXT: Symbols:
# CHECK-NEXT: - { Name: bar, Type: Object, Size: 42 }
# CHECK-NEXT: - { Name: baz, Type: Object, Size: 8 }
# CHECK-NEXT: - { Name: foo, Type: Func }
# CHECK-NEXT: - { Name: nor, Type: Func, Undefined: true }
# CHECK-NEXT: - { Name: not, Type: Object, Size: 128, Undefined: true }
# CHECK-NEXT: ...
9 changes: 4 additions & 5 deletions llvm/test/tools/llvm-ifs/ios-tbd.ifs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# RUN: llvm-ifs --action write-bin -o - %s | FileCheck %s
# RUN: llvm-ifs --input-format=IFS --output-format=TBD -o - %s | FileCheck %s

# CHECK: --- !tapi-tbd-v3
# CHECK-NEXT: archs: [ arm64 ]
Expand All @@ -13,10 +13,9 @@
# CHECK-NEXT: symbols: [ __Z3fooi ]
# CHECK-NEXT: ...

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: arm64-apple-ios
ObjectFileFormat: TBD
--- !ifs-v1
IfsVersion: 3.0
Target: arm64-apple-ios
Symbols:
- { Name: __Z3fooi, Type: Func }
...
9 changes: 4 additions & 5 deletions llvm/test/tools/llvm-ifs/macos-tbd.ifs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# RUN: llvm-ifs --action write-bin -o - %s | FileCheck %s
# RUN: llvm-ifs --input-format=IFS --output-format=TBD -o - %s | FileCheck %s

# CHECK: --- !tapi-tbd-v3
# CHECK-NEXT: archs: [ arm64 ]
Expand All @@ -13,10 +13,9 @@
# CHECK-NEXT: symbols: [ __Z3fooi ]
# CHECK-NEXT: ...

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: arm64-apple-macosx
ObjectFileFormat: TBD
--- !ifs-v1
IfsVersion: 3.0
Target: arm64-apple-macosx
Symbols:
- { Name: __Z3fooi, Type: Func }
...
18 changes: 8 additions & 10 deletions llvm/test/tools/llvm-ifs/object-function-size-weak-combo.ifs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# RUN: llvm-ifs -action write-ifs -o - %s %S/func.ifs %S/object.ifs %S/weak.ifs | \
# RUN: llvm-ifs --input-format=IFS --output-format=IFS -o - %s %S/func.ifs %S/object.ifs %S/weak.ifs | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS

# RUN: llvm-ifs -action write-bin -o - %s %S/func.ifs %S/object.ifs %S/weak.ifs | \
# RUN: llvm-ifs --input-format=IFS --output-format=ELF -o - %s %S/func.ifs %S/object.ifs %S/weak.ifs | \
# RUN: llvm-readelf --all - | FileCheck %s --check-prefixes=CHECK-ELF

# CHECK-IFS: --- !experimental-ifs-v2
# CHECK-IFS-NEXT: IfsVersion: 2.0
# CHECK-IFS-NEXT: Triple: x86_64-unknown-linux-gnu
# CHECK-IFS-NEXT: ObjectFileFormat: ELF
# CHECK-IFS: --- !ifs-v1
# CHECK-IFS-NEXT: IfsVersion: 3.0
# CHECK-IFS-NEXT: Target: x86_64-unknown-linux-gnu
# CHECK-IFS-NEXT: Symbols:
# CHECK-IFS-DAG: - { Name: e, Type: Object, Size: 8 }
# CHECK-IFS-DAG: - { Name: a, Type: Func }
Expand All @@ -24,10 +23,9 @@
# CHECK-ELF: OBJECT GLOBAL DEFAULT 1 e
# CHECK-ELF: OBJECT GLOBAL DEFAULT 1 f

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
--- !ifs-v1
IfsVersion: 3.0
Target: x86_64-unknown-linux-gnu
Symbols:
- { Name: e, Type: Object, Size: 8 }
- { Name: f, Type: Object, Size: 2 }
Expand Down
18 changes: 8 additions & 10 deletions llvm/test/tools/llvm-ifs/object.ifs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# RUN: llvm-ifs -action write-ifs -o - %s | \
# RUN: llvm-ifs --input-format=IFS --output-format=IFS -o - %s | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS

# RUN: llvm-ifs -action write-bin -o - %s | \
# RUN: llvm-ifs --input-format=IFS --output-format=ELF -o - %s | \
# RUN: llvm-readelf --all - | FileCheck %s --check-prefixes=CHECK-ELF

# CHECK-IFS: --- !experimental-ifs-v2
# CHECK-IFS-NEXT: IfsVersion: 2.0
# CHECK-IFS-NEXT: Triple: x86_64-unknown-linux-gnu
# CHECK-IFS-NEXT: ObjectFileFormat: ELF
# CHECK-IFS: --- !ifs-v1
# CHECK-IFS-NEXT: IfsVersion: 3.0
# CHECK-IFS-NEXT: Target: x86_64-unknown-linux-gnu
# CHECK-IFS-NEXT: Symbols:
# CHECK-IFS-NEXT: - { Name: b, Type: Object, Size: 4 }
# CHECK-IFS-NEXT: ...
Expand All @@ -19,10 +18,9 @@
# CHECK-ELF-NOT: FUNC GLOBAL DEFAULT 1 a
# CHECK-ELF: OBJECT GLOBAL DEFAULT 1 b

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
--- !ifs-v1
IfsVersion: 3.0
Target: x86_64-unknown-linux-gnu
Symbols:
- { Name: b, Type: Object, Size: 4 }
...
15 changes: 15 additions & 0 deletions llvm/test/tools/llvm-ifs/output-target-error.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## Test running llvm-ifs without specifying a valid target.

# RUN: not llvm-ifs --output=%t %s 2>&1 | FileCheck %s --check-prefix=MISSING
# RUN: not llvm-ifs --output-format=nope --output=%t %s 2>&1 | FileCheck %s --check-prefix=INVALID

--- !ifs-v1
SoName: somelib.so
IfsVersion: 3.0
Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: little, BitWidth: 64 }
Symbols: []
...

# MISSING: {{llvm-ifs(\.exe)?}}: for the --output-format option: must be specified at least once!

# INVALID: {{llvm-ifs(\.exe)?}}: for the --output-format option: Cannot find option named 'nope'!
8 changes: 8 additions & 0 deletions llvm/test/tools/llvm-ifs/preserve-dates-ifs.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Test writing unchanged content to TBE file with --write-if-changed flag.

# RUN: llvm-ifs --input-format=ELF --output-format=IFS --output=%t %p/Inputs/gnu_hash.so
# RUN: env TZ=GMT touch -m -t 197001010000 %t
# RUN: llvm-ifs --input-format=ELF --output-format=IFS --output=%t --write-if-changed %p/Inputs/gnu_hash.so
# RUN: env TZ=GMT ls -l %t | FileCheck %s

# CHECK: {{[[:space:]]1970}}
19 changes: 19 additions & 0 deletions llvm/test/tools/llvm-ifs/preserve-dates-stub.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
## Test writing unchanged content to ELF Stub file with --write-if-changed flag.

# RUN: llvm-ifs --output-format=ELF --output=%t %s
# RUN: env TZ=GMT touch -m -t 197001010000 %t
# RUN: llvm-ifs --output-format=ELF --output=%t --write-if-changed %s
# RUN: env TZ=GMT ls -l %t | FileCheck %s

--- !ifs-v1
IfsVersion: 3.0
Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: little, BitWidth: 64 }
NeededLibs:
- libc.so.6
Symbols:
- { Name: bar, Type: Object, Size: 42 }
- { Name: baz, Type: TLS, Size: 3 }
- { Name: plus, Type: Func }
...

# CHECK: {{[[:space:]]1970}}
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,28 @@
## * Section headers are stripped but there is a DT_GNU_HASH dynamic tag.
## * Section headers are stripped but there is a DT_HASH dynamic tag.

## Test if llvm-elfabi reads DT_SYMTAB size through section headers by puting the wrong terminator in DT_GNU_HASH.
## Test if llvm-ifs reads DT_SYMTAB size through section headers by puting the wrong terminator in DT_GNU_HASH.
# RUN: yaml2obj %s -o %tfull -DGNUHASHVALUE="[0x9]" -DTAG1="DT_GNU_HASH" -DVAL1="0xC00"
# RUN: llvm-elfabi --elf %tfull --emit-tbe=- | FileCheck %s
# RUN: llvm-ifs --input-format=ELF --output-format=IFS --output=- %tfull | FileCheck %s

## Test if llvm-elfabi fails to read DT_SYMTAB size through section headers when the value of sh_entsize is invalid.
## Test if llvm-ifs fails to read DT_SYMTAB size through section headers when the value of sh_entsize is invalid.
# RUN: yaml2obj %s -o %tfull -DGNUHASHVALUE="[0x9]" -DTAG1="DT_GNU_HASH" -DVAL1="0xC00" -DENTSIZE="0x19"
# RUN: not llvm-elfabi --elf %tfull --emit-tbe=- 2>&1 | FileCheck %s --check-prefix=BADENTSIZE
# RUN: not llvm-ifs --input-format=ELF --output-format=IFS --output=- %tfull 2>&1 | FileCheck %s --check-prefix=BADENTSIZE

## Test if llvm-elfabi reads DT_SYMTAB size through DT_GNU_HASH.
## Test if llvm-ifs reads DT_SYMTAB size through DT_GNU_HASH.
# RUN: yaml2obj %s -o %tw.gnu.hash -DGNUHASHVALUE="[0x8, 0x9]" -DTAG1="DT_GNU_HASH" -DVAL1="0xC00" -DNOHEADER="true"
# RUN: llvm-elfabi --elf %tw.gnu.hash --emit-tbe=- | FileCheck %s
# RUN: llvm-ifs --input-format=ELF --output-format=IFS --output=- %tw.gnu.hash | FileCheck %s

## Test if llvm-elfabi fails to read DT_SYMTAB size through DT_GNU_HASH when there is no terminator.
## Test if llvm-ifs fails to read DT_SYMTAB size through DT_GNU_HASH when there is no terminator.
# RUN: yaml2obj %s -o %tw.gnu.hash -DGNUHASHVALUE="[0x8, 0xA]" -DTAG1="DT_GNU_HASH" -DVAL1="0xC00" -DNOHEADER="true"
# RUN: not llvm-elfabi --elf %tw.gnu.hash --emit-tbe=- 2>&1 | FileCheck %s --check-prefix=NOTERMINATOR
# RUN: not llvm-ifs --input-format=ELF --output-format=IFS --output=- %tw.gnu.hash 2>&1 | FileCheck %s --check-prefix=NOTERMINATOR

# CHECK: --- !tapi-tbe
# CHECK-NEXT: TbeVersion: 1.0
# CHECK-NEXT: Arch: AArch64
# CHECK: --- !ifs-v1
# CHECK-NEXT: IfsVersion: 3.0
# CHECK-NEXT: Target: { ObjectFormat: ELF, Arch: AArch64, Endianness: little, BitWidth: 64 }
# CHECK-NEXT: Symbols:
# CHECK-NEXT: bar: { Type: Object, Size: 0, Undefined: true }
# CHECK-NEXT: foo: { Type: Func, Undefined: true }
# CHECK-NEXT: - { Name: bar, Type: Object, Size: 0, Undefined: true }
# CHECK-NEXT: - { Name: foo, Type: Func, Undefined: true }
# CHECK-NEXT: ...

# BADENTSIZE: SHT_DYNSYM section has sh_size (72) % sh_entsize (25) that is not 0
Expand Down
16 changes: 16 additions & 0 deletions llvm/test/tools/llvm-ifs/read-ifs-as-elf.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# RUN: not llvm-ifs --input-format=ELF --output-format=IFS --output=%t %s 2>&1 | FileCheck %s

--- !ifs-v1
SoName: somelib.so
IfsVersion: 3.0
Target: { ObjectFormat: ELF, Arch: AArch64, Endianness: little, BitWidth: 64 }
Symbols:
- { Name: foo, Type: Func }
- { Name: bar, Type: Object, Size: 42 }
- { Name: baz, Type: Object, Size: 8 }
- { Name: not, Type: Object, Undefined: true, Size: 128 }
- { Name: nor, Type: Func, Undefined: true }
...

# CHECK: The file was not recognized as a valid object file
# CHECK: No file readers succeeded reading `{{.*}}read-ifs-as-elf.test` (unsupported/malformed file?)
13 changes: 13 additions & 0 deletions llvm/test/tools/llvm-ifs/read-ifs-as-ifs.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# RUN: llvm-ifs --input-format=IFS --output-format=IFS --output=- %s | FileCheck %s

--- !ifs-v1
IfsVersion: 3.0
Target: { ObjectFormat: ELF, Arch: AArch64, Endianness: little, BitWidth: 64 }
Symbols: []
...

# CHECK: --- !ifs-v1
# CHECK-NEXT: IfsVersion: {{[1-9]\d*\.(0|([1-9]\d*))}}
# CHECK-NEXT: Target: { ObjectFormat: ELF, Arch: AArch64, Endianness: little, BitWidth: 64 }
# CHECK-NEXT: Symbols: []
# CHECK-NEXT: ...
17 changes: 17 additions & 0 deletions llvm/test/tools/llvm-ifs/read-ifs-with-bad-bitwidth.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## Test reading TBE file with bad bit width.

# RUN: not llvm-ifs --output-format=IFS --output=- %s 2>&1 | FileCheck %s

--- !ifs-v1
SoName: somelib.so
IfsVersion: 3.0
Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: little, BitWidth: 65 }
Symbols:
- { Name: foo, Type: Func }
- { Name: bar, Type: Object, Size: 42 }
- { Name: baz, Type: Object, Size: 8 }
- { Name: not, Type: Object, Size: 128, Undefined: true }
- { Name: nor, Type: Func, Undefined: true }
...

# CHECK: YAML:8:74: error: Unsupported bit width
17 changes: 17 additions & 0 deletions llvm/test/tools/llvm-ifs/read-ifs-with-bad-endianness.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## Test reading TBE file with bad endianness.

# RUN: not llvm-ifs --output-format=IFS --output=- %s 2>&1 | FileCheck %s

--- !ifs-v1
SoName: somelib.so
IfsVersion: 3.0
Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: lit, BitWidth: 64 }
Symbols:
- { Name: foo, Type: Func }
- { Name: bar, Type: Object, Size: 42 }
- { Name: baz, Type: Object, Size: 8 }
- { Name: not, Type: Object, Size: 128, Undefined: true }
- { Name: nor, Type: Func, Undefined: true }
...

# CHECK: YAML:8:56: error: Unsupported endianness
7 changes: 7 additions & 0 deletions llvm/test/tools/llvm-ifs/read-unsupported-file.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# RUN: not llvm-ifs --output-format=IFS --output=- %s 2>&1| FileCheck %s

This is just some text that cannot be read by llvm-ifs.

# CHECK: The file was not recognized as a valid object file
# CHECK: YAML failed reading as IFS
# CHECK: No file readers succeeded reading `{{.*}}` (unsupported/malformed file?)
27 changes: 27 additions & 0 deletions llvm/test/tools/llvm-ifs/strip-target.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
## Test writing tbe with stripped target information.

# RUN: llvm-ifs --input-format=ELF --output-format=IFS --strip-ifs-target --output=- %p/Inputs/sysv_hash.so | FileCheck %s --check-prefix=NOTARGET
# RUN: llvm-ifs --input-format=ELF --output-format=IFS --strip-ifs-arch --strip-ifs-endianness --strip-ifs-bitwidth --output=- %p/Inputs/sysv_hash.so | FileCheck %s --check-prefix=NOTARGET
# RUN: llvm-ifs --input-format=ELF --output-format=IFS --strip-ifs-arch --output=- %p/Inputs/sysv_hash.so | FileCheck %s -DELFTARGET="ObjectFormat: ELF, Endianness: little, BitWidth: 64" --check-prefix=CHECK
# RUN: llvm-ifs --input-format=ELF --output-format=IFS --strip-ifs-endianness --output=- %p/Inputs/sysv_hash.so | FileCheck %s -DELFTARGET="ObjectFormat: ELF, Arch: x86_64, BitWidth: 64" --check-prefix=CHECK
# RUN: llvm-ifs --input-format=ELF --output-format=IFS --strip-ifs-bitwidth --output=- %p/Inputs/sysv_hash.so | FileCheck %s -DELFTARGET="ObjectFormat: ELF, Arch: x86_64, Endianness: little" --check-prefix=CHECK


# CHECK: --- !ifs-v1
# CHECK-NEXT: IfsVersion: 3.0
# CHECK-NEXT: SoName: libsomething.so
# CHECK-NEXT: Target: { [[ELFTARGET]] }
# CHECK-NEXT: NeededLibs:
# CHECK-NEXT: - libm.so.6
# CHECK-NEXT: - libc.so.6
# CHECK-NEXT: - ld-linux-x86-64.so.2
# CHECK-NEXT: Symbols:

# NOTARGET: --- !ifs-v1
# NOTARGET-NEXT: IfsVersion: 3.0
# NOTARGET-NEXT: SoName: libsomething.so
# NOTARGET-NEXT: NeededLibs:
# NOTARGET-NEXT: - libm.so.6
# NOTARGET-NEXT: - libc.so.6
# NOTARGET-NEXT: - ld-linux-x86-64.so.2
# NOTARGET-NEXT: Symbols:
16 changes: 7 additions & 9 deletions llvm/test/tools/llvm-ifs/strong.ifs
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
# RUN: llvm-ifs -action write-ifs -o - %s %S/strong.ifs | FileCheck %s --check-prefixes=CHECK-IFS
# RUN: llvm-ifs --input-format=IFS --output-format=IFS -o - %s %S/strong.ifs | FileCheck %s --check-prefixes=CHECK-IFS

# CHECK-IFS: --- !experimental-ifs-v2
# CHECK-IFS-NEXT: IfsVersion: 2.0
# CHECK-IFS-NEXT: Triple: x86_64-unknown-linux-gnu
# CHECK-IFS-NEXT: ObjectFileFormat: ELF
# CHECK-IFS: --- !ifs-v1
# CHECK-IFS-NEXT: IfsVersion: 3.0
# CHECK-IFS-NEXT: Target: x86_64-unknown-linux-gnu
# CHECK-IFS-NEXT: Symbols:
# CHECK-IFS-DAG: - { Name: _Z8weakFuncv, Type: Func }
# CHECK-IFS: ...

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
--- !ifs-v1
IfsVersion: 3.0
Target: x86_64-unknown-linux-gnu
Symbols:
- { Name: _Z8weakFuncv, Type: Func }
...
9 changes: 4 additions & 5 deletions llvm/test/tools/llvm-ifs/tvos-tbd.ifs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# RUN: llvm-ifs --action write-bin -o - %s | FileCheck %s
# RUN: llvm-ifs --input-format=IFS --output-format=TBD -o - %s | FileCheck %s

# CHECK: --- !tapi-tbd-v3
# CHECK-NEXT: archs: [ arm64 ]
Expand All @@ -13,10 +13,9 @@
# CHECK-NEXT: symbols: [ __Z3fooi ]
# CHECK-NEXT: ...

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: arm64-apple-tvos
ObjectFileFormat: TBD
--- !ifs-v1
IfsVersion: 3.0
Target: arm64-apple-tvos
Symbols:
- { Name: __Z3fooi, Type: Func }
...
9 changes: 4 additions & 5 deletions llvm/test/tools/llvm-ifs/version-ok.ifs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# RUN: llvm-ifs -action write-ifs -o - %s %S/object.ifs
# RUN: llvm-ifs --input-format=IFS --output-format=IFS -o - %s %S/object.ifs

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
--- !ifs-v1
IfsVersion: 3.0
Target: x86_64-unknown-linux-gnu
Symbols:
- { Name: a, Type: Func }
...
9 changes: 4 additions & 5 deletions llvm/test/tools/llvm-ifs/watchos-tbd.ifs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# RUN: llvm-ifs --action write-bin -o - %s | FileCheck %s
# RUN: llvm-ifs --input-format=IFS --output-format=TBD -o - %s | FileCheck %s

# CHECK: --- !tapi-tbd-v3
# CHECK-NEXT: archs: [ arm64 ]
Expand All @@ -13,10 +13,9 @@
# CHECK-NEXT: symbols: [ __Z3fooi ]
# CHECK-NEXT: ...

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: arm64-apple-watchos
ObjectFileFormat: TBD
--- !ifs-v1
IfsVersion: 3.0
Target: arm64-apple-watchos
Symbols:
- { Name: __Z3fooi, Type: Func }
...
11 changes: 5 additions & 6 deletions llvm/test/tools/llvm-ifs/weak-mismatch.ifs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# RUN: not llvm-ifs -action write-ifs -o - %s %S/Inputs/strong-mismatch-size.ifs 2>&1 | FileCheck %s --check-prefixes=CHECK-SIZE
# RUN: not llvm-ifs -action write-ifs -o - %s %S/Inputs/strong-mismatch-type.ifs 2>&1 | FileCheck %s --check-prefixes=CHECK-TYPE
# RUN: not llvm-ifs --input-format=IFS --output-format=IFS -o - %s %S/Inputs/strong-mismatch-size.ifs 2>&1 | FileCheck %s --check-prefixes=CHECK-SIZE
# RUN: not llvm-ifs --input-format=IFS --output-format=IFS -o - %s %S/Inputs/strong-mismatch-type.ifs 2>&1 | FileCheck %s --check-prefixes=CHECK-TYPE

# CHECK-SIZE: error: Interface Stub: Size Mismatch for foobar.
# CHECK-SIZE-NEXT: Filename:
Expand All @@ -10,10 +10,9 @@
# CHECK-TYPE-NEXT: Filename:
# CHECK-TYPE-NEXT: Type Values: Object Func

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
--- !ifs-v1
IfsVersion: 3.0
Target: x86_64-unknown-linux-gnu
Symbols:
- { Name: foobar, Type: Object, Size: 1, Weak: true }
...
16 changes: 7 additions & 9 deletions llvm/test/tools/llvm-ifs/weak.ifs
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
# RUN: llvm-ifs -action write-ifs -o - %s | FileCheck %s --check-prefixes=CHECK-IFS
# RUN: llvm-ifs --input-format=IFS --output-format=IFS -o - %s | FileCheck %s --check-prefixes=CHECK-IFS

# CHECK-IFS: --- !experimental-ifs-v2
# CHECK-IFS-NEXT: IfsVersion: 2.0
# CHECK-IFS-NEXT: Triple: x86_64-unknown-linux-gnu
# CHECK-IFS-NEXT: ObjectFileFormat: ELF
# CHECK-IFS: --- !ifs-v1
# CHECK-IFS-NEXT: IfsVersion: 3.0
# CHECK-IFS-NEXT: Target: x86_64-unknown-linux-gnu
# CHECK-IFS-NEXT: Symbols:
# CHECK-IFS-DAG: - { Name: _Z8weakFuncv, Type: Func, Weak: true }
# CHECK-IFS-DAG: - { Name: _Z10strongFuncv, Type: Func }
# CHECK-IFS: ...

--- !experimental-ifs-v2
IfsVersion: 2.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
--- !ifs-v1
IfsVersion: 3.0
Target: x86_64-unknown-linux-gnu
Symbols:
- { Name: _Z8weakFuncv, Type: Func, Weak: true }
- { Name: _Z10strongFuncv, Type: Func }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
## Test writing stub elf when symbol table contains no non-local symbol.

# RUN: llvm-elfabi %s --output-target=elf64-little %t
# RUN: llvm-ifs --output-format=ELF --output=%t %s
# RUN: llvm-readobj -S %t | FileCheck %s -DCLASS="64-bit (0x2)" -DDE="LittleEndian (0x1)" -DHS=64 -DPHES=56 -DSHES=64 -DDYNSYMAL=8 -DDYNSYMES=24 -DDYNAMICAL=8 -DDYNAMICES=16 -DDYNTABZ=000000000

--- !tapi-tbe
TbeVersion: 1.0
Arch: x86_64
--- !ifs-v1
IfsVersion: 3.0
Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: little, BitWidth: 64 }
NeededLibs:
- libc.so.6
Symbols: {}
Symbols: []
...

# CHECK: Section {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,44 @@
## Test writing stub elf with minimal sections.

# RUN: llvm-elfabi %s --output-target=elf32-little %t.elf32l
# RUN: llvm-ifs --output-format=ELF --output=%t.elf32l --arch=x86_64 --bitwidth=32 --endianness=little %s
# RUN: llvm-readobj -h -S --string-dump .dynstr --string-dump .shstrtab --dyn-symbols --dynamic-table %t.elf32l | FileCheck %s -DCLASS="32-bit (0x1)" -DDE="LittleEndian (0x1)" -DHS=52 -DPHES=32 -DSHES=40 -DDYNSYMAL=4 -DDYNSYMES=16 -DDYNAMICAL=4 -DDYNAMICES=8 -DDYNTABZ=0

# RUN: llvm-elfabi %s --output-target=elf32-big %t.elf32b
# RUN: llvm-ifs --output-format=ELF --output=%t.elf32b --arch=x86_64 --bitwidth=32 --endianness=big %s
# RUN: llvm-readobj -h -S --string-dump .dynstr --string-dump .shstrtab --dyn-symbols --dynamic-table %t.elf32b | FileCheck %s -DCLASS="32-bit (0x1)" -DDE="BigEndian (0x2)" -DHS=52 -DPHES=32 -DSHES=40 -DDYNSYMAL=4 -DDYNSYMES=16 -DDYNAMICAL=4 -DDYNAMICES=8 -DDYNTABZ=0

# RUN: llvm-elfabi %s --output-target=elf64-little %t.elf64l
# RUN: llvm-ifs --output-format=ELF --output=%t.elf64l --arch=x86_64 --bitwidth=64 --endianness=little %s
# RUN: llvm-readobj -h -S --string-dump .dynstr --string-dump .shstrtab --dyn-symbols --dynamic-table %t.elf64l | FileCheck %s -DCLASS="64-bit (0x2)" -DDE="LittleEndian (0x1)" -DHS=64 -DPHES=56 -DSHES=64 -DDYNSYMAL=8 -DDYNSYMES=24 -DDYNAMICAL=8 -DDYNAMICES=16 -DDYNTABZ=000000000

# RUN: llvm-elfabi %s --output-target=elf64-big %t.elf64b
# RUN: llvm-ifs --output-format=ELF --output=%t.elf64l --target=x86_64-linux-gnu %s
# RUN: llvm-readobj -h -S --string-dump .dynstr --string-dump .shstrtab --dyn-symbols --dynamic-table %t.elf64l | FileCheck %s -DCLASS="64-bit (0x2)" -DDE="LittleEndian (0x1)" -DHS=64 -DPHES=56 -DSHES=64 -DDYNSYMAL=8 -DDYNSYMES=24 -DDYNAMICAL=8 -DDYNAMICES=16 -DDYNTABZ=000000000

# RUN: llvm-ifs --output-format=ELF --output=%t.elf64b --arch=x86_64 --bitwidth=64 --endianness=big %s
# RUN: llvm-readobj -h -S --string-dump .dynstr --string-dump .shstrtab --dyn-symbols --dynamic-table %t.elf64b | FileCheck %s -DCLASS="64-bit (0x2)" -DDE="BigEndian (0x2)" -DHS=64 -DPHES=56 -DSHES=64 -DDYNSYMAL=8 -DDYNSYMES=24 -DDYNAMICAL=8 -DDYNAMICES=16 -DDYNTABZ=000000000

--- !tapi-tbe
TbeVersion: 1.0
Arch: x86_64
# RUN: not llvm-ifs --output-format=ELF --output=%t --arch=x86_64 --bitwidth=64 --endianness=big --target=x86_64-linux-gnu %s 2>&1 | FileCheck %s --check-prefix=TRIPLEERR

# RUN: not llvm-ifs --output-format=ELF --output=%t --bitwidth=64 --endianness=big %s 2>&1 | FileCheck %s -DMSG="Arch" --check-prefix=TARGETERR

# RUN: not llvm-ifs --output-format=ELF --output=%t --arch=x86_64 --endianness=big %s 2>&1 | FileCheck %s -DMSG="BitWidth" --check-prefix=TARGETERR

# RUN: not llvm-ifs --output-format=ELF --output=%t --arch=x86_64 --bitwidth=64 %s 2>&1 | FileCheck %s -DMSG="Endianness" --check-prefix=TARGETERR

# RUN: llvm-ifs --output-format=IFS --output=%t.target --target=x86_64-linux-gnu %s
# RUN: not llvm-ifs --output-format=ELF --output=%t --target=aarch64-linux-gnu %t.target 2>&1 | FileCheck %s -DMSG="Triple" --check-prefix=CONFLICTERR

# RUN: llvm-ifs --output-format=IFS --output=%t.target --arch=x86_64 --endianness=little --bitwidth=64 %s
# RUN: not llvm-ifs --output-format=ELF --output=%t --arch=AArch64 %t.target 2>&1 | FileCheck %s -DMSG=Arch --check-prefix=CONFLICTERR
# RUN: not llvm-ifs --output-format=ELF --output=%t --endianness=big %t.target 2>&1 | FileCheck %s -DMSG=Endianness --check-prefix=CONFLICTERR
# RUN: not llvm-ifs --output-format=ELF --output=%t --bitwidth=32 %t.target 2>&1 | FileCheck %s -DMSG=BitWidth --check-prefix=CONFLICTERR

--- !ifs-v1
IfsVersion: 3.0
NeededLibs:
- libc.so.6
Symbols:
bar: { Type: Object, Size: 42 }
baz: { Type: TLS, Size: 3 }
plus: { Type: Func }
- { Name: bar, Type: Object, Size: 42 }
- { Name: baz, Type: TLS, Size: 3 }
- { Name: plus, Type: Func }
...

# CHECK: ElfHeader {
Expand Down Expand Up @@ -175,3 +193,7 @@ Symbols:
# CHECK-NEXT: [ 9] .dynsym
# CHECK-NEXT: [ 11] .dynamic
# CHECK-NEXT: [ 1a] .shstrtab

# TRIPLEERR: error: Target triple cannot be used simultaneously with ELF target format
# TARGETERR: error: [[MSG]] is not defined in the text stub
# CONFLICTERR: error: Supplied [[MSG]] conflicts with the text stub
11 changes: 0 additions & 11 deletions llvm/tools/llvm-elfabi/CMakeLists.txt

This file was deleted.

Loading