15921782fSKazushi (Jam) Marukawa //===- ELFObjectFileTest.cpp - Tests for ELFObjectFile --------------------===// 25921782fSKazushi (Jam) Marukawa // 35921782fSKazushi (Jam) Marukawa // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45921782fSKazushi (Jam) Marukawa // See https://llvm.org/LICENSE.txt for license information. 55921782fSKazushi (Jam) Marukawa // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65921782fSKazushi (Jam) Marukawa // 75921782fSKazushi (Jam) Marukawa //===----------------------------------------------------------------------===// 85921782fSKazushi (Jam) Marukawa 95921782fSKazushi (Jam) Marukawa #include "llvm/Object/ELFObjectFile.h" 105921782fSKazushi (Jam) Marukawa #include "llvm/Support/MemoryBuffer.h" 111af3cb54SGeorgii Rymar #include "llvm/ObjectYAML/yaml2obj.h" 121af3cb54SGeorgii Rymar #include "llvm/Support/YAMLTraits.h" 135921782fSKazushi (Jam) Marukawa #include "llvm/Testing/Support/Error.h" 145921782fSKazushi (Jam) Marukawa #include "gtest/gtest.h" 155921782fSKazushi (Jam) Marukawa 165921782fSKazushi (Jam) Marukawa using namespace llvm; 175921782fSKazushi (Jam) Marukawa using namespace llvm::object; 185921782fSKazushi (Jam) Marukawa 19154901c2SGeorgii Rymar namespace { 205921782fSKazushi (Jam) Marukawa 21154901c2SGeorgii Rymar // A struct to initialize a buffer to represent an ELF object file. 225921782fSKazushi (Jam) Marukawa struct DataForTest { 235921782fSKazushi (Jam) Marukawa std::vector<uint8_t> Data; 245921782fSKazushi (Jam) Marukawa 255921782fSKazushi (Jam) Marukawa template <typename T> 265921782fSKazushi (Jam) Marukawa std::vector<uint8_t> makeElfData(uint8_t Class, uint8_t Encoding, 275921782fSKazushi (Jam) Marukawa uint16_t Machine) { 285921782fSKazushi (Jam) Marukawa T Ehdr{}; // Zero-initialise the header. 295921782fSKazushi (Jam) Marukawa Ehdr.e_ident[ELF::EI_MAG0] = 0x7f; 305921782fSKazushi (Jam) Marukawa Ehdr.e_ident[ELF::EI_MAG1] = 'E'; 315921782fSKazushi (Jam) Marukawa Ehdr.e_ident[ELF::EI_MAG2] = 'L'; 325921782fSKazushi (Jam) Marukawa Ehdr.e_ident[ELF::EI_MAG3] = 'F'; 335921782fSKazushi (Jam) Marukawa Ehdr.e_ident[ELF::EI_CLASS] = Class; 345921782fSKazushi (Jam) Marukawa Ehdr.e_ident[ELF::EI_DATA] = Encoding; 355921782fSKazushi (Jam) Marukawa Ehdr.e_ident[ELF::EI_VERSION] = 1; 365921782fSKazushi (Jam) Marukawa Ehdr.e_type = ELF::ET_REL; 375921782fSKazushi (Jam) Marukawa Ehdr.e_machine = Machine; 385921782fSKazushi (Jam) Marukawa Ehdr.e_version = 1; 395921782fSKazushi (Jam) Marukawa Ehdr.e_ehsize = sizeof(T); 405921782fSKazushi (Jam) Marukawa 415921782fSKazushi (Jam) Marukawa bool IsLittleEndian = Encoding == ELF::ELFDATA2LSB; 425921782fSKazushi (Jam) Marukawa if (sys::IsLittleEndianHost != IsLittleEndian) { 435921782fSKazushi (Jam) Marukawa sys::swapByteOrder(Ehdr.e_type); 445921782fSKazushi (Jam) Marukawa sys::swapByteOrder(Ehdr.e_machine); 455921782fSKazushi (Jam) Marukawa sys::swapByteOrder(Ehdr.e_version); 465921782fSKazushi (Jam) Marukawa sys::swapByteOrder(Ehdr.e_ehsize); 475921782fSKazushi (Jam) Marukawa } 485921782fSKazushi (Jam) Marukawa 495921782fSKazushi (Jam) Marukawa uint8_t *EhdrBytes = reinterpret_cast<uint8_t *>(&Ehdr); 505921782fSKazushi (Jam) Marukawa std::vector<uint8_t> Bytes; 515921782fSKazushi (Jam) Marukawa std::copy(EhdrBytes, EhdrBytes + sizeof(Ehdr), std::back_inserter(Bytes)); 525921782fSKazushi (Jam) Marukawa return Bytes; 535921782fSKazushi (Jam) Marukawa } 545921782fSKazushi (Jam) Marukawa 555921782fSKazushi (Jam) Marukawa DataForTest(uint8_t Class, uint8_t Encoding, uint16_t Machine) { 565921782fSKazushi (Jam) Marukawa if (Class == ELF::ELFCLASS64) 575921782fSKazushi (Jam) Marukawa Data = makeElfData<ELF::Elf64_Ehdr>(Class, Encoding, Machine); 585921782fSKazushi (Jam) Marukawa else { 595921782fSKazushi (Jam) Marukawa assert(Class == ELF::ELFCLASS32); 60154901c2SGeorgii Rymar Data = makeElfData<ELF::Elf32_Ehdr>(Class, Encoding, Machine); 615921782fSKazushi (Jam) Marukawa } 625921782fSKazushi (Jam) Marukawa } 635921782fSKazushi (Jam) Marukawa }; 645921782fSKazushi (Jam) Marukawa 65154901c2SGeorgii Rymar void checkFormatAndArch(const DataForTest &D, StringRef Fmt, 66154901c2SGeorgii Rymar Triple::ArchType Arch) { 67154901c2SGeorgii Rymar Expected<std::unique_ptr<ObjectFile>> ELFObjOrErr = 68154901c2SGeorgii Rymar object::ObjectFile::createELFObjectFile( 69154901c2SGeorgii Rymar MemoryBufferRef(toStringRef(D.Data), "dummyELF")); 70154901c2SGeorgii Rymar ASSERT_THAT_EXPECTED(ELFObjOrErr, Succeeded()); 71154901c2SGeorgii Rymar 72154901c2SGeorgii Rymar const ObjectFile &File = *(*ELFObjOrErr).get(); 73154901c2SGeorgii Rymar EXPECT_EQ(Fmt, File.getFileFormatName()); 74154901c2SGeorgii Rymar EXPECT_EQ(Arch, File.getArch()); 75154901c2SGeorgii Rymar } 76154901c2SGeorgii Rymar 77c78d2766SGeorgii Rymar std::array<DataForTest, 4> generateData(uint16_t Machine) { 78c78d2766SGeorgii Rymar return {DataForTest(ELF::ELFCLASS32, ELF::ELFDATA2LSB, Machine), 79c78d2766SGeorgii Rymar DataForTest(ELF::ELFCLASS32, ELF::ELFDATA2MSB, Machine), 80c78d2766SGeorgii Rymar DataForTest(ELF::ELFCLASS64, ELF::ELFDATA2LSB, Machine), 81c78d2766SGeorgii Rymar DataForTest(ELF::ELFCLASS64, ELF::ELFDATA2MSB, Machine)}; 82c78d2766SGeorgii Rymar } 83c78d2766SGeorgii Rymar 84154901c2SGeorgii Rymar } // namespace 85154901c2SGeorgii Rymar 86c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForNoneOrUnused) { 87c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown", 88c78d2766SGeorgii Rymar "elf64-unknown", "elf64-unknown"}; 89c78d2766SGeorgii Rymar size_t I = 0; 90c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_NONE)) 91c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I++], Triple::UnknownArch); 92c78d2766SGeorgii Rymar 93c78d2766SGeorgii Rymar // Test an arbitrary unused EM_* value (255). 94c78d2766SGeorgii Rymar I = 0; 95c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(255)) 96c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I++], Triple::UnknownArch); 97c78d2766SGeorgii Rymar } 98c78d2766SGeorgii Rymar 995921782fSKazushi (Jam) Marukawa TEST(ELFObjectFileTest, MachineTestForVE) { 100c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown", 101c78d2766SGeorgii Rymar "elf64-ve", "elf64-ve"}; 102c78d2766SGeorgii Rymar size_t I = 0; 103c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_VE)) 104c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I++], Triple::ve); 1055921782fSKazushi (Jam) Marukawa } 1065921782fSKazushi (Jam) Marukawa 1075921782fSKazushi (Jam) Marukawa TEST(ELFObjectFileTest, MachineTestForX86_64) { 108c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-x86-64", "elf32-x86-64", 109c78d2766SGeorgii Rymar "elf64-x86-64", "elf64-x86-64"}; 110c78d2766SGeorgii Rymar size_t I = 0; 111c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_X86_64)) 112c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I++], Triple::x86_64); 1135921782fSKazushi (Jam) Marukawa } 1145921782fSKazushi (Jam) Marukawa 1155921782fSKazushi (Jam) Marukawa TEST(ELFObjectFileTest, MachineTestFor386) { 116c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-i386", "elf32-i386", "elf64-i386", 117c78d2766SGeorgii Rymar "elf64-i386"}; 118c78d2766SGeorgii Rymar size_t I = 0; 119c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_386)) 120c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I++], Triple::x86); 1215921782fSKazushi (Jam) Marukawa } 1225921782fSKazushi (Jam) Marukawa 1235921782fSKazushi (Jam) Marukawa TEST(ELFObjectFileTest, MachineTestForMIPS) { 124c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-mips", "elf32-mips", "elf64-mips", 125c78d2766SGeorgii Rymar "elf64-mips"}; 126c78d2766SGeorgii Rymar std::array<Triple::ArchType, 4> Archs = {Triple::mipsel, Triple::mips, 127c78d2766SGeorgii Rymar Triple::mips64el, Triple::mips64}; 128c78d2766SGeorgii Rymar size_t I = 0; 129c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_MIPS)) { 130c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I], Archs[I]); 131c78d2766SGeorgii Rymar ++I; 132c78d2766SGeorgii Rymar } 133c78d2766SGeorgii Rymar } 134154901c2SGeorgii Rymar 135c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForAMDGPU) { 136c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-amdgpu", "elf32-amdgpu", 137c78d2766SGeorgii Rymar "elf64-amdgpu", "elf64-amdgpu"}; 138c78d2766SGeorgii Rymar size_t I = 0; 139c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_AMDGPU)) 140c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I++], Triple::UnknownArch); 141c78d2766SGeorgii Rymar } 142154901c2SGeorgii Rymar 143c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForIAMCU) { 144c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-iamcu", "elf32-iamcu", 145c78d2766SGeorgii Rymar "elf64-unknown", "elf64-unknown"}; 146c78d2766SGeorgii Rymar size_t I = 0; 147c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_IAMCU)) 148c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I++], Triple::x86); 149c78d2766SGeorgii Rymar } 150154901c2SGeorgii Rymar 151c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForAARCH64) { 152c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown", 153c78d2766SGeorgii Rymar "elf64-littleaarch64", 154c78d2766SGeorgii Rymar "elf64-bigaarch64"}; 155c78d2766SGeorgii Rymar std::array<Triple::ArchType, 4> Archs = {Triple::aarch64, Triple::aarch64_be, 156c78d2766SGeorgii Rymar Triple::aarch64, Triple::aarch64_be}; 157c78d2766SGeorgii Rymar size_t I = 0; 158c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_AARCH64)) { 159c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I], Archs[I]); 160c78d2766SGeorgii Rymar ++I; 161c78d2766SGeorgii Rymar } 162c78d2766SGeorgii Rymar } 163c78d2766SGeorgii Rymar 164c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForPPC64) { 165c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown", 166c78d2766SGeorgii Rymar "elf64-powerpcle", "elf64-powerpc"}; 167c78d2766SGeorgii Rymar std::array<Triple::ArchType, 4> Archs = {Triple::ppc64le, Triple::ppc64, 168c78d2766SGeorgii Rymar Triple::ppc64le, Triple::ppc64}; 169c78d2766SGeorgii Rymar size_t I = 0; 170c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_PPC64)) { 171c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I], Archs[I]); 172c78d2766SGeorgii Rymar ++I; 173c78d2766SGeorgii Rymar } 174c78d2766SGeorgii Rymar } 175c78d2766SGeorgii Rymar 176c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForPPC) { 177*696bd307SBrandon Bergren std::array<StringRef, 4> Formats = {"elf32-powerpcle", "elf32-powerpc", 178c78d2766SGeorgii Rymar "elf64-unknown", "elf64-unknown"}; 179*696bd307SBrandon Bergren std::array<Triple::ArchType, 4> Archs = {Triple::ppcle, Triple::ppc, 180*696bd307SBrandon Bergren Triple::ppcle, Triple::ppc}; 181c78d2766SGeorgii Rymar size_t I = 0; 182*696bd307SBrandon Bergren for (const DataForTest &D : generateData(ELF::EM_PPC)) { 183*696bd307SBrandon Bergren checkFormatAndArch(D, Formats[I], Archs[I]); 184*696bd307SBrandon Bergren ++I; 185*696bd307SBrandon Bergren } 186c78d2766SGeorgii Rymar } 187c78d2766SGeorgii Rymar 188c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForRISCV) { 189c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-littleriscv", "elf32-littleriscv", 190c78d2766SGeorgii Rymar "elf64-littleriscv", "elf64-littleriscv"}; 191c78d2766SGeorgii Rymar std::array<Triple::ArchType, 4> Archs = {Triple::riscv32, Triple::riscv32, 192c78d2766SGeorgii Rymar Triple::riscv64, Triple::riscv64}; 193c78d2766SGeorgii Rymar size_t I = 0; 194c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_RISCV)) { 195c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I], Archs[I]); 196c78d2766SGeorgii Rymar ++I; 197c78d2766SGeorgii Rymar } 198c78d2766SGeorgii Rymar } 199c78d2766SGeorgii Rymar 200c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForARM) { 201c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-littlearm", "elf32-bigarm", 202c78d2766SGeorgii Rymar "elf64-unknown", "elf64-unknown"}; 203c78d2766SGeorgii Rymar size_t I = 0; 204c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_ARM)) 205c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I++], Triple::arm); 206c78d2766SGeorgii Rymar } 207c78d2766SGeorgii Rymar 208c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForS390) { 209c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown", 210c78d2766SGeorgii Rymar "elf64-s390", "elf64-s390"}; 211c78d2766SGeorgii Rymar size_t I = 0; 212c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_S390)) 213c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I++], Triple::systemz); 214c78d2766SGeorgii Rymar } 215c78d2766SGeorgii Rymar 216c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForSPARCV9) { 217c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown", 218c78d2766SGeorgii Rymar "elf64-sparc", "elf64-sparc"}; 219c78d2766SGeorgii Rymar size_t I = 0; 220c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_SPARCV9)) 221c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I++], Triple::sparcv9); 222c78d2766SGeorgii Rymar } 223c78d2766SGeorgii Rymar 224c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForSPARC) { 225c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-sparc", "elf32-sparc", 226c78d2766SGeorgii Rymar "elf64-unknown", "elf64-unknown"}; 227c78d2766SGeorgii Rymar std::array<Triple::ArchType, 4> Archs = {Triple::sparcel, Triple::sparc, 228c78d2766SGeorgii Rymar Triple::sparcel, Triple::sparc}; 229c78d2766SGeorgii Rymar size_t I = 0; 230c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_SPARC)) { 231c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I], Archs[I]); 232c78d2766SGeorgii Rymar ++I; 233c78d2766SGeorgii Rymar } 234c78d2766SGeorgii Rymar } 235c78d2766SGeorgii Rymar 236c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForSPARC32PLUS) { 237c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-sparc", "elf32-sparc", 238c78d2766SGeorgii Rymar "elf64-unknown", "elf64-unknown"}; 239c78d2766SGeorgii Rymar std::array<Triple::ArchType, 4> Archs = {Triple::sparcel, Triple::sparc, 240c78d2766SGeorgii Rymar Triple::sparcel, Triple::sparc}; 241c78d2766SGeorgii Rymar size_t I = 0; 242c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_SPARC32PLUS)) { 243c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I], Archs[I]); 244c78d2766SGeorgii Rymar ++I; 245c78d2766SGeorgii Rymar } 246c78d2766SGeorgii Rymar } 247c78d2766SGeorgii Rymar 248c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForBPF) { 249c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown", 250c78d2766SGeorgii Rymar "elf64-bpf", "elf64-bpf"}; 251c78d2766SGeorgii Rymar std::array<Triple::ArchType, 4> Archs = {Triple::bpfel, Triple::bpfeb, 252c78d2766SGeorgii Rymar Triple::bpfel, Triple::bpfeb}; 253c78d2766SGeorgii Rymar size_t I = 0; 254c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_BPF)) { 255c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I], Archs[I]); 256c78d2766SGeorgii Rymar ++I; 257c78d2766SGeorgii Rymar } 258c78d2766SGeorgii Rymar } 259c78d2766SGeorgii Rymar 260c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForAVR) { 261c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-avr", "elf32-avr", "elf64-unknown", 262c78d2766SGeorgii Rymar "elf64-unknown"}; 263c78d2766SGeorgii Rymar size_t I = 0; 264c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_AVR)) 265c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I++], Triple::avr); 266c78d2766SGeorgii Rymar } 267c78d2766SGeorgii Rymar 268c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForHEXAGON) { 269c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-hexagon", "elf32-hexagon", 270c78d2766SGeorgii Rymar "elf64-unknown", "elf64-unknown"}; 271c78d2766SGeorgii Rymar size_t I = 0; 272c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_HEXAGON)) 273c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I++], Triple::hexagon); 274c78d2766SGeorgii Rymar } 275c78d2766SGeorgii Rymar 276c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForLANAI) { 277c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-lanai", "elf32-lanai", 278c78d2766SGeorgii Rymar "elf64-unknown", "elf64-unknown"}; 279c78d2766SGeorgii Rymar size_t I = 0; 280c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_LANAI)) 281c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I++], Triple::lanai); 282c78d2766SGeorgii Rymar } 283c78d2766SGeorgii Rymar 284c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForMSP430) { 285c78d2766SGeorgii Rymar std::array<StringRef, 4> Formats = {"elf32-msp430", "elf32-msp430", 286c78d2766SGeorgii Rymar "elf64-unknown", "elf64-unknown"}; 287c78d2766SGeorgii Rymar size_t I = 0; 288c78d2766SGeorgii Rymar for (const DataForTest &D : generateData(ELF::EM_MSP430)) 289c78d2766SGeorgii Rymar checkFormatAndArch(D, Formats[I++], Triple::msp430); 2905921782fSKazushi (Jam) Marukawa } 29169f2c79fSZi Xuan Wu 29269f2c79fSZi Xuan Wu TEST(ELFObjectFileTest, MachineTestForCSKY) { 29369f2c79fSZi Xuan Wu std::array<StringRef, 4> Formats = {"elf32-csky", "elf32-csky", 29469f2c79fSZi Xuan Wu "elf64-unknown", "elf64-unknown"}; 29569f2c79fSZi Xuan Wu size_t I = 0; 29669f2c79fSZi Xuan Wu for (const DataForTest &D : generateData(ELF::EM_CSKY)) 29769f2c79fSZi Xuan Wu checkFormatAndArch(D, Formats[I++], Triple::csky); 29869f2c79fSZi Xuan Wu } 29969f2c79fSZi Xuan Wu 30069f2c79fSZi Xuan Wu // ELF relative relocation type test. 30169f2c79fSZi Xuan Wu TEST(ELFObjectFileTest, RelativeRelocationTypeTest) { 30269f2c79fSZi Xuan Wu EXPECT_EQ(ELF::R_CKCORE_RELATIVE, getELFRelativeRelocationType(ELF::EM_CSKY)); 30369f2c79fSZi Xuan Wu } 3041af3cb54SGeorgii Rymar 3051af3cb54SGeorgii Rymar template <class ELFT> 3061af3cb54SGeorgii Rymar static Expected<ELFObjectFile<ELFT>> toBinary(SmallVectorImpl<char> &Storage, 3071af3cb54SGeorgii Rymar StringRef Yaml) { 3081af3cb54SGeorgii Rymar raw_svector_ostream OS(Storage); 3091af3cb54SGeorgii Rymar yaml::Input YIn(Yaml); 3101af3cb54SGeorgii Rymar if (!yaml::convertYAML(YIn, OS, [](const Twine &Msg) {})) 3111af3cb54SGeorgii Rymar return createStringError(std::errc::invalid_argument, 3121af3cb54SGeorgii Rymar "unable to convert YAML"); 3131af3cb54SGeorgii Rymar return ELFObjectFile<ELFT>::create(MemoryBufferRef(OS.str(), "dummyELF")); 3141af3cb54SGeorgii Rymar } 3151af3cb54SGeorgii Rymar 3161af3cb54SGeorgii Rymar // Check we are able to create an ELFObjectFile even when the content of the 3171af3cb54SGeorgii Rymar // SHT_SYMTAB_SHNDX section can't be read properly. 3181af3cb54SGeorgii Rymar TEST(ELFObjectFileTest, InvalidSymtabShndxTest) { 3191af3cb54SGeorgii Rymar SmallString<0> Storage; 3201af3cb54SGeorgii Rymar Expected<ELFObjectFile<ELF64LE>> ExpectedFile = toBinary<ELF64LE>(Storage, R"( 3211af3cb54SGeorgii Rymar --- !ELF 3221af3cb54SGeorgii Rymar FileHeader: 3231af3cb54SGeorgii Rymar Class: ELFCLASS64 3241af3cb54SGeorgii Rymar Data: ELFDATA2LSB 3251af3cb54SGeorgii Rymar Type: ET_REL 3261af3cb54SGeorgii Rymar Sections: 3271af3cb54SGeorgii Rymar - Name: .symtab_shndx 3281af3cb54SGeorgii Rymar Type: SHT_SYMTAB_SHNDX 3291af3cb54SGeorgii Rymar Entries: [ 0 ] 3301af3cb54SGeorgii Rymar ShSize: 0xFFFFFFFF 3311af3cb54SGeorgii Rymar )"); 3321af3cb54SGeorgii Rymar 3331af3cb54SGeorgii Rymar ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded()); 3341af3cb54SGeorgii Rymar } 33578aea983SGeorgii Rymar 33678aea983SGeorgii Rymar // Test that we are able to create an ELFObjectFile even when loadable segments 33778aea983SGeorgii Rymar // are unsorted by virtual address. 33878aea983SGeorgii Rymar // Test that ELFFile<ELFT>::toMappedAddr works properly in this case. 33978aea983SGeorgii Rymar 34078aea983SGeorgii Rymar TEST(ELFObjectFileTest, InvalidLoadSegmentsOrderTest) { 34178aea983SGeorgii Rymar SmallString<0> Storage; 34278aea983SGeorgii Rymar Expected<ELFObjectFile<ELF64LE>> ExpectedFile = toBinary<ELF64LE>(Storage, R"( 34378aea983SGeorgii Rymar --- !ELF 34478aea983SGeorgii Rymar FileHeader: 34578aea983SGeorgii Rymar Class: ELFCLASS64 34678aea983SGeorgii Rymar Data: ELFDATA2LSB 34778aea983SGeorgii Rymar Type: ET_EXEC 34878aea983SGeorgii Rymar Sections: 34978aea983SGeorgii Rymar - Name: .foo 35078aea983SGeorgii Rymar Type: SHT_PROGBITS 35178aea983SGeorgii Rymar Address: 0x1000 35278aea983SGeorgii Rymar Offset: 0x3000 35378aea983SGeorgii Rymar ContentArray: [ 0x11 ] 35478aea983SGeorgii Rymar - Name: .bar 35578aea983SGeorgii Rymar Type: SHT_PROGBITS 35678aea983SGeorgii Rymar Address: 0x2000 35778aea983SGeorgii Rymar Offset: 0x4000 35878aea983SGeorgii Rymar ContentArray: [ 0x99 ] 35978aea983SGeorgii Rymar ProgramHeaders: 36078aea983SGeorgii Rymar - Type: PT_LOAD 36178aea983SGeorgii Rymar VAddr: 0x2000 36278aea983SGeorgii Rymar FirstSec: .bar 36378aea983SGeorgii Rymar LastSec: .bar 36478aea983SGeorgii Rymar - Type: PT_LOAD 36578aea983SGeorgii Rymar VAddr: 0x1000 36678aea983SGeorgii Rymar FirstSec: .foo 36778aea983SGeorgii Rymar LastSec: .foo 36878aea983SGeorgii Rymar )"); 36978aea983SGeorgii Rymar 37078aea983SGeorgii Rymar ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded()); 37178aea983SGeorgii Rymar 37278aea983SGeorgii Rymar std::string WarnString; 37378aea983SGeorgii Rymar auto ToMappedAddr = [&](uint64_t Addr) -> const uint8_t * { 37478aea983SGeorgii Rymar Expected<const uint8_t *> DataOrErr = 37578aea983SGeorgii Rymar ExpectedFile->getELFFile().toMappedAddr(Addr, [&](const Twine &Msg) { 37678aea983SGeorgii Rymar EXPECT_TRUE(WarnString.empty()); 37778aea983SGeorgii Rymar WarnString = Msg.str(); 37878aea983SGeorgii Rymar return Error::success(); 37978aea983SGeorgii Rymar }); 38078aea983SGeorgii Rymar 38178aea983SGeorgii Rymar if (!DataOrErr) { 38278aea983SGeorgii Rymar ADD_FAILURE() << toString(DataOrErr.takeError()); 38378aea983SGeorgii Rymar return nullptr; 38478aea983SGeorgii Rymar } 38578aea983SGeorgii Rymar 38678aea983SGeorgii Rymar EXPECT_TRUE(WarnString == 38778aea983SGeorgii Rymar "loadable segments are unsorted by virtual address"); 38878aea983SGeorgii Rymar WarnString = ""; 38978aea983SGeorgii Rymar return *DataOrErr; 39078aea983SGeorgii Rymar }; 39178aea983SGeorgii Rymar 39278aea983SGeorgii Rymar const uint8_t *Data = ToMappedAddr(0x1000); 39378aea983SGeorgii Rymar ASSERT_TRUE(Data); 39478aea983SGeorgii Rymar MemoryBufferRef Buf = ExpectedFile->getMemoryBufferRef(); 39578aea983SGeorgii Rymar EXPECT_EQ((const char *)Data - Buf.getBufferStart(), 0x3000); 39678aea983SGeorgii Rymar EXPECT_EQ(Data[0], 0x11); 39778aea983SGeorgii Rymar 39878aea983SGeorgii Rymar Data = ToMappedAddr(0x2000); 39978aea983SGeorgii Rymar ASSERT_TRUE(Data); 40078aea983SGeorgii Rymar Buf = ExpectedFile->getMemoryBufferRef(); 40178aea983SGeorgii Rymar EXPECT_EQ((const char *)Data - Buf.getBufferStart(), 0x4000); 40278aea983SGeorgii Rymar EXPECT_EQ(Data[0], 0x99); 40378aea983SGeorgii Rymar } 404407d4200SGeorgii Rymar 405407d4200SGeorgii Rymar // This is a test for API that is related to symbols. 406407d4200SGeorgii Rymar // We check that errors are properly reported here. 407407d4200SGeorgii Rymar TEST(ELFObjectFileTest, InvalidSymbolTest) { 408407d4200SGeorgii Rymar SmallString<0> Storage; 409407d4200SGeorgii Rymar Expected<ELFObjectFile<ELF64LE>> ElfOrErr = toBinary<ELF64LE>(Storage, R"( 410407d4200SGeorgii Rymar --- !ELF 411407d4200SGeorgii Rymar FileHeader: 412407d4200SGeorgii Rymar Class: ELFCLASS64 413407d4200SGeorgii Rymar Data: ELFDATA2LSB 414407d4200SGeorgii Rymar Type: ET_DYN 415407d4200SGeorgii Rymar Machine: EM_X86_64 416407d4200SGeorgii Rymar Sections: 417407d4200SGeorgii Rymar - Name: .symtab 418407d4200SGeorgii Rymar Type: SHT_SYMTAB 419407d4200SGeorgii Rymar )"); 420407d4200SGeorgii Rymar 421407d4200SGeorgii Rymar ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded()); 422407d4200SGeorgii Rymar const ELFFile<ELF64LE> &Elf = ElfOrErr->getELFFile(); 423407d4200SGeorgii Rymar const ELFObjectFile<ELF64LE> &Obj = *ElfOrErr; 424407d4200SGeorgii Rymar 425407d4200SGeorgii Rymar Expected<const typename ELF64LE::Shdr *> SymtabSecOrErr = Elf.getSection(1); 426407d4200SGeorgii Rymar ASSERT_THAT_EXPECTED(SymtabSecOrErr, Succeeded()); 427407d4200SGeorgii Rymar ASSERT_EQ((*SymtabSecOrErr)->sh_type, ELF::SHT_SYMTAB); 428407d4200SGeorgii Rymar 4298590b5ccSGeorgii Rymar auto DoCheck = [&](unsigned BrokenSymIndex, const char *ErrMsg) { 430407d4200SGeorgii Rymar ELFSymbolRef BrokenSym = Obj.toSymbolRef(*SymtabSecOrErr, BrokenSymIndex); 431407d4200SGeorgii Rymar 432407d4200SGeorgii Rymar // 1) Check the behavior of ELFObjectFile<ELFT>::getSymbolName(). 433407d4200SGeorgii Rymar // SymbolRef::getName() calls it internally. We can't test it directly, 434407d4200SGeorgii Rymar // because it is protected. 4358590b5ccSGeorgii Rymar EXPECT_THAT_ERROR(BrokenSym.getName().takeError(), 4368590b5ccSGeorgii Rymar FailedWithMessage(ErrMsg)); 437407d4200SGeorgii Rymar 438407d4200SGeorgii Rymar // 2) Check the behavior of ELFObjectFile<ELFT>::getSymbol(). 439407d4200SGeorgii Rymar EXPECT_THAT_ERROR(Obj.getSymbol(BrokenSym.getRawDataRefImpl()).takeError(), 440407d4200SGeorgii Rymar FailedWithMessage(ErrMsg)); 441407d4200SGeorgii Rymar 442407d4200SGeorgii Rymar // 3) Check the behavior of ELFObjectFile<ELFT>::getSymbolSection(). 4438590b5ccSGeorgii Rymar // SymbolRef::getSection() calls it internally. We can't test it 4448590b5ccSGeorgii Rymar // directly, because it is protected. 445407d4200SGeorgii Rymar EXPECT_THAT_ERROR(BrokenSym.getSection().takeError(), 446407d4200SGeorgii Rymar FailedWithMessage(ErrMsg)); 447407d4200SGeorgii Rymar 448407d4200SGeorgii Rymar // 4) Check the behavior of ELFObjectFile<ELFT>::getSymbolFlags(). 449407d4200SGeorgii Rymar // SymbolRef::getFlags() calls it internally. We can't test it directly, 450407d4200SGeorgii Rymar // because it is protected. 451407d4200SGeorgii Rymar EXPECT_THAT_ERROR(BrokenSym.getFlags().takeError(), 452407d4200SGeorgii Rymar FailedWithMessage(ErrMsg)); 453407d4200SGeorgii Rymar 454407d4200SGeorgii Rymar // 5) Check the behavior of ELFObjectFile<ELFT>::getSymbolType(). 455407d4200SGeorgii Rymar // SymbolRef::getType() calls it internally. We can't test it directly, 456407d4200SGeorgii Rymar // because it is protected. 4578590b5ccSGeorgii Rymar EXPECT_THAT_ERROR(BrokenSym.getType().takeError(), 4588590b5ccSGeorgii Rymar FailedWithMessage(ErrMsg)); 459407d4200SGeorgii Rymar 460407d4200SGeorgii Rymar // 6) Check the behavior of ELFObjectFile<ELFT>::getSymbolAddress(). 4618590b5ccSGeorgii Rymar // SymbolRef::getAddress() calls it internally. We can't test it 4628590b5ccSGeorgii Rymar // directly, because it is protected. 463407d4200SGeorgii Rymar EXPECT_THAT_ERROR(BrokenSym.getAddress().takeError(), 464407d4200SGeorgii Rymar FailedWithMessage(ErrMsg)); 465407d4200SGeorgii Rymar 466407d4200SGeorgii Rymar // Finally, check the `ELFFile<ELFT>::getEntry` API. This is an underlying 467407d4200SGeorgii Rymar // method that generates errors for all cases above. 4688590b5ccSGeorgii Rymar EXPECT_THAT_EXPECTED( 4698590b5ccSGeorgii Rymar Elf.getEntry<typename ELF64LE::Sym>(**SymtabSecOrErr, 0), Succeeded()); 470407d4200SGeorgii Rymar EXPECT_THAT_ERROR( 471407d4200SGeorgii Rymar Elf.getEntry<typename ELF64LE::Sym>(**SymtabSecOrErr, BrokenSymIndex) 472407d4200SGeorgii Rymar .takeError(), 473407d4200SGeorgii Rymar FailedWithMessage(ErrMsg)); 4748590b5ccSGeorgii Rymar }; 4758590b5ccSGeorgii Rymar 4768590b5ccSGeorgii Rymar // We create a symbol with an index that is too large to exist in the symbol 4778590b5ccSGeorgii Rymar // table. 4788590b5ccSGeorgii Rymar DoCheck(0x1, "can't read an entry at 0x18: it goes past the end of the " 4798590b5ccSGeorgii Rymar "section (0x18)"); 4808590b5ccSGeorgii Rymar 4818590b5ccSGeorgii Rymar // We create a symbol with an index that is too large to exist in the object. 4828590b5ccSGeorgii Rymar DoCheck(0xFFFFFFFF, "can't read an entry at 0x17ffffffe8: it goes past the " 4838590b5ccSGeorgii Rymar "end of the section (0x18)"); 484407d4200SGeorgii Rymar } 485