xref: /llvm-project/llvm/unittests/Object/ELFObjectFileTest.cpp (revision cf83a7fdc2dfac8220d9923a831181dccb9f7277)
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"
108a0e0c22SSergei Barannikov #include "llvm/ADT/STLExtras.h"
111af3cb54SGeorgii Rymar #include "llvm/ObjectYAML/yaml2obj.h"
12105adf2cSMicah Weston #include "llvm/Support/BlockFrequency.h"
138a0e0c22SSergei Barannikov #include "llvm/Support/MemoryBuffer.h"
141af3cb54SGeorgii Rymar #include "llvm/Support/YAMLTraits.h"
155921782fSKazushi (Jam) Marukawa #include "llvm/Testing/Support/Error.h"
165921782fSKazushi (Jam) Marukawa #include "gtest/gtest.h"
175921782fSKazushi (Jam) Marukawa 
183d6841b2SRahman Lavaee #include "llvm/Support/thread.h"
19d768bf99SArchibald Elliott #include "llvm/TargetParser/Host.h"
203d6841b2SRahman Lavaee 
215921782fSKazushi (Jam) Marukawa using namespace llvm;
225921782fSKazushi (Jam) Marukawa using namespace llvm::object;
235921782fSKazushi (Jam) Marukawa 
24154901c2SGeorgii Rymar namespace {
255921782fSKazushi (Jam) Marukawa 
26154901c2SGeorgii Rymar // A struct to initialize a buffer to represent an ELF object file.
275921782fSKazushi (Jam) Marukawa struct DataForTest {
285921782fSKazushi (Jam) Marukawa   std::vector<uint8_t> Data;
295921782fSKazushi (Jam) Marukawa 
305921782fSKazushi (Jam) Marukawa   template <typename T>
315921782fSKazushi (Jam) Marukawa   std::vector<uint8_t> makeElfData(uint8_t Class, uint8_t Encoding,
323b337bbcSJoseph Huber                                    uint16_t Machine, uint8_t OS,
333b337bbcSJoseph Huber                                    uint16_t Flags) {
345921782fSKazushi (Jam) Marukawa     T Ehdr{}; // Zero-initialise the header.
355921782fSKazushi (Jam) Marukawa     Ehdr.e_ident[ELF::EI_MAG0] = 0x7f;
365921782fSKazushi (Jam) Marukawa     Ehdr.e_ident[ELF::EI_MAG1] = 'E';
375921782fSKazushi (Jam) Marukawa     Ehdr.e_ident[ELF::EI_MAG2] = 'L';
385921782fSKazushi (Jam) Marukawa     Ehdr.e_ident[ELF::EI_MAG3] = 'F';
395921782fSKazushi (Jam) Marukawa     Ehdr.e_ident[ELF::EI_CLASS] = Class;
405921782fSKazushi (Jam) Marukawa     Ehdr.e_ident[ELF::EI_DATA] = Encoding;
415921782fSKazushi (Jam) Marukawa     Ehdr.e_ident[ELF::EI_VERSION] = 1;
423b337bbcSJoseph Huber     Ehdr.e_ident[ELF::EI_OSABI] = OS;
435921782fSKazushi (Jam) Marukawa     Ehdr.e_type = ELF::ET_REL;
445921782fSKazushi (Jam) Marukawa     Ehdr.e_machine = Machine;
455921782fSKazushi (Jam) Marukawa     Ehdr.e_version = 1;
463b337bbcSJoseph Huber     Ehdr.e_flags = Flags;
475921782fSKazushi (Jam) Marukawa     Ehdr.e_ehsize = sizeof(T);
485921782fSKazushi (Jam) Marukawa 
495921782fSKazushi (Jam) Marukawa     bool IsLittleEndian = Encoding == ELF::ELFDATA2LSB;
505921782fSKazushi (Jam) Marukawa     if (sys::IsLittleEndianHost != IsLittleEndian) {
515921782fSKazushi (Jam) Marukawa       sys::swapByteOrder(Ehdr.e_type);
525921782fSKazushi (Jam) Marukawa       sys::swapByteOrder(Ehdr.e_machine);
535921782fSKazushi (Jam) Marukawa       sys::swapByteOrder(Ehdr.e_version);
545921782fSKazushi (Jam) Marukawa       sys::swapByteOrder(Ehdr.e_ehsize);
555921782fSKazushi (Jam) Marukawa     }
565921782fSKazushi (Jam) Marukawa 
575921782fSKazushi (Jam) Marukawa     uint8_t *EhdrBytes = reinterpret_cast<uint8_t *>(&Ehdr);
585921782fSKazushi (Jam) Marukawa     std::vector<uint8_t> Bytes;
595921782fSKazushi (Jam) Marukawa     std::copy(EhdrBytes, EhdrBytes + sizeof(Ehdr), std::back_inserter(Bytes));
605921782fSKazushi (Jam) Marukawa     return Bytes;
615921782fSKazushi (Jam) Marukawa   }
625921782fSKazushi (Jam) Marukawa 
633b337bbcSJoseph Huber   DataForTest(uint8_t Class, uint8_t Encoding, uint16_t Machine,
643b337bbcSJoseph Huber               uint8_t OS = ELF::ELFOSABI_NONE, uint16_t Flags = 0) {
655921782fSKazushi (Jam) Marukawa     if (Class == ELF::ELFCLASS64)
663b337bbcSJoseph Huber       Data = makeElfData<ELF::Elf64_Ehdr>(Class, Encoding, Machine, OS, Flags);
675921782fSKazushi (Jam) Marukawa     else {
685921782fSKazushi (Jam) Marukawa       assert(Class == ELF::ELFCLASS32);
693b337bbcSJoseph Huber       Data = makeElfData<ELF::Elf32_Ehdr>(Class, Encoding, Machine, OS, Flags);
705921782fSKazushi (Jam) Marukawa     }
715921782fSKazushi (Jam) Marukawa   }
725921782fSKazushi (Jam) Marukawa };
735921782fSKazushi (Jam) Marukawa 
74154901c2SGeorgii Rymar void checkFormatAndArch(const DataForTest &D, StringRef Fmt,
75154901c2SGeorgii Rymar                         Triple::ArchType Arch) {
76154901c2SGeorgii Rymar   Expected<std::unique_ptr<ObjectFile>> ELFObjOrErr =
77154901c2SGeorgii Rymar       object::ObjectFile::createELFObjectFile(
78154901c2SGeorgii Rymar           MemoryBufferRef(toStringRef(D.Data), "dummyELF"));
79154901c2SGeorgii Rymar   ASSERT_THAT_EXPECTED(ELFObjOrErr, Succeeded());
80154901c2SGeorgii Rymar 
81154901c2SGeorgii Rymar   const ObjectFile &File = *(*ELFObjOrErr).get();
82154901c2SGeorgii Rymar   EXPECT_EQ(Fmt, File.getFileFormatName());
83154901c2SGeorgii Rymar   EXPECT_EQ(Arch, File.getArch());
84154901c2SGeorgii Rymar }
85154901c2SGeorgii Rymar 
86c78d2766SGeorgii Rymar std::array<DataForTest, 4> generateData(uint16_t Machine) {
87c78d2766SGeorgii Rymar   return {DataForTest(ELF::ELFCLASS32, ELF::ELFDATA2LSB, Machine),
88c78d2766SGeorgii Rymar           DataForTest(ELF::ELFCLASS32, ELF::ELFDATA2MSB, Machine),
89c78d2766SGeorgii Rymar           DataForTest(ELF::ELFCLASS64, ELF::ELFDATA2LSB, Machine),
90c78d2766SGeorgii Rymar           DataForTest(ELF::ELFCLASS64, ELF::ELFDATA2MSB, Machine)};
91c78d2766SGeorgii Rymar }
92c78d2766SGeorgii Rymar 
93154901c2SGeorgii Rymar } // namespace
94154901c2SGeorgii Rymar 
95c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForNoneOrUnused) {
96c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown",
97c78d2766SGeorgii Rymar                                       "elf64-unknown", "elf64-unknown"};
988a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_NONE)))
998a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Triple::UnknownArch);
100c78d2766SGeorgii Rymar 
101c78d2766SGeorgii Rymar   // Test an arbitrary unused EM_* value (255).
1028a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(255)))
1038a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Triple::UnknownArch);
104c78d2766SGeorgii Rymar }
105c78d2766SGeorgii Rymar 
1065921782fSKazushi (Jam) Marukawa TEST(ELFObjectFileTest, MachineTestForVE) {
107c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown",
108c78d2766SGeorgii Rymar                                       "elf64-ve", "elf64-ve"};
1098a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_VE)))
1108a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Triple::ve);
1115921782fSKazushi (Jam) Marukawa }
1125921782fSKazushi (Jam) Marukawa 
1135921782fSKazushi (Jam) Marukawa TEST(ELFObjectFileTest, MachineTestForX86_64) {
114c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-x86-64", "elf32-x86-64",
115c78d2766SGeorgii Rymar                                       "elf64-x86-64", "elf64-x86-64"};
1168a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_X86_64)))
1178a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Triple::x86_64);
1185921782fSKazushi (Jam) Marukawa }
1195921782fSKazushi (Jam) Marukawa 
1205921782fSKazushi (Jam) Marukawa TEST(ELFObjectFileTest, MachineTestFor386) {
121c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-i386", "elf32-i386", "elf64-i386",
122c78d2766SGeorgii Rymar                                       "elf64-i386"};
1238a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_386)))
1248a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Triple::x86);
1255921782fSKazushi (Jam) Marukawa }
1265921782fSKazushi (Jam) Marukawa 
1275921782fSKazushi (Jam) Marukawa TEST(ELFObjectFileTest, MachineTestForMIPS) {
128c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-mips", "elf32-mips", "elf64-mips",
129c78d2766SGeorgii Rymar                                       "elf64-mips"};
130c78d2766SGeorgii Rymar   std::array<Triple::ArchType, 4> Archs = {Triple::mipsel, Triple::mips,
131c78d2766SGeorgii Rymar                                            Triple::mips64el, Triple::mips64};
1328a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_MIPS)))
1338a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);
134c78d2766SGeorgii Rymar }
135154901c2SGeorgii Rymar 
136c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForAMDGPU) {
137c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-amdgpu", "elf32-amdgpu",
138c78d2766SGeorgii Rymar                                       "elf64-amdgpu", "elf64-amdgpu"};
1398a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_AMDGPU)))
1408a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], 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"};
1468a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_IAMCU)))
1478a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Triple::x86);
148c78d2766SGeorgii Rymar }
149154901c2SGeorgii Rymar 
150c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForAARCH64) {
151c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown",
152c78d2766SGeorgii Rymar                                       "elf64-littleaarch64",
153c78d2766SGeorgii Rymar                                       "elf64-bigaarch64"};
154c78d2766SGeorgii Rymar   std::array<Triple::ArchType, 4> Archs = {Triple::aarch64, Triple::aarch64_be,
155c78d2766SGeorgii Rymar                                            Triple::aarch64, Triple::aarch64_be};
1568a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_AARCH64)))
1578a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);
158c78d2766SGeorgii Rymar }
159c78d2766SGeorgii Rymar 
160c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForPPC64) {
161c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown",
162c78d2766SGeorgii Rymar                                       "elf64-powerpcle", "elf64-powerpc"};
163c78d2766SGeorgii Rymar   std::array<Triple::ArchType, 4> Archs = {Triple::ppc64le, Triple::ppc64,
164c78d2766SGeorgii Rymar                                            Triple::ppc64le, Triple::ppc64};
1658a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_PPC64)))
1668a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);
167c78d2766SGeorgii Rymar }
168c78d2766SGeorgii Rymar 
169c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForPPC) {
170696bd307SBrandon Bergren   std::array<StringRef, 4> Formats = {"elf32-powerpcle", "elf32-powerpc",
171c78d2766SGeorgii Rymar                                       "elf64-unknown", "elf64-unknown"};
172696bd307SBrandon Bergren   std::array<Triple::ArchType, 4> Archs = {Triple::ppcle, Triple::ppc,
173696bd307SBrandon Bergren                                            Triple::ppcle, Triple::ppc};
1748a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_PPC)))
1758a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);
176c78d2766SGeorgii Rymar }
177c78d2766SGeorgii Rymar 
178c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForRISCV) {
179c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-littleriscv", "elf32-littleriscv",
180c78d2766SGeorgii Rymar                                       "elf64-littleriscv", "elf64-littleriscv"};
181c78d2766SGeorgii Rymar   std::array<Triple::ArchType, 4> Archs = {Triple::riscv32, Triple::riscv32,
182c78d2766SGeorgii Rymar                                            Triple::riscv64, Triple::riscv64};
1838a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_RISCV)))
1848a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);
185c78d2766SGeorgii Rymar }
186c78d2766SGeorgii Rymar 
187c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForARM) {
188c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-littlearm", "elf32-bigarm",
189c78d2766SGeorgii Rymar                                       "elf64-unknown", "elf64-unknown"};
1908a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_ARM)))
1918a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Triple::arm);
192c78d2766SGeorgii Rymar }
193c78d2766SGeorgii Rymar 
194c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForS390) {
195c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown",
196c78d2766SGeorgii Rymar                                       "elf64-s390", "elf64-s390"};
1978a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_S390)))
1988a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Triple::systemz);
199c78d2766SGeorgii Rymar }
200c78d2766SGeorgii Rymar 
201c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForSPARCV9) {
202c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown",
203c78d2766SGeorgii Rymar                                       "elf64-sparc", "elf64-sparc"};
2048a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_SPARCV9)))
2058a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Triple::sparcv9);
206c78d2766SGeorgii Rymar }
207c78d2766SGeorgii Rymar 
208c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForSPARC) {
209c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-sparc", "elf32-sparc",
210c78d2766SGeorgii Rymar                                       "elf64-unknown", "elf64-unknown"};
211c78d2766SGeorgii Rymar   std::array<Triple::ArchType, 4> Archs = {Triple::sparcel, Triple::sparc,
212c78d2766SGeorgii Rymar                                            Triple::sparcel, Triple::sparc};
2138a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_SPARC)))
2148a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);
215c78d2766SGeorgii Rymar }
216c78d2766SGeorgii Rymar 
217c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForSPARC32PLUS) {
218c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-sparc", "elf32-sparc",
219c78d2766SGeorgii Rymar                                       "elf64-unknown", "elf64-unknown"};
220c78d2766SGeorgii Rymar   std::array<Triple::ArchType, 4> Archs = {Triple::sparcel, Triple::sparc,
221c78d2766SGeorgii Rymar                                            Triple::sparcel, Triple::sparc};
2228a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_SPARC32PLUS)))
2238a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);
224c78d2766SGeorgii Rymar }
225c78d2766SGeorgii Rymar 
226c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForBPF) {
227c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown",
228c78d2766SGeorgii Rymar                                       "elf64-bpf", "elf64-bpf"};
229c78d2766SGeorgii Rymar   std::array<Triple::ArchType, 4> Archs = {Triple::bpfel, Triple::bpfeb,
230c78d2766SGeorgii Rymar                                            Triple::bpfel, Triple::bpfeb};
2318a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_BPF)))
2328a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);
233c78d2766SGeorgii Rymar }
234c78d2766SGeorgii Rymar 
235c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForAVR) {
236c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-avr", "elf32-avr", "elf64-unknown",
237c78d2766SGeorgii Rymar                                       "elf64-unknown"};
2388a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_AVR)))
2398a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Triple::avr);
240c78d2766SGeorgii Rymar }
241c78d2766SGeorgii Rymar 
242c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForHEXAGON) {
243c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-hexagon", "elf32-hexagon",
244c78d2766SGeorgii Rymar                                       "elf64-unknown", "elf64-unknown"};
2458a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_HEXAGON)))
2468a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Triple::hexagon);
247c78d2766SGeorgii Rymar }
248c78d2766SGeorgii Rymar 
249c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForLANAI) {
250c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-lanai", "elf32-lanai",
251c78d2766SGeorgii Rymar                                       "elf64-unknown", "elf64-unknown"};
2528a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_LANAI)))
2538a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Triple::lanai);
254c78d2766SGeorgii Rymar }
255c78d2766SGeorgii Rymar 
256c78d2766SGeorgii Rymar TEST(ELFObjectFileTest, MachineTestForMSP430) {
257c78d2766SGeorgii Rymar   std::array<StringRef, 4> Formats = {"elf32-msp430", "elf32-msp430",
258c78d2766SGeorgii Rymar                                       "elf64-unknown", "elf64-unknown"};
2598a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_MSP430)))
2608a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Triple::msp430);
2615921782fSKazushi (Jam) Marukawa }
26269f2c79fSZi Xuan Wu 
263e53e6ec6SLu Weining TEST(ELFObjectFileTest, MachineTestForLoongArch) {
264e53e6ec6SLu Weining   std::array<StringRef, 4> Formats = {"elf32-loongarch", "elf32-loongarch",
265e53e6ec6SLu Weining                                       "elf64-loongarch", "elf64-loongarch"};
266e53e6ec6SLu Weining   std::array<Triple::ArchType, 4> Archs = {
267e53e6ec6SLu Weining       Triple::loongarch32, Triple::loongarch32, Triple::loongarch64,
268e53e6ec6SLu Weining       Triple::loongarch64};
2698a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_LOONGARCH)))
2708a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);
271e53e6ec6SLu Weining }
272e53e6ec6SLu Weining 
27369f2c79fSZi Xuan Wu TEST(ELFObjectFileTest, MachineTestForCSKY) {
27469f2c79fSZi Xuan Wu   std::array<StringRef, 4> Formats = {"elf32-csky", "elf32-csky",
27569f2c79fSZi Xuan Wu                                       "elf64-unknown", "elf64-unknown"};
2768a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_CSKY)))
2778a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Triple::csky);
27869f2c79fSZi Xuan Wu }
27969f2c79fSZi Xuan Wu 
280310f7652SAndrei Safronov TEST(ELFObjectFileTest, MachineTestForXtensa) {
281310f7652SAndrei Safronov   std::array<StringRef, 4> Formats = {"elf32-xtensa", "elf32-xtensa",
282310f7652SAndrei Safronov                                       "elf64-unknown", "elf64-unknown"};
2838a0e0c22SSergei Barannikov   for (auto [Idx, Data] : enumerate(generateData(ELF::EM_XTENSA)))
2848a0e0c22SSergei Barannikov     checkFormatAndArch(Data, Formats[Idx], Triple::xtensa);
285310f7652SAndrei Safronov }
286310f7652SAndrei Safronov 
2873b337bbcSJoseph Huber TEST(ELFObjectFileTest, CheckOSAndTriple) {
2883b337bbcSJoseph Huber   std::tuple<uint16_t, uint8_t, StringRef> Formats[] = {
2893b337bbcSJoseph Huber       {ELF::EM_AMDGPU, ELF::ELFOSABI_AMDGPU_HSA, "amdgcn-amd-amdhsa"},
2903b337bbcSJoseph Huber       {ELF::EM_X86_64, ELF::ELFOSABI_LINUX, "x86_64--linux"},
2913b337bbcSJoseph Huber       {ELF::EM_X86_64, ELF::ELFOSABI_NETBSD, "x86_64--netbsd"},
2923b337bbcSJoseph Huber       {ELF::EM_X86_64, ELF::ELFOSABI_HURD, "x86_64--hurd"},
2933b337bbcSJoseph Huber       {ELF::EM_X86_64, ELF::ELFOSABI_SOLARIS, "x86_64--solaris"},
2943b337bbcSJoseph Huber       {ELF::EM_X86_64, ELF::ELFOSABI_AIX, "x86_64--aix"},
2953b337bbcSJoseph Huber       {ELF::EM_X86_64, ELF::ELFOSABI_FREEBSD, "x86_64--freebsd"},
2963b337bbcSJoseph Huber       {ELF::EM_X86_64, ELF::ELFOSABI_OPENBSD, "x86_64--openbsd"},
2973b337bbcSJoseph Huber       {ELF::EM_CUDA, ELF::ELFOSABI_CUDA, "nvptx64-nvidia-cuda"}};
2983b337bbcSJoseph Huber   for (auto [Machine, OS, Triple] : Formats) {
2993b337bbcSJoseph Huber     const DataForTest D(ELF::ELFCLASS64, ELF::ELFDATA2LSB, Machine, OS,
3003b337bbcSJoseph Huber                         ELF::EF_AMDGPU_MACH_AMDGCN_LAST);
301dfe9bb4dSJoseph Huber     Expected<ELF64LEObjectFile> ELFObjOrErr = ELF64LEObjectFile::create(
3023b337bbcSJoseph Huber         MemoryBufferRef(toStringRef(D.Data), "dummyELF"));
3033b337bbcSJoseph Huber     ASSERT_THAT_EXPECTED(ELFObjOrErr, Succeeded());
3043b337bbcSJoseph Huber 
305dfe9bb4dSJoseph Huber     auto &ELFObj = *ELFObjOrErr;
306c2f5e435SJoseph Huber     llvm::Triple TheTriple = ELFObj.makeTriple();
307c2f5e435SJoseph Huber 
308c2f5e435SJoseph Huber     // The AMDGPU architecture will be unknown on big-endian testers.
3090cb98167SJoseph Huber     if (TheTriple.getArch() == Triple::UnknownArch)
310c2f5e435SJoseph Huber       continue;
311c2f5e435SJoseph Huber 
312c2f5e435SJoseph Huber     EXPECT_EQ(Triple, TheTriple.getTriple());
3133b337bbcSJoseph Huber   }
3143b337bbcSJoseph Huber }
3153b337bbcSJoseph Huber 
31669f2c79fSZi Xuan Wu // ELF relative relocation type test.
31769f2c79fSZi Xuan Wu TEST(ELFObjectFileTest, RelativeRelocationTypeTest) {
31869f2c79fSZi Xuan Wu   EXPECT_EQ(ELF::R_CKCORE_RELATIVE, getELFRelativeRelocationType(ELF::EM_CSKY));
31969f2c79fSZi Xuan Wu }
3201af3cb54SGeorgii Rymar 
3211af3cb54SGeorgii Rymar template <class ELFT>
3221af3cb54SGeorgii Rymar static Expected<ELFObjectFile<ELFT>> toBinary(SmallVectorImpl<char> &Storage,
3231af3cb54SGeorgii Rymar                                               StringRef Yaml) {
3241af3cb54SGeorgii Rymar   raw_svector_ostream OS(Storage);
3251af3cb54SGeorgii Rymar   yaml::Input YIn(Yaml);
3261af3cb54SGeorgii Rymar   if (!yaml::convertYAML(YIn, OS, [](const Twine &Msg) {}))
3271af3cb54SGeorgii Rymar     return createStringError(std::errc::invalid_argument,
3281af3cb54SGeorgii Rymar                              "unable to convert YAML");
3291af3cb54SGeorgii Rymar   return ELFObjectFile<ELFT>::create(MemoryBufferRef(OS.str(), "dummyELF"));
3301af3cb54SGeorgii Rymar }
3311af3cb54SGeorgii Rymar 
3321af3cb54SGeorgii Rymar // Check we are able to create an ELFObjectFile even when the content of the
3331af3cb54SGeorgii Rymar // SHT_SYMTAB_SHNDX section can't be read properly.
3341af3cb54SGeorgii Rymar TEST(ELFObjectFileTest, InvalidSymtabShndxTest) {
3351af3cb54SGeorgii Rymar   SmallString<0> Storage;
3361af3cb54SGeorgii Rymar   Expected<ELFObjectFile<ELF64LE>> ExpectedFile = toBinary<ELF64LE>(Storage, R"(
3371af3cb54SGeorgii Rymar --- !ELF
3381af3cb54SGeorgii Rymar FileHeader:
3391af3cb54SGeorgii Rymar   Class: ELFCLASS64
3401af3cb54SGeorgii Rymar   Data:  ELFDATA2LSB
3411af3cb54SGeorgii Rymar   Type:  ET_REL
3421af3cb54SGeorgii Rymar Sections:
3431af3cb54SGeorgii Rymar   - Name:    .symtab_shndx
3441af3cb54SGeorgii Rymar     Type:    SHT_SYMTAB_SHNDX
3451af3cb54SGeorgii Rymar     Entries: [ 0 ]
3461af3cb54SGeorgii Rymar     ShSize: 0xFFFFFFFF
3471af3cb54SGeorgii Rymar )");
3481af3cb54SGeorgii Rymar 
3491af3cb54SGeorgii Rymar   ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
3501af3cb54SGeorgii Rymar }
35178aea983SGeorgii Rymar 
35278aea983SGeorgii Rymar // Test that we are able to create an ELFObjectFile even when loadable segments
35378aea983SGeorgii Rymar // are unsorted by virtual address.
35478aea983SGeorgii Rymar // Test that ELFFile<ELFT>::toMappedAddr works properly in this case.
35578aea983SGeorgii Rymar 
35678aea983SGeorgii Rymar TEST(ELFObjectFileTest, InvalidLoadSegmentsOrderTest) {
35778aea983SGeorgii Rymar   SmallString<0> Storage;
35878aea983SGeorgii Rymar   Expected<ELFObjectFile<ELF64LE>> ExpectedFile = toBinary<ELF64LE>(Storage, R"(
35978aea983SGeorgii Rymar --- !ELF
36078aea983SGeorgii Rymar FileHeader:
36178aea983SGeorgii Rymar   Class: ELFCLASS64
36278aea983SGeorgii Rymar   Data:  ELFDATA2LSB
36378aea983SGeorgii Rymar   Type:  ET_EXEC
36478aea983SGeorgii Rymar Sections:
36578aea983SGeorgii Rymar   - Name:         .foo
36678aea983SGeorgii Rymar     Type:         SHT_PROGBITS
36778aea983SGeorgii Rymar     Address:      0x1000
36878aea983SGeorgii Rymar     Offset:       0x3000
36978aea983SGeorgii Rymar     ContentArray: [ 0x11 ]
37078aea983SGeorgii Rymar   - Name:         .bar
37178aea983SGeorgii Rymar     Type:         SHT_PROGBITS
37278aea983SGeorgii Rymar     Address:      0x2000
37378aea983SGeorgii Rymar     Offset:       0x4000
37478aea983SGeorgii Rymar     ContentArray: [ 0x99 ]
37578aea983SGeorgii Rymar ProgramHeaders:
37678aea983SGeorgii Rymar   - Type:     PT_LOAD
37778aea983SGeorgii Rymar     VAddr:    0x2000
37878aea983SGeorgii Rymar     FirstSec: .bar
37978aea983SGeorgii Rymar     LastSec:  .bar
38078aea983SGeorgii Rymar   - Type:     PT_LOAD
38178aea983SGeorgii Rymar     VAddr:    0x1000
38278aea983SGeorgii Rymar     FirstSec: .foo
38378aea983SGeorgii Rymar     LastSec:  .foo
38478aea983SGeorgii Rymar )");
38578aea983SGeorgii Rymar 
38678aea983SGeorgii Rymar   ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
38778aea983SGeorgii Rymar 
38878aea983SGeorgii Rymar   std::string WarnString;
38978aea983SGeorgii Rymar   auto ToMappedAddr = [&](uint64_t Addr) -> const uint8_t * {
39078aea983SGeorgii Rymar     Expected<const uint8_t *> DataOrErr =
39178aea983SGeorgii Rymar         ExpectedFile->getELFFile().toMappedAddr(Addr, [&](const Twine &Msg) {
39278aea983SGeorgii Rymar           EXPECT_TRUE(WarnString.empty());
39378aea983SGeorgii Rymar           WarnString = Msg.str();
39478aea983SGeorgii Rymar           return Error::success();
39578aea983SGeorgii Rymar         });
39678aea983SGeorgii Rymar 
39778aea983SGeorgii Rymar     if (!DataOrErr) {
39878aea983SGeorgii Rymar       ADD_FAILURE() << toString(DataOrErr.takeError());
39978aea983SGeorgii Rymar       return nullptr;
40078aea983SGeorgii Rymar     }
40178aea983SGeorgii Rymar 
40278aea983SGeorgii Rymar     EXPECT_TRUE(WarnString ==
40378aea983SGeorgii Rymar                 "loadable segments are unsorted by virtual address");
40478aea983SGeorgii Rymar     WarnString = "";
40578aea983SGeorgii Rymar     return *DataOrErr;
40678aea983SGeorgii Rymar   };
40778aea983SGeorgii Rymar 
40878aea983SGeorgii Rymar   const uint8_t *Data = ToMappedAddr(0x1000);
40978aea983SGeorgii Rymar   ASSERT_TRUE(Data);
41078aea983SGeorgii Rymar   MemoryBufferRef Buf = ExpectedFile->getMemoryBufferRef();
41178aea983SGeorgii Rymar   EXPECT_EQ((const char *)Data - Buf.getBufferStart(), 0x3000);
41278aea983SGeorgii Rymar   EXPECT_EQ(Data[0], 0x11);
41378aea983SGeorgii Rymar 
41478aea983SGeorgii Rymar   Data = ToMappedAddr(0x2000);
41578aea983SGeorgii Rymar   ASSERT_TRUE(Data);
41678aea983SGeorgii Rymar   Buf = ExpectedFile->getMemoryBufferRef();
41778aea983SGeorgii Rymar   EXPECT_EQ((const char *)Data - Buf.getBufferStart(), 0x4000);
41878aea983SGeorgii Rymar   EXPECT_EQ(Data[0], 0x99);
41978aea983SGeorgii Rymar }
420407d4200SGeorgii Rymar 
421407d4200SGeorgii Rymar // This is a test for API that is related to symbols.
422407d4200SGeorgii Rymar // We check that errors are properly reported here.
423407d4200SGeorgii Rymar TEST(ELFObjectFileTest, InvalidSymbolTest) {
424407d4200SGeorgii Rymar   SmallString<0> Storage;
425407d4200SGeorgii Rymar   Expected<ELFObjectFile<ELF64LE>> ElfOrErr = toBinary<ELF64LE>(Storage, R"(
426407d4200SGeorgii Rymar --- !ELF
427407d4200SGeorgii Rymar FileHeader:
428407d4200SGeorgii Rymar   Class:   ELFCLASS64
429407d4200SGeorgii Rymar   Data:    ELFDATA2LSB
430407d4200SGeorgii Rymar   Type:    ET_DYN
431407d4200SGeorgii Rymar   Machine: EM_X86_64
432407d4200SGeorgii Rymar Sections:
433407d4200SGeorgii Rymar   - Name: .symtab
434407d4200SGeorgii Rymar     Type: SHT_SYMTAB
435407d4200SGeorgii Rymar )");
436407d4200SGeorgii Rymar 
437407d4200SGeorgii Rymar   ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
438407d4200SGeorgii Rymar   const ELFFile<ELF64LE> &Elf = ElfOrErr->getELFFile();
439407d4200SGeorgii Rymar   const ELFObjectFile<ELF64LE> &Obj = *ElfOrErr;
440407d4200SGeorgii Rymar 
441407d4200SGeorgii Rymar   Expected<const typename ELF64LE::Shdr *> SymtabSecOrErr = Elf.getSection(1);
442407d4200SGeorgii Rymar   ASSERT_THAT_EXPECTED(SymtabSecOrErr, Succeeded());
443407d4200SGeorgii Rymar   ASSERT_EQ((*SymtabSecOrErr)->sh_type, ELF::SHT_SYMTAB);
444407d4200SGeorgii Rymar 
4458590b5ccSGeorgii Rymar   auto DoCheck = [&](unsigned BrokenSymIndex, const char *ErrMsg) {
446407d4200SGeorgii Rymar     ELFSymbolRef BrokenSym = Obj.toSymbolRef(*SymtabSecOrErr, BrokenSymIndex);
447407d4200SGeorgii Rymar 
448407d4200SGeorgii Rymar     // 1) Check the behavior of ELFObjectFile<ELFT>::getSymbolName().
449407d4200SGeorgii Rymar     //    SymbolRef::getName() calls it internally. We can't test it directly,
450407d4200SGeorgii Rymar     //    because it is protected.
4518590b5ccSGeorgii Rymar     EXPECT_THAT_ERROR(BrokenSym.getName().takeError(),
4528590b5ccSGeorgii Rymar                       FailedWithMessage(ErrMsg));
453407d4200SGeorgii Rymar 
454407d4200SGeorgii Rymar     // 2) Check the behavior of ELFObjectFile<ELFT>::getSymbol().
455407d4200SGeorgii Rymar     EXPECT_THAT_ERROR(Obj.getSymbol(BrokenSym.getRawDataRefImpl()).takeError(),
456407d4200SGeorgii Rymar                       FailedWithMessage(ErrMsg));
457407d4200SGeorgii Rymar 
458407d4200SGeorgii Rymar     // 3) Check the behavior of ELFObjectFile<ELFT>::getSymbolSection().
4598590b5ccSGeorgii Rymar     //    SymbolRef::getSection() calls it internally. We can't test it
4608590b5ccSGeorgii Rymar     //    directly, because it is protected.
461407d4200SGeorgii Rymar     EXPECT_THAT_ERROR(BrokenSym.getSection().takeError(),
462407d4200SGeorgii Rymar                       FailedWithMessage(ErrMsg));
463407d4200SGeorgii Rymar 
464407d4200SGeorgii Rymar     // 4) Check the behavior of ELFObjectFile<ELFT>::getSymbolFlags().
465407d4200SGeorgii Rymar     //    SymbolRef::getFlags() calls it internally. We can't test it directly,
466407d4200SGeorgii Rymar     //    because it is protected.
467407d4200SGeorgii Rymar     EXPECT_THAT_ERROR(BrokenSym.getFlags().takeError(),
468407d4200SGeorgii Rymar                       FailedWithMessage(ErrMsg));
469407d4200SGeorgii Rymar 
470407d4200SGeorgii Rymar     // 5) Check the behavior of ELFObjectFile<ELFT>::getSymbolType().
471407d4200SGeorgii Rymar     //    SymbolRef::getType() calls it internally. We can't test it directly,
472407d4200SGeorgii Rymar     //    because it is protected.
4738590b5ccSGeorgii Rymar     EXPECT_THAT_ERROR(BrokenSym.getType().takeError(),
4748590b5ccSGeorgii Rymar                       FailedWithMessage(ErrMsg));
475407d4200SGeorgii Rymar 
476407d4200SGeorgii Rymar     // 6) Check the behavior of ELFObjectFile<ELFT>::getSymbolAddress().
4778590b5ccSGeorgii Rymar     //    SymbolRef::getAddress() calls it internally. We can't test it
4788590b5ccSGeorgii Rymar     //    directly, because it is protected.
479407d4200SGeorgii Rymar     EXPECT_THAT_ERROR(BrokenSym.getAddress().takeError(),
480407d4200SGeorgii Rymar                       FailedWithMessage(ErrMsg));
481407d4200SGeorgii Rymar 
482407d4200SGeorgii Rymar     // Finally, check the `ELFFile<ELFT>::getEntry` API. This is an underlying
483407d4200SGeorgii Rymar     // method that generates errors for all cases above.
4848590b5ccSGeorgii Rymar     EXPECT_THAT_EXPECTED(
4858590b5ccSGeorgii Rymar         Elf.getEntry<typename ELF64LE::Sym>(**SymtabSecOrErr, 0), Succeeded());
486407d4200SGeorgii Rymar     EXPECT_THAT_ERROR(
487407d4200SGeorgii Rymar         Elf.getEntry<typename ELF64LE::Sym>(**SymtabSecOrErr, BrokenSymIndex)
488407d4200SGeorgii Rymar             .takeError(),
489407d4200SGeorgii Rymar         FailedWithMessage(ErrMsg));
4908590b5ccSGeorgii Rymar   };
4918590b5ccSGeorgii Rymar 
4928590b5ccSGeorgii Rymar   // We create a symbol with an index that is too large to exist in the symbol
4938590b5ccSGeorgii Rymar   // table.
4948590b5ccSGeorgii Rymar   DoCheck(0x1, "can't read an entry at 0x18: it goes past the end of the "
4958590b5ccSGeorgii Rymar                "section (0x18)");
4968590b5ccSGeorgii Rymar 
4978590b5ccSGeorgii Rymar   // We create a symbol with an index that is too large to exist in the object.
4988590b5ccSGeorgii Rymar   DoCheck(0xFFFFFFFF, "can't read an entry at 0x17ffffffe8: it goes past the "
4998590b5ccSGeorgii Rymar                       "end of the section (0x18)");
500407d4200SGeorgii Rymar }
501c245c21cSRahman Lavaee 
502c245c21cSRahman Lavaee // Tests for error paths of the ELFFile::decodeBBAddrMap API.
5035f7ef652SRahman Lavaee TEST(ELFObjectFileTest, InvalidDecodeBBAddrMap) {
504c245c21cSRahman Lavaee   StringRef CommonYamlString(R"(
505c245c21cSRahman Lavaee --- !ELF
506c245c21cSRahman Lavaee FileHeader:
507c245c21cSRahman Lavaee   Class: ELFCLASS64
508c245c21cSRahman Lavaee   Data:  ELFDATA2LSB
509c245c21cSRahman Lavaee   Type:  ET_EXEC
510c245c21cSRahman Lavaee Sections:
5110aa6df65SRahman Lavaee   - Type: SHT_LLVM_BB_ADDR_MAP
5120aa6df65SRahman Lavaee     Name: .llvm_bb_addr_map
513c245c21cSRahman Lavaee     Entries:
514c245c21cSRahman Lavaee )");
515c245c21cSRahman Lavaee 
516c245c21cSRahman Lavaee   auto DoCheck = [&](StringRef YamlString, const char *ErrMsg) {
517c245c21cSRahman Lavaee     SmallString<0> Storage;
518c245c21cSRahman Lavaee     Expected<ELFObjectFile<ELF64LE>> ElfOrErr =
519c245c21cSRahman Lavaee         toBinary<ELF64LE>(Storage, YamlString);
520c245c21cSRahman Lavaee     ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
521c245c21cSRahman Lavaee     const ELFFile<ELF64LE> &Elf = ElfOrErr->getELFFile();
522c245c21cSRahman Lavaee 
523c245c21cSRahman Lavaee     Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr =
524c245c21cSRahman Lavaee         Elf.getSection(1);
525c245c21cSRahman Lavaee     ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded());
526c245c21cSRahman Lavaee     EXPECT_THAT_ERROR(Elf.decodeBBAddrMap(**BBAddrMapSecOrErr).takeError(),
527c245c21cSRahman Lavaee                       FailedWithMessage(ErrMsg));
528c245c21cSRahman Lavaee   };
529c245c21cSRahman Lavaee 
5300aa6df65SRahman Lavaee   // Check that we can detect unsupported versions.
5310aa6df65SRahman Lavaee   SmallString<128> UnsupportedVersionYamlString(CommonYamlString);
5320aa6df65SRahman Lavaee   UnsupportedVersionYamlString += R"(
533acec6419SRahman Lavaee       - Version: 3
534acec6419SRahman Lavaee         BBRanges:
535acec6419SRahman Lavaee           - BaseAddress: 0x11111
5360aa6df65SRahman Lavaee             BBEntries:
5370aa6df65SRahman Lavaee               - AddressOffset: 0x0
5380aa6df65SRahman Lavaee                 Size:          0x1
5390aa6df65SRahman Lavaee                 Metadata:      0x2
5400aa6df65SRahman Lavaee )";
5410aa6df65SRahman Lavaee 
5426ba2c2bbSRahman Lavaee   {
5436ba2c2bbSRahman Lavaee     SCOPED_TRACE("unsupported version");
5440aa6df65SRahman Lavaee     DoCheck(UnsupportedVersionYamlString,
5453d6841b2SRahman Lavaee             "unsupported SHT_LLVM_BB_ADDR_MAP version: 3");
5466ba2c2bbSRahman Lavaee   }
5470aa6df65SRahman Lavaee 
548acec6419SRahman Lavaee   SmallString<128> ZeroBBRangesYamlString(CommonYamlString);
549acec6419SRahman Lavaee   ZeroBBRangesYamlString += R"(
550acec6419SRahman Lavaee       - Version: 2
551acec6419SRahman Lavaee         Feature: 0x8
552acec6419SRahman Lavaee         BBRanges: []
553acec6419SRahman Lavaee )";
554acec6419SRahman Lavaee   {
555acec6419SRahman Lavaee     SCOPED_TRACE("zero bb ranges");
556acec6419SRahman Lavaee     DoCheck(ZeroBBRangesYamlString,
557acec6419SRahman Lavaee             "invalid zero number of BB ranges at offset 3 in "
558acec6419SRahman Lavaee             "SHT_LLVM_BB_ADDR_MAP section with index 1");
559acec6419SRahman Lavaee   }
560acec6419SRahman Lavaee 
5610aa6df65SRahman Lavaee   SmallString<128> CommonVersionedYamlString(CommonYamlString);
5620aa6df65SRahman Lavaee   CommonVersionedYamlString += R"(
563acec6419SRahman Lavaee       - Version: 2
564acec6419SRahman Lavaee         BBRanges:
565acec6419SRahman Lavaee           - BaseAddress: 0x11111
5660aa6df65SRahman Lavaee             BBEntries:
567acec6419SRahman Lavaee               - AddressOffset: 0x0
5680aa6df65SRahman Lavaee                 Size:          0x1
5690aa6df65SRahman Lavaee                 Metadata:      0x2
5700aa6df65SRahman Lavaee )";
5710aa6df65SRahman Lavaee 
572c245c21cSRahman Lavaee   // Check that we can detect the malformed encoding when the section is
573c245c21cSRahman Lavaee   // truncated.
5740aa6df65SRahman Lavaee   SmallString<128> TruncatedYamlString(CommonVersionedYamlString);
575c245c21cSRahman Lavaee   TruncatedYamlString += R"(
5763d6841b2SRahman Lavaee     ShSize: 0xb
577c245c21cSRahman Lavaee )";
5786ba2c2bbSRahman Lavaee   {
5796ba2c2bbSRahman Lavaee     SCOPED_TRACE("truncated section");
5806ba2c2bbSRahman Lavaee     DoCheck(TruncatedYamlString,
5816ba2c2bbSRahman Lavaee             "unable to decode LEB128 at offset 0x0000000b: "
582c245c21cSRahman Lavaee             "malformed uleb128, extends past end");
5836ba2c2bbSRahman Lavaee   }
584c245c21cSRahman Lavaee 
585c245c21cSRahman Lavaee   // Check that we can detect when the encoded BB entry fields exceed the UINT32
586c245c21cSRahman Lavaee   // limit.
5870aa6df65SRahman Lavaee   SmallVector<SmallString<128>, 3> OverInt32LimitYamlStrings(
5880aa6df65SRahman Lavaee       3, CommonVersionedYamlString);
589c245c21cSRahman Lavaee   OverInt32LimitYamlStrings[0] += R"(
5903d6841b2SRahman Lavaee               - ID:            1
5913d6841b2SRahman Lavaee                 AddressOffset: 0x100000000
592c245c21cSRahman Lavaee                 Size:          0xFFFFFFFF
593c245c21cSRahman Lavaee                 Metadata:      0xFFFFFFFF
594c245c21cSRahman Lavaee )";
595c245c21cSRahman Lavaee 
596c245c21cSRahman Lavaee   OverInt32LimitYamlStrings[1] += R"(
5973d6841b2SRahman Lavaee               - ID:            2
5983d6841b2SRahman Lavaee                 AddressOffset: 0xFFFFFFFF
599c245c21cSRahman Lavaee                 Size:          0x100000000
600c245c21cSRahman Lavaee                 Metadata:      0xFFFFFFFF
601c245c21cSRahman Lavaee )";
602c245c21cSRahman Lavaee 
603c245c21cSRahman Lavaee   OverInt32LimitYamlStrings[2] += R"(
6043d6841b2SRahman Lavaee               - ID:            3
6053d6841b2SRahman Lavaee                 AddressOffset: 0xFFFFFFFF
606c245c21cSRahman Lavaee                 Size:          0xFFFFFFFF
607c245c21cSRahman Lavaee                 Metadata:      0x100000000
608c245c21cSRahman Lavaee )";
609c245c21cSRahman Lavaee 
6106ba2c2bbSRahman Lavaee   {
6116ba2c2bbSRahman Lavaee     SCOPED_TRACE("overlimit fields");
612c245c21cSRahman Lavaee     DoCheck(OverInt32LimitYamlStrings[0],
6133d6841b2SRahman Lavaee             "ULEB128 value at offset 0x10 exceeds UINT32_MAX (0x100000000)");
614c245c21cSRahman Lavaee     DoCheck(OverInt32LimitYamlStrings[1],
6153d6841b2SRahman Lavaee             "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000)");
616c245c21cSRahman Lavaee     DoCheck(OverInt32LimitYamlStrings[2],
6173d6841b2SRahman Lavaee             "ULEB128 value at offset 0x1a exceeds UINT32_MAX (0x100000000)");
6186ba2c2bbSRahman Lavaee   }
619c245c21cSRahman Lavaee 
620c245c21cSRahman Lavaee   // Check the proper error handling when the section has fields exceeding
621c245c21cSRahman Lavaee   // UINT32 and is also truncated. This is for checking that we don't generate
622c245c21cSRahman Lavaee   // unhandled errors.
623c245c21cSRahman Lavaee   SmallVector<SmallString<128>, 3> OverInt32LimitAndTruncated(
624c245c21cSRahman Lavaee       3, OverInt32LimitYamlStrings[1]);
625c245c21cSRahman Lavaee   // Truncate before the end of the 5-byte field.
626c245c21cSRahman Lavaee   OverInt32LimitAndTruncated[0] += R"(
6273d6841b2SRahman Lavaee     ShSize: 0x19
628c245c21cSRahman Lavaee )";
629c245c21cSRahman Lavaee   // Truncate at the end of the 5-byte field.
630c245c21cSRahman Lavaee   OverInt32LimitAndTruncated[1] += R"(
6313d6841b2SRahman Lavaee     ShSize: 0x1a
632c245c21cSRahman Lavaee )";
633c245c21cSRahman Lavaee   // Truncate after the end of the 5-byte field.
634c245c21cSRahman Lavaee   OverInt32LimitAndTruncated[2] += R"(
6353d6841b2SRahman Lavaee     ShSize: 0x1b
636c245c21cSRahman Lavaee )";
637c245c21cSRahman Lavaee 
6386ba2c2bbSRahman Lavaee   {
6396ba2c2bbSRahman Lavaee     SCOPED_TRACE("overlimit fields, truncated section");
640c245c21cSRahman Lavaee     DoCheck(OverInt32LimitAndTruncated[0],
6413d6841b2SRahman Lavaee             "unable to decode LEB128 at offset 0x00000015: malformed uleb128, "
642c245c21cSRahman Lavaee             "extends past end");
643c245c21cSRahman Lavaee     DoCheck(OverInt32LimitAndTruncated[1],
6443d6841b2SRahman Lavaee             "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000)");
645c245c21cSRahman Lavaee     DoCheck(OverInt32LimitAndTruncated[2],
6463d6841b2SRahman Lavaee             "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000)");
6476ba2c2bbSRahman Lavaee   }
648c245c21cSRahman Lavaee 
649c245c21cSRahman Lavaee   // Check for proper error handling when the 'NumBlocks' field is overridden
650c245c21cSRahman Lavaee   // with an out-of-range value.
6510aa6df65SRahman Lavaee   SmallString<128> OverLimitNumBlocks(CommonVersionedYamlString);
652c245c21cSRahman Lavaee   OverLimitNumBlocks += R"(
653c245c21cSRahman Lavaee             NumBlocks: 0x100000000
654c245c21cSRahman Lavaee )";
655c245c21cSRahman Lavaee 
6566ba2c2bbSRahman Lavaee   {
6576ba2c2bbSRahman Lavaee     SCOPED_TRACE("overlimit 'NumBlocks' field");
658c245c21cSRahman Lavaee     DoCheck(OverLimitNumBlocks,
6590aa6df65SRahman Lavaee             "ULEB128 value at offset 0xa exceeds UINT32_MAX (0x100000000)");
660c245c21cSRahman Lavaee   }
661acec6419SRahman Lavaee 
662acec6419SRahman Lavaee   // Check for proper error handling when the 'NumBBRanges' field is overridden
663acec6419SRahman Lavaee   // with an out-of-range value.
664acec6419SRahman Lavaee   SmallString<128> OverLimitNumBBRanges(CommonVersionedYamlString);
665acec6419SRahman Lavaee   OverLimitNumBBRanges += R"(
666acec6419SRahman Lavaee         NumBBRanges: 0x100000000
667acec6419SRahman Lavaee         Feature:     0x8
668acec6419SRahman Lavaee )";
669acec6419SRahman Lavaee   DoCheck(OverLimitNumBBRanges,
670acec6419SRahman Lavaee           "ULEB128 value at offset 0x2 exceeds UINT32_MAX (0x100000000)");
6716ba2c2bbSRahman Lavaee }
6728ec73e96SAmir Ayupov 
6735f7ef652SRahman Lavaee // Test for the ELFObjectFile::readBBAddrMap API.
6745f7ef652SRahman Lavaee TEST(ELFObjectFileTest, ReadBBAddrMap) {
6755f7ef652SRahman Lavaee   StringRef CommonYamlString(R"(
6765f7ef652SRahman Lavaee --- !ELF
6775f7ef652SRahman Lavaee FileHeader:
6785f7ef652SRahman Lavaee   Class: ELFCLASS64
6795f7ef652SRahman Lavaee   Data:  ELFDATA2LSB
6805f7ef652SRahman Lavaee   Type:  ET_EXEC
6815f7ef652SRahman Lavaee Sections:
6825f7ef652SRahman Lavaee   - Name: .llvm_bb_addr_map_1
6835f7ef652SRahman Lavaee     Type: SHT_LLVM_BB_ADDR_MAP
6845f7ef652SRahman Lavaee     Link: 1
6855f7ef652SRahman Lavaee     Entries:
6863d6841b2SRahman Lavaee       - Version: 2
687acec6419SRahman Lavaee         BBRanges:
688acec6419SRahman Lavaee           - BaseAddress: 0x11111
6895f7ef652SRahman Lavaee             BBEntries:
6903d6841b2SRahman Lavaee               - ID:            1
6913d6841b2SRahman Lavaee                 AddressOffset: 0x0
6925f7ef652SRahman Lavaee                 Size:          0x1
6935f7ef652SRahman Lavaee                 Metadata:      0x2
6945f7ef652SRahman Lavaee   - Name: .llvm_bb_addr_map_2
6955f7ef652SRahman Lavaee     Type: SHT_LLVM_BB_ADDR_MAP
6965f7ef652SRahman Lavaee     Link: 1
6975f7ef652SRahman Lavaee     Entries:
6983d6841b2SRahman Lavaee       - Version: 2
699acec6419SRahman Lavaee         Feature: 0x8
700acec6419SRahman Lavaee         BBRanges:
701acec6419SRahman Lavaee           - BaseAddress: 0x22222
7025f7ef652SRahman Lavaee             BBEntries:
7033d6841b2SRahman Lavaee               - ID:            2
7043d6841b2SRahman Lavaee                 AddressOffset: 0x0
7055f7ef652SRahman Lavaee                 Size:          0x2
7065f7ef652SRahman Lavaee                 Metadata:      0x4
707acec6419SRahman Lavaee           - BaseAddress: 0xFFFFF
708acec6419SRahman Lavaee             BBEntries:
709acec6419SRahman Lavaee               - ID:            15
710acec6419SRahman Lavaee                 AddressOffset: 0xF0
711acec6419SRahman Lavaee                 Size:          0xF1
712acec6419SRahman Lavaee                 Metadata:      0x1F
7133d6841b2SRahman Lavaee   - Name: .llvm_bb_addr_map_3
7143d6841b2SRahman Lavaee     Type: SHT_LLVM_BB_ADDR_MAP
7153d6841b2SRahman Lavaee     Link: 2
7166015a045SRahman Lavaee     Entries:
7173d6841b2SRahman Lavaee       - Version: 1
718acec6419SRahman Lavaee         BBRanges:
719acec6419SRahman Lavaee           - BaseAddress: 0x33333
7206015a045SRahman Lavaee             BBEntries:
7213d6841b2SRahman Lavaee               - ID:            0
7223d6841b2SRahman Lavaee                 AddressOffset: 0x0
72396b6ee1bSRahman Lavaee                 Size:          0x3
72496b6ee1bSRahman Lavaee                 Metadata:      0x6
7253d6841b2SRahman Lavaee   - Name: .llvm_bb_addr_map_4
726acec6419SRahman Lavaee     Type: SHT_LLVM_BB_ADDR_MAP
7273d6841b2SRahman Lavaee   # Link: 0 (by default, can be overriden)
7283d6841b2SRahman Lavaee     Entries:
729acec6419SRahman Lavaee       - Version: 2
730acec6419SRahman Lavaee         BBRanges:
731acec6419SRahman Lavaee           - BaseAddress: 0x44444
7323d6841b2SRahman Lavaee             BBEntries:
7333d6841b2SRahman Lavaee               - ID:            0
7343d6841b2SRahman Lavaee                 AddressOffset: 0x0
7353d6841b2SRahman Lavaee                 Size:          0x4
7369c3c6f6aSRahman Lavaee                 Metadata:      0x18
7375f7ef652SRahman Lavaee )");
7385f7ef652SRahman Lavaee 
739acec6419SRahman Lavaee   BBAddrMap E1 = {
740acec6419SRahman Lavaee       {{0x11111, {{1, 0x0, 0x1, {false, true, false, false, false}}}}}};
741acec6419SRahman Lavaee   BBAddrMap E2 = {
742acec6419SRahman Lavaee       {{0x22222, {{2, 0x0, 0x2, {false, false, true, false, false}}}},
743acec6419SRahman Lavaee        {0xFFFFF, {{15, 0xF0, 0xF1, {true, true, true, true, true}}}}}};
744acec6419SRahman Lavaee   BBAddrMap E3 = {
745acec6419SRahman Lavaee       {{0x33333, {{0, 0x0, 0x3, {false, true, true, false, false}}}}}};
746acec6419SRahman Lavaee   BBAddrMap E4 = {
747acec6419SRahman Lavaee       {{0x44444, {{0, 0x0, 0x4, {false, false, false, true, true}}}}}};
7485f7ef652SRahman Lavaee 
7493d6841b2SRahman Lavaee   std::vector<BBAddrMap> Section0BBAddrMaps = {E4};
7503d6841b2SRahman Lavaee   std::vector<BBAddrMap> Section1BBAddrMaps = {E3};
7513d6841b2SRahman Lavaee   std::vector<BBAddrMap> Section2BBAddrMaps = {E1, E2};
7523d6841b2SRahman Lavaee   std::vector<BBAddrMap> AllBBAddrMaps = {E1, E2, E3, E4};
7535f7ef652SRahman Lavaee 
7545f7ef652SRahman Lavaee   auto DoCheckSucceeds = [&](StringRef YamlString,
755c302fb5cSFangrui Song                              std::optional<unsigned> TextSectionIndex,
7565f7ef652SRahman Lavaee                              std::vector<BBAddrMap> ExpectedResult) {
7576ba2c2bbSRahman Lavaee     SCOPED_TRACE("for TextSectionIndex: " +
7586ba2c2bbSRahman Lavaee                  (TextSectionIndex ? llvm::Twine(*TextSectionIndex) : "{}") +
7596ba2c2bbSRahman Lavaee                  " and object yaml:\n" + YamlString);
7605f7ef652SRahman Lavaee     SmallString<0> Storage;
7615f7ef652SRahman Lavaee     Expected<ELFObjectFile<ELF64LE>> ElfOrErr =
7625f7ef652SRahman Lavaee         toBinary<ELF64LE>(Storage, YamlString);
7635f7ef652SRahman Lavaee     ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
7645f7ef652SRahman Lavaee 
7655f7ef652SRahman Lavaee     Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr =
7665f7ef652SRahman Lavaee         ElfOrErr->getELFFile().getSection(1);
7675f7ef652SRahman Lavaee     ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded());
7685f7ef652SRahman Lavaee     auto BBAddrMaps = ElfOrErr->readBBAddrMap(TextSectionIndex);
769105adf2cSMicah Weston     ASSERT_THAT_EXPECTED(BBAddrMaps, Succeeded());
7705f7ef652SRahman Lavaee     EXPECT_EQ(*BBAddrMaps, ExpectedResult);
7715f7ef652SRahman Lavaee   };
7725f7ef652SRahman Lavaee 
7735f7ef652SRahman Lavaee   auto DoCheckFails = [&](StringRef YamlString,
774c302fb5cSFangrui Song                           std::optional<unsigned> TextSectionIndex,
7755f7ef652SRahman Lavaee                           const char *ErrMsg) {
7766ba2c2bbSRahman Lavaee     SCOPED_TRACE("for TextSectionIndex: " +
7776ba2c2bbSRahman Lavaee                  (TextSectionIndex ? llvm::Twine(*TextSectionIndex) : "{}") +
7786ba2c2bbSRahman Lavaee                  " and object yaml:\n" + YamlString);
7795f7ef652SRahman Lavaee     SmallString<0> Storage;
7805f7ef652SRahman Lavaee     Expected<ELFObjectFile<ELF64LE>> ElfOrErr =
7815f7ef652SRahman Lavaee         toBinary<ELF64LE>(Storage, YamlString);
7825f7ef652SRahman Lavaee     ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
7835f7ef652SRahman Lavaee 
7845f7ef652SRahman Lavaee     Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr =
7855f7ef652SRahman Lavaee         ElfOrErr->getELFFile().getSection(1);
7865f7ef652SRahman Lavaee     ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded());
7875f7ef652SRahman Lavaee     EXPECT_THAT_ERROR(ElfOrErr->readBBAddrMap(TextSectionIndex).takeError(),
7885f7ef652SRahman Lavaee                       FailedWithMessage(ErrMsg));
7895f7ef652SRahman Lavaee   };
7905f7ef652SRahman Lavaee 
7916ba2c2bbSRahman Lavaee   {
7926ba2c2bbSRahman Lavaee     SCOPED_TRACE("normal sections");
7935f7ef652SRahman Lavaee     // Check that we can retrieve the data in the normal case.
794b6a01caaSKazu Hirata     DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/std::nullopt,
795b6a01caaSKazu Hirata                     AllBBAddrMaps);
7966ba2c2bbSRahman Lavaee     DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/0,
7976ba2c2bbSRahman Lavaee                     Section0BBAddrMaps);
7986ba2c2bbSRahman Lavaee     DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/2,
7996ba2c2bbSRahman Lavaee                     Section1BBAddrMaps);
8006ba2c2bbSRahman Lavaee     DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/1,
8016ba2c2bbSRahman Lavaee                     Section2BBAddrMaps);
8025f7ef652SRahman Lavaee     // Check that when no bb-address-map section is found for a text section,
8035f7ef652SRahman Lavaee     // we return an empty result.
8043d6841b2SRahman Lavaee     DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/3, {});
8056ba2c2bbSRahman Lavaee   }
8065f7ef652SRahman Lavaee 
8075f7ef652SRahman Lavaee   // Check that we detect when a bb-addr-map section is linked to an invalid
8085f7ef652SRahman Lavaee   // (not present) section.
8095f7ef652SRahman Lavaee   SmallString<128> InvalidLinkedYamlString(CommonYamlString);
8105f7ef652SRahman Lavaee   InvalidLinkedYamlString += R"(
811acec6419SRahman Lavaee     Link: 121
8125f7ef652SRahman Lavaee )";
8135f7ef652SRahman Lavaee 
8143d6841b2SRahman Lavaee   DoCheckFails(InvalidLinkedYamlString, /*TextSectionIndex=*/4,
8150aa6df65SRahman Lavaee                "unable to get the linked-to section for "
816acec6419SRahman Lavaee                "SHT_LLVM_BB_ADDR_MAP section with index 4: invalid section "
817acec6419SRahman Lavaee                "index: 121");
8186ba2c2bbSRahman Lavaee   {
8196ba2c2bbSRahman Lavaee     SCOPED_TRACE("invalid linked section");
8205f7ef652SRahman Lavaee     // Linked sections are not checked when we don't target a specific text
8215f7ef652SRahman Lavaee     // section.
822b6a01caaSKazu Hirata     DoCheckSucceeds(InvalidLinkedYamlString, /*TextSectionIndex=*/std::nullopt,
8235f7ef652SRahman Lavaee                     AllBBAddrMaps);
8246ba2c2bbSRahman Lavaee   }
8255f7ef652SRahman Lavaee 
8265f7ef652SRahman Lavaee   // Check that we can detect when bb-address-map decoding fails.
8275f7ef652SRahman Lavaee   SmallString<128> TruncatedYamlString(CommonYamlString);
8285f7ef652SRahman Lavaee   TruncatedYamlString += R"(
829acec6419SRahman Lavaee     ShSize: 0xa
8305f7ef652SRahman Lavaee )";
8315f7ef652SRahman Lavaee 
8326ba2c2bbSRahman Lavaee   {
8336ba2c2bbSRahman Lavaee     SCOPED_TRACE("truncated section");
834b6a01caaSKazu Hirata     DoCheckFails(TruncatedYamlString, /*TextSectionIndex=*/std::nullopt,
835acec6419SRahman Lavaee                  "unable to read SHT_LLVM_BB_ADDR_MAP section with index 4: "
836acec6419SRahman Lavaee                  "unable to decode LEB128 at offset 0x0000000a: malformed "
8375f7ef652SRahman Lavaee                  "uleb128, extends past end");
8386ba2c2bbSRahman Lavaee 
8395f7ef652SRahman Lavaee     // Check that we can read the other section's bb-address-maps which are
8405f7ef652SRahman Lavaee     // valid.
8413d6841b2SRahman Lavaee     DoCheckSucceeds(TruncatedYamlString, /*TextSectionIndex=*/2,
8425f7ef652SRahman Lavaee                     Section1BBAddrMaps);
8435f7ef652SRahman Lavaee   }
8446ba2c2bbSRahman Lavaee }
8455f7ef652SRahman Lavaee 
846105adf2cSMicah Weston // Tests for error paths of the ELFFile::decodeBBAddrMap with PGOAnalysisMap
847105adf2cSMicah Weston // API.
848105adf2cSMicah Weston TEST(ELFObjectFileTest, InvalidDecodePGOAnalysisMap) {
849105adf2cSMicah Weston   StringRef CommonYamlString(R"(
850105adf2cSMicah Weston --- !ELF
851105adf2cSMicah Weston FileHeader:
852105adf2cSMicah Weston   Class: ELFCLASS64
853105adf2cSMicah Weston   Data:  ELFDATA2LSB
854105adf2cSMicah Weston   Type:  ET_EXEC
855105adf2cSMicah Weston Sections:
856105adf2cSMicah Weston   - Type: SHT_LLVM_BB_ADDR_MAP
857105adf2cSMicah Weston     Name: .llvm_bb_addr_map
858105adf2cSMicah Weston     Entries:
859105adf2cSMicah Weston )");
860105adf2cSMicah Weston 
861105adf2cSMicah Weston   auto DoCheck = [&](StringRef YamlString, const char *ErrMsg) {
862105adf2cSMicah Weston     SmallString<0> Storage;
863105adf2cSMicah Weston     Expected<ELFObjectFile<ELF64LE>> ElfOrErr =
864105adf2cSMicah Weston         toBinary<ELF64LE>(Storage, YamlString);
865105adf2cSMicah Weston     ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
866105adf2cSMicah Weston     const ELFFile<ELF64LE> &Elf = ElfOrErr->getELFFile();
867105adf2cSMicah Weston 
868105adf2cSMicah Weston     Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr =
869105adf2cSMicah Weston         Elf.getSection(1);
870105adf2cSMicah Weston     ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded());
871105adf2cSMicah Weston 
872105adf2cSMicah Weston     std::vector<PGOAnalysisMap> PGOAnalyses;
873105adf2cSMicah Weston     EXPECT_THAT_ERROR(
874105adf2cSMicah Weston         Elf.decodeBBAddrMap(**BBAddrMapSecOrErr, nullptr, &PGOAnalyses)
875105adf2cSMicah Weston             .takeError(),
876105adf2cSMicah Weston         FailedWithMessage(ErrMsg));
877105adf2cSMicah Weston   };
878105adf2cSMicah Weston 
879105adf2cSMicah Weston   // Check that we can detect unsupported versions that are too old.
880105adf2cSMicah Weston   SmallString<128> UnsupportedLowVersionYamlString(CommonYamlString);
881105adf2cSMicah Weston   UnsupportedLowVersionYamlString += R"(
882acec6419SRahman Lavaee       - Version: 1
883105adf2cSMicah Weston         Feature: 0x4
884acec6419SRahman Lavaee         BBRanges:
885acec6419SRahman Lavaee           - BBEntries:
886105adf2cSMicah Weston               - AddressOffset: 0x0
887105adf2cSMicah Weston                 Size:          0x1
888105adf2cSMicah Weston                 Metadata:      0x2
889105adf2cSMicah Weston )";
890105adf2cSMicah Weston 
8916ba2c2bbSRahman Lavaee   {
8926ba2c2bbSRahman Lavaee     SCOPED_TRACE("unsupported version");
893105adf2cSMicah Weston     DoCheck(UnsupportedLowVersionYamlString,
894105adf2cSMicah Weston             "version should be >= 2 for SHT_LLVM_BB_ADDR_MAP when PGO features "
895105adf2cSMicah Weston             "are enabled: version = 1 feature = 4");
8966ba2c2bbSRahman Lavaee   }
897105adf2cSMicah Weston 
898105adf2cSMicah Weston   SmallString<128> CommonVersionedYamlString(CommonYamlString);
899105adf2cSMicah Weston   CommonVersionedYamlString += R"(
900acec6419SRahman Lavaee       - Version: 2
901acec6419SRahman Lavaee         BBRanges:
902acec6419SRahman Lavaee           - BBEntries:
903105adf2cSMicah Weston               - ID:            1
904105adf2cSMicah Weston                 AddressOffset: 0x0
905105adf2cSMicah Weston                 Size:          0x1
906105adf2cSMicah Weston                 Metadata:      0x2
907105adf2cSMicah Weston )";
908105adf2cSMicah Weston 
909105adf2cSMicah Weston   // Check that we fail when function entry count is enabled but not provided.
910105adf2cSMicah Weston   SmallString<128> MissingFuncEntryCount(CommonYamlString);
911105adf2cSMicah Weston   MissingFuncEntryCount += R"(
912acec6419SRahman Lavaee       - Version: 2
913105adf2cSMicah Weston         Feature: 0x01
914105adf2cSMicah Weston )";
915105adf2cSMicah Weston 
9166ba2c2bbSRahman Lavaee   {
9176ba2c2bbSRahman Lavaee     SCOPED_TRACE("missing function entry count");
918105adf2cSMicah Weston     DoCheck(MissingFuncEntryCount,
919acec6419SRahman Lavaee             "unexpected end of data at offset 0x2 while reading [0x2, 0xa)");
9206ba2c2bbSRahman Lavaee   }
921105adf2cSMicah Weston 
922105adf2cSMicah Weston   // Check that we fail when basic block frequency is enabled but not provided.
923105adf2cSMicah Weston   SmallString<128> MissingBBFreq(CommonYamlString);
924105adf2cSMicah Weston   MissingBBFreq += R"(
925acec6419SRahman Lavaee       - Version: 2
926105adf2cSMicah Weston         Feature: 0x02
927acec6419SRahman Lavaee         BBRanges:
928acec6419SRahman Lavaee           - BBEntries:
929105adf2cSMicah Weston               - ID:            1
930105adf2cSMicah Weston                 AddressOffset: 0x0
931105adf2cSMicah Weston                 Size:          0x1
932105adf2cSMicah Weston                 Metadata:      0x2
933105adf2cSMicah Weston )";
934105adf2cSMicah Weston 
9356ba2c2bbSRahman Lavaee   {
9366ba2c2bbSRahman Lavaee     SCOPED_TRACE("missing bb frequency");
937105adf2cSMicah Weston     DoCheck(MissingBBFreq, "unable to decode LEB128 at offset 0x0000000f: "
938105adf2cSMicah Weston                            "malformed uleb128, extends past end");
9396ba2c2bbSRahman Lavaee   }
940105adf2cSMicah Weston 
941105adf2cSMicah Weston   // Check that we fail when branch probability is enabled but not provided.
942105adf2cSMicah Weston   SmallString<128> MissingBrProb(CommonYamlString);
943105adf2cSMicah Weston   MissingBrProb += R"(
944acec6419SRahman Lavaee       - Version: 2
945105adf2cSMicah Weston         Feature: 0x04
946acec6419SRahman Lavaee         BBRanges:
947acec6419SRahman Lavaee           - BBEntries:
948105adf2cSMicah Weston               - ID:            1
949105adf2cSMicah Weston                 AddressOffset: 0x0
950105adf2cSMicah Weston                 Size:          0x1
951105adf2cSMicah Weston                 Metadata:      0x6
952105adf2cSMicah Weston               - ID:            2
953105adf2cSMicah Weston                 AddressOffset: 0x1
954105adf2cSMicah Weston                 Size:          0x1
955105adf2cSMicah Weston                 Metadata:      0x2
956105adf2cSMicah Weston               - ID:            3
957105adf2cSMicah Weston                 AddressOffset: 0x2
958105adf2cSMicah Weston                 Size:          0x1
959105adf2cSMicah Weston                 Metadata:      0x2
960105adf2cSMicah Weston     PGOAnalyses:
961105adf2cSMicah Weston       - PGOBBEntries:
962105adf2cSMicah Weston          - Successors:
963105adf2cSMicah Weston             - ID:          2
964105adf2cSMicah Weston               BrProb:      0x80000000
965105adf2cSMicah Weston             - ID:          3
966105adf2cSMicah Weston               BrProb:      0x80000000
967105adf2cSMicah Weston          - Successors:
968105adf2cSMicah Weston             - ID:          3
969105adf2cSMicah Weston               BrProb:      0xF0000000
970105adf2cSMicah Weston )";
971105adf2cSMicah Weston 
9726ba2c2bbSRahman Lavaee   {
9736ba2c2bbSRahman Lavaee     SCOPED_TRACE("missing branch probability");
974105adf2cSMicah Weston     DoCheck(MissingBrProb, "unable to decode LEB128 at offset 0x00000017: "
975105adf2cSMicah Weston                            "malformed uleb128, extends past end");
976105adf2cSMicah Weston   }
9776ba2c2bbSRahman Lavaee }
978105adf2cSMicah Weston 
979105adf2cSMicah Weston // Test for the ELFObjectFile::readBBAddrMap API with PGOAnalysisMap.
980105adf2cSMicah Weston TEST(ELFObjectFileTest, ReadPGOAnalysisMap) {
981105adf2cSMicah Weston   StringRef CommonYamlString(R"(
982105adf2cSMicah Weston --- !ELF
983105adf2cSMicah Weston FileHeader:
984105adf2cSMicah Weston   Class: ELFCLASS64
985105adf2cSMicah Weston   Data:  ELFDATA2LSB
986105adf2cSMicah Weston   Type:  ET_EXEC
987105adf2cSMicah Weston Sections:
988105adf2cSMicah Weston   - Name: .llvm_bb_addr_map_1
989105adf2cSMicah Weston     Type: SHT_LLVM_BB_ADDR_MAP
990105adf2cSMicah Weston     Link: 1
991105adf2cSMicah Weston     Entries:
992105adf2cSMicah Weston       - Version: 2
993105adf2cSMicah Weston         Feature: 0x1
994acec6419SRahman Lavaee         BBRanges:
995acec6419SRahman Lavaee           - BaseAddress: 0x11111
996105adf2cSMicah Weston             BBEntries:
997105adf2cSMicah Weston               - ID:            1
998105adf2cSMicah Weston                 AddressOffset: 0x0
999105adf2cSMicah Weston                 Size:          0x1
1000105adf2cSMicah Weston                 Metadata:      0x2
1001105adf2cSMicah Weston     PGOAnalyses:
1002105adf2cSMicah Weston       - FuncEntryCount: 892
1003105adf2cSMicah Weston   - Name: .llvm_bb_addr_map_2
1004105adf2cSMicah Weston     Type: SHT_LLVM_BB_ADDR_MAP
1005105adf2cSMicah Weston     Link: 1
1006105adf2cSMicah Weston     Entries:
1007105adf2cSMicah Weston       - Version: 2
1008105adf2cSMicah Weston         Feature: 0x2
1009acec6419SRahman Lavaee         BBRanges:
1010acec6419SRahman Lavaee           - BaseAddress: 0x22222
1011105adf2cSMicah Weston             BBEntries:
1012105adf2cSMicah Weston               - ID:            2
1013105adf2cSMicah Weston                 AddressOffset: 0x0
1014105adf2cSMicah Weston                 Size:          0x2
1015105adf2cSMicah Weston                 Metadata:      0x4
1016105adf2cSMicah Weston     PGOAnalyses:
1017105adf2cSMicah Weston       - PGOBBEntries:
1018105adf2cSMicah Weston          - BBFreq:         343
1019105adf2cSMicah Weston   - Name: .llvm_bb_addr_map_3
1020105adf2cSMicah Weston     Type: SHT_LLVM_BB_ADDR_MAP
1021105adf2cSMicah Weston     Link: 2
1022105adf2cSMicah Weston     Entries:
1023105adf2cSMicah Weston       - Version: 2
1024105adf2cSMicah Weston         Feature: 0x4
1025acec6419SRahman Lavaee         BBRanges:
1026acec6419SRahman Lavaee           - BaseAddress: 0x33333
1027105adf2cSMicah Weston             BBEntries:
1028105adf2cSMicah Weston               - ID:            0
1029105adf2cSMicah Weston                 AddressOffset: 0x0
1030105adf2cSMicah Weston                 Size:          0x3
1031105adf2cSMicah Weston                 Metadata:      0x6
1032105adf2cSMicah Weston               - ID:            1
1033105adf2cSMicah Weston                 AddressOffset: 0x0
1034105adf2cSMicah Weston                 Size:          0x3
1035105adf2cSMicah Weston                 Metadata:      0x4
1036105adf2cSMicah Weston               - ID:            2
1037105adf2cSMicah Weston                 AddressOffset: 0x0
1038105adf2cSMicah Weston                 Size:          0x3
1039105adf2cSMicah Weston                 Metadata:      0x0
1040105adf2cSMicah Weston     PGOAnalyses:
1041105adf2cSMicah Weston       - PGOBBEntries:
1042105adf2cSMicah Weston          - Successors:
1043105adf2cSMicah Weston             - ID:          1
1044105adf2cSMicah Weston               BrProb:      0x11111111
1045105adf2cSMicah Weston             - ID:          2
1046105adf2cSMicah Weston               BrProb:      0xeeeeeeee
1047105adf2cSMicah Weston          - Successors:
1048105adf2cSMicah Weston             - ID:          2
1049105adf2cSMicah Weston               BrProb:      0xffffffff
1050105adf2cSMicah Weston          - Successors:     []
1051105adf2cSMicah Weston   - Name: .llvm_bb_addr_map_4
1052105adf2cSMicah Weston     Type: SHT_LLVM_BB_ADDR_MAP
1053105adf2cSMicah Weston   # Link: 0 (by default, can be overriden)
1054105adf2cSMicah Weston     Entries:
1055105adf2cSMicah Weston       - Version: 2
1056105adf2cSMicah Weston         Feature: 0x7
1057acec6419SRahman Lavaee         BBRanges:
1058acec6419SRahman Lavaee           - BaseAddress: 0x44444
1059105adf2cSMicah Weston             BBEntries:
1060105adf2cSMicah Weston               - ID:            0
1061105adf2cSMicah Weston                 AddressOffset: 0x0
1062105adf2cSMicah Weston                 Size:          0x4
1063105adf2cSMicah Weston                 Metadata:      0x18
1064105adf2cSMicah Weston               - ID:            1
1065105adf2cSMicah Weston                 AddressOffset: 0x0
1066105adf2cSMicah Weston                 Size:          0x4
1067105adf2cSMicah Weston                 Metadata:      0x0
1068105adf2cSMicah Weston               - ID:            2
1069105adf2cSMicah Weston                 AddressOffset: 0x0
1070105adf2cSMicah Weston                 Size:          0x4
1071105adf2cSMicah Weston                 Metadata:      0x0
1072105adf2cSMicah Weston               - ID:            3
1073105adf2cSMicah Weston                 AddressOffset: 0x0
1074105adf2cSMicah Weston                 Size:          0x4
1075105adf2cSMicah Weston                 Metadata:      0x0
1076105adf2cSMicah Weston     PGOAnalyses:
1077105adf2cSMicah Weston       - FuncEntryCount: 1000
1078105adf2cSMicah Weston         PGOBBEntries:
1079105adf2cSMicah Weston           - BBFreq:         1000
1080105adf2cSMicah Weston             Successors:
1081105adf2cSMicah Weston             - ID:          1
1082105adf2cSMicah Weston               BrProb:      0x22222222
1083105adf2cSMicah Weston             - ID:          2
1084105adf2cSMicah Weston               BrProb:      0x33333333
1085105adf2cSMicah Weston             - ID:          3
1086105adf2cSMicah Weston               BrProb:      0xaaaaaaaa
1087105adf2cSMicah Weston           - BBFreq:         133
1088105adf2cSMicah Weston             Successors:
1089105adf2cSMicah Weston             - ID:          2
1090105adf2cSMicah Weston               BrProb:      0x11111111
1091105adf2cSMicah Weston             - ID:          3
1092105adf2cSMicah Weston               BrProb:      0xeeeeeeee
1093105adf2cSMicah Weston           - BBFreq:         18
1094105adf2cSMicah Weston             Successors:
1095105adf2cSMicah Weston             - ID:          3
1096105adf2cSMicah Weston               BrProb:      0xffffffff
1097105adf2cSMicah Weston           - BBFreq:         1000
1098105adf2cSMicah Weston             Successors:    []
10992873060fSMicah Weston   - Name: .llvm_bb_addr_map_5
11002873060fSMicah Weston     Type: SHT_LLVM_BB_ADDR_MAP
11012873060fSMicah Weston   # Link: 0 (by default, can be overriden)
11022873060fSMicah Weston     Entries:
11032873060fSMicah Weston       - Version: 2
11042873060fSMicah Weston         Feature: 0x0
1105acec6419SRahman Lavaee         BBRanges:
1106acec6419SRahman Lavaee           - BaseAddress: 0x55555
11072873060fSMicah Weston             BBEntries:
11082873060fSMicah Weston               - ID:            2
11092873060fSMicah Weston                 AddressOffset: 0x0
11102873060fSMicah Weston                 Size:          0x2
11112873060fSMicah Weston                 Metadata:      0x4
11122873060fSMicah Weston     PGOAnalyses: [{}]
1113acec6419SRahman Lavaee   - Name: .llvm_bb_addr_map_6
1114acec6419SRahman Lavaee     Type: SHT_LLVM_BB_ADDR_MAP
1115acec6419SRahman Lavaee   # Link: 0 (by default, can be overriden)
1116acec6419SRahman Lavaee     Entries:
1117acec6419SRahman Lavaee       - Version: 2
1118acec6419SRahman Lavaee         Feature: 0xc
1119acec6419SRahman Lavaee         BBRanges:
1120acec6419SRahman Lavaee           - BaseAddress: 0x66666
1121acec6419SRahman Lavaee             BBEntries:
1122acec6419SRahman Lavaee               - ID:            0
1123acec6419SRahman Lavaee                 AddressOffset: 0x0
1124acec6419SRahman Lavaee                 Size:          0x6
1125acec6419SRahman Lavaee                 Metadata:      0x6
1126acec6419SRahman Lavaee               - ID:            1
1127acec6419SRahman Lavaee                 AddressOffset: 0x0
1128acec6419SRahman Lavaee                 Size:          0x6
1129acec6419SRahman Lavaee                 Metadata:      0x4
1130acec6419SRahman Lavaee           - BaseAddress: 0x666661
1131acec6419SRahman Lavaee             BBEntries:
1132acec6419SRahman Lavaee               - ID:            2
1133acec6419SRahman Lavaee                 AddressOffset: 0x0
1134acec6419SRahman Lavaee                 Size:          0x6
1135acec6419SRahman Lavaee                 Metadata:      0x0
1136acec6419SRahman Lavaee     PGOAnalyses:
1137acec6419SRahman Lavaee       - PGOBBEntries:
1138acec6419SRahman Lavaee          - Successors:
1139acec6419SRahman Lavaee             - ID:          1
1140acec6419SRahman Lavaee               BrProb:      0x22222222
1141acec6419SRahman Lavaee             - ID:          2
1142acec6419SRahman Lavaee               BrProb:      0xcccccccc
1143acec6419SRahman Lavaee          - Successors:
1144acec6419SRahman Lavaee             - ID:          2
1145acec6419SRahman Lavaee               BrProb:      0x88888888
1146acec6419SRahman Lavaee          - Successors:     []
1147105adf2cSMicah Weston )");
1148105adf2cSMicah Weston 
1149acec6419SRahman Lavaee   BBAddrMap E1 = {
1150acec6419SRahman Lavaee       {{0x11111, {{1, 0x0, 0x1, {false, true, false, false, false}}}}}};
1151*cf83a7fdSLei Wang   PGOAnalysisMap P1 = {892, {}, {true, false, false, false, false}};
1152acec6419SRahman Lavaee   BBAddrMap E2 = {
1153acec6419SRahman Lavaee       {{0x22222, {{2, 0x0, 0x2, {false, false, true, false, false}}}}}};
1154acec6419SRahman Lavaee   PGOAnalysisMap P2 = {
1155*cf83a7fdSLei Wang       {}, {{BlockFrequency(343), {}}}, {false, true, false, false, false}};
1156acec6419SRahman Lavaee   BBAddrMap E3 = {{{0x33333,
1157acec6419SRahman Lavaee                     {{0, 0x0, 0x3, {false, true, true, false, false}},
1158105adf2cSMicah Weston                      {1, 0x3, 0x3, {false, false, true, false, false}},
1159acec6419SRahman Lavaee                      {2, 0x6, 0x3, {false, false, false, false, false}}}}}};
1160105adf2cSMicah Weston   PGOAnalysisMap P3 = {{},
1161105adf2cSMicah Weston                        {{{},
1162105adf2cSMicah Weston                          {{1, BranchProbability::getRaw(0x1111'1111)},
1163105adf2cSMicah Weston                           {2, BranchProbability::getRaw(0xeeee'eeee)}}},
1164105adf2cSMicah Weston                         {{}, {{2, BranchProbability::getRaw(0xffff'ffff)}}},
1165105adf2cSMicah Weston                         {{}, {}}},
1166*cf83a7fdSLei Wang                        {false, false, true, false, false}};
1167acec6419SRahman Lavaee   BBAddrMap E4 = {{{0x44444,
1168acec6419SRahman Lavaee                     {{0, 0x0, 0x4, {false, false, false, true, true}},
1169105adf2cSMicah Weston                      {1, 0x4, 0x4, {false, false, false, false, false}},
1170105adf2cSMicah Weston                      {2, 0x8, 0x4, {false, false, false, false, false}},
1171acec6419SRahman Lavaee                      {3, 0xc, 0x4, {false, false, false, false, false}}}}}};
1172105adf2cSMicah Weston   PGOAnalysisMap P4 = {
1173105adf2cSMicah Weston       1000,
1174105adf2cSMicah Weston       {{BlockFrequency(1000),
1175105adf2cSMicah Weston         {{1, BranchProbability::getRaw(0x2222'2222)},
1176105adf2cSMicah Weston          {2, BranchProbability::getRaw(0x3333'3333)},
1177105adf2cSMicah Weston          {3, BranchProbability::getRaw(0xaaaa'aaaa)}}},
1178105adf2cSMicah Weston        {BlockFrequency(133),
1179105adf2cSMicah Weston         {{2, BranchProbability::getRaw(0x1111'1111)},
1180105adf2cSMicah Weston          {3, BranchProbability::getRaw(0xeeee'eeee)}}},
1181105adf2cSMicah Weston        {BlockFrequency(18), {{3, BranchProbability::getRaw(0xffff'ffff)}}},
1182105adf2cSMicah Weston        {BlockFrequency(1000), {}}},
1183*cf83a7fdSLei Wang       {true, true, true, false, false}};
1184acec6419SRahman Lavaee   BBAddrMap E5 = {
1185acec6419SRahman Lavaee       {{0x55555, {{2, 0x0, 0x2, {false, false, true, false, false}}}}}};
1186*cf83a7fdSLei Wang   PGOAnalysisMap P5 = {{}, {}, {false, false, false, false, false}};
1187acec6419SRahman Lavaee   BBAddrMap E6 = {
1188acec6419SRahman Lavaee       {{0x66666,
1189acec6419SRahman Lavaee         {{0, 0x0, 0x6, {false, true, true, false, false}},
1190acec6419SRahman Lavaee          {1, 0x6, 0x6, {false, false, true, false, false}}}},
1191acec6419SRahman Lavaee        {0x666661, {{2, 0x0, 0x6, {false, false, false, false, false}}}}}};
1192acec6419SRahman Lavaee   PGOAnalysisMap P6 = {{},
1193acec6419SRahman Lavaee                        {{{},
1194acec6419SRahman Lavaee                          {{1, BranchProbability::getRaw(0x2222'2222)},
1195acec6419SRahman Lavaee                           {2, BranchProbability::getRaw(0xcccc'cccc)}}},
1196acec6419SRahman Lavaee                         {{}, {{2, BranchProbability::getRaw(0x8888'8888)}}},
1197acec6419SRahman Lavaee                         {{}, {}}},
1198*cf83a7fdSLei Wang                        {false, false, true, true, false}};
1199105adf2cSMicah Weston 
1200acec6419SRahman Lavaee   std::vector<BBAddrMap> Section0BBAddrMaps = {E4, E5, E6};
1201105adf2cSMicah Weston   std::vector<BBAddrMap> Section1BBAddrMaps = {E3};
1202105adf2cSMicah Weston   std::vector<BBAddrMap> Section2BBAddrMaps = {E1, E2};
1203acec6419SRahman Lavaee   std::vector<BBAddrMap> AllBBAddrMaps = {E1, E2, E3, E4, E5, E6};
1204105adf2cSMicah Weston 
1205acec6419SRahman Lavaee   std::vector<PGOAnalysisMap> Section0PGOAnalysisMaps = {P4, P5, P6};
1206105adf2cSMicah Weston   std::vector<PGOAnalysisMap> Section1PGOAnalysisMaps = {P3};
1207105adf2cSMicah Weston   std::vector<PGOAnalysisMap> Section2PGOAnalysisMaps = {P1, P2};
1208acec6419SRahman Lavaee   std::vector<PGOAnalysisMap> AllPGOAnalysisMaps = {P1, P2, P3, P4, P5, P6};
1209105adf2cSMicah Weston 
1210105adf2cSMicah Weston   auto DoCheckSucceeds =
1211105adf2cSMicah Weston       [&](StringRef YamlString, std::optional<unsigned> TextSectionIndex,
1212105adf2cSMicah Weston           std::vector<BBAddrMap> ExpectedResult,
1213105adf2cSMicah Weston           std::optional<std::vector<PGOAnalysisMap>> ExpectedPGO) {
12146ba2c2bbSRahman Lavaee         SCOPED_TRACE(
12156ba2c2bbSRahman Lavaee             "for TextSectionIndex: " +
12166ba2c2bbSRahman Lavaee             (TextSectionIndex ? llvm::Twine(*TextSectionIndex) : "{}") +
12176ba2c2bbSRahman Lavaee             " and object yaml:\n" + YamlString);
1218105adf2cSMicah Weston         SmallString<0> Storage;
1219105adf2cSMicah Weston         Expected<ELFObjectFile<ELF64LE>> ElfOrErr =
1220105adf2cSMicah Weston             toBinary<ELF64LE>(Storage, YamlString);
1221105adf2cSMicah Weston         ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
1222105adf2cSMicah Weston 
1223105adf2cSMicah Weston         Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr =
1224105adf2cSMicah Weston             ElfOrErr->getELFFile().getSection(1);
1225105adf2cSMicah Weston         ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded());
1226105adf2cSMicah Weston 
1227105adf2cSMicah Weston         std::vector<PGOAnalysisMap> PGOAnalyses;
1228105adf2cSMicah Weston         auto BBAddrMaps = ElfOrErr->readBBAddrMap(
1229105adf2cSMicah Weston             TextSectionIndex, ExpectedPGO ? &PGOAnalyses : nullptr);
1230105adf2cSMicah Weston         ASSERT_THAT_EXPECTED(BBAddrMaps, Succeeded());
1231105adf2cSMicah Weston         EXPECT_EQ(*BBAddrMaps, ExpectedResult);
1232105adf2cSMicah Weston         if (ExpectedPGO) {
1233105adf2cSMicah Weston           EXPECT_EQ(BBAddrMaps->size(), PGOAnalyses.size());
1234acec6419SRahman Lavaee           for (const auto &PGO : PGOAnalyses) {
1235acec6419SRahman Lavaee             errs() << "FuncEntryCount: " << PGO.FuncEntryCount << "\n";
1236acec6419SRahman Lavaee             for (const auto &PGOBB : PGO.BBEntries)
1237acec6419SRahman Lavaee               errs() << "\tBB: " << PGOBB.BlockFreq.getFrequency() << "\n";
1238acec6419SRahman Lavaee           }
1239acec6419SRahman Lavaee           errs() << " To expected:\n";
1240acec6419SRahman Lavaee           for (const auto &PGO : *ExpectedPGO) {
1241acec6419SRahman Lavaee             errs() << "FuncEntryCount: " << PGO.FuncEntryCount << "\n";
1242acec6419SRahman Lavaee             for (const auto &PGOBB : PGO.BBEntries)
1243acec6419SRahman Lavaee               errs() << "\tBB: " << PGOBB.BlockFreq.getFrequency() << "\n";
1244acec6419SRahman Lavaee           }
1245105adf2cSMicah Weston           EXPECT_EQ(PGOAnalyses, *ExpectedPGO);
12462873060fSMicah Weston           for (auto &&[BB, PGO] : llvm::zip(*BBAddrMaps, PGOAnalyses)) {
12472873060fSMicah Weston             if (PGO.FeatEnable.BBFreq || PGO.FeatEnable.BrProb)
1248acec6419SRahman Lavaee               EXPECT_EQ(BB.getNumBBEntries(), PGO.BBEntries.size());
12492873060fSMicah Weston           }
1250105adf2cSMicah Weston         }
1251105adf2cSMicah Weston       };
1252105adf2cSMicah Weston 
1253105adf2cSMicah Weston   auto DoCheckFails = [&](StringRef YamlString,
1254105adf2cSMicah Weston                           std::optional<unsigned> TextSectionIndex,
1255105adf2cSMicah Weston                           const char *ErrMsg) {
12566ba2c2bbSRahman Lavaee     SCOPED_TRACE("for TextSectionIndex: " +
12576ba2c2bbSRahman Lavaee                  (TextSectionIndex ? llvm::Twine(*TextSectionIndex) : "{}") +
12586ba2c2bbSRahman Lavaee                  " and object yaml:\n" + YamlString);
1259105adf2cSMicah Weston     SmallString<0> Storage;
1260105adf2cSMicah Weston     Expected<ELFObjectFile<ELF64LE>> ElfOrErr =
1261105adf2cSMicah Weston         toBinary<ELF64LE>(Storage, YamlString);
1262105adf2cSMicah Weston     ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
1263105adf2cSMicah Weston 
1264105adf2cSMicah Weston     Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr =
1265105adf2cSMicah Weston         ElfOrErr->getELFFile().getSection(1);
1266105adf2cSMicah Weston     ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded());
1267105adf2cSMicah Weston     std::vector<PGOAnalysisMap> PGOAnalyses;
1268105adf2cSMicah Weston     EXPECT_THAT_ERROR(
1269105adf2cSMicah Weston         ElfOrErr->readBBAddrMap(TextSectionIndex, &PGOAnalyses).takeError(),
1270105adf2cSMicah Weston         FailedWithMessage(ErrMsg));
1271105adf2cSMicah Weston   };
1272105adf2cSMicah Weston 
12736ba2c2bbSRahman Lavaee   {
12746ba2c2bbSRahman Lavaee     SCOPED_TRACE("normal sections");
1275105adf2cSMicah Weston     // Check that we can retrieve the data in the normal case.
1276105adf2cSMicah Weston     DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/std::nullopt,
1277105adf2cSMicah Weston                     AllBBAddrMaps, std::nullopt);
12786ba2c2bbSRahman Lavaee     DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/0,
12796ba2c2bbSRahman Lavaee                     Section0BBAddrMaps, std::nullopt);
12806ba2c2bbSRahman Lavaee     DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/2,
12816ba2c2bbSRahman Lavaee                     Section1BBAddrMaps, std::nullopt);
12826ba2c2bbSRahman Lavaee     DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/1,
12836ba2c2bbSRahman Lavaee                     Section2BBAddrMaps, std::nullopt);
1284105adf2cSMicah Weston 
1285105adf2cSMicah Weston     DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/std::nullopt,
1286105adf2cSMicah Weston                     AllBBAddrMaps, AllPGOAnalysisMaps);
12876ba2c2bbSRahman Lavaee     DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/0,
12886ba2c2bbSRahman Lavaee                     Section0BBAddrMaps, Section0PGOAnalysisMaps);
12896ba2c2bbSRahman Lavaee     DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/2,
12906ba2c2bbSRahman Lavaee                     Section1BBAddrMaps, Section1PGOAnalysisMaps);
12916ba2c2bbSRahman Lavaee     DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/1,
12926ba2c2bbSRahman Lavaee                     Section2BBAddrMaps, Section2PGOAnalysisMaps);
1293105adf2cSMicah Weston     // Check that when no bb-address-map section is found for a text section,
1294105adf2cSMicah Weston     // we return an empty result.
1295105adf2cSMicah Weston     DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/3, {}, std::nullopt);
1296105adf2cSMicah Weston     DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/3, {},
1297105adf2cSMicah Weston                     std::vector<PGOAnalysisMap>{});
12986ba2c2bbSRahman Lavaee   }
1299105adf2cSMicah Weston 
1300105adf2cSMicah Weston   // Check that we detect when a bb-addr-map section is linked to an invalid
1301105adf2cSMicah Weston   // (not present) section.
1302105adf2cSMicah Weston   SmallString<128> InvalidLinkedYamlString(CommonYamlString);
1303105adf2cSMicah Weston   InvalidLinkedYamlString += R"(
1304acec6419SRahman Lavaee     Link: 121
1305105adf2cSMicah Weston )";
1306105adf2cSMicah Weston 
13076ba2c2bbSRahman Lavaee   {
13086ba2c2bbSRahman Lavaee     SCOPED_TRACE("invalid linked section");
13092873060fSMicah Weston     DoCheckFails(InvalidLinkedYamlString, /*TextSectionIndex=*/5,
1310105adf2cSMicah Weston                  "unable to get the linked-to section for "
1311acec6419SRahman Lavaee                  "SHT_LLVM_BB_ADDR_MAP section with index 6: invalid section "
1312acec6419SRahman Lavaee                  "index: 121");
13136ba2c2bbSRahman Lavaee 
1314105adf2cSMicah Weston     // Linked sections are not checked when we don't target a specific text
1315105adf2cSMicah Weston     // section.
1316105adf2cSMicah Weston     DoCheckSucceeds(InvalidLinkedYamlString, /*TextSectionIndex=*/std::nullopt,
1317105adf2cSMicah Weston                     AllBBAddrMaps, std::nullopt);
1318105adf2cSMicah Weston     DoCheckSucceeds(InvalidLinkedYamlString, /*TextSectionIndex=*/std::nullopt,
1319105adf2cSMicah Weston                     AllBBAddrMaps, AllPGOAnalysisMaps);
13206ba2c2bbSRahman Lavaee   }
1321105adf2cSMicah Weston 
1322105adf2cSMicah Weston   // Check that we can detect when bb-address-map decoding fails.
1323105adf2cSMicah Weston   SmallString<128> TruncatedYamlString(CommonYamlString);
1324105adf2cSMicah Weston   TruncatedYamlString += R"(
1325105adf2cSMicah Weston     ShSize: 0xa
1326105adf2cSMicah Weston )";
1327105adf2cSMicah Weston 
13286ba2c2bbSRahman Lavaee   {
13296ba2c2bbSRahman Lavaee     SCOPED_TRACE("truncated section");
1330acec6419SRahman Lavaee     DoCheckFails(
1331acec6419SRahman Lavaee         TruncatedYamlString, /*TextSectionIndex=*/std::nullopt,
1332acec6419SRahman Lavaee         "unable to read SHT_LLVM_BB_ADDR_MAP section with index 6: "
1333acec6419SRahman Lavaee         "unexpected end of data at offset 0xa while reading [0x3, 0xb)");
1334105adf2cSMicah Weston     // Check that we can read the other section's bb-address-maps which are
1335105adf2cSMicah Weston     // valid.
1336105adf2cSMicah Weston     DoCheckSucceeds(TruncatedYamlString, /*TextSectionIndex=*/2,
1337105adf2cSMicah Weston                     Section1BBAddrMaps, std::nullopt);
1338105adf2cSMicah Weston     DoCheckSucceeds(TruncatedYamlString, /*TextSectionIndex=*/2,
1339105adf2cSMicah Weston                     Section1BBAddrMaps, Section1PGOAnalysisMaps);
1340105adf2cSMicah Weston   }
13416ba2c2bbSRahman Lavaee }
1342105adf2cSMicah Weston 
13438ec73e96SAmir Ayupov // Test for ObjectFile::getRelocatedSection: check that it returns a relocated
13448ec73e96SAmir Ayupov // section for executable and relocatable files.
13458ec73e96SAmir Ayupov TEST(ELFObjectFileTest, ExecutableWithRelocs) {
13468ec73e96SAmir Ayupov   StringRef HeaderString(R"(
13478ec73e96SAmir Ayupov --- !ELF
13488ec73e96SAmir Ayupov FileHeader:
13498ec73e96SAmir Ayupov   Class: ELFCLASS64
13508ec73e96SAmir Ayupov   Data:  ELFDATA2LSB
13518ec73e96SAmir Ayupov )");
13528ec73e96SAmir Ayupov   StringRef ContentsString(R"(
13538ec73e96SAmir Ayupov Sections:
13548ec73e96SAmir Ayupov   - Name:  .text
13558ec73e96SAmir Ayupov     Type:  SHT_PROGBITS
13568ec73e96SAmir Ayupov     Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
13578ec73e96SAmir Ayupov   - Name:  .rela.text
13588ec73e96SAmir Ayupov     Type:  SHT_RELA
13598ec73e96SAmir Ayupov     Flags: [ SHF_INFO_LINK ]
13608ec73e96SAmir Ayupov     Info:  .text
13618ec73e96SAmir Ayupov )");
13628ec73e96SAmir Ayupov 
13638ec73e96SAmir Ayupov   auto DoCheck = [&](StringRef YamlString) {
13648ec73e96SAmir Ayupov     SmallString<0> Storage;
13658ec73e96SAmir Ayupov     Expected<ELFObjectFile<ELF64LE>> ElfOrErr =
13668ec73e96SAmir Ayupov         toBinary<ELF64LE>(Storage, YamlString);
13678ec73e96SAmir Ayupov     ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
13688ec73e96SAmir Ayupov     const ELFObjectFile<ELF64LE> &Obj = *ElfOrErr;
13698ec73e96SAmir Ayupov 
13708ec73e96SAmir Ayupov     bool FoundRela;
13718ec73e96SAmir Ayupov 
13728ec73e96SAmir Ayupov     for (SectionRef Sec : Obj.sections()) {
13738ec73e96SAmir Ayupov       Expected<StringRef> SecNameOrErr = Sec.getName();
13748ec73e96SAmir Ayupov       ASSERT_THAT_EXPECTED(SecNameOrErr, Succeeded());
13758ec73e96SAmir Ayupov       StringRef SecName = *SecNameOrErr;
13768ec73e96SAmir Ayupov       if (SecName != ".rela.text")
13778ec73e96SAmir Ayupov         continue;
13788ec73e96SAmir Ayupov       FoundRela = true;
13798ec73e96SAmir Ayupov       Expected<section_iterator> RelSecOrErr = Sec.getRelocatedSection();
13808ec73e96SAmir Ayupov       ASSERT_THAT_EXPECTED(RelSecOrErr, Succeeded());
13818ec73e96SAmir Ayupov       section_iterator RelSec = *RelSecOrErr;
13828ec73e96SAmir Ayupov       ASSERT_NE(RelSec, Obj.section_end());
13838ec73e96SAmir Ayupov       Expected<StringRef> TextSecNameOrErr = RelSec->getName();
13848ec73e96SAmir Ayupov       ASSERT_THAT_EXPECTED(TextSecNameOrErr, Succeeded());
13858ec73e96SAmir Ayupov       StringRef TextSecName = *TextSecNameOrErr;
13868ec73e96SAmir Ayupov       EXPECT_EQ(TextSecName, ".text");
13878ec73e96SAmir Ayupov     }
13888ec73e96SAmir Ayupov     ASSERT_TRUE(FoundRela);
13898ec73e96SAmir Ayupov   };
13908ec73e96SAmir Ayupov 
13918ec73e96SAmir Ayupov   // Check ET_EXEC file (`ld --emit-relocs` use-case).
13928ec73e96SAmir Ayupov   SmallString<128> ExecFileYamlString(HeaderString);
13938ec73e96SAmir Ayupov   ExecFileYamlString += R"(
13948ec73e96SAmir Ayupov   Type:  ET_EXEC
13958ec73e96SAmir Ayupov )";
13968ec73e96SAmir Ayupov   ExecFileYamlString += ContentsString;
13978ec73e96SAmir Ayupov   DoCheck(ExecFileYamlString);
13988ec73e96SAmir Ayupov 
13998ec73e96SAmir Ayupov   // Check ET_REL file.
14008ec73e96SAmir Ayupov   SmallString<128> RelocatableFileYamlString(HeaderString);
14018ec73e96SAmir Ayupov   RelocatableFileYamlString += R"(
14028ec73e96SAmir Ayupov   Type:  ET_REL
14038ec73e96SAmir Ayupov )";
14048ec73e96SAmir Ayupov   RelocatableFileYamlString += ContentsString;
14058ec73e96SAmir Ayupov   DoCheck(RelocatableFileYamlString);
14068ec73e96SAmir Ayupov }
14079c645a99SAiden Grossman 
14089c645a99SAiden Grossman TEST(ELFObjectFileTest, GetSectionAndRelocations) {
14099c645a99SAiden Grossman   StringRef HeaderString(R"(
14109c645a99SAiden Grossman --- !ELF
14119c645a99SAiden Grossman FileHeader:
14129c645a99SAiden Grossman   Class: ELFCLASS64
14139c645a99SAiden Grossman   Data:  ELFDATA2LSB
14149c645a99SAiden Grossman   Type:  ET_EXEC
14159c645a99SAiden Grossman )");
14169c645a99SAiden Grossman 
14179c645a99SAiden Grossman   using Elf_Shdr = Elf_Shdr_Impl<ELF64LE>;
14189c645a99SAiden Grossman 
14199c645a99SAiden Grossman   auto DoCheckSucceeds = [&](StringRef ContentsString,
14209c645a99SAiden Grossman                              std::function<Expected<bool>(const Elf_Shdr &)>
14219c645a99SAiden Grossman                                  Matcher) {
14229c645a99SAiden Grossman     SmallString<0> Storage;
14239c645a99SAiden Grossman     SmallString<128> FullYamlString(HeaderString);
14249c645a99SAiden Grossman     FullYamlString += ContentsString;
14259c645a99SAiden Grossman     Expected<ELFObjectFile<ELF64LE>> ElfOrErr =
14269c645a99SAiden Grossman         toBinary<ELF64LE>(Storage, FullYamlString);
14279c645a99SAiden Grossman     ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
14289c645a99SAiden Grossman 
14299c645a99SAiden Grossman     Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SecToRelocMapOrErr =
14309c645a99SAiden Grossman         ElfOrErr->getELFFile().getSectionAndRelocations(Matcher);
14319c645a99SAiden Grossman     ASSERT_THAT_EXPECTED(SecToRelocMapOrErr, Succeeded());
14329c645a99SAiden Grossman 
14339c645a99SAiden Grossman     // Basic verification to make sure we have the correct section types.
14349c645a99SAiden Grossman     for (auto const &[Sec, RelaSec] : *SecToRelocMapOrErr) {
14359c645a99SAiden Grossman       ASSERT_EQ(Sec->sh_type, ELF::SHT_PROGBITS);
14369c645a99SAiden Grossman       ASSERT_EQ(RelaSec->sh_type, ELF::SHT_RELA);
14379c645a99SAiden Grossman     }
14389c645a99SAiden Grossman   };
14399c645a99SAiden Grossman 
14409c645a99SAiden Grossman   auto DoCheckFails = [&](StringRef ContentsString,
14419c645a99SAiden Grossman                           std::function<Expected<bool>(const Elf_Shdr &)>
14429c645a99SAiden Grossman                               Matcher,
14439c645a99SAiden Grossman                           const char *ErrorMessage) {
14449c645a99SAiden Grossman     SmallString<0> Storage;
14459c645a99SAiden Grossman     SmallString<128> FullYamlString(HeaderString);
14469c645a99SAiden Grossman     FullYamlString += ContentsString;
14479c645a99SAiden Grossman     Expected<ELFObjectFile<ELF64LE>> ElfOrErr =
14489c645a99SAiden Grossman         toBinary<ELF64LE>(Storage, FullYamlString);
14499c645a99SAiden Grossman     ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
14509c645a99SAiden Grossman 
14519c645a99SAiden Grossman     Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SecToRelocMapOrErr =
14529c645a99SAiden Grossman         ElfOrErr->getELFFile().getSectionAndRelocations(Matcher);
14539c645a99SAiden Grossman     ASSERT_THAT_ERROR(SecToRelocMapOrErr.takeError(),
14549c645a99SAiden Grossman                       FailedWithMessage(ErrorMessage));
14559c645a99SAiden Grossman   };
14569c645a99SAiden Grossman 
14579c645a99SAiden Grossman   auto DefaultMatcher = [](const Elf_Shdr &Sec) -> bool {
14589c645a99SAiden Grossman     return Sec.sh_type == ELF::SHT_PROGBITS;
14599c645a99SAiden Grossman   };
14609c645a99SAiden Grossman 
14619c645a99SAiden Grossman   StringRef TwoTextSections = R"(
14629c645a99SAiden Grossman Sections:
14639c645a99SAiden Grossman   - Name: .text
14649c645a99SAiden Grossman     Type: SHT_PROGBITS
14659c645a99SAiden Grossman     Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
14669c645a99SAiden Grossman   - Name: .rela.text
14679c645a99SAiden Grossman     Type: SHT_RELA
14689c645a99SAiden Grossman     Flags: [ SHF_INFO_LINK ]
14699c645a99SAiden Grossman     Info: .text
14709c645a99SAiden Grossman   - Name: .text2
14719c645a99SAiden Grossman     Type: SHT_PROGBITS
14729c645a99SAiden Grossman     Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
14739c645a99SAiden Grossman   - Name: .rela.text2
14749c645a99SAiden Grossman     Type: SHT_RELA
14759c645a99SAiden Grossman     Flags: [ SHF_INFO_LINK ]
14769c645a99SAiden Grossman     Info: .text2
14779c645a99SAiden Grossman )";
14789c645a99SAiden Grossman   DoCheckSucceeds(TwoTextSections, DefaultMatcher);
14799c645a99SAiden Grossman 
14809c645a99SAiden Grossman   StringRef OneTextSection = R"(
14819c645a99SAiden Grossman Sections:
14829c645a99SAiden Grossman   - Name: .text
14839c645a99SAiden Grossman     Type: SHT_PROGBITS
14849c645a99SAiden Grossman     Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
14859c645a99SAiden Grossman )";
14869c645a99SAiden Grossman 
14879c645a99SAiden Grossman   auto ErroringMatcher = [](const Elf_Shdr &Sec) -> Expected<bool> {
14889c645a99SAiden Grossman     if (Sec.sh_type == ELF::SHT_PROGBITS)
14899c645a99SAiden Grossman       return createError("This was supposed to fail.");
14909c645a99SAiden Grossman     return false;
14919c645a99SAiden Grossman   };
14929c645a99SAiden Grossman 
14933b337bbcSJoseph Huber   DoCheckFails(OneTextSection, ErroringMatcher, "This was supposed to fail.");
14949c645a99SAiden Grossman 
14959c645a99SAiden Grossman   StringRef MissingRelocatableContent = R"(
14969c645a99SAiden Grossman Sections:
14979c645a99SAiden Grossman   - Name: .rela.text
14989c645a99SAiden Grossman     Type: SHT_RELA
14999c645a99SAiden Grossman     Flags: [ SHF_INFO_LINK ]
15009c645a99SAiden Grossman     Info: 0xFF
15019c645a99SAiden Grossman )";
15029c645a99SAiden Grossman 
15039c645a99SAiden Grossman   DoCheckFails(MissingRelocatableContent, DefaultMatcher,
15049c645a99SAiden Grossman                "SHT_RELA section with index 1: failed to get a "
15059c645a99SAiden Grossman                "relocated section: invalid section index: 255");
15069c645a99SAiden Grossman }
1507df6d2faaSAmir Ayupov 
1508df6d2faaSAmir Ayupov TEST(ELFObjectFileTest, ELFSymbolRefLess) {
1509df6d2faaSAmir Ayupov   SmallString<0> Storage;
1510df6d2faaSAmir Ayupov   Expected<ELFObjectFile<ELF64LE>> ElfOrErr = toBinary<ELF64LE>(Storage, R"(
1511df6d2faaSAmir Ayupov --- !ELF
1512df6d2faaSAmir Ayupov FileHeader:
1513df6d2faaSAmir Ayupov   Class:   ELFCLASS64
1514df6d2faaSAmir Ayupov   Data:    ELFDATA2LSB
1515df6d2faaSAmir Ayupov   Type:    ET_DYN
1516df6d2faaSAmir Ayupov   Machine: EM_X86_64
1517df6d2faaSAmir Ayupov )");
1518df6d2faaSAmir Ayupov 
1519df6d2faaSAmir Ayupov   ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
1520df6d2faaSAmir Ayupov   const ELFObjectFile<ELF64LE> &Obj = *ElfOrErr;
1521df6d2faaSAmir Ayupov 
1522df6d2faaSAmir Ayupov   const uint32_t ValLow = 0x00000001;
1523df6d2faaSAmir Ayupov   const uint32_t ValHigh = 0x00000100;
1524df6d2faaSAmir Ayupov 
1525df6d2faaSAmir Ayupov   auto MakeSymbol = [&Obj](size_t SymtabIndex, size_t SymbolIndex) {
1526df6d2faaSAmir Ayupov     DataRefImpl Data;
1527df6d2faaSAmir Ayupov     Data.d.a = SymtabIndex;
1528df6d2faaSAmir Ayupov     Data.d.b = SymbolIndex;
1529df6d2faaSAmir Ayupov     SymbolRef Sym(Data, &Obj);
1530df6d2faaSAmir Ayupov     return ELFSymbolRef(Sym);
1531df6d2faaSAmir Ayupov   };
1532df6d2faaSAmir Ayupov 
1533df6d2faaSAmir Ayupov   ELFSymbolRef ELFSymLowLow = MakeSymbol(ValLow, ValLow);
1534df6d2faaSAmir Ayupov   ELFSymbolRef ELFSymLowHigh = MakeSymbol(ValLow, ValHigh);
1535df6d2faaSAmir Ayupov   ELFSymbolRef ELFSymHighLow = MakeSymbol(ValHigh, ValLow);
1536df6d2faaSAmir Ayupov   ELFSymbolRef ELFSymHighHigh = MakeSymbol(ValHigh, ValHigh);
1537df6d2faaSAmir Ayupov 
1538df6d2faaSAmir Ayupov   EXPECT_TRUE(ELFSymLowLow < ELFSymLowHigh);
1539df6d2faaSAmir Ayupov   EXPECT_FALSE(ELFSymLowHigh < ELFSymLowLow);
1540df6d2faaSAmir Ayupov   EXPECT_FALSE(ELFSymLowLow < ELFSymLowLow);
1541df6d2faaSAmir Ayupov 
1542df6d2faaSAmir Ayupov   EXPECT_TRUE(ELFSymLowLow < ELFSymHighHigh);
1543df6d2faaSAmir Ayupov   EXPECT_TRUE(ELFSymLowHigh < ELFSymHighLow);
1544df6d2faaSAmir Ayupov   EXPECT_TRUE(ELFSymLowLow < ELFSymHighLow);
1545df6d2faaSAmir Ayupov 
1546df6d2faaSAmir Ayupov   EXPECT_FALSE(ELFSymHighLow < ELFSymLowHigh);
1547df6d2faaSAmir Ayupov   EXPECT_FALSE(ELFSymHighHigh < ELFSymLowLow);
1548df6d2faaSAmir Ayupov   EXPECT_FALSE(ELFSymHighLow < ELFSymLowLow);
1549df6d2faaSAmir Ayupov }
1550