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>
makeElfData__anon1f6e23b00111::DataForTest265921782fSKazushi (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 
DataForTest__anon1f6e23b00111::DataForTest555921782fSKazushi (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 
checkFormatAndArch(const DataForTest & D,StringRef Fmt,Triple::ArchType Arch)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 
generateData(uint16_t Machine)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 
TEST(ELFObjectFileTest,MachineTestForNoneOrUnused)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 
TEST(ELFObjectFileTest,MachineTestForVE)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 
TEST(ELFObjectFileTest,MachineTestForX86_64)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 
TEST(ELFObjectFileTest,MachineTestFor386)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 
TEST(ELFObjectFileTest,MachineTestForMIPS)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 
TEST(ELFObjectFileTest,MachineTestForAMDGPU)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 
TEST(ELFObjectFileTest,MachineTestForIAMCU)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 
TEST(ELFObjectFileTest,MachineTestForAARCH64)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 
TEST(ELFObjectFileTest,MachineTestForPPC64)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 
TEST(ELFObjectFileTest,MachineTestForPPC)176c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForPPC) {
177696bd307SBrandon Bergren   std::array<StringRef, 4> Formats = {"elf32-powerpcle", "elf32-powerpc",
178c78d2766SGeorgii Rymar                                       "elf64-unknown", "elf64-unknown"};
179696bd307SBrandon Bergren   std::array<Triple::ArchType, 4> Archs = {Triple::ppcle, Triple::ppc,
180696bd307SBrandon Bergren                                            Triple::ppcle, Triple::ppc};
181c78d2766SGeorgii Rymar   size_t I = 0;
182696bd307SBrandon Bergren   for (const DataForTest &D : generateData(ELF::EM_PPC)) {
183696bd307SBrandon Bergren     checkFormatAndArch(D, Formats[I], Archs[I]);
184696bd307SBrandon Bergren     ++I;
185696bd307SBrandon Bergren   }
186c78d2766SGeorgii Rymar }
187c78d2766SGeorgii Rymar 
TEST(ELFObjectFileTest,MachineTestForRISCV)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 
TEST(ELFObjectFileTest,MachineTestForARM)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 
TEST(ELFObjectFileTest,MachineTestForS390)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 
TEST(ELFObjectFileTest,MachineTestForSPARCV9)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 
TEST(ELFObjectFileTest,MachineTestForSPARC)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 
TEST(ELFObjectFileTest,MachineTestForSPARC32PLUS)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 
TEST(ELFObjectFileTest,MachineTestForBPF)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 
TEST(ELFObjectFileTest,MachineTestForAVR)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 
TEST(ELFObjectFileTest,MachineTestForHEXAGON)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 
TEST(ELFObjectFileTest,MachineTestForLANAI)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 
TEST(ELFObjectFileTest,MachineTestForMSP430)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 
TEST(ELFObjectFileTest,MachineTestForLoongArch)292e53e6ec6SLu Weining TEST(ELFObjectFileTest, MachineTestForLoongArch) {
293e53e6ec6SLu Weining   std::array<StringRef, 4> Formats = {"elf32-loongarch", "elf32-loongarch",
294e53e6ec6SLu Weining                                       "elf64-loongarch", "elf64-loongarch"};
295e53e6ec6SLu Weining   std::array<Triple::ArchType, 4> Archs = {
296e53e6ec6SLu Weining       Triple::loongarch32, Triple::loongarch32, Triple::loongarch64,
297e53e6ec6SLu Weining       Triple::loongarch64};
298e53e6ec6SLu Weining   size_t I = 0;
299e53e6ec6SLu Weining   for (const DataForTest &D : generateData(ELF::EM_LOONGARCH)) {
300e53e6ec6SLu Weining     checkFormatAndArch(D, Formats[I], Archs[I]);
301e53e6ec6SLu Weining     ++I;
302e53e6ec6SLu Weining   }
303e53e6ec6SLu Weining }
304e53e6ec6SLu Weining 
TEST(ELFObjectFileTest,MachineTestForCSKY)30569f2c79fSZi Xuan Wu TEST(ELFObjectFileTest, MachineTestForCSKY) {
30669f2c79fSZi Xuan Wu   std::array<StringRef, 4> Formats = {"elf32-csky", "elf32-csky",
30769f2c79fSZi Xuan Wu                                       "elf64-unknown", "elf64-unknown"};
30869f2c79fSZi Xuan Wu   size_t I = 0;
30969f2c79fSZi Xuan Wu   for (const DataForTest &D : generateData(ELF::EM_CSKY))
31069f2c79fSZi Xuan Wu     checkFormatAndArch(D, Formats[I++], Triple::csky);
31169f2c79fSZi Xuan Wu }
31269f2c79fSZi Xuan Wu 
31369f2c79fSZi Xuan Wu // ELF relative relocation type test.
TEST(ELFObjectFileTest,RelativeRelocationTypeTest)31469f2c79fSZi Xuan Wu TEST(ELFObjectFileTest, RelativeRelocationTypeTest) {
31569f2c79fSZi Xuan Wu   EXPECT_EQ(ELF::R_CKCORE_RELATIVE, getELFRelativeRelocationType(ELF::EM_CSKY));
31669f2c79fSZi Xuan Wu }
3171af3cb54SGeorgii Rymar 
3181af3cb54SGeorgii Rymar template <class ELFT>
toBinary(SmallVectorImpl<char> & Storage,StringRef Yaml)3191af3cb54SGeorgii Rymar static Expected<ELFObjectFile<ELFT>> toBinary(SmallVectorImpl<char> &Storage,
3201af3cb54SGeorgii Rymar                                               StringRef Yaml) {
3211af3cb54SGeorgii Rymar   raw_svector_ostream OS(Storage);
3221af3cb54SGeorgii Rymar   yaml::Input YIn(Yaml);
3231af3cb54SGeorgii Rymar   if (!yaml::convertYAML(YIn, OS, [](const Twine &Msg) {}))
3241af3cb54SGeorgii Rymar     return createStringError(std::errc::invalid_argument,
3251af3cb54SGeorgii Rymar                              "unable to convert YAML");
3261af3cb54SGeorgii Rymar   return ELFObjectFile<ELFT>::create(MemoryBufferRef(OS.str(), "dummyELF"));
3271af3cb54SGeorgii Rymar }
3281af3cb54SGeorgii Rymar 
3291af3cb54SGeorgii Rymar // Check we are able to create an ELFObjectFile even when the content of the
3301af3cb54SGeorgii Rymar // SHT_SYMTAB_SHNDX section can't be read properly.
TEST(ELFObjectFileTest,InvalidSymtabShndxTest)3311af3cb54SGeorgii Rymar TEST(ELFObjectFileTest, InvalidSymtabShndxTest) {
3321af3cb54SGeorgii Rymar   SmallString<0> Storage;
3331af3cb54SGeorgii Rymar   Expected<ELFObjectFile<ELF64LE>> ExpectedFile = toBinary<ELF64LE>(Storage, R"(
3341af3cb54SGeorgii Rymar --- !ELF
3351af3cb54SGeorgii Rymar FileHeader:
3361af3cb54SGeorgii Rymar   Class: ELFCLASS64
3371af3cb54SGeorgii Rymar   Data:  ELFDATA2LSB
3381af3cb54SGeorgii Rymar   Type:  ET_REL
3391af3cb54SGeorgii Rymar Sections:
3401af3cb54SGeorgii Rymar   - Name:    .symtab_shndx
3411af3cb54SGeorgii Rymar     Type:    SHT_SYMTAB_SHNDX
3421af3cb54SGeorgii Rymar     Entries: [ 0 ]
3431af3cb54SGeorgii Rymar     ShSize: 0xFFFFFFFF
3441af3cb54SGeorgii Rymar )");
3451af3cb54SGeorgii Rymar 
3461af3cb54SGeorgii Rymar   ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
3471af3cb54SGeorgii Rymar }
34878aea983SGeorgii Rymar 
34978aea983SGeorgii Rymar // Test that we are able to create an ELFObjectFile even when loadable segments
35078aea983SGeorgii Rymar // are unsorted by virtual address.
35178aea983SGeorgii Rymar // Test that ELFFile<ELFT>::toMappedAddr works properly in this case.
35278aea983SGeorgii Rymar 
TEST(ELFObjectFileTest,InvalidLoadSegmentsOrderTest)35378aea983SGeorgii Rymar TEST(ELFObjectFileTest, InvalidLoadSegmentsOrderTest) {
35478aea983SGeorgii Rymar   SmallString<0> Storage;
35578aea983SGeorgii Rymar   Expected<ELFObjectFile<ELF64LE>> ExpectedFile = toBinary<ELF64LE>(Storage, R"(
35678aea983SGeorgii Rymar --- !ELF
35778aea983SGeorgii Rymar FileHeader:
35878aea983SGeorgii Rymar   Class: ELFCLASS64
35978aea983SGeorgii Rymar   Data:  ELFDATA2LSB
36078aea983SGeorgii Rymar   Type:  ET_EXEC
36178aea983SGeorgii Rymar Sections:
36278aea983SGeorgii Rymar   - Name:         .foo
36378aea983SGeorgii Rymar     Type:         SHT_PROGBITS
36478aea983SGeorgii Rymar     Address:      0x1000
36578aea983SGeorgii Rymar     Offset:       0x3000
36678aea983SGeorgii Rymar     ContentArray: [ 0x11 ]
36778aea983SGeorgii Rymar   - Name:         .bar
36878aea983SGeorgii Rymar     Type:         SHT_PROGBITS
36978aea983SGeorgii Rymar     Address:      0x2000
37078aea983SGeorgii Rymar     Offset:       0x4000
37178aea983SGeorgii Rymar     ContentArray: [ 0x99 ]
37278aea983SGeorgii Rymar ProgramHeaders:
37378aea983SGeorgii Rymar   - Type:     PT_LOAD
37478aea983SGeorgii Rymar     VAddr:    0x2000
37578aea983SGeorgii Rymar     FirstSec: .bar
37678aea983SGeorgii Rymar     LastSec:  .bar
37778aea983SGeorgii Rymar   - Type:     PT_LOAD
37878aea983SGeorgii Rymar     VAddr:    0x1000
37978aea983SGeorgii Rymar     FirstSec: .foo
38078aea983SGeorgii Rymar     LastSec:  .foo
38178aea983SGeorgii Rymar )");
38278aea983SGeorgii Rymar 
38378aea983SGeorgii Rymar   ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
38478aea983SGeorgii Rymar 
38578aea983SGeorgii Rymar   std::string WarnString;
38678aea983SGeorgii Rymar   auto ToMappedAddr = [&](uint64_t Addr) -> const uint8_t * {
38778aea983SGeorgii Rymar     Expected<const uint8_t *> DataOrErr =
38878aea983SGeorgii Rymar         ExpectedFile->getELFFile().toMappedAddr(Addr, [&](const Twine &Msg) {
38978aea983SGeorgii Rymar           EXPECT_TRUE(WarnString.empty());
39078aea983SGeorgii Rymar           WarnString = Msg.str();
39178aea983SGeorgii Rymar           return Error::success();
39278aea983SGeorgii Rymar         });
39378aea983SGeorgii Rymar 
39478aea983SGeorgii Rymar     if (!DataOrErr) {
39578aea983SGeorgii Rymar       ADD_FAILURE() << toString(DataOrErr.takeError());
39678aea983SGeorgii Rymar       return nullptr;
39778aea983SGeorgii Rymar     }
39878aea983SGeorgii Rymar 
39978aea983SGeorgii Rymar     EXPECT_TRUE(WarnString ==
40078aea983SGeorgii Rymar                 "loadable segments are unsorted by virtual address");
40178aea983SGeorgii Rymar     WarnString = "";
40278aea983SGeorgii Rymar     return *DataOrErr;
40378aea983SGeorgii Rymar   };
40478aea983SGeorgii Rymar 
40578aea983SGeorgii Rymar   const uint8_t *Data = ToMappedAddr(0x1000);
40678aea983SGeorgii Rymar   ASSERT_TRUE(Data);
40778aea983SGeorgii Rymar   MemoryBufferRef Buf = ExpectedFile->getMemoryBufferRef();
40878aea983SGeorgii Rymar   EXPECT_EQ((const char *)Data - Buf.getBufferStart(), 0x3000);
40978aea983SGeorgii Rymar   EXPECT_EQ(Data[0], 0x11);
41078aea983SGeorgii Rymar 
41178aea983SGeorgii Rymar   Data = ToMappedAddr(0x2000);
41278aea983SGeorgii Rymar   ASSERT_TRUE(Data);
41378aea983SGeorgii Rymar   Buf = ExpectedFile->getMemoryBufferRef();
41478aea983SGeorgii Rymar   EXPECT_EQ((const char *)Data - Buf.getBufferStart(), 0x4000);
41578aea983SGeorgii Rymar   EXPECT_EQ(Data[0], 0x99);
41678aea983SGeorgii Rymar }
417407d4200SGeorgii Rymar 
418407d4200SGeorgii Rymar // This is a test for API that is related to symbols.
419407d4200SGeorgii Rymar // We check that errors are properly reported here.
TEST(ELFObjectFileTest,InvalidSymbolTest)420407d4200SGeorgii Rymar TEST(ELFObjectFileTest, InvalidSymbolTest) {
421407d4200SGeorgii Rymar   SmallString<0> Storage;
422407d4200SGeorgii Rymar   Expected<ELFObjectFile<ELF64LE>> ElfOrErr = toBinary<ELF64LE>(Storage, R"(
423407d4200SGeorgii Rymar --- !ELF
424407d4200SGeorgii Rymar FileHeader:
425407d4200SGeorgii Rymar   Class:   ELFCLASS64
426407d4200SGeorgii Rymar   Data:    ELFDATA2LSB
427407d4200SGeorgii Rymar   Type:    ET_DYN
428407d4200SGeorgii Rymar   Machine: EM_X86_64
429407d4200SGeorgii Rymar Sections:
430407d4200SGeorgii Rymar   - Name: .symtab
431407d4200SGeorgii Rymar     Type: SHT_SYMTAB
432407d4200SGeorgii Rymar )");
433407d4200SGeorgii Rymar 
434407d4200SGeorgii Rymar   ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
435407d4200SGeorgii Rymar   const ELFFile<ELF64LE> &Elf = ElfOrErr->getELFFile();
436407d4200SGeorgii Rymar   const ELFObjectFile<ELF64LE> &Obj = *ElfOrErr;
437407d4200SGeorgii Rymar 
438407d4200SGeorgii Rymar   Expected<const typename ELF64LE::Shdr *> SymtabSecOrErr = Elf.getSection(1);
439407d4200SGeorgii Rymar   ASSERT_THAT_EXPECTED(SymtabSecOrErr, Succeeded());
440407d4200SGeorgii Rymar   ASSERT_EQ((*SymtabSecOrErr)->sh_type, ELF::SHT_SYMTAB);
441407d4200SGeorgii Rymar 
4428590b5ccSGeorgii Rymar   auto DoCheck = [&](unsigned BrokenSymIndex, const char *ErrMsg) {
443407d4200SGeorgii Rymar     ELFSymbolRef BrokenSym = Obj.toSymbolRef(*SymtabSecOrErr, BrokenSymIndex);
444407d4200SGeorgii Rymar 
445407d4200SGeorgii Rymar     // 1) Check the behavior of ELFObjectFile<ELFT>::getSymbolName().
446407d4200SGeorgii Rymar     //    SymbolRef::getName() calls it internally. We can't test it directly,
447407d4200SGeorgii Rymar     //    because it is protected.
4488590b5ccSGeorgii Rymar     EXPECT_THAT_ERROR(BrokenSym.getName().takeError(),
4498590b5ccSGeorgii Rymar                       FailedWithMessage(ErrMsg));
450407d4200SGeorgii Rymar 
451407d4200SGeorgii Rymar     // 2) Check the behavior of ELFObjectFile<ELFT>::getSymbol().
452407d4200SGeorgii Rymar     EXPECT_THAT_ERROR(Obj.getSymbol(BrokenSym.getRawDataRefImpl()).takeError(),
453407d4200SGeorgii Rymar                       FailedWithMessage(ErrMsg));
454407d4200SGeorgii Rymar 
455407d4200SGeorgii Rymar     // 3) Check the behavior of ELFObjectFile<ELFT>::getSymbolSection().
4568590b5ccSGeorgii Rymar     //    SymbolRef::getSection() calls it internally. We can't test it
4578590b5ccSGeorgii Rymar     //    directly, because it is protected.
458407d4200SGeorgii Rymar     EXPECT_THAT_ERROR(BrokenSym.getSection().takeError(),
459407d4200SGeorgii Rymar                       FailedWithMessage(ErrMsg));
460407d4200SGeorgii Rymar 
461407d4200SGeorgii Rymar     // 4) Check the behavior of ELFObjectFile<ELFT>::getSymbolFlags().
462407d4200SGeorgii Rymar     //    SymbolRef::getFlags() calls it internally. We can't test it directly,
463407d4200SGeorgii Rymar     //    because it is protected.
464407d4200SGeorgii Rymar     EXPECT_THAT_ERROR(BrokenSym.getFlags().takeError(),
465407d4200SGeorgii Rymar                       FailedWithMessage(ErrMsg));
466407d4200SGeorgii Rymar 
467407d4200SGeorgii Rymar     // 5) Check the behavior of ELFObjectFile<ELFT>::getSymbolType().
468407d4200SGeorgii Rymar     //    SymbolRef::getType() calls it internally. We can't test it directly,
469407d4200SGeorgii Rymar     //    because it is protected.
4708590b5ccSGeorgii Rymar     EXPECT_THAT_ERROR(BrokenSym.getType().takeError(),
4718590b5ccSGeorgii Rymar                       FailedWithMessage(ErrMsg));
472407d4200SGeorgii Rymar 
473407d4200SGeorgii Rymar     // 6) Check the behavior of ELFObjectFile<ELFT>::getSymbolAddress().
4748590b5ccSGeorgii Rymar     //    SymbolRef::getAddress() calls it internally. We can't test it
4758590b5ccSGeorgii Rymar     //    directly, because it is protected.
476407d4200SGeorgii Rymar     EXPECT_THAT_ERROR(BrokenSym.getAddress().takeError(),
477407d4200SGeorgii Rymar                       FailedWithMessage(ErrMsg));
478407d4200SGeorgii Rymar 
479407d4200SGeorgii Rymar     // Finally, check the `ELFFile<ELFT>::getEntry` API. This is an underlying
480407d4200SGeorgii Rymar     // method that generates errors for all cases above.
4818590b5ccSGeorgii Rymar     EXPECT_THAT_EXPECTED(
4828590b5ccSGeorgii Rymar         Elf.getEntry<typename ELF64LE::Sym>(**SymtabSecOrErr, 0), Succeeded());
483407d4200SGeorgii Rymar     EXPECT_THAT_ERROR(
484407d4200SGeorgii Rymar         Elf.getEntry<typename ELF64LE::Sym>(**SymtabSecOrErr, BrokenSymIndex)
485407d4200SGeorgii Rymar             .takeError(),
486407d4200SGeorgii Rymar         FailedWithMessage(ErrMsg));
4878590b5ccSGeorgii Rymar   };
4888590b5ccSGeorgii Rymar 
4898590b5ccSGeorgii Rymar   // We create a symbol with an index that is too large to exist in the symbol
4908590b5ccSGeorgii Rymar   // table.
4918590b5ccSGeorgii Rymar   DoCheck(0x1, "can't read an entry at 0x18: it goes past the end of the "
4928590b5ccSGeorgii Rymar                "section (0x18)");
4938590b5ccSGeorgii Rymar 
4948590b5ccSGeorgii Rymar   // We create a symbol with an index that is too large to exist in the object.
4958590b5ccSGeorgii Rymar   DoCheck(0xFFFFFFFF, "can't read an entry at 0x17ffffffe8: it goes past the "
4968590b5ccSGeorgii Rymar                       "end of the section (0x18)");
497407d4200SGeorgii Rymar }
498c245c21cSRahman Lavaee 
499c245c21cSRahman Lavaee // Tests for error paths of the ELFFile::decodeBBAddrMap API.
TEST(ELFObjectFileTest,InvalidDecodeBBAddrMap)5005f7ef652SRahman Lavaee TEST(ELFObjectFileTest, InvalidDecodeBBAddrMap) {
501c245c21cSRahman Lavaee   StringRef CommonYamlString(R"(
502c245c21cSRahman Lavaee --- !ELF
503c245c21cSRahman Lavaee FileHeader:
504c245c21cSRahman Lavaee   Class: ELFCLASS64
505c245c21cSRahman Lavaee   Data:  ELFDATA2LSB
506c245c21cSRahman Lavaee   Type:  ET_EXEC
507c245c21cSRahman Lavaee Sections:
508*0aa6df65SRahman Lavaee   - Type: SHT_LLVM_BB_ADDR_MAP
509*0aa6df65SRahman Lavaee     Name: .llvm_bb_addr_map
510c245c21cSRahman Lavaee     Entries:
511c245c21cSRahman Lavaee       - Address: 0x11111
512c245c21cSRahman Lavaee )");
513c245c21cSRahman Lavaee 
514c245c21cSRahman Lavaee   auto DoCheck = [&](StringRef YamlString, const char *ErrMsg) {
515c245c21cSRahman Lavaee     SmallString<0> Storage;
516c245c21cSRahman Lavaee     Expected<ELFObjectFile<ELF64LE>> ElfOrErr =
517c245c21cSRahman Lavaee         toBinary<ELF64LE>(Storage, YamlString);
518c245c21cSRahman Lavaee     ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
519c245c21cSRahman Lavaee     const ELFFile<ELF64LE> &Elf = ElfOrErr->getELFFile();
520c245c21cSRahman Lavaee 
521c245c21cSRahman Lavaee     Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr =
522c245c21cSRahman Lavaee         Elf.getSection(1);
523c245c21cSRahman Lavaee     ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded());
524c245c21cSRahman Lavaee     EXPECT_THAT_ERROR(Elf.decodeBBAddrMap(**BBAddrMapSecOrErr).takeError(),
525c245c21cSRahman Lavaee                       FailedWithMessage(ErrMsg));
526c245c21cSRahman Lavaee   };
527c245c21cSRahman Lavaee 
528*0aa6df65SRahman Lavaee   // Check that we can detect unsupported versions.
529*0aa6df65SRahman Lavaee   SmallString<128> UnsupportedVersionYamlString(CommonYamlString);
530*0aa6df65SRahman Lavaee   UnsupportedVersionYamlString += R"(
531*0aa6df65SRahman Lavaee         Version: 2
532*0aa6df65SRahman Lavaee         BBEntries:
533*0aa6df65SRahman Lavaee           - AddressOffset: 0x0
534*0aa6df65SRahman Lavaee             Size:          0x1
535*0aa6df65SRahman Lavaee             Metadata:      0x2
536*0aa6df65SRahman Lavaee )";
537*0aa6df65SRahman Lavaee 
538*0aa6df65SRahman Lavaee   DoCheck(UnsupportedVersionYamlString,
539*0aa6df65SRahman Lavaee           "unsupported SHT_LLVM_BB_ADDR_MAP version: 2");
540*0aa6df65SRahman Lavaee 
541*0aa6df65SRahman Lavaee   SmallString<128> CommonVersionedYamlString(CommonYamlString);
542*0aa6df65SRahman Lavaee   CommonVersionedYamlString += R"(
543*0aa6df65SRahman Lavaee         Version: 1
544*0aa6df65SRahman Lavaee         BBEntries:
545*0aa6df65SRahman Lavaee           - AddressOffset: 0x0
546*0aa6df65SRahman Lavaee             Size:          0x1
547*0aa6df65SRahman Lavaee             Metadata:      0x2
548*0aa6df65SRahman Lavaee )";
549*0aa6df65SRahman Lavaee 
550c245c21cSRahman Lavaee   // Check that we can detect the malformed encoding when the section is
551c245c21cSRahman Lavaee   // truncated.
552*0aa6df65SRahman Lavaee   SmallString<128> TruncatedYamlString(CommonVersionedYamlString);
553c245c21cSRahman Lavaee   TruncatedYamlString += R"(
554*0aa6df65SRahman Lavaee     ShSize: 0xa
555c245c21cSRahman Lavaee )";
556*0aa6df65SRahman Lavaee   DoCheck(TruncatedYamlString, "unable to decode LEB128 at offset 0x0000000a: "
557c245c21cSRahman Lavaee                                "malformed uleb128, extends past end");
558c245c21cSRahman Lavaee 
559c245c21cSRahman Lavaee   // Check that we can detect when the encoded BB entry fields exceed the UINT32
560c245c21cSRahman Lavaee   // limit.
561*0aa6df65SRahman Lavaee   SmallVector<SmallString<128>, 3> OverInt32LimitYamlStrings(
562*0aa6df65SRahman Lavaee       3, CommonVersionedYamlString);
563c245c21cSRahman Lavaee   OverInt32LimitYamlStrings[0] += R"(
564c245c21cSRahman Lavaee           - AddressOffset: 0x100000000
565c245c21cSRahman Lavaee             Size:          0xFFFFFFFF
566c245c21cSRahman Lavaee             Metadata:      0xFFFFFFFF
567c245c21cSRahman Lavaee )";
568c245c21cSRahman Lavaee 
569c245c21cSRahman Lavaee   OverInt32LimitYamlStrings[1] += R"(
570c245c21cSRahman Lavaee           - AddressOffset: 0xFFFFFFFF
571c245c21cSRahman Lavaee             Size:          0x100000000
572c245c21cSRahman Lavaee             Metadata:      0xFFFFFFFF
573c245c21cSRahman Lavaee )";
574c245c21cSRahman Lavaee 
575c245c21cSRahman Lavaee   OverInt32LimitYamlStrings[2] += R"(
576c245c21cSRahman Lavaee           - AddressOffset: 0xFFFFFFFF
577c245c21cSRahman Lavaee             Size:          0xFFFFFFFF
578c245c21cSRahman Lavaee             Metadata:      0x100000000
579c245c21cSRahman Lavaee )";
580c245c21cSRahman Lavaee 
581c245c21cSRahman Lavaee   DoCheck(OverInt32LimitYamlStrings[0],
582*0aa6df65SRahman Lavaee           "ULEB128 value at offset 0xe exceeds UINT32_MAX (0x100000000)");
583c245c21cSRahman Lavaee   DoCheck(OverInt32LimitYamlStrings[1],
584*0aa6df65SRahman Lavaee           "ULEB128 value at offset 0x13 exceeds UINT32_MAX (0x100000000)");
585c245c21cSRahman Lavaee   DoCheck(OverInt32LimitYamlStrings[2],
586*0aa6df65SRahman Lavaee           "ULEB128 value at offset 0x18 exceeds UINT32_MAX (0x100000000)");
587c245c21cSRahman Lavaee 
588c245c21cSRahman Lavaee   // Check the proper error handling when the section has fields exceeding
589c245c21cSRahman Lavaee   // UINT32 and is also truncated. This is for checking that we don't generate
590c245c21cSRahman Lavaee   // unhandled errors.
591c245c21cSRahman Lavaee   SmallVector<SmallString<128>, 3> OverInt32LimitAndTruncated(
592c245c21cSRahman Lavaee       3, OverInt32LimitYamlStrings[1]);
593c245c21cSRahman Lavaee   // Truncate before the end of the 5-byte field.
594c245c21cSRahman Lavaee   OverInt32LimitAndTruncated[0] += R"(
595*0aa6df65SRahman Lavaee     ShSize: 0x17
596c245c21cSRahman Lavaee )";
597c245c21cSRahman Lavaee   // Truncate at the end of the 5-byte field.
598c245c21cSRahman Lavaee   OverInt32LimitAndTruncated[1] += R"(
599*0aa6df65SRahman Lavaee     ShSize: 0x18
600c245c21cSRahman Lavaee )";
601c245c21cSRahman Lavaee   // Truncate after the end of the 5-byte field.
602c245c21cSRahman Lavaee   OverInt32LimitAndTruncated[2] += R"(
603*0aa6df65SRahman Lavaee     ShSize: 0x19
604c245c21cSRahman Lavaee )";
605c245c21cSRahman Lavaee 
606c245c21cSRahman Lavaee   DoCheck(OverInt32LimitAndTruncated[0],
607*0aa6df65SRahman Lavaee           "unable to decode LEB128 at offset 0x00000013: malformed uleb128, "
608c245c21cSRahman Lavaee           "extends past end");
609c245c21cSRahman Lavaee   DoCheck(OverInt32LimitAndTruncated[1],
610*0aa6df65SRahman Lavaee           "ULEB128 value at offset 0x13 exceeds UINT32_MAX (0x100000000)");
611c245c21cSRahman Lavaee   DoCheck(OverInt32LimitAndTruncated[2],
612*0aa6df65SRahman Lavaee           "ULEB128 value at offset 0x13 exceeds UINT32_MAX (0x100000000)");
613c245c21cSRahman Lavaee 
614c245c21cSRahman Lavaee   // Check for proper error handling when the 'NumBlocks' field is overridden
615c245c21cSRahman Lavaee   // with an out-of-range value.
616*0aa6df65SRahman Lavaee   SmallString<128> OverLimitNumBlocks(CommonVersionedYamlString);
617c245c21cSRahman Lavaee   OverLimitNumBlocks += R"(
618c245c21cSRahman Lavaee         NumBlocks: 0x100000000
619c245c21cSRahman Lavaee )";
620c245c21cSRahman Lavaee 
621c245c21cSRahman Lavaee   DoCheck(OverLimitNumBlocks,
622*0aa6df65SRahman Lavaee           "ULEB128 value at offset 0xa exceeds UINT32_MAX (0x100000000)");
623c245c21cSRahman Lavaee }
6248ec73e96SAmir Ayupov 
6255f7ef652SRahman Lavaee // Test for the ELFObjectFile::readBBAddrMap API.
TEST(ELFObjectFileTest,ReadBBAddrMap)6265f7ef652SRahman Lavaee TEST(ELFObjectFileTest, ReadBBAddrMap) {
6275f7ef652SRahman Lavaee   StringRef CommonYamlString(R"(
6285f7ef652SRahman Lavaee --- !ELF
6295f7ef652SRahman Lavaee FileHeader:
6305f7ef652SRahman Lavaee   Class: ELFCLASS64
6315f7ef652SRahman Lavaee   Data:  ELFDATA2LSB
6325f7ef652SRahman Lavaee   Type:  ET_EXEC
6335f7ef652SRahman Lavaee Sections:
6345f7ef652SRahman Lavaee   - Name: .llvm_bb_addr_map_1
6355f7ef652SRahman Lavaee     Type: SHT_LLVM_BB_ADDR_MAP
6365f7ef652SRahman Lavaee     Link: 1
6375f7ef652SRahman Lavaee     Entries:
638*0aa6df65SRahman Lavaee       - Version: 1
639*0aa6df65SRahman Lavaee         Address: 0x11111
6405f7ef652SRahman Lavaee         BBEntries:
6415f7ef652SRahman Lavaee           - AddressOffset: 0x0
6425f7ef652SRahman Lavaee             Size:          0x1
6435f7ef652SRahman Lavaee             Metadata:      0x2
6445f7ef652SRahman Lavaee   - Name: .llvm_bb_addr_map_2
6455f7ef652SRahman Lavaee     Type: SHT_LLVM_BB_ADDR_MAP
6465f7ef652SRahman Lavaee     Link: 1
6475f7ef652SRahman Lavaee     Entries:
648*0aa6df65SRahman Lavaee       - Version: 1
649*0aa6df65SRahman Lavaee         Address: 0x22222
6505f7ef652SRahman Lavaee         BBEntries:
6515f7ef652SRahman Lavaee           - AddressOffset: 0x0
6525f7ef652SRahman Lavaee             Size:          0x2
6535f7ef652SRahman Lavaee             Metadata:      0x4
6545f7ef652SRahman Lavaee   - Name: .llvm_bb_addr_map
655*0aa6df65SRahman Lavaee     Type: SHT_LLVM_BB_ADDR_MAP_V0
6565f7ef652SRahman Lavaee   # Link: 0 (by default)
6575f7ef652SRahman Lavaee     Entries:
658*0aa6df65SRahman Lavaee       - Version: 0
659*0aa6df65SRahman Lavaee         Address: 0x33333
6605f7ef652SRahman Lavaee         BBEntries:
6615f7ef652SRahman Lavaee           - AddressOffset: 0x0
6625f7ef652SRahman Lavaee             Size:          0x3
6635f7ef652SRahman Lavaee             Metadata:      0x6
6645f7ef652SRahman Lavaee )");
6655f7ef652SRahman Lavaee 
6665f7ef652SRahman Lavaee   BBAddrMap E1 = {0x11111, {{0x0, 0x1, 0x2}}};
6675f7ef652SRahman Lavaee   BBAddrMap E2 = {0x22222, {{0x0, 0x2, 0x4}}};
6685f7ef652SRahman Lavaee   BBAddrMap E3 = {0x33333, {{0x0, 0x3, 0x6}}};
6695f7ef652SRahman Lavaee 
6705f7ef652SRahman Lavaee   std::vector<BBAddrMap> Section0BBAddrMaps = {E3};
6715f7ef652SRahman Lavaee   std::vector<BBAddrMap> Section1BBAddrMaps = {E1, E2};
6725f7ef652SRahman Lavaee   std::vector<BBAddrMap> AllBBAddrMaps = {E1, E2, E3};
6735f7ef652SRahman Lavaee 
6745f7ef652SRahman Lavaee   auto DoCheckSucceeds = [&](StringRef YamlString,
6755f7ef652SRahman Lavaee                              Optional<unsigned> TextSectionIndex,
6765f7ef652SRahman Lavaee                              std::vector<BBAddrMap> ExpectedResult) {
6775f7ef652SRahman Lavaee     SmallString<0> Storage;
6785f7ef652SRahman Lavaee     Expected<ELFObjectFile<ELF64LE>> ElfOrErr =
6795f7ef652SRahman Lavaee         toBinary<ELF64LE>(Storage, YamlString);
6805f7ef652SRahman Lavaee     ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
6815f7ef652SRahman Lavaee 
6825f7ef652SRahman Lavaee     Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr =
6835f7ef652SRahman Lavaee         ElfOrErr->getELFFile().getSection(1);
6845f7ef652SRahman Lavaee     ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded());
6855f7ef652SRahman Lavaee     auto BBAddrMaps = ElfOrErr->readBBAddrMap(TextSectionIndex);
6865f7ef652SRahman Lavaee     EXPECT_THAT_EXPECTED(BBAddrMaps, Succeeded());
6875f7ef652SRahman Lavaee     EXPECT_EQ(*BBAddrMaps, ExpectedResult);
6885f7ef652SRahman Lavaee   };
6895f7ef652SRahman Lavaee 
6905f7ef652SRahman Lavaee   auto DoCheckFails = [&](StringRef YamlString,
6915f7ef652SRahman Lavaee                           Optional<unsigned> TextSectionIndex,
6925f7ef652SRahman Lavaee                           const char *ErrMsg) {
6935f7ef652SRahman Lavaee     SmallString<0> Storage;
6945f7ef652SRahman Lavaee     Expected<ELFObjectFile<ELF64LE>> ElfOrErr =
6955f7ef652SRahman Lavaee         toBinary<ELF64LE>(Storage, YamlString);
6965f7ef652SRahman Lavaee     ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
6975f7ef652SRahman Lavaee 
6985f7ef652SRahman Lavaee     Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr =
6995f7ef652SRahman Lavaee         ElfOrErr->getELFFile().getSection(1);
7005f7ef652SRahman Lavaee     ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded());
7015f7ef652SRahman Lavaee     EXPECT_THAT_ERROR(ElfOrErr->readBBAddrMap(TextSectionIndex).takeError(),
7025f7ef652SRahman Lavaee                       FailedWithMessage(ErrMsg));
7035f7ef652SRahman Lavaee   };
7045f7ef652SRahman Lavaee 
7055f7ef652SRahman Lavaee   // Check that we can retrieve the data in the normal case.
7065f7ef652SRahman Lavaee   DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/None, AllBBAddrMaps);
7075f7ef652SRahman Lavaee   DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/0, Section0BBAddrMaps);
7085f7ef652SRahman Lavaee   DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/1, Section1BBAddrMaps);
7095f7ef652SRahman Lavaee   // Check that when no bb-address-map section is found for a text section,
7105f7ef652SRahman Lavaee   // we return an empty result.
7115f7ef652SRahman Lavaee   DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/2, {});
7125f7ef652SRahman Lavaee 
7135f7ef652SRahman Lavaee   // Check that we detect when a bb-addr-map section is linked to an invalid
7145f7ef652SRahman Lavaee   // (not present) section.
7155f7ef652SRahman Lavaee   SmallString<128> InvalidLinkedYamlString(CommonYamlString);
7165f7ef652SRahman Lavaee   InvalidLinkedYamlString += R"(
7175f7ef652SRahman Lavaee     Link: 10
7185f7ef652SRahman Lavaee )";
7195f7ef652SRahman Lavaee 
7205f7ef652SRahman Lavaee   DoCheckFails(InvalidLinkedYamlString, /*TextSectionIndex=*/1,
721*0aa6df65SRahman Lavaee                "unable to get the linked-to section for "
722*0aa6df65SRahman Lavaee                "SHT_LLVM_BB_ADDR_MAP_V0 section with index 3: invalid section "
723*0aa6df65SRahman Lavaee                "index: 10");
7245f7ef652SRahman Lavaee   // Linked sections are not checked when we don't target a specific text
7255f7ef652SRahman Lavaee   // section.
7265f7ef652SRahman Lavaee   DoCheckSucceeds(InvalidLinkedYamlString, /*TextSectionIndex=*/None,
7275f7ef652SRahman Lavaee                   AllBBAddrMaps);
7285f7ef652SRahman Lavaee 
7295f7ef652SRahman Lavaee   // Check that we can detect when bb-address-map decoding fails.
7305f7ef652SRahman Lavaee   SmallString<128> TruncatedYamlString(CommonYamlString);
7315f7ef652SRahman Lavaee   TruncatedYamlString += R"(
7325f7ef652SRahman Lavaee     ShSize: 0x8
7335f7ef652SRahman Lavaee )";
7345f7ef652SRahman Lavaee 
7355f7ef652SRahman Lavaee   DoCheckFails(TruncatedYamlString, /*TextSectionIndex=*/None,
736*0aa6df65SRahman Lavaee                "unable to read SHT_LLVM_BB_ADDR_MAP_V0 section with index 3: "
7375f7ef652SRahman Lavaee                "unable to decode LEB128 at offset 0x00000008: malformed "
7385f7ef652SRahman Lavaee                "uleb128, extends past end");
7395f7ef652SRahman Lavaee   // Check that we can read the other section's bb-address-maps which are
7405f7ef652SRahman Lavaee   // valid.
7415f7ef652SRahman Lavaee   DoCheckSucceeds(TruncatedYamlString, /*TextSectionIndex=*/1,
7425f7ef652SRahman Lavaee                   Section1BBAddrMaps);
7435f7ef652SRahman Lavaee }
7445f7ef652SRahman Lavaee 
7458ec73e96SAmir Ayupov // Test for ObjectFile::getRelocatedSection: check that it returns a relocated
7468ec73e96SAmir Ayupov // section for executable and relocatable files.
TEST(ELFObjectFileTest,ExecutableWithRelocs)7478ec73e96SAmir Ayupov TEST(ELFObjectFileTest, ExecutableWithRelocs) {
7488ec73e96SAmir Ayupov   StringRef HeaderString(R"(
7498ec73e96SAmir Ayupov --- !ELF
7508ec73e96SAmir Ayupov FileHeader:
7518ec73e96SAmir Ayupov   Class: ELFCLASS64
7528ec73e96SAmir Ayupov   Data:  ELFDATA2LSB
7538ec73e96SAmir Ayupov )");
7548ec73e96SAmir Ayupov   StringRef ContentsString(R"(
7558ec73e96SAmir Ayupov Sections:
7568ec73e96SAmir Ayupov   - Name:  .text
7578ec73e96SAmir Ayupov     Type:  SHT_PROGBITS
7588ec73e96SAmir Ayupov     Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
7598ec73e96SAmir Ayupov   - Name:  .rela.text
7608ec73e96SAmir Ayupov     Type:  SHT_RELA
7618ec73e96SAmir Ayupov     Flags: [ SHF_INFO_LINK ]
7628ec73e96SAmir Ayupov     Info:  .text
7638ec73e96SAmir Ayupov )");
7648ec73e96SAmir Ayupov 
7658ec73e96SAmir Ayupov   auto DoCheck = [&](StringRef YamlString) {
7668ec73e96SAmir Ayupov     SmallString<0> Storage;
7678ec73e96SAmir Ayupov     Expected<ELFObjectFile<ELF64LE>> ElfOrErr =
7688ec73e96SAmir Ayupov         toBinary<ELF64LE>(Storage, YamlString);
7698ec73e96SAmir Ayupov     ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
7708ec73e96SAmir Ayupov     const ELFObjectFile<ELF64LE> &Obj = *ElfOrErr;
7718ec73e96SAmir Ayupov 
7728ec73e96SAmir Ayupov     bool FoundRela;
7738ec73e96SAmir Ayupov 
7748ec73e96SAmir Ayupov     for (SectionRef Sec : Obj.sections()) {
7758ec73e96SAmir Ayupov       Expected<StringRef> SecNameOrErr = Sec.getName();
7768ec73e96SAmir Ayupov       ASSERT_THAT_EXPECTED(SecNameOrErr, Succeeded());
7778ec73e96SAmir Ayupov       StringRef SecName = *SecNameOrErr;
7788ec73e96SAmir Ayupov       if (SecName != ".rela.text")
7798ec73e96SAmir Ayupov         continue;
7808ec73e96SAmir Ayupov       FoundRela = true;
7818ec73e96SAmir Ayupov       Expected<section_iterator> RelSecOrErr = Sec.getRelocatedSection();
7828ec73e96SAmir Ayupov       ASSERT_THAT_EXPECTED(RelSecOrErr, Succeeded());
7838ec73e96SAmir Ayupov       section_iterator RelSec = *RelSecOrErr;
7848ec73e96SAmir Ayupov       ASSERT_NE(RelSec, Obj.section_end());
7858ec73e96SAmir Ayupov       Expected<StringRef> TextSecNameOrErr = RelSec->getName();
7868ec73e96SAmir Ayupov       ASSERT_THAT_EXPECTED(TextSecNameOrErr, Succeeded());
7878ec73e96SAmir Ayupov       StringRef TextSecName = *TextSecNameOrErr;
7888ec73e96SAmir Ayupov       EXPECT_EQ(TextSecName, ".text");
7898ec73e96SAmir Ayupov     }
7908ec73e96SAmir Ayupov     ASSERT_TRUE(FoundRela);
7918ec73e96SAmir Ayupov   };
7928ec73e96SAmir Ayupov 
7938ec73e96SAmir Ayupov   // Check ET_EXEC file (`ld --emit-relocs` use-case).
7948ec73e96SAmir Ayupov   SmallString<128> ExecFileYamlString(HeaderString);
7958ec73e96SAmir Ayupov   ExecFileYamlString += R"(
7968ec73e96SAmir Ayupov   Type:  ET_EXEC
7978ec73e96SAmir Ayupov )";
7988ec73e96SAmir Ayupov   ExecFileYamlString += ContentsString;
7998ec73e96SAmir Ayupov   DoCheck(ExecFileYamlString);
8008ec73e96SAmir Ayupov 
8018ec73e96SAmir Ayupov   // Check ET_REL file.
8028ec73e96SAmir Ayupov   SmallString<128> RelocatableFileYamlString(HeaderString);
8038ec73e96SAmir Ayupov   RelocatableFileYamlString += R"(
8048ec73e96SAmir Ayupov   Type:  ET_REL
8058ec73e96SAmir Ayupov )";
8068ec73e96SAmir Ayupov   RelocatableFileYamlString += ContentsString;
8078ec73e96SAmir Ayupov   DoCheck(RelocatableFileYamlString);
8088ec73e96SAmir Ayupov }
809