mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[elfabi] Prepare elfabi/ifs merging.
This change implements unified text stub format and command line interface proposed in the elfabi/ifs merge plan. Differential Revision: https://reviews.llvm.org/D99399
This commit is contained in:
parent
6713c55c41
commit
db5e2f303b
@ -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 {
|
||||
@ -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
|
||||
|
||||
|
@ -35,11 +35,10 @@ Expected<std::unique_ptr<ELFStub>> readELFFile(MemoryBufferRef Buf);
|
||||
///
|
||||
/// @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);
|
||||
bool WriteIfChanged = false);
|
||||
|
||||
} // end namespace elfabi
|
||||
} // end namespace llvm
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define LLVM_INTERFACESTUB_ELFSTUB_H
|
||||
|
||||
#include "llvm/BinaryFormat/ELF.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/VersionTuple.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
@ -34,8 +35,25 @@ enum class ELFSymbolType {
|
||||
Unknown = 16,
|
||||
};
|
||||
|
||||
enum class ELFEndiannessType {
|
||||
Little = ELF::ELFDATA2LSB,
|
||||
Big = ELF::ELFDATA2MSB,
|
||||
|
||||
// Endianness info is 1 bytes, 256 is safely out of rance.
|
||||
Unknown = 256,
|
||||
};
|
||||
|
||||
enum class ELFBitWidthType {
|
||||
ELF32 = ELF::ELFCLASS32,
|
||||
ELF64 = ELF::ELFCLASS64,
|
||||
|
||||
// Bit width info is 1 bytes, 256 is safely out of rance.
|
||||
Unknown = 256,
|
||||
};
|
||||
|
||||
struct ELFSymbol {
|
||||
ELFSymbol(std::string SymbolName) : Name(SymbolName) {}
|
||||
ELFSymbol() = default;
|
||||
explicit ELFSymbol(std::string SymbolName) : Name(std::move(SymbolName)) {}
|
||||
std::string Name;
|
||||
uint64_t Size;
|
||||
ELFSymbolType Type;
|
||||
@ -45,21 +63,42 @@ struct ELFSymbol {
|
||||
bool operator<(const ELFSymbol &RHS) const { return Name < RHS.Name; }
|
||||
};
|
||||
|
||||
struct IFSTarget {
|
||||
Optional<std::string> Triple;
|
||||
Optional<std::string> ObjectFormat;
|
||||
Optional<ELFArch> Arch;
|
||||
Optional<std::string> ArchString;
|
||||
Optional<ELFEndiannessType> Endianness;
|
||||
Optional<ELFBitWidthType> BitWidth;
|
||||
};
|
||||
|
||||
// A cumulative representation of ELF stubs.
|
||||
// Both textual and binary stubs will read into and write from this object.
|
||||
class ELFStub {
|
||||
struct ELFStub {
|
||||
// TODO: Add support for symbol versioning.
|
||||
public:
|
||||
VersionTuple TbeVersion;
|
||||
Optional<std::string> SoName;
|
||||
ELFArch Arch;
|
||||
IFSTarget Target;
|
||||
std::vector<std::string> NeededLibs;
|
||||
std::set<ELFSymbol> Symbols;
|
||||
std::vector<ELFSymbol> Symbols;
|
||||
|
||||
ELFStub() {}
|
||||
ELFStub(const ELFStub &Stub);
|
||||
ELFStub(ELFStub &&Stub);
|
||||
};
|
||||
|
||||
// Create a alias class for ELFStub.
|
||||
// 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 ELFStubTriple : ELFStub {
|
||||
ELFStubTriple() {}
|
||||
ELFStubTriple(const ELFStub &Stub);
|
||||
ELFStubTriple(const ELFStubTriple &Stub);
|
||||
ELFStubTriple(ELFStubTriple &&Stub);
|
||||
};
|
||||
|
||||
} // end namespace elfabi
|
||||
} // end namespace llvm
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#ifndef LLVM_INTERFACESTUB_TBEHANDLER_H
|
||||
#define LLVM_INTERFACESTUB_TBEHANDLER_H
|
||||
|
||||
#include "ELFStub.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/VersionTuple.h"
|
||||
#include <memory>
|
||||
@ -27,7 +28,7 @@ class StringRef;
|
||||
|
||||
namespace elfabi {
|
||||
|
||||
class ELFStub;
|
||||
struct ELFStub;
|
||||
|
||||
const VersionTuple TBEVersionCurrent(1, 0);
|
||||
|
||||
@ -37,6 +38,22 @@ Expected<std::unique_ptr<ELFStub>> readTBEFromBuffer(StringRef Buf);
|
||||
/// Attempts to write an ELF interface file to a raw_ostream.
|
||||
Error writeTBEToOutputStream(raw_ostream &OS, const ELFStub &Stub);
|
||||
|
||||
/// Override the target platform inforation in the text stub.
|
||||
Error overrideTBETarget(ELFStub &Stub, Optional<ELFArch> OverrideArch,
|
||||
Optional<ELFEndiannessType> OverrideEndianness,
|
||||
Optional<ELFBitWidthType> OverrideBitWidth,
|
||||
Optional<std::string> OverrideTriple);
|
||||
|
||||
/// Validate the target platform inforation in the text stub.
|
||||
Error validateTBETarget(ELFStub &Stub, bool ParseTriple);
|
||||
|
||||
/// Strips target platform information from the text stub.
|
||||
void stripTBETarget(ELFStub &Stub, bool StripTriple, bool StripArch,
|
||||
bool StripEndianness, bool StripBitWidth);
|
||||
|
||||
/// Parse llvm triple string into a IFSTarget struct.
|
||||
IFSTarget parseTriple(StringRef TripleStr);
|
||||
|
||||
} // end namespace elfabi
|
||||
} // end namespace llvm
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
add_llvm_component_library(LLVMBinaryFormat
|
||||
AMDGPUMetadataVerifier.cpp
|
||||
Dwarf.cpp
|
||||
ELF.cpp
|
||||
MachO.cpp
|
||||
Magic.cpp
|
||||
Minidump.cpp
|
||||
|
568
lib/BinaryFormat/ELF.cpp
Normal file
568
lib/BinaryFormat/ELF.cpp
Normal file
@ -0,0 +1,568 @@
|
||||
//===- llvm/BinaryFormat/ELF.cpp - The ELF format ---------------*- 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/BinaryFormat/ELF.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace ELF;
|
||||
|
||||
/// Convert an architecture name into ELF's e_machine value.
|
||||
uint16_t ELF::convertArchNameToEMachine(StringRef Arch) {
|
||||
std::string LowerArch = Arch.lower();
|
||||
return StringSwitch<uint16_t>(LowerArch)
|
||||
.Case("none", EM_NONE)
|
||||
.Case("m32", EM_M32)
|
||||
.Case("sparc", EM_SPARC)
|
||||
.Case("386", EM_386)
|
||||
.Case("68k", EM_68K)
|
||||
.Case("88k", EM_88K)
|
||||
.Case("iamcu", EM_IAMCU)
|
||||
.Case("860", EM_860)
|
||||
.Case("mips", EM_MIPS)
|
||||
.Case("s370", EM_S370)
|
||||
.Case("mips_rs3_le", EM_MIPS_RS3_LE)
|
||||
.Case("parisc", EM_PARISC)
|
||||
.Case("vpp500", EM_VPP500)
|
||||
.Case("sparc32plus", EM_SPARC32PLUS)
|
||||
.Case("960", EM_960)
|
||||
.Case("ppc", EM_PPC)
|
||||
.Case("ppc64", EM_PPC64)
|
||||
.Case("s390", EM_S390)
|
||||
.Case("spu", EM_SPU)
|
||||
.Case("v800", EM_V800)
|
||||
.Case("fr20", EM_FR20)
|
||||
.Case("rh32", EM_RH32)
|
||||
.Case("rce", EM_RCE)
|
||||
.Case("arm", EM_ARM)
|
||||
.Case("alpha", EM_ALPHA)
|
||||
.Case("sh", EM_SH)
|
||||
.Case("sparcv9", EM_SPARCV9)
|
||||
.Case("tricore", EM_TRICORE)
|
||||
.Case("arc", EM_ARC)
|
||||
.Case("h8_300", EM_H8_300)
|
||||
.Case("h8_300h", EM_H8_300H)
|
||||
.Case("h8s", EM_H8S)
|
||||
.Case("h8_500", EM_H8_500)
|
||||
.Case("ia_64", EM_IA_64)
|
||||
.Case("mips_x", EM_MIPS_X)
|
||||
.Case("coldfire", EM_COLDFIRE)
|
||||
.Case("68hc12", EM_68HC12)
|
||||
.Case("mma", EM_MMA)
|
||||
.Case("pcp", EM_PCP)
|
||||
.Case("ncpu", EM_NCPU)
|
||||
.Case("ndr1", EM_NDR1)
|
||||
.Case("starcore", EM_STARCORE)
|
||||
.Case("me16", EM_ME16)
|
||||
.Case("st100", EM_ST100)
|
||||
.Case("tinyj", EM_TINYJ)
|
||||
.Case("x86_64", EM_X86_64)
|
||||
.Case("pdsp", EM_PDSP)
|
||||
.Case("pdp10", EM_PDP10)
|
||||
.Case("pdp11", EM_PDP11)
|
||||
.Case("fx66", EM_FX66)
|
||||
.Case("st9plus", EM_ST9PLUS)
|
||||
.Case("st7", EM_ST7)
|
||||
.Case("68hc16", EM_68HC16)
|
||||
.Case("68hc11", EM_68HC11)
|
||||
.Case("68hc08", EM_68HC08)
|
||||
.Case("68hc05", EM_68HC05)
|
||||
.Case("svx", EM_SVX)
|
||||
.Case("st19", EM_ST19)
|
||||
.Case("vax", EM_VAX)
|
||||
.Case("cris", EM_CRIS)
|
||||
.Case("javelin", EM_JAVELIN)
|
||||
.Case("firepath", EM_FIREPATH)
|
||||
.Case("zsp", EM_ZSP)
|
||||
.Case("mmix", EM_MMIX)
|
||||
.Case("huany", EM_HUANY)
|
||||
.Case("prism", EM_PRISM)
|
||||
.Case("avr", EM_AVR)
|
||||
.Case("fr30", EM_FR30)
|
||||
.Case("d10v", EM_D10V)
|
||||
.Case("d30v", EM_D30V)
|
||||
.Case("v850", EM_V850)
|
||||
.Case("m32r", EM_M32R)
|
||||
.Case("mn10300", EM_MN10300)
|
||||
.Case("mn10200", EM_MN10200)
|
||||
.Case("pj", EM_PJ)
|
||||
.Case("openrisc", EM_OPENRISC)
|
||||
.Case("arc_compact", EM_ARC_COMPACT)
|
||||
.Case("xtensa", EM_XTENSA)
|
||||
.Case("videocore", EM_VIDEOCORE)
|
||||
.Case("tmm_gpp", EM_TMM_GPP)
|
||||
.Case("ns32k", EM_NS32K)
|
||||
.Case("tpc", EM_TPC)
|
||||
.Case("snp1k", EM_SNP1K)
|
||||
.Case("st200", EM_ST200)
|
||||
.Case("ip2k", EM_IP2K)
|
||||
.Case("max", EM_MAX)
|
||||
.Case("cr", EM_CR)
|
||||
.Case("f2mc16", EM_F2MC16)
|
||||
.Case("msp430", EM_MSP430)
|
||||
.Case("blackfin", EM_BLACKFIN)
|
||||
.Case("se_c33", EM_SE_C33)
|
||||
.Case("sep", EM_SEP)
|
||||
.Case("arca", EM_ARCA)
|
||||
.Case("unicore", EM_UNICORE)
|
||||
.Case("excess", EM_EXCESS)
|
||||
.Case("dxp", EM_DXP)
|
||||
.Case("altera_nios2", EM_ALTERA_NIOS2)
|
||||
.Case("crx", EM_CRX)
|
||||
.Case("xgate", EM_XGATE)
|
||||
.Case("c166", EM_C166)
|
||||
.Case("m16c", EM_M16C)
|
||||
.Case("dspic30f", EM_DSPIC30F)
|
||||
.Case("ce", EM_CE)
|
||||
.Case("m32c", EM_M32C)
|
||||
.Case("tsk3000", EM_TSK3000)
|
||||
.Case("rs08", EM_RS08)
|
||||
.Case("sharc", EM_SHARC)
|
||||
.Case("ecog2", EM_ECOG2)
|
||||
.Case("score7", EM_SCORE7)
|
||||
.Case("dsp24", EM_DSP24)
|
||||
.Case("videocore3", EM_VIDEOCORE3)
|
||||
.Case("latticemico32", EM_LATTICEMICO32)
|
||||
.Case("se_c17", EM_SE_C17)
|
||||
.Case("ti_c6000", EM_TI_C6000)
|
||||
.Case("ti_c2000", EM_TI_C2000)
|
||||
.Case("ti_c5500", EM_TI_C5500)
|
||||
.Case("mmdsp_plus", EM_MMDSP_PLUS)
|
||||
.Case("cypress_m8c", EM_CYPRESS_M8C)
|
||||
.Case("r32c", EM_R32C)
|
||||
.Case("trimedia", EM_TRIMEDIA)
|
||||
.Case("hexagon", EM_HEXAGON)
|
||||
.Case("8051", EM_8051)
|
||||
.Case("stxp7x", EM_STXP7X)
|
||||
.Case("nds32", EM_NDS32)
|
||||
.Case("ecog1", EM_ECOG1)
|
||||
.Case("ecog1x", EM_ECOG1X)
|
||||
.Case("maxq30", EM_MAXQ30)
|
||||
.Case("ximo16", EM_XIMO16)
|
||||
.Case("manik", EM_MANIK)
|
||||
.Case("craynv2", EM_CRAYNV2)
|
||||
.Case("rx", EM_RX)
|
||||
.Case("metag", EM_METAG)
|
||||
.Case("mcst_elbrus", EM_MCST_ELBRUS)
|
||||
.Case("ecog16", EM_ECOG16)
|
||||
.Case("cr16", EM_CR16)
|
||||
.Case("etpu", EM_ETPU)
|
||||
.Case("sle9x", EM_SLE9X)
|
||||
.Case("l10m", EM_L10M)
|
||||
.Case("k10m", EM_K10M)
|
||||
.Case("aarch64", EM_AARCH64)
|
||||
.Case("avr32", EM_AVR32)
|
||||
.Case("stm8", EM_STM8)
|
||||
.Case("tile64", EM_TILE64)
|
||||
.Case("tilepro", EM_TILEPRO)
|
||||
.Case("cuda", EM_CUDA)
|
||||
.Case("tilegx", EM_TILEGX)
|
||||
.Case("cloudshield", EM_CLOUDSHIELD)
|
||||
.Case("corea_1st", EM_COREA_1ST)
|
||||
.Case("corea_2nd", EM_COREA_2ND)
|
||||
.Case("arc_compact2", EM_ARC_COMPACT2)
|
||||
.Case("open8", EM_OPEN8)
|
||||
.Case("rl78", EM_RL78)
|
||||
.Case("videocore5", EM_VIDEOCORE5)
|
||||
.Case("78kor", EM_78KOR)
|
||||
.Case("56800ex", EM_56800EX)
|
||||
.Case("ba1", EM_BA1)
|
||||
.Case("ba2", EM_BA2)
|
||||
.Case("xcore", EM_XCORE)
|
||||
.Case("mchp_pic", EM_MCHP_PIC)
|
||||
.Case("intel205", EM_INTEL205)
|
||||
.Case("intel206", EM_INTEL206)
|
||||
.Case("intel207", EM_INTEL207)
|
||||
.Case("intel208", EM_INTEL208)
|
||||
.Case("intel209", EM_INTEL209)
|
||||
.Case("km32", EM_KM32)
|
||||
.Case("kmx32", EM_KMX32)
|
||||
.Case("kmx16", EM_KMX16)
|
||||
.Case("kmx8", EM_KMX8)
|
||||
.Case("kvarc", EM_KVARC)
|
||||
.Case("cdp", EM_CDP)
|
||||
.Case("coge", EM_COGE)
|
||||
.Case("cool", EM_COOL)
|
||||
.Case("norc", EM_NORC)
|
||||
.Case("csr_kalimba", EM_CSR_KALIMBA)
|
||||
.Case("amdgpu", EM_AMDGPU)
|
||||
.Case("riscv", EM_RISCV)
|
||||
.Case("lanai", EM_LANAI)
|
||||
.Case("bpf", EM_BPF)
|
||||
.Case("ve", EM_VE)
|
||||
.Case("csky", EM_CSKY)
|
||||
.Default(EM_NONE);
|
||||
}
|
||||
|
||||
/// Convert an ELF's e_machine value into an architecture name.
|
||||
StringRef ELF::convertEMachineToArchName(uint16_t EMachine) {
|
||||
switch (EMachine) {
|
||||
case EM_NONE:
|
||||
return "None";
|
||||
case EM_M32:
|
||||
return "m32";
|
||||
case EM_SPARC:
|
||||
return "sparc";
|
||||
case EM_386:
|
||||
return "386";
|
||||
case EM_68K:
|
||||
return "68k";
|
||||
case EM_88K:
|
||||
return "88k";
|
||||
case EM_IAMCU:
|
||||
return "iamcu";
|
||||
case EM_860:
|
||||
return "860";
|
||||
case EM_MIPS:
|
||||
return "mips";
|
||||
case EM_S370:
|
||||
return "s370";
|
||||
case EM_MIPS_RS3_LE:
|
||||
return "mips_rs3_le";
|
||||
case EM_PARISC:
|
||||
return "parisc";
|
||||
case EM_VPP500:
|
||||
return "vpp500";
|
||||
case EM_SPARC32PLUS:
|
||||
return "sparc32plus";
|
||||
case EM_960:
|
||||
return "960";
|
||||
case EM_PPC:
|
||||
return "ppc";
|
||||
case EM_PPC64:
|
||||
return "ppc64";
|
||||
case EM_S390:
|
||||
return "s390";
|
||||
case EM_SPU:
|
||||
return "spu";
|
||||
case EM_V800:
|
||||
return "v800";
|
||||
case EM_FR20:
|
||||
return "fr20";
|
||||
case EM_RH32:
|
||||
return "rh32";
|
||||
case EM_RCE:
|
||||
return "rce";
|
||||
case EM_ARM:
|
||||
return "arm";
|
||||
case EM_ALPHA:
|
||||
return "alpha";
|
||||
case EM_SH:
|
||||
return "sh";
|
||||
case EM_SPARCV9:
|
||||
return "sparcv9";
|
||||
case EM_TRICORE:
|
||||
return "tricore";
|
||||
case EM_ARC:
|
||||
return "arc";
|
||||
case EM_H8_300:
|
||||
return "h8_300";
|
||||
case EM_H8_300H:
|
||||
return "h8_300h";
|
||||
case EM_H8S:
|
||||
return "h8s";
|
||||
case EM_H8_500:
|
||||
return "h8_500";
|
||||
case EM_IA_64:
|
||||
return "ia_64";
|
||||
case EM_MIPS_X:
|
||||
return "mips_x";
|
||||
case EM_COLDFIRE:
|
||||
return "coldfire";
|
||||
case EM_68HC12:
|
||||
return "68hc12";
|
||||
case EM_MMA:
|
||||
return "mma";
|
||||
case EM_PCP:
|
||||
return "pcp";
|
||||
case EM_NCPU:
|
||||
return "ncpu";
|
||||
case EM_NDR1:
|
||||
return "ndr1";
|
||||
case EM_STARCORE:
|
||||
return "starcore";
|
||||
case EM_ME16:
|
||||
return "me16";
|
||||
case EM_ST100:
|
||||
return "st100";
|
||||
case EM_TINYJ:
|
||||
return "tinyj";
|
||||
case EM_X86_64:
|
||||
return "x86_64";
|
||||
case EM_PDSP:
|
||||
return "pdsp";
|
||||
case EM_PDP10:
|
||||
return "pdp10";
|
||||
case EM_PDP11:
|
||||
return "pdp11";
|
||||
case EM_FX66:
|
||||
return "fx66";
|
||||
case EM_ST9PLUS:
|
||||
return "st9plus";
|
||||
case EM_ST7:
|
||||
return "st7";
|
||||
case EM_68HC16:
|
||||
return "68hc16";
|
||||
case EM_68HC11:
|
||||
return "68hc11";
|
||||
case EM_68HC08:
|
||||
return "68hc08";
|
||||
case EM_68HC05:
|
||||
return "68hc05";
|
||||
case EM_SVX:
|
||||
return "svx";
|
||||
case EM_ST19:
|
||||
return "st19";
|
||||
case EM_VAX:
|
||||
return "vax";
|
||||
case EM_CRIS:
|
||||
return "cris";
|
||||
case EM_JAVELIN:
|
||||
return "javelin";
|
||||
case EM_FIREPATH:
|
||||
return "firepath";
|
||||
case EM_ZSP:
|
||||
return "zsp";
|
||||
case EM_MMIX:
|
||||
return "mmix";
|
||||
case EM_HUANY:
|
||||
return "huany";
|
||||
case EM_PRISM:
|
||||
return "prism";
|
||||
case EM_AVR:
|
||||
return "avr";
|
||||
case EM_FR30:
|
||||
return "fr30";
|
||||
case EM_D10V:
|
||||
return "d10v";
|
||||
case EM_D30V:
|
||||
return "d30v";
|
||||
case EM_V850:
|
||||
return "v850";
|
||||
case EM_M32R:
|
||||
return "m32r";
|
||||
case EM_MN10300:
|
||||
return "mn10300";
|
||||
case EM_MN10200:
|
||||
return "mn10200";
|
||||
case EM_PJ:
|
||||
return "pj";
|
||||
case EM_OPENRISC:
|
||||
return "openrisc";
|
||||
case EM_ARC_COMPACT:
|
||||
return "arc_compact";
|
||||
case EM_XTENSA:
|
||||
return "xtensa";
|
||||
case EM_VIDEOCORE:
|
||||
return "videocore";
|
||||
case EM_TMM_GPP:
|
||||
return "tmm_gpp";
|
||||
case EM_NS32K:
|
||||
return "ns32k";
|
||||
case EM_TPC:
|
||||
return "tpc";
|
||||
case EM_SNP1K:
|
||||
return "snp1k";
|
||||
case EM_ST200:
|
||||
return "st200";
|
||||
case EM_IP2K:
|
||||
return "ip2k";
|
||||
case EM_MAX:
|
||||
return "max";
|
||||
case EM_CR:
|
||||
return "cr";
|
||||
case EM_F2MC16:
|
||||
return "f2mc16";
|
||||
case EM_MSP430:
|
||||
return "msp430";
|
||||
case EM_BLACKFIN:
|
||||
return "blackfin";
|
||||
case EM_SE_C33:
|
||||
return "se_c33";
|
||||
case EM_SEP:
|
||||
return "sep";
|
||||
case EM_ARCA:
|
||||
return "arca";
|
||||
case EM_UNICORE:
|
||||
return "unicore";
|
||||
case EM_EXCESS:
|
||||
return "excess";
|
||||
case EM_DXP:
|
||||
return "dxp";
|
||||
case EM_ALTERA_NIOS2:
|
||||
return "altera_nios2";
|
||||
case EM_CRX:
|
||||
return "crx";
|
||||
case EM_XGATE:
|
||||
return "xgate";
|
||||
case EM_C166:
|
||||
return "c166";
|
||||
case EM_M16C:
|
||||
return "m16c";
|
||||
case EM_DSPIC30F:
|
||||
return "dspic30f";
|
||||
case EM_CE:
|
||||
return "ce";
|
||||
case EM_M32C:
|
||||
return "m32c";
|
||||
case EM_TSK3000:
|
||||
return "tsk3000";
|
||||
case EM_RS08:
|
||||
return "rs08";
|
||||
case EM_SHARC:
|
||||
return "sharc";
|
||||
case EM_ECOG2:
|
||||
return "ecog2";
|
||||
case EM_SCORE7:
|
||||
return "score7";
|
||||
case EM_DSP24:
|
||||
return "dsp24";
|
||||
case EM_VIDEOCORE3:
|
||||
return "videocore3";
|
||||
case EM_LATTICEMICO32:
|
||||
return "latticemico32";
|
||||
case EM_SE_C17:
|
||||
return "se_c17";
|
||||
case EM_TI_C6000:
|
||||
return "ti_c6000";
|
||||
case EM_TI_C2000:
|
||||
return "ti_c2000";
|
||||
case EM_TI_C5500:
|
||||
return "ti_c5500";
|
||||
case EM_MMDSP_PLUS:
|
||||
return "mmdsp_plus";
|
||||
case EM_CYPRESS_M8C:
|
||||
return "cypress_m8c";
|
||||
case EM_R32C:
|
||||
return "r32c";
|
||||
case EM_TRIMEDIA:
|
||||
return "trimedia";
|
||||
case EM_HEXAGON:
|
||||
return "hexagon";
|
||||
case EM_8051:
|
||||
return "8051";
|
||||
case EM_STXP7X:
|
||||
return "stxp7x";
|
||||
case EM_NDS32:
|
||||
return "nds32";
|
||||
case EM_ECOG1:
|
||||
return "ecog1";
|
||||
case EM_MAXQ30:
|
||||
return "maxq30";
|
||||
case EM_XIMO16:
|
||||
return "ximo16";
|
||||
case EM_MANIK:
|
||||
return "manik";
|
||||
case EM_CRAYNV2:
|
||||
return "craynv2";
|
||||
case EM_RX:
|
||||
return "rx";
|
||||
case EM_METAG:
|
||||
return "metag";
|
||||
case EM_MCST_ELBRUS:
|
||||
return "mcst_elbrus";
|
||||
case EM_ECOG16:
|
||||
return "ecog16";
|
||||
case EM_CR16:
|
||||
return "cr16";
|
||||
case EM_ETPU:
|
||||
return "etpu";
|
||||
case EM_SLE9X:
|
||||
return "sle9x";
|
||||
case EM_L10M:
|
||||
return "l10m";
|
||||
case EM_K10M:
|
||||
return "k10m";
|
||||
case EM_AARCH64:
|
||||
return "AArch64";
|
||||
case EM_AVR32:
|
||||
return "avr32";
|
||||
case EM_STM8:
|
||||
return "stm8";
|
||||
case EM_TILE64:
|
||||
return "tile64";
|
||||
case EM_TILEPRO:
|
||||
return "tilepro";
|
||||
case EM_CUDA:
|
||||
return "cuda";
|
||||
case EM_TILEGX:
|
||||
return "tilegx";
|
||||
case EM_CLOUDSHIELD:
|
||||
return "cloudshield";
|
||||
case EM_COREA_1ST:
|
||||
return "corea_1st";
|
||||
case EM_COREA_2ND:
|
||||
return "corea_2nd";
|
||||
case EM_ARC_COMPACT2:
|
||||
return "arc_compact2";
|
||||
case EM_OPEN8:
|
||||
return "open8";
|
||||
case EM_RL78:
|
||||
return "rl78";
|
||||
case EM_VIDEOCORE5:
|
||||
return "videocore5";
|
||||
case EM_78KOR:
|
||||
return "78kor";
|
||||
case EM_56800EX:
|
||||
return "56800ex";
|
||||
case EM_BA1:
|
||||
return "ba1";
|
||||
case EM_BA2:
|
||||
return "ba2";
|
||||
case EM_XCORE:
|
||||
return "xcore";
|
||||
case EM_MCHP_PIC:
|
||||
return "mchp_pic";
|
||||
case EM_INTEL205:
|
||||
return "intel205";
|
||||
case EM_INTEL206:
|
||||
return "intel206";
|
||||
case EM_INTEL207:
|
||||
return "intel207";
|
||||
case EM_INTEL208:
|
||||
return "intel208";
|
||||
case EM_INTEL209:
|
||||
return "intel209";
|
||||
case EM_KM32:
|
||||
return "km32";
|
||||
case EM_KMX32:
|
||||
return "kmx32";
|
||||
case EM_KMX16:
|
||||
return "kmx16";
|
||||
case EM_KMX8:
|
||||
return "kmx8";
|
||||
case EM_KVARC:
|
||||
return "kvarc";
|
||||
case EM_CDP:
|
||||
return "cdp";
|
||||
case EM_COGE:
|
||||
return "coge";
|
||||
case EM_COOL:
|
||||
return "cool";
|
||||
case EM_NORC:
|
||||
return "norc";
|
||||
case EM_CSR_KALIMBA:
|
||||
return "csr_kalimba";
|
||||
case EM_AMDGPU:
|
||||
return "amdgpu";
|
||||
case EM_RISCV:
|
||||
return "riscv";
|
||||
case EM_LANAI:
|
||||
return "lanai";
|
||||
case EM_BPF:
|
||||
return "bpf";
|
||||
case EM_VE:
|
||||
return "ve";
|
||||
case EM_CSKY:
|
||||
return "csky";
|
||||
default:
|
||||
return "None";
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ add_llvm_component_library(LLVMInterfaceStub
|
||||
TBEHandler.cpp
|
||||
|
||||
LINK_COMPONENTS
|
||||
BinaryFormat
|
||||
MC
|
||||
Object
|
||||
Support
|
||||
|
@ -250,7 +250,8 @@ public:
|
||||
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 =
|
||||
@ -517,7 +518,7 @@ static Error populateSymbols(ELFStub &TargetStub,
|
||||
if (!SymName)
|
||||
return SymName.takeError();
|
||||
ELFSymbol Sym = createELFSym<ELFT>(*SymName, RawSym);
|
||||
TargetStub.Symbols.insert(std::move(Sym));
|
||||
TargetStub.Symbols.push_back(std::move(Sym));
|
||||
// TODO: Populate symbol warning.
|
||||
}
|
||||
return Error::success();
|
||||
@ -561,7 +562,12 @@ buildStub(const ELFObjectFile<ELFT> &ElfObj) {
|
||||
DynEnt.StrSize);
|
||||
|
||||
// Populate Arch from ELF header.
|
||||
DestStub->Arch = ElfFile.getHeader().e_machine;
|
||||
DestStub->Target.Arch = static_cast<ELFArch>(ElfFile.getHeader().e_machine);
|
||||
DestStub->Target.BitWidth =
|
||||
(ELFBitWidthType)ElfFile.getHeader().e_ident[EI_CLASS];
|
||||
DestStub->Target.Endianness =
|
||||
(ELFEndiannessType)ElfFile.getHeader().e_ident[EI_DATA];
|
||||
DestStub->Target.ObjectFormat = "ELF";
|
||||
|
||||
// Populate SoName from .dynamic entries and dynamic string table.
|
||||
if (DynEnt.SONameOffset.hasValue()) {
|
||||
@ -667,15 +673,23 @@ 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);
|
||||
bool WriteIfChanged) {
|
||||
assert(Stub.Target.Arch);
|
||||
assert(Stub.Target.BitWidth);
|
||||
assert(Stub.Target.Endianness);
|
||||
if (Stub.Target.BitWidth == ELFBitWidthType::ELF32) {
|
||||
if (Stub.Target.Endianness == ELFEndiannessType::Little) {
|
||||
return writeELFBinaryToFile<ELF32LE>(FilePath, Stub, WriteIfChanged);
|
||||
} else {
|
||||
return writeELFBinaryToFile<ELF32BE>(FilePath, Stub, WriteIfChanged);
|
||||
}
|
||||
} else {
|
||||
if (Stub.Target.Endianness == ELFEndiannessType::Little) {
|
||||
return writeELFBinaryToFile<ELF64LE>(FilePath, Stub, WriteIfChanged);
|
||||
} else {
|
||||
return writeELFBinaryToFile<ELF64BE>(FilePath, Stub, WriteIfChanged);
|
||||
}
|
||||
}
|
||||
llvm_unreachable("invalid binary output target");
|
||||
}
|
||||
|
||||
|
@ -7,13 +7,14 @@
|
||||
//===-----------------------------------------------------------------------===/
|
||||
|
||||
#include "llvm/InterfaceStub/ELFStub.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::elfabi;
|
||||
|
||||
ELFStub::ELFStub(ELFStub const &Stub) {
|
||||
TbeVersion = Stub.TbeVersion;
|
||||
Arch = Stub.Arch;
|
||||
Target = Stub.Target;
|
||||
SoName = Stub.SoName;
|
||||
NeededLibs = Stub.NeededLibs;
|
||||
Symbols = Stub.Symbols;
|
||||
@ -21,7 +22,31 @@ ELFStub::ELFStub(ELFStub const &Stub) {
|
||||
|
||||
ELFStub::ELFStub(ELFStub &&Stub) {
|
||||
TbeVersion = std::move(Stub.TbeVersion);
|
||||
Arch = std::move(Stub.Arch);
|
||||
Target = std::move(Stub.Target);
|
||||
SoName = std::move(Stub.SoName);
|
||||
NeededLibs = std::move(Stub.NeededLibs);
|
||||
Symbols = std::move(Stub.Symbols);
|
||||
}
|
||||
|
||||
ELFStubTriple::ELFStubTriple(ELFStubTriple const &Stub) {
|
||||
TbeVersion = Stub.TbeVersion;
|
||||
Target = Stub.Target;
|
||||
SoName = Stub.SoName;
|
||||
NeededLibs = Stub.NeededLibs;
|
||||
Symbols = Stub.Symbols;
|
||||
}
|
||||
|
||||
ELFStubTriple::ELFStubTriple(ELFStub const &Stub) {
|
||||
TbeVersion = Stub.TbeVersion;
|
||||
Target = Stub.Target;
|
||||
SoName = Stub.SoName;
|
||||
NeededLibs = Stub.NeededLibs;
|
||||
Symbols = Stub.Symbols;
|
||||
}
|
||||
|
||||
ELFStubTriple::ELFStubTriple(ELFStubTriple &&Stub) {
|
||||
TbeVersion = std::move(Stub.TbeVersion);
|
||||
Target = std::move(Stub.Target);
|
||||
SoName = std::move(Stub.SoName);
|
||||
NeededLibs = std::move(Stub.NeededLibs);
|
||||
Symbols = std::move(Stub.Symbols);
|
||||
|
@ -9,14 +9,16 @@
|
||||
#include "llvm/InterfaceStub/TBEHandler.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/InterfaceStub/ELFStub.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/LineIterator.h"
|
||||
#include "llvm/Support/YAMLTraits.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::elfabi;
|
||||
|
||||
LLVM_YAML_STRONG_TYPEDEF(ELFArch, ELFArchMapper)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(ELFSymbol)
|
||||
|
||||
namespace llvm {
|
||||
namespace yaml {
|
||||
@ -35,43 +37,80 @@ template <> struct ScalarEnumerationTraits<ELFSymbolType> {
|
||||
}
|
||||
};
|
||||
|
||||
/// YAML traits for ELFArch.
|
||||
template <> struct ScalarTraits<ELFArchMapper> {
|
||||
static void output(const ELFArchMapper &Value, void *,
|
||||
template <> struct ScalarTraits<ELFEndiannessType> {
|
||||
static void output(const ELFEndiannessType &Value, void *,
|
||||
llvm::raw_ostream &Out) {
|
||||
// Map from integer to architecture string.
|
||||
switch (Value) {
|
||||
case (ELFArch)ELF::EM_X86_64:
|
||||
Out << "x86_64";
|
||||
case ELFEndiannessType::Big:
|
||||
Out << "big";
|
||||
break;
|
||||
case (ELFArch)ELF::EM_AARCH64:
|
||||
Out << "AArch64";
|
||||
case ELFEndiannessType::Little:
|
||||
Out << "little";
|
||||
break;
|
||||
case (ELFArch)ELF::EM_NONE:
|
||||
default:
|
||||
Out << "Unknown";
|
||||
llvm_unreachable("Unsupported endianness");
|
||||
}
|
||||
}
|
||||
|
||||
static StringRef input(StringRef Scalar, void *, ELFArchMapper &Value) {
|
||||
// Map from architecture string to integer.
|
||||
Value = StringSwitch<ELFArch>(Scalar)
|
||||
.Case("x86_64", ELF::EM_X86_64)
|
||||
.Case("AArch64", ELF::EM_AARCH64)
|
||||
.Case("Unknown", ELF::EM_NONE)
|
||||
.Default(ELF::EM_NONE);
|
||||
|
||||
// Returning empty StringRef indicates successful parse.
|
||||
static StringRef input(StringRef Scalar, void *, ELFEndiannessType &Value) {
|
||||
Value = StringSwitch<ELFEndiannessType>(Scalar)
|
||||
.Case("big", ELFEndiannessType::Big)
|
||||
.Case("little", ELFEndiannessType::Little)
|
||||
.Default(ELFEndiannessType::Unknown);
|
||||
if (Value == ELFEndiannessType::Unknown) {
|
||||
return "Unsupported endianness";
|
||||
}
|
||||
return StringRef();
|
||||
}
|
||||
|
||||
// Don't place quotation marks around architecture value.
|
||||
static QuotingType mustQuote(StringRef) { return QuotingType::None; }
|
||||
};
|
||||
|
||||
template <> struct ScalarTraits<ELFBitWidthType> {
|
||||
static void output(const ELFBitWidthType &Value, void *,
|
||||
llvm::raw_ostream &Out) {
|
||||
switch (Value) {
|
||||
case ELFBitWidthType::ELF32:
|
||||
Out << "32";
|
||||
break;
|
||||
case ELFBitWidthType::ELF64:
|
||||
Out << "64";
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unsupported bit width");
|
||||
}
|
||||
}
|
||||
|
||||
static StringRef input(StringRef Scalar, void *, ELFBitWidthType &Value) {
|
||||
Value = StringSwitch<ELFBitWidthType>(Scalar)
|
||||
.Case("32", ELFBitWidthType::ELF32)
|
||||
.Case("64", ELFBitWidthType::ELF64)
|
||||
.Default(ELFBitWidthType::Unknown);
|
||||
if (Value == ELFBitWidthType::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<ELFSymbol> {
|
||||
static void mapping(IO &IO, ELFSymbol &Symbol) {
|
||||
IO.mapRequired("Name", Symbol.Name);
|
||||
IO.mapRequired("Type", Symbol.Type);
|
||||
// The need for symbol size depends on the symbol type.
|
||||
if (Symbol.Type == ELFSymbolType::NoType) {
|
||||
@ -87,57 +126,203 @@ template <> struct MappingTraits<ELFSymbol> {
|
||||
}
|
||||
|
||||
// Compacts symbol information into a single line.
|
||||
static const bool flow = true;
|
||||
};
|
||||
|
||||
/// YAML traits for set of ELFSymbols.
|
||||
template <> struct CustomMappingTraits<std::set<ELFSymbol>> {
|
||||
static void inputOne(IO &IO, StringRef Key, std::set<ELFSymbol> &Set) {
|
||||
ELFSymbol Sym(Key.str());
|
||||
IO.mapRequired(Key.str().c_str(), Sym);
|
||||
Set.insert(Sym);
|
||||
}
|
||||
|
||||
static void output(IO &IO, std::set<ELFSymbol> &Set) {
|
||||
for (auto &Sym : Set)
|
||||
IO.mapRequired(Sym.Name.c_str(), const_cast<ELFSymbol &>(Sym));
|
||||
}
|
||||
static const bool flow = true; // NOLINT(readability-identifier-naming)
|
||||
};
|
||||
|
||||
/// YAML traits for ELFStub objects.
|
||||
template <> struct MappingTraits<ELFStub> {
|
||||
static void mapping(IO &IO, ELFStub &Stub) {
|
||||
if (!IO.mapTag("!tapi-tbe", true))
|
||||
if (!IO.mapTag("!ifs-v1", true))
|
||||
IO.setError("Not a .tbe YAML file.");
|
||||
IO.mapRequired("TbeVersion", Stub.TbeVersion);
|
||||
IO.mapOptional("SoName", Stub.SoName);
|
||||
IO.mapRequired("Arch", (ELFArchMapper &)Stub.Arch);
|
||||
IO.mapOptional("Target", Stub.Target);
|
||||
IO.mapOptional("NeededLibs", Stub.NeededLibs);
|
||||
IO.mapRequired("Symbols", Stub.Symbols);
|
||||
}
|
||||
};
|
||||
|
||||
/// YAML traits for ELFStubTriple objects.
|
||||
template <> struct MappingTraits<ELFStubTriple> {
|
||||
static void mapping(IO &IO, ELFStubTriple &Stub) {
|
||||
if (!IO.mapTag("!ifs-v1", true))
|
||||
IO.setError("Not a .tbe YAML file.");
|
||||
IO.mapRequired("TbeVersion", Stub.TbeVersion);
|
||||
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<ELFStub>> elfabi::readTBEFromBuffer(StringRef Buf) {
|
||||
yaml::Input YamlIn(Buf);
|
||||
std::unique_ptr<ELFStub> Stub(new ELFStub());
|
||||
YamlIn >> *Stub;
|
||||
if (std::error_code Err = YamlIn.error())
|
||||
std::unique_ptr<ELFStubTriple> Stub(new ELFStubTriple());
|
||||
if (usesTriple(Buf)) {
|
||||
YamlIn >> *Stub;
|
||||
} else {
|
||||
YamlIn >> *static_cast<ELFStub *>(Stub.get());
|
||||
}
|
||||
if (std::error_code Err = YamlIn.error()) {
|
||||
return createStringError(Err, "YAML failed reading as TBE");
|
||||
}
|
||||
|
||||
if (Stub->TbeVersion > elfabi::TBEVersionCurrent)
|
||||
return make_error<StringError>(
|
||||
"TBE version " + Stub->TbeVersion.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 elfabi::writeTBEToOutputStream(raw_ostream &OS, const ELFStub &Stub) {
|
||||
yaml::Output YamlOut(OS, NULL, /*WrapColumn =*/0);
|
||||
std::unique_ptr<ELFStubTriple> CopyStub(new ELFStubTriple(Stub));
|
||||
if (Stub.Target.Arch) {
|
||||
CopyStub->Target.ArchString = std::string(
|
||||
ELF::convertEMachineToArchName(Stub.Target.Arch.getValue()));
|
||||
}
|
||||
IFSTarget Target = Stub.Target;
|
||||
|
||||
YamlOut << const_cast<ELFStub &>(Stub);
|
||||
if (CopyStub->Target.Triple ||
|
||||
(!CopyStub->Target.ArchString && !CopyStub->Target.Endianness &&
|
||||
!CopyStub->Target.BitWidth))
|
||||
YamlOut << *CopyStub;
|
||||
else
|
||||
YamlOut << *static_cast<ELFStub *>(CopyStub.get());
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error elfabi::overrideTBETarget(ELFStub &Stub, Optional<ELFArch> OverrideArch,
|
||||
Optional<ELFEndiannessType> OverrideEndianness,
|
||||
Optional<ELFBitWidthType> 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 elfabi::validateTBETarget(ELFStub &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 elfabi::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 = (ELFArch)ELF::EM_AARCH64;
|
||||
break;
|
||||
case Triple::ArchType::x86_64:
|
||||
RetTarget.Arch = (ELFArch)ELF::EM_X86_64;
|
||||
break;
|
||||
default:
|
||||
RetTarget.Arch = (ELFArch)ELF::EM_NONE;
|
||||
}
|
||||
RetTarget.Endianness = IFSTriple.isLittleEndian() ? ELFEndiannessType::Little
|
||||
: ELFEndiannessType::Big;
|
||||
RetTarget.BitWidth =
|
||||
IFSTriple.isArch64Bit() ? ELFBitWidthType::ELF64 : ELFBitWidthType::ELF32;
|
||||
return RetTarget;
|
||||
}
|
||||
|
||||
void elfabi::stripTBETarget(ELFStub &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();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
# RUN: yaml2obj %s -o %t
|
||||
# RUN: llvm-elfabi --elf %t --emit-tbe=- --soname=best.so | FileCheck %s
|
||||
# RUN: llvm-elfabi --input-format=ELF --output-format=TBE --output=- --soname=best.so %t | FileCheck %s
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
@ -42,9 +42,9 @@ ProgramHeaders:
|
||||
FirstSec: .dynamic
|
||||
LastSec: .dynamic
|
||||
|
||||
# CHECK: --- !tapi-tbe
|
||||
# CHECK: --- !ifs-v1
|
||||
# CHECK-NEXT: TbeVersion: {{[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: ...
|
||||
|
@ -1,7 +1,8 @@
|
||||
# RUN: yaml2obj %s -o %t
|
||||
# RUN: llvm-elfabi --elf %t --emit-tbe=- | FileCheck %s
|
||||
# RUN: yaml2obj --docnum=1 %s -o %t
|
||||
# RUN: llvm-elfabi --input-format=ELF --output-format=TBE --output=- %t | FileCheck %s -DTARGET="{ ObjectFormat: ELF, Arch: x86_64, Endianness: little, BitWidth: 64 }"
|
||||
# RUN: llvm-elfabi --input-format=ELF --output-format=TBE --output=- --hint-ifs-target="x86_64-linux-gnu" %t | FileCheck %s -DTARGET="x86_64-linux-gnu"
|
||||
|
||||
!ELF
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
@ -42,8 +43,101 @@ ProgramHeaders:
|
||||
FirstSec: .dynamic
|
||||
LastSec: .dynamic
|
||||
|
||||
# CHECK: --- !tapi-tbe
|
||||
# CHECK: --- !ifs-v1
|
||||
# CHECK-NEXT: TbeVersion: {{[1-9]\d*\.(0|([1-9]\d*))}}
|
||||
# CHECK-NEXT: Arch: x86_64
|
||||
# CHECK-NEXT: Symbols: {}
|
||||
# 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-elfabi --input-format=ELF --output-format=TBE --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-elfabi --input-format=ELF --output-format=TBE --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-elfabi --input-format=ELF --output-format=TBE --output=%t.tbe --hint-ifs-target="x86_64-unknown-linux-gnu" %t 2>&1 | FileCheck %s -DMSG="bit width" --check-prefix=HINTERR
|
||||
|
@ -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-elfabi --input-format=ELF --output-format=TBE --output=%t.tbe %t 2>&1 | FileCheck %s
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
|
@ -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-elfabi --input-format=ELF --output-format=TBE --output=%t.tbe %t 2>&1 | FileCheck %s
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
|
@ -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-elfabi --input-format=ELF --output-format=TBE --output=%t.tbe %t 2>&1 | FileCheck %s
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
|
@ -1,5 +1,5 @@
|
||||
# RUN: yaml2obj %s -o %t
|
||||
# RUN: llvm-elfabi --elf %t --emit-tbe=- | FileCheck %s
|
||||
# RUN: llvm-elfabi --input-format=ELF --output-format=TBE --output=- %t | FileCheck %s
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
@ -48,4 +48,4 @@ ProgramHeaders:
|
||||
# CHECK: NeededLibs:
|
||||
# CHECK-NEXT: - libfoo.so{{$}}
|
||||
# CHECK-NEXT: - libbar.so{{$}}
|
||||
# CHECK-NEXT: Symbols: {}
|
||||
# CHECK-NEXT: Symbols: []
|
||||
|
@ -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-elfabi --input-format=ELF --output-format=TBE --output=%t.tbe %t 2>&1 | FileCheck %s
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
|
@ -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-elfabi --input-format=ELF --output-format=TBE --output=%t.tbe %t 2>&1 | FileCheck %s
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
|
@ -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-elfabi --input-format=ELF --output-format=TBE --output=%t.tbe %t 2>&1 | FileCheck %s
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
|
@ -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-elfabi --input-format=ELF --output-format=TBE --output=- %t | FileCheck %s --check-prefix=ORIGINAL
|
||||
# RUN: llvm-elfabi --input-format=ELF --output-format=TBE --soname=libbest.so --output=- %t | FileCheck %s --check-prefix=REPLACED
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
|
@ -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-elfabi --input-format=ELF --output-format=TBE --output=%t.tbe %t 2>&1 | FileCheck %s
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
|
@ -1,5 +1,5 @@
|
||||
# RUN: yaml2obj %s -o %t
|
||||
# RUN: llvm-elfabi --elf %t --emit-tbe=- | FileCheck %s
|
||||
# RUN: llvm-elfabi --input-format=ELF --output-format=TBE --output=- %t | FileCheck %s
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
@ -45,9 +45,9 @@ ProgramHeaders:
|
||||
FirstSec: .dynamic
|
||||
LastSec: .dynamic
|
||||
|
||||
# CHECK: --- !tapi-tbe
|
||||
# CHECK: --- !ifs-v1
|
||||
# CHECK-NEXT: TbeVersion: {{[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: ...
|
||||
|
@ -1,22 +1,22 @@
|
||||
# RUN: llvm-elfabi --elf %p/Inputs/gnu_hash.so --emit-tbe=- | FileCheck %s
|
||||
# RUN: llvm-elfabi --input-format=ELF --output-format=TBE --output=- %p/Inputs/gnu_hash.so | FileCheck %s
|
||||
|
||||
# CHECK: --- !tapi-tbe
|
||||
# CHECK: --- !ifs-v1
|
||||
# CHECK-NEXT: TbeVersion: 1.0
|
||||
# CHECK-NEXT: SoName: libsomething.so
|
||||
# CHECK-NEXT: Arch: x86_64
|
||||
# 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: AGlobalInteger: { Type: Object, Size: 4 }
|
||||
# CHECK-NEXT: AThreadLocalLongInteger: { Type: TLS, Size: 8 }
|
||||
# CHECK-NEXT: _ITM_deregisterTMCloneTable: { Type: NoType, Undefined: true, Weak: true }
|
||||
# CHECK-NEXT: _ITM_registerTMCloneTable: { Type: NoType, Undefined: true, Weak: true }
|
||||
# CHECK-NEXT: _Z11rotateArrayPii: { Type: Func }
|
||||
# CHECK-NEXT: __cxa_finalize: { Type: Func, Undefined: true, Weak: true }
|
||||
# CHECK-NEXT: __gmon_start__: { Type: NoType, Undefined: true, Weak: true }
|
||||
# CHECK-NEXT: __tls_get_addr: { Type: Func, Undefined: true }
|
||||
# CHECK-NEXT: _fini: { Type: Func }
|
||||
# CHECK-NEXT: _init: { Type: Func }
|
||||
# CHECK-NEXT: - { Name: __gmon_start__, Type: NoType, Undefined: true, Weak: true }
|
||||
# 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: __cxa_finalize, Type: Func, Undefined: true, Weak: true }
|
||||
# CHECK-NEXT: - { Name: __tls_get_addr, Type: Func, Undefined: true }
|
||||
# CHECK-NEXT: - { Name: _init, Type: Func }
|
||||
# CHECK-NEXT: - { Name: _fini, Type: Func }
|
||||
# CHECK-NEXT: - { Name: AGlobalInteger, Type: Object, Size: 4 }
|
||||
# CHECK-NEXT: - { Name: AThreadLocalLongInteger, Type: TLS, Size: 8 }
|
||||
# CHECK-NEXT: - { Name: _Z11rotateArrayPii, Type: Func }
|
||||
# CHECK-NEXT: ...
|
||||
|
@ -1,22 +1,22 @@
|
||||
# RUN: llvm-elfabi --elf %p/Inputs/sysv_hash.so --emit-tbe=- | FileCheck %s
|
||||
# RUN: llvm-elfabi --input-format=ELF --output-format=TBE --output=- %p/Inputs/sysv_hash.so | FileCheck %s
|
||||
|
||||
# CHECK: --- !tapi-tbe
|
||||
# CHECK: --- !ifs-v1
|
||||
# CHECK-NEXT: TbeVersion: 1.0
|
||||
# CHECK-NEXT: SoName: libsomething.so
|
||||
# CHECK-NEXT: Arch: x86_64
|
||||
# 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: AGlobalInteger: { Type: Object, Size: 4 }
|
||||
# CHECK-NEXT: AThreadLocalLongInteger: { Type: TLS, Size: 8 }
|
||||
# CHECK-NEXT: _ITM_deregisterTMCloneTable: { Type: NoType, Undefined: true, Weak: true }
|
||||
# CHECK-NEXT: _ITM_registerTMCloneTable: { Type: NoType, Undefined: true, Weak: true }
|
||||
# CHECK-NEXT: _Z11rotateArrayPii: { Type: Func }
|
||||
# CHECK-NEXT: __cxa_finalize: { Type: Func, Undefined: true, Weak: true }
|
||||
# CHECK-NEXT: __gmon_start__: { Type: NoType, Undefined: true, Weak: true }
|
||||
# CHECK-NEXT: __tls_get_addr: { Type: Func, Undefined: true }
|
||||
# CHECK-NEXT: _fini: { Type: Func }
|
||||
# CHECK-NEXT: _init: { Type: Func }
|
||||
# CHECK-NEXT: - { Name: __gmon_start__, Type: NoType, Undefined: true, Weak: true }
|
||||
# CHECK-NEXT: - { Name: _init, Type: Func }
|
||||
# CHECK-NEXT: - { Name: _fini, Type: Func }
|
||||
# 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: __cxa_finalize, Type: Func, Undefined: true, Weak: true }
|
||||
# CHECK-NEXT: - { Name: AGlobalInteger, Type: Object, Size: 4 }
|
||||
# CHECK-NEXT: - { Name: AThreadLocalLongInteger, Type: TLS, Size: 8 }
|
||||
# CHECK-NEXT: - { Name: _Z11rotateArrayPii, Type: Func }
|
||||
# CHECK-NEXT: - { Name: __tls_get_addr, Type: Func, Undefined: true }
|
||||
# CHECK-NEXT: ...
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: not llvm-elfabi %s.NotAFileInTestingDir --emit-tbe=%t 2>&1 | FileCheck %s
|
||||
# RUN: not llvm-elfabi --output-format=TBE --output=%t.tbe %s.NotAFileInTestingDir 2>&1 | FileCheck %s
|
||||
|
||||
This file will not be read. An invalid file path is fed to llvm-elfabi.
|
||||
|
||||
|
@ -3,14 +3,14 @@
|
||||
# REQUIRES: system-windows
|
||||
# RUN: touch %t.TestFile
|
||||
# RUN: chmod 400 %t.TestFile
|
||||
# RUN: not llvm-elfabi %s --output-target=elf64-little %t.TestFile 2>&1 | FileCheck -DMSG=%errc_EACCES %s --check-prefix=ERR
|
||||
# RUN: not llvm-elfabi --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
|
||||
|
||||
--- !tapi-tbe
|
||||
--- !ifs-v1
|
||||
TbeVersion: 1.0
|
||||
Arch: AArch64
|
||||
Symbols: {}
|
||||
Target: { ObjectFormat: ELF, Arch: AArch64, Endianness: little, BitWidth: 64 }
|
||||
Symbols: []
|
||||
...
|
||||
|
||||
# ERR: error: [[MSG]]
|
||||
|
@ -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-elfabi --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
|
||||
--- !ifs-v1
|
||||
TbeVersion: 1.0
|
||||
Arch: AArch64
|
||||
Symbols: {}
|
||||
Target: { ObjectFormat: ELF, Arch: AArch64, Endianness: little, BitWidth: 64 }
|
||||
Symbols: []
|
||||
...
|
||||
|
||||
# ERR: [[MSG]] when trying to open `{{.*}}.TestDir/Output.TestFile` for writing
|
||||
|
@ -1,15 +1,15 @@
|
||||
## Test running llvm-elfabi without specifying a valid target.
|
||||
|
||||
# RUN: not llvm-elfabi %s %t 2>&1 | FileCheck %s --check-prefix=MISSING
|
||||
# RUN: not llvm-elfabi %s --output-target=nope %t 2>&1 | FileCheck %s --check-prefix=INVALID
|
||||
# RUN: not llvm-elfabi --output=%t %s 2>&1 | FileCheck %s --check-prefix=MISSING
|
||||
# RUN: not llvm-elfabi --output-format=nope --output=%t %s 2>&1 | FileCheck %s --check-prefix=INVALID
|
||||
|
||||
--- !tapi-tbe
|
||||
--- !ifs-v1
|
||||
SoName: somelib.so
|
||||
TbeVersion: 1.0
|
||||
Arch: x86_64
|
||||
Symbols: {}
|
||||
Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: little, BitWidth: 64 }
|
||||
Symbols: []
|
||||
...
|
||||
|
||||
# MISSING: error: no binary output target specified.
|
||||
# MISSING: llvm-elfabi: for the --output-format option: must be specified at least once!
|
||||
|
||||
# INVALID: llvm-elfabi: for the --output-target option: Cannot find option named 'nope'!
|
||||
# INVALID: llvm-elfabi: for the --output-format option: Cannot find option named 'nope'!
|
||||
|
@ -1,19 +1,19 @@
|
||||
## Test writing unchanged content to ELF Stub file with --write-if-changed flag.
|
||||
|
||||
# RUN: llvm-elfabi %s --output-target=elf64-little %t
|
||||
# RUN: llvm-elfabi --output-format=ELF --output=%t %s
|
||||
# RUN: env TZ=GMT touch -m -t 197001010000 %t
|
||||
# RUN: llvm-elfabi %s --output-target=elf64-little %t --write-if-changed
|
||||
# RUN: llvm-elfabi --output-format=ELF --output=%t --write-if-changed %s
|
||||
# RUN: env TZ=GMT ls -l %t | FileCheck %s
|
||||
|
||||
--- !tapi-tbe
|
||||
--- !ifs-v1
|
||||
TbeVersion: 1.0
|
||||
Arch: x86_64
|
||||
Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: little, BitWidth: 64 }
|
||||
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: {{[[:space:]]1970}}
|
||||
|
@ -1,8 +1,8 @@
|
||||
## Test writing unchanged content to TBE file with --write-if-changed flag.
|
||||
|
||||
# RUN: llvm-elfabi --elf %p/Inputs/gnu_hash.so --emit-tbe=%t
|
||||
# RUN: llvm-elfabi --input-format=ELF --output-format=TBE --output=%t %p/Inputs/gnu_hash.so
|
||||
# RUN: env TZ=GMT touch -m -t 197001010000 %t
|
||||
# RUN: llvm-elfabi --elf %p/Inputs/gnu_hash.so --emit-tbe=%t --write-if-changed
|
||||
# RUN: llvm-elfabi --input-format=ELF --output-format=TBE --output=%t --write-if-changed %p/Inputs/gnu_hash.so
|
||||
# RUN: env TZ=GMT ls -l %t | FileCheck %s
|
||||
|
||||
# CHECK: {{[[:space:]]1970}}
|
||||
|
@ -5,26 +5,26 @@
|
||||
|
||||
## Test if llvm-elfabi 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-elfabi --input-format=ELF --output-format=TBE --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.
|
||||
# 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-elfabi --input-format=ELF --output-format=TBE --output=- %tfull 2>&1 | FileCheck %s --check-prefix=BADENTSIZE
|
||||
|
||||
## Test if llvm-elfabi 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-elfabi --input-format=ELF --output-format=TBE --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.
|
||||
# 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-elfabi --input-format=ELF --output-format=TBE --output=- %tw.gnu.hash 2>&1 | FileCheck %s --check-prefix=NOTERMINATOR
|
||||
|
||||
# CHECK: --- !tapi-tbe
|
||||
# CHECK: --- !ifs-v1
|
||||
# CHECK-NEXT: TbeVersion: 1.0
|
||||
# CHECK-NEXT: Arch: AArch64
|
||||
# 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: foo, Type: Func, Undefined: true }
|
||||
# CHECK-NEXT: - { Name: bar, Type: Object, Size: 0, Undefined: true }
|
||||
# CHECK-NEXT: ...
|
||||
|
||||
# BADENTSIZE: SHT_DYNSYM section has sh_size (72) % sh_entsize (25) that is not 0
|
||||
|
@ -1,15 +1,15 @@
|
||||
# RUN: not llvm-elfabi --elf %s --emit-tbe=%t 2>&1 | FileCheck %s
|
||||
# RUN: not llvm-elfabi --input-format=ELF --output-format=TBE --output=%t %s 2>&1 | FileCheck %s
|
||||
|
||||
--- !tapi-tbe
|
||||
--- !ifs-v1
|
||||
SoName: somelib.so
|
||||
TbeVersion: 1.0
|
||||
Arch: x86_64
|
||||
Target: { ObjectFormat: ELF, Arch: AArch64, Endianness: little, BitWidth: 64 }
|
||||
Symbols:
|
||||
foo: { Type: Func }
|
||||
bar: { Type: Object, Size: 42 }
|
||||
baz: { Type: Object, Size: 8 }
|
||||
not: { Type: Object, Undefined: true, Size: 128 }
|
||||
nor: { Type: Func, Undefined: true }
|
||||
- { 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
|
||||
|
@ -1,13 +1,13 @@
|
||||
# RUN: llvm-elfabi --tbe %s --emit-tbe=- | FileCheck %s
|
||||
# RUN: llvm-elfabi --input-format=TBE --output-format=TBE --output=- %s | FileCheck %s
|
||||
|
||||
--- !tapi-tbe
|
||||
--- !ifs-v1
|
||||
TbeVersion: 1.0
|
||||
Arch: AArch64
|
||||
Symbols: {}
|
||||
Target: { ObjectFormat: ELF, Arch: AArch64, Endianness: little, BitWidth: 64 }
|
||||
Symbols: []
|
||||
...
|
||||
|
||||
# CHECK: --- !tapi-tbe
|
||||
# CHECK: --- !ifs-v1
|
||||
# CHECK-NEXT: TbeVersion: {{[1-9]\d*\.(0|([1-9]\d*))}}
|
||||
# CHECK-NEXT: Arch: AArch64
|
||||
# CHECK-NEXT: Symbols: {}
|
||||
# CHECK-NEXT: Target: { ObjectFormat: ELF, Arch: AArch64, Endianness: little, BitWidth: 64 }
|
||||
# CHECK-NEXT: Symbols: []
|
||||
# CHECK-NEXT: ...
|
||||
|
17
test/tools/llvm-elfabi/read-tbe-with-bad-bitwidth.test
Normal file
17
test/tools/llvm-elfabi/read-tbe-with-bad-bitwidth.test
Normal file
@ -0,0 +1,17 @@
|
||||
## Test reading TBE file with bad bit width.
|
||||
|
||||
# RUN: not llvm-elfabi --output-format=TBE --output=- %s 2>&1 | FileCheck %s
|
||||
|
||||
--- !ifs-v1
|
||||
SoName: somelib.so
|
||||
TbeVersion: 1.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
test/tools/llvm-elfabi/read-tbe-with-bad-endianness.test
Normal file
17
test/tools/llvm-elfabi/read-tbe-with-bad-endianness.test
Normal file
@ -0,0 +1,17 @@
|
||||
## Test reading TBE file with bad endianness.
|
||||
|
||||
# RUN: not llvm-elfabi --output-format=TBE --output=- %s 2>&1 | FileCheck %s
|
||||
|
||||
--- !ifs-v1
|
||||
SoName: somelib.so
|
||||
TbeVersion: 1.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
|
@ -1,4 +1,4 @@
|
||||
# RUN: not llvm-elfabi %s --emit-tbe=%t 2>&1 | FileCheck %s
|
||||
# RUN: not llvm-elfabi --output-format=TBE --output=- %s 2>&1| FileCheck %s
|
||||
|
||||
This is just some text that cannot be read by llvm-elfabi.
|
||||
|
||||
|
27
test/tools/llvm-elfabi/strip-target.test
Normal file
27
test/tools/llvm-elfabi/strip-target.test
Normal file
@ -0,0 +1,27 @@
|
||||
## Test writing tbe with stripped target information.
|
||||
|
||||
# RUN: llvm-elfabi --input-format=ELF --output-format=TBE --strip-ifs-target --output=- %p/Inputs/sysv_hash.so | FileCheck %s --check-prefix=NOTARGET
|
||||
# RUN: llvm-elfabi --input-format=ELF --output-format=TBE --strip-ifs-arch --strip-ifs-endianness --strip-ifs-bitwidth --output=- %p/Inputs/sysv_hash.so | FileCheck %s --check-prefix=NOTARGET
|
||||
# RUN: llvm-elfabi --input-format=ELF --output-format=TBE --strip-ifs-arch --output=- %p/Inputs/sysv_hash.so | FileCheck %s -DELFTARGET="ObjectFormat: ELF, Endianness: little, BitWidth: 64" --check-prefix=CHECK
|
||||
# RUN: llvm-elfabi --input-format=ELF --output-format=TBE --strip-ifs-endianness --output=- %p/Inputs/sysv_hash.so | FileCheck %s -DELFTARGET="ObjectFormat: ELF, Arch: x86_64, BitWidth: 64" --check-prefix=CHECK
|
||||
# RUN: llvm-elfabi --input-format=ELF --output-format=TBE --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: TbeVersion: 1.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: TbeVersion: 1.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:
|
@ -1,13 +1,13 @@
|
||||
# RUN: llvm-elfabi %s --emit-tbe=- | FileCheck %s
|
||||
# RUN: llvm-elfabi --output-format=TBE --output=- %s | FileCheck %s
|
||||
|
||||
--- !tapi-tbe
|
||||
--- !ifs-v1
|
||||
TbeVersion: 1.0
|
||||
Arch: AArch64
|
||||
Symbols: {}
|
||||
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: --- !tapi-tbe
|
||||
# CHECK: --- !ifs-v1
|
||||
# CHECK-NEXT: TbeVersion: 1.0
|
||||
|
@ -1,25 +1,25 @@
|
||||
# RUN: llvm-elfabi %s --emit-tbe=- | FileCheck %s
|
||||
# RUN: llvm-elfabi --output-format=TBE --output=- %s | FileCheck %s
|
||||
|
||||
--- !tapi-tbe
|
||||
--- !ifs-v1
|
||||
SoName: somelib.so
|
||||
TbeVersion: 1.0
|
||||
Arch: x86_64
|
||||
Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: little, BitWidth: 64 }
|
||||
Symbols:
|
||||
foo: { Type: Func }
|
||||
bar: { Type: Object, Size: 42 }
|
||||
baz: { Type: Object, Size: 8 }
|
||||
not: { Type: Object, Undefined: true, Size: 128 }
|
||||
nor: { Type: Func, Undefined: true }
|
||||
- { 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: --- !tapi-tbe
|
||||
# CHECK: --- !ifs-v1
|
||||
# CHECK-NEXT: TbeVersion: {{[1-9]\d*\.(0|([1-9]\d*))}}
|
||||
# CHECK-NEXT: SoName: somelib.so
|
||||
# CHECK-NEXT: Arch: x86_64
|
||||
# CHECK-NEXT: Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: little, BitWidth: 64 }
|
||||
# CHECK-NEXT: Symbols:
|
||||
# CHECK-NEXT: bar: { Type: Object, Size: 42 }
|
||||
# CHECK-NEXT: baz: { Type: Object, Size: 8 }
|
||||
# CHECK-NEXT: foo: { Type: Func }
|
||||
# CHECK-NEXT: nor: { Type: Func, Undefined: true }
|
||||
# CHECK-NEXT: not: { Type: Object, Size: 128, Undefined: true }
|
||||
# CHECK-NEXT: - { Name: foo, Type: Func }
|
||||
# CHECK-NEXT: - { Name: bar, Type: Object, Size: 42 }
|
||||
# CHECK-NEXT: - { Name: baz, Type: Object, Size: 8 }
|
||||
# CHECK-NEXT: - { Name: not, Type: Object, Size: 128, Undefined: true }
|
||||
# CHECK-NEXT: - { Name: nor, Type: Func, Undefined: true }
|
||||
# CHECK-NEXT: ...
|
||||
|
@ -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-elfabi --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
|
||||
--- !ifs-v1
|
||||
TbeVersion: 1.0
|
||||
Arch: x86_64
|
||||
Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: little, BitWidth: 64 }
|
||||
NeededLibs:
|
||||
- libc.so.6
|
||||
Symbols: {}
|
||||
Symbols: []
|
||||
...
|
||||
|
||||
# CHECK: Section {
|
||||
|
@ -1,26 +1,44 @@
|
||||
## Test writing stub elf with minimal sections.
|
||||
|
||||
# RUN: llvm-elfabi %s --output-target=elf32-little %t.elf32l
|
||||
# RUN: llvm-elfabi --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-elfabi --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-elfabi --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-elfabi --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-elfabi --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
|
||||
# RUN: not llvm-elfabi --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-elfabi --output-format=ELF --output=%t --bitwidth=64 --endianness=big %s 2>&1 | FileCheck %s -DMSG="Arch" --check-prefix=TARGETERR
|
||||
|
||||
# RUN: not llvm-elfabi --output-format=ELF --output=%t --arch=x86_64 --endianness=big %s 2>&1 | FileCheck %s -DMSG="BitWidth" --check-prefix=TARGETERR
|
||||
|
||||
# RUN: not llvm-elfabi --output-format=ELF --output=%t --arch=x86_64 --bitwidth=64 %s 2>&1 | FileCheck %s -DMSG="Endianness" --check-prefix=TARGETERR
|
||||
|
||||
# RUN: llvm-elfabi --output-format=TBE --output=%t.target --target=x86_64-linux-gnu %s
|
||||
# RUN: not llvm-elfabi --output-format=ELF --output=%t --target=aarch64-linux-gnu %t.target 2>&1 | FileCheck %s -DMSG="Triple" --check-prefix=CONFLICTERR
|
||||
|
||||
# RUN: llvm-elfabi --output-format=TBE --output=%t.target --arch=x86_64 --endianness=little --bitwidth=64 %s
|
||||
# RUN: not llvm-elfabi --output-format=ELF --output=%t --arch=AArch64 %t.target 2>&1 | FileCheck %s -DMSG=Arch --check-prefix=CONFLICTERR
|
||||
# RUN: not llvm-elfabi --output-format=ELF --output=%t --endianness=big %t.target 2>&1 | FileCheck %s -DMSG=Endianness --check-prefix=CONFLICTERR
|
||||
# RUN: not llvm-elfabi --output-format=ELF --output=%t --bitwidth=32 %t.target 2>&1 | FileCheck %s -DMSG=BitWidth --check-prefix=CONFLICTERR
|
||||
|
||||
--- !ifs-v1
|
||||
TbeVersion: 1.0
|
||||
Arch: x86_64
|
||||
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 {
|
||||
@ -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
|
@ -1,4 +1,5 @@
|
||||
set(LLVM_LINK_COMPONENTS
|
||||
BinaryFormat
|
||||
InterfaceStub
|
||||
Object
|
||||
Support
|
||||
|
@ -30,33 +30,50 @@ using namespace llvm;
|
||||
using namespace llvm::elfabi;
|
||||
|
||||
// Command line flags:
|
||||
cl::opt<FileFormat> InputFileFormat(
|
||||
cl::desc("Force input file format:"),
|
||||
cl::values(clEnumValN(FileFormat::TBE, "tbe",
|
||||
"Read `input` as text-based ELF stub"),
|
||||
clEnumValN(FileFormat::ELF, "elf",
|
||||
"Read `input` as ELF binary")));
|
||||
cl::opt<std::string> InputFilePath(cl::Positional, cl::desc("input"),
|
||||
cl::Required);
|
||||
cl::opt<std::string>
|
||||
EmitTBE("emit-tbe",
|
||||
cl::desc("Emit a text-based ELF stub (.tbe) from the input file"),
|
||||
cl::value_desc("path"));
|
||||
cl::opt<FileFormat> InputFormat(
|
||||
"input-format", cl::desc("Specify the input file format"),
|
||||
cl::values(clEnumValN(FileFormat::TBE, "TBE", "Text based ELF stub file"),
|
||||
clEnumValN(FileFormat::ELF, "ELF", "ELF object file")));
|
||||
cl::opt<FileFormat> OutputFormat(
|
||||
"output-format", cl::desc("Specify the output file format"),
|
||||
cl::values(clEnumValN(FileFormat::TBE, "TBE", "Text based ELF stub file"),
|
||||
clEnumValN(FileFormat::ELF, "ELF", "ELF stub file")),
|
||||
cl::Required);
|
||||
cl::opt<std::string> OptArch("arch",
|
||||
cl::desc("Specify the architecture, e.g. x86_64"));
|
||||
cl::opt<ELFBitWidthType> OptBitWidth(
|
||||
"bitwidth", cl::desc("Specify the bit width"),
|
||||
cl::values(clEnumValN(ELFBitWidthType::ELF32, "32", "32 bits"),
|
||||
clEnumValN(ELFBitWidthType::ELF64, "64", "64 bits")));
|
||||
cl::opt<ELFEndiannessType> OptEndianness(
|
||||
"endianness", cl::desc("Specify the endianness"),
|
||||
cl::values(clEnumValN(ELFEndiannessType::Little, "little", "Little Endian"),
|
||||
clEnumValN(ELFEndiannessType::Big, "big", "Big Endian")));
|
||||
cl::opt<std::string> OptTargetTriple(
|
||||
"target", cl::desc("Specify the target triple, e.g. x86_64-linux-gnu"));
|
||||
cl::opt<std::string> OptTargetTripleHint(
|
||||
"hint-ifs-target",
|
||||
cl::desc("When --output-format is 'TBE', this flag will hint the expected "
|
||||
"target triple for IFS output"));
|
||||
cl::opt<bool> StripIFSArch(
|
||||
"strip-ifs-arch",
|
||||
cl::desc("Strip target architecture information away from IFS output"));
|
||||
cl::opt<bool> StripIFSBitWidth(
|
||||
"strip-ifs-bitwidth",
|
||||
cl::desc("Strip target bit width information away from IFS output"));
|
||||
cl::opt<bool> StripIFSEndiannessWidth(
|
||||
"strip-ifs-endianness",
|
||||
cl::desc("Strip target endianness information away from IFS output"));
|
||||
cl::opt<bool> StripIFSTarget(
|
||||
"strip-ifs-target",
|
||||
cl::desc("Strip all target information away from IFS output"));
|
||||
cl::opt<std::string>
|
||||
SOName("soname",
|
||||
cl::desc("Manually set the DT_SONAME entry of any emitted files"),
|
||||
cl::value_desc("name"));
|
||||
cl::opt<ELFTarget> BinaryOutputTarget(
|
||||
"output-target", cl::desc("Create a binary stub for the specified target"),
|
||||
cl::values(clEnumValN(ELFTarget::ELF32LE, "elf32-little",
|
||||
"32-bit little-endian ELF stub"),
|
||||
clEnumValN(ELFTarget::ELF32BE, "elf32-big",
|
||||
"32-bit big-endian ELF stub"),
|
||||
clEnumValN(ELFTarget::ELF64LE, "elf64-little",
|
||||
"64-bit little-endian ELF stub"),
|
||||
clEnumValN(ELFTarget::ELF64BE, "elf64-big",
|
||||
"64-bit big-endian ELF stub")));
|
||||
cl::opt<std::string> BinaryOutputFilePath(cl::Positional, cl::desc("output"));
|
||||
cl::opt<std::string> OutputFilePath("output", cl::desc("Output file"));
|
||||
cl::opt<bool> WriteIfChanged(
|
||||
"write-if-changed",
|
||||
cl::desc("Write the output file only if it is new or has changed."));
|
||||
@ -106,8 +123,7 @@ static Expected<std::unique_ptr<ELFStub>> readInputFile(StringRef FilePath) {
|
||||
ErrorCollector EC(/*UseFatalErrors=*/false);
|
||||
|
||||
// First try to read as a binary (fails fast if not binary).
|
||||
if (InputFileFormat.getNumOccurrences() == 0 ||
|
||||
InputFileFormat == FileFormat::ELF) {
|
||||
if (InputFormat.getNumOccurrences() == 0 || InputFormat == FileFormat::ELF) {
|
||||
Expected<std::unique_ptr<ELFStub>> StubFromELF =
|
||||
readELFFile(FileReadBuffer->getMemBufferRef());
|
||||
if (StubFromELF) {
|
||||
@ -117,8 +133,7 @@ static Expected<std::unique_ptr<ELFStub>> readInputFile(StringRef FilePath) {
|
||||
}
|
||||
|
||||
// Fall back to reading as a tbe.
|
||||
if (InputFileFormat.getNumOccurrences() == 0 ||
|
||||
InputFileFormat == FileFormat::TBE) {
|
||||
if (InputFormat.getNumOccurrences() == 0 || InputFormat == FileFormat::TBE) {
|
||||
Expected<std::unique_ptr<ELFStub>> StubFromTBE =
|
||||
readTBEFromBuffer(FileReadBuffer->getBuffer());
|
||||
if (StubFromTBE) {
|
||||
@ -145,7 +160,6 @@ static void fatalError(Error Err) {
|
||||
int main(int argc, char *argv[]) {
|
||||
// Parse arguments.
|
||||
cl::ParseCommandLineOptions(argc, argv);
|
||||
|
||||
Expected<std::unique_ptr<ELFStub>> StubOrErr = readInputFile(InputFilePath);
|
||||
if (!StubOrErr)
|
||||
fatalError(StubOrErr.takeError());
|
||||
@ -155,22 +169,65 @@ int main(int argc, char *argv[]) {
|
||||
// Change SoName before emitting stubs.
|
||||
if (SOName.getNumOccurrences() == 1)
|
||||
TargetStub->SoName = SOName;
|
||||
|
||||
if (EmitTBE.getNumOccurrences() == 1) {
|
||||
Optional<ELFArch> OverrideArch;
|
||||
Optional<ELFEndiannessType> OverrideEndianness;
|
||||
Optional<ELFBitWidthType> OverrideBitWidth;
|
||||
Optional<std::string> OverrideTriple;
|
||||
if (OptArch.getNumOccurrences() == 1) {
|
||||
OverrideArch = ELF::convertArchNameToEMachine(OptArch.getValue());
|
||||
}
|
||||
if (OptEndianness.getNumOccurrences() == 1)
|
||||
OverrideEndianness = OptEndianness.getValue();
|
||||
if (OptBitWidth.getNumOccurrences() == 1)
|
||||
OverrideBitWidth = OptBitWidth.getValue();
|
||||
if (OptTargetTriple.getNumOccurrences() == 1)
|
||||
OverrideTriple = OptTargetTriple.getValue();
|
||||
Error OverrideError =
|
||||
overrideTBETarget(*TargetStub, OverrideArch, OverrideEndianness,
|
||||
OverrideBitWidth, OverrideTriple);
|
||||
if (OverrideError)
|
||||
fatalError(std::move(OverrideError));
|
||||
switch (OutputFormat.getValue()) {
|
||||
case FileFormat::TBE: {
|
||||
TargetStub->TbeVersion = TBEVersionCurrent;
|
||||
Error TBEWriteError = writeTBE(EmitTBE, *TargetStub);
|
||||
if (InputFormat.getValue() == FileFormat::ELF &&
|
||||
OptTargetTripleHint.getNumOccurrences() == 1) {
|
||||
std::error_code HintEC(1, std::generic_category());
|
||||
IFSTarget HintTarget = parseTriple(OptTargetTripleHint);
|
||||
if (TargetStub->Target.Arch.getValue() != HintTarget.Arch.getValue()) {
|
||||
fatalError(make_error<StringError>(
|
||||
"Triple hint does not match the actual architecture", HintEC));
|
||||
}
|
||||
if (TargetStub->Target.Endianness.getValue() !=
|
||||
HintTarget.Endianness.getValue()) {
|
||||
fatalError(make_error<StringError>(
|
||||
"Triple hint does not match the actual endianness", HintEC));
|
||||
}
|
||||
if (TargetStub->Target.BitWidth.getValue() !=
|
||||
HintTarget.BitWidth.getValue()) {
|
||||
fatalError(make_error<StringError>(
|
||||
"Triple hint does not match the actual bit width", HintEC));
|
||||
}
|
||||
stripTBETarget(*TargetStub, true, false, false, false);
|
||||
TargetStub->Target.Triple = OptTargetTripleHint.getValue();
|
||||
} else {
|
||||
stripTBETarget(*TargetStub, StripIFSTarget, StripIFSArch,
|
||||
StripIFSEndiannessWidth, StripIFSBitWidth);
|
||||
}
|
||||
Error TBEWriteError = writeTBE(OutputFilePath.getValue(), *TargetStub);
|
||||
if (TBEWriteError)
|
||||
fatalError(std::move(TBEWriteError));
|
||||
break;
|
||||
}
|
||||
|
||||
// Write out binary ELF stub.
|
||||
if (BinaryOutputFilePath.getNumOccurrences() == 1) {
|
||||
if (BinaryOutputTarget.getNumOccurrences() == 0)
|
||||
fatalError(createStringError(errc::not_supported,
|
||||
"no binary output target specified."));
|
||||
Error BinaryWriteError = writeBinaryStub(
|
||||
BinaryOutputFilePath, *TargetStub, BinaryOutputTarget, WriteIfChanged);
|
||||
case FileFormat::ELF: {
|
||||
Error TargetError = validateTBETarget(*TargetStub, true);
|
||||
if (TargetError)
|
||||
fatalError(std::move(TargetError));
|
||||
Error BinaryWriteError =
|
||||
writeBinaryStub(OutputFilePath, *TargetStub, WriteIfChanged);
|
||||
if (BinaryWriteError)
|
||||
fatalError(std::move(BinaryWriteError));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
set(LLVM_LINK_COMPONENTS
|
||||
InterfaceStub
|
||||
InterfaceStub
|
||||
Object
|
||||
Support
|
||||
TextAPI
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/InterfaceStub/ELFObjHandler.h"
|
||||
#include "llvm/InterfaceStub/ELFStub.h"
|
||||
#include "llvm/InterfaceStub/TBEHandler.h"
|
||||
#include "llvm/ObjectYAML/yaml2obj.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
@ -348,23 +350,10 @@ static int writeElfStub(const Triple &T, const std::vector<IFSSymbol> &Symbols,
|
||||
return convertYAML(YIn, Out, ErrHandler) ? 0 : 1;
|
||||
}
|
||||
|
||||
static elfabi::ELFTarget convertIFSStub(const IFSStub &IfsStub,
|
||||
elfabi::ELFStub &ElfStub) {
|
||||
static Error 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.Target.Triple = IfsStub.Triple;
|
||||
ElfStub.NeededLibs = IfsStub.NeededLibs;
|
||||
for (const IFSSymbol &IfsSymbol : IfsStub.Symbols) {
|
||||
elfabi::ELFSymbol ElfSymbol(IfsSymbol.Name);
|
||||
@ -387,9 +376,9 @@ static elfabi::ELFTarget convertIFSStub(const IFSStub &IfsStub,
|
||||
ElfSymbol.Undefined = false;
|
||||
ElfSymbol.Weak = IfsSymbol.Weak;
|
||||
ElfSymbol.Warning = IfsSymbol.Warning;
|
||||
ElfStub.Symbols.insert(ElfSymbol);
|
||||
ElfStub.Symbols.push_back(ElfSymbol);
|
||||
}
|
||||
return Target;
|
||||
return llvm::elfabi::validateTBETarget(ElfStub, true);
|
||||
}
|
||||
|
||||
static int writeIfso(const IFSStub &Stub, bool IsWriteIfs) {
|
||||
@ -400,9 +389,11 @@ static int writeIfso(const IFSStub &Stub, bool IsWriteIfs) {
|
||||
// format is ELF.
|
||||
if (UseInterfaceStub && (!IsWriteIfs) && ObjectFileFormat != "TBD") {
|
||||
elfabi::ELFStub ElfStub;
|
||||
elfabi::ELFTarget Target = convertIFSStub(Stub, ElfStub);
|
||||
Error BinaryWriteError =
|
||||
elfabi::writeBinaryStub(OutputFilename, ElfStub, Target);
|
||||
Error ConvertError = convertIFSStub(Stub, ElfStub);
|
||||
if (ConvertError) {
|
||||
return -1;
|
||||
}
|
||||
Error BinaryWriteError = elfabi::writeBinaryStub(OutputFilename, ElfStub);
|
||||
if (BinaryWriteError) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -34,19 +34,21 @@ void compareByLine(StringRef LHS, StringRef RHS) {
|
||||
}
|
||||
|
||||
TEST(ElfYamlTextAPI, YAMLReadableTBE) {
|
||||
const char Data[] = "--- !tapi-tbe\n"
|
||||
const char Data[] = "--- !ifs-v1\n"
|
||||
"TbeVersion: 1.0\n"
|
||||
"Arch: x86_64\n"
|
||||
"Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: "
|
||||
"little, BitWidth: 64 }\n"
|
||||
"NeededLibs: [libc.so, libfoo.so, libbar.so]\n"
|
||||
"Symbols:\n"
|
||||
" foo: { Type: Func, Undefined: true }\n"
|
||||
" - { Name: foo, Type: Func, Undefined: true }\n"
|
||||
"...\n";
|
||||
Expected<std::unique_ptr<ELFStub>> StubOrErr = readTBEFromBuffer(Data);
|
||||
ASSERT_THAT_ERROR(StubOrErr.takeError(), Succeeded());
|
||||
std::unique_ptr<ELFStub> Stub = std::move(StubOrErr.get());
|
||||
EXPECT_NE(Stub.get(), nullptr);
|
||||
EXPECT_FALSE(Stub->SoName.hasValue());
|
||||
EXPECT_EQ(Stub->Arch, (uint16_t)llvm::ELF::EM_X86_64);
|
||||
EXPECT_TRUE(Stub->Target.Arch.hasValue());
|
||||
EXPECT_EQ(Stub->Target.Arch.getValue(), (uint16_t)llvm::ELF::EM_X86_64);
|
||||
EXPECT_EQ(Stub->NeededLibs.size(), 3u);
|
||||
EXPECT_STREQ(Stub->NeededLibs[0].c_str(), "libc.so");
|
||||
EXPECT_STREQ(Stub->NeededLibs[1].c_str(), "libfoo.so");
|
||||
@ -54,18 +56,20 @@ TEST(ElfYamlTextAPI, YAMLReadableTBE) {
|
||||
}
|
||||
|
||||
TEST(ElfYamlTextAPI, YAMLReadsTBESymbols) {
|
||||
const char Data[] = "--- !tapi-tbe\n"
|
||||
"TbeVersion: 1.0\n"
|
||||
"SoName: test.so\n"
|
||||
"Arch: x86_64\n"
|
||||
"Symbols:\n"
|
||||
" bar: { Type: Object, Size: 42 }\n"
|
||||
" baz: { Type: TLS, Size: 3 }\n"
|
||||
" foo: { Type: Func, Warning: \"Deprecated!\" }\n"
|
||||
" nor: { Type: NoType, Undefined: true }\n"
|
||||
" not: { Type: File, Undefined: true, Size: 111, "
|
||||
"Weak: true, Warning: \'All fields populated!\' }\n"
|
||||
"...\n";
|
||||
const char Data[] =
|
||||
"--- !ifs-v1\n"
|
||||
"TbeVersion: 1.0\n"
|
||||
"SoName: test.so\n"
|
||||
"Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: little, "
|
||||
"BitWidth: 64 }\n"
|
||||
"Symbols:\n"
|
||||
" - { Name: bar, Type: Object, Size: 42 }\n"
|
||||
" - { Name: baz, Type: TLS, Size: 3 }\n"
|
||||
" - { Name: foo, Type: Func, Warning: \"Deprecated!\" }\n"
|
||||
" - { Name: nor, Type: NoType, Undefined: true }\n"
|
||||
" - { Name: not, Type: File, Undefined: true, Size: 111, "
|
||||
"Weak: true, Warning: \'All fields populated!\' }\n"
|
||||
"...\n";
|
||||
Expected<std::unique_ptr<ELFStub>> StubOrErr = readTBEFromBuffer(Data);
|
||||
ASSERT_THAT_ERROR(StubOrErr.takeError(), Succeeded());
|
||||
std::unique_ptr<ELFStub> Stub = std::move(StubOrErr.get());
|
||||
@ -119,11 +123,12 @@ TEST(ElfYamlTextAPI, YAMLReadsTBESymbols) {
|
||||
}
|
||||
|
||||
TEST(ElfYamlTextAPI, YAMLReadsNoTBESyms) {
|
||||
const char Data[] = "--- !tapi-tbe\n"
|
||||
const char Data[] = "--- !ifs-v1\n"
|
||||
"TbeVersion: 1.0\n"
|
||||
"SoName: test.so\n"
|
||||
"Arch: x86_64\n"
|
||||
"Symbols: {}\n"
|
||||
"Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: "
|
||||
"little, BitWidth: 64 }\n"
|
||||
"Symbols: []\n"
|
||||
"...\n";
|
||||
Expected<std::unique_ptr<ELFStub>> StubOrErr = readTBEFromBuffer(Data);
|
||||
ASSERT_THAT_ERROR(StubOrErr.takeError(), Succeeded());
|
||||
@ -137,7 +142,8 @@ TEST(ElfYamlTextAPI, YAMLUnreadableTBE) {
|
||||
const char Data[] = "--- !tapi-tbz\n"
|
||||
"TbeVersion: z.3\n"
|
||||
"SoName: test.so\n"
|
||||
"Arch: x86_64\n"
|
||||
"Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: "
|
||||
"little, BitWidth: 64 }\n"
|
||||
"Symbols:\n"
|
||||
" foo: { Type: Func, Undefined: true }\n";
|
||||
Expected<std::unique_ptr<ELFStub>> StubOrErr = readTBEFromBuffer(Data);
|
||||
@ -145,11 +151,12 @@ TEST(ElfYamlTextAPI, YAMLUnreadableTBE) {
|
||||
}
|
||||
|
||||
TEST(ElfYamlTextAPI, YAMLUnsupportedVersion) {
|
||||
const char Data[] = "--- !tapi-tbe\n"
|
||||
const char Data[] = "--- !ifs-v1\n"
|
||||
"TbeVersion: 9.9.9\n"
|
||||
"SoName: test.so\n"
|
||||
"Arch: x86_64\n"
|
||||
"Symbols: {}\n"
|
||||
"Target: { ObjectFormat: ELF, Arch: x86_64, Endianness: "
|
||||
"little, BitWidth: 64 }\n"
|
||||
"Symbols: []\n"
|
||||
"...\n";
|
||||
Expected<std::unique_ptr<ELFStub>> StubOrErr = readTBEFromBuffer(Data);
|
||||
std::string ErrorMessage = toString(StubOrErr.takeError());
|
||||
@ -158,18 +165,28 @@ TEST(ElfYamlTextAPI, YAMLUnsupportedVersion) {
|
||||
|
||||
TEST(ElfYamlTextAPI, YAMLWritesTBESymbols) {
|
||||
const char Expected[] =
|
||||
"--- !tapi-tbe\n"
|
||||
"--- !ifs-v1\n"
|
||||
"TbeVersion: 1.0\n"
|
||||
"Arch: AArch64\n"
|
||||
"Target: { ObjectFormat: ELF, Arch: AArch64, Endianness: "
|
||||
"little, BitWidth: 64 }\n"
|
||||
"Symbols:\n"
|
||||
" bar: { Type: Func, Weak: true }\n"
|
||||
" foo: { Type: NoType, Size: 99, Warning: Does nothing }\n"
|
||||
" nor: { Type: Func, Undefined: true }\n"
|
||||
" not: { Type: Unknown, Size: 12345678901234 }\n"
|
||||
" - { Name: bar, Type: Func, Weak: true }\n"
|
||||
" - { Name: foo, Type: NoType, Size: 99, Warning: Does nothing }\n"
|
||||
" - { Name: nor, Type: Func, Undefined: true }\n"
|
||||
" - { Name: not, Type: Unknown, Size: 12345678901234 }\n"
|
||||
"...\n";
|
||||
ELFStub Stub;
|
||||
Stub.TbeVersion = VersionTuple(1, 0);
|
||||
Stub.Arch = ELF::EM_AARCH64;
|
||||
Stub.Target.Arch = ELF::EM_AARCH64;
|
||||
Stub.Target.BitWidth = ELFBitWidthType::ELF64;
|
||||
Stub.Target.Endianness = ELFEndiannessType::Little;
|
||||
Stub.Target.ObjectFormat = "ELF";
|
||||
|
||||
ELFSymbol SymBar("bar");
|
||||
SymBar.Size = 128u;
|
||||
SymBar.Type = ELFSymbolType::Func;
|
||||
SymBar.Undefined = false;
|
||||
SymBar.Weak = true;
|
||||
|
||||
ELFSymbol SymFoo("foo");
|
||||
SymFoo.Size = 99u;
|
||||
@ -178,12 +195,6 @@ TEST(ElfYamlTextAPI, YAMLWritesTBESymbols) {
|
||||
SymFoo.Weak = false;
|
||||
SymFoo.Warning = "Does nothing";
|
||||
|
||||
ELFSymbol SymBar("bar");
|
||||
SymBar.Size = 128u;
|
||||
SymBar.Type = ELFSymbolType::Func;
|
||||
SymBar.Undefined = false;
|
||||
SymBar.Weak = true;
|
||||
|
||||
ELFSymbol SymNor("nor");
|
||||
SymNor.Size = 1234u;
|
||||
SymNor.Type = ELFSymbolType::Func;
|
||||
@ -196,11 +207,11 @@ TEST(ElfYamlTextAPI, YAMLWritesTBESymbols) {
|
||||
SymNot.Undefined = false;
|
||||
SymNot.Weak = false;
|
||||
|
||||
// Deliberately not in order to check that result is sorted.
|
||||
Stub.Symbols.insert(SymNot);
|
||||
Stub.Symbols.insert(SymBar);
|
||||
Stub.Symbols.insert(SymFoo);
|
||||
Stub.Symbols.insert(SymNor);
|
||||
// Symbol order is preserved instead of being sorted.
|
||||
Stub.Symbols.push_back(SymBar);
|
||||
Stub.Symbols.push_back(SymFoo);
|
||||
Stub.Symbols.push_back(SymNor);
|
||||
Stub.Symbols.push_back(SymNot);
|
||||
|
||||
// Ensure move constructor works as expected.
|
||||
ELFStub Moved = std::move(Stub);
|
||||
@ -213,20 +224,24 @@ TEST(ElfYamlTextAPI, YAMLWritesTBESymbols) {
|
||||
}
|
||||
|
||||
TEST(ElfYamlTextAPI, YAMLWritesNoTBESyms) {
|
||||
const char Expected[] = "--- !tapi-tbe\n"
|
||||
const char Expected[] = "--- !ifs-v1\n"
|
||||
"TbeVersion: 1.0\n"
|
||||
"SoName: nosyms.so\n"
|
||||
"Arch: x86_64\n"
|
||||
"Target: { ObjectFormat: ELF, Arch: x86_64, "
|
||||
"Endianness: little, BitWidth: 64 }\n"
|
||||
"NeededLibs:\n"
|
||||
" - libc.so\n"
|
||||
" - libfoo.so\n"
|
||||
" - libbar.so\n"
|
||||
"Symbols: {}\n"
|
||||
"Symbols: []\n"
|
||||
"...\n";
|
||||
ELFStub Stub;
|
||||
Stub.TbeVersion = VersionTuple(1, 0);
|
||||
Stub.SoName = "nosyms.so";
|
||||
Stub.Arch = ELF::EM_X86_64;
|
||||
Stub.Target.Arch = ELF::EM_X86_64;
|
||||
Stub.Target.BitWidth = ELFBitWidthType::ELF64;
|
||||
Stub.Target.Endianness = ELFEndiannessType::Little;
|
||||
Stub.Target.ObjectFormat = "ELF";
|
||||
Stub.NeededLibs.push_back("libc.so");
|
||||
Stub.NeededLibs.push_back("libfoo.so");
|
||||
Stub.NeededLibs.push_back("libbar.so");
|
||||
|
Loading…
Reference in New Issue
Block a user