brintos

brintos / llvm-project-archived public Read only

0
0
Text · 60.1 KiB · 1e2955a Raw
1708 lines · cpp
1//===- ELFObjectFileTest.cpp - Tests for ELFObjectFile --------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/Object/ELFObjectFile.h"10#include "llvm/ADT/STLExtras.h"11#include "llvm/BinaryFormat/ELF.h"12#include "llvm/ObjectYAML/yaml2obj.h"13#include "llvm/Support/BlockFrequency.h"14#include "llvm/Support/MemoryBuffer.h"15#include "llvm/Support/YAMLTraits.h"16#include "llvm/Testing/Support/Error.h"17#include "gtest/gtest.h"18 19#include "llvm/Support/thread.h"20#include "llvm/TargetParser/Host.h"21 22using namespace llvm;23using namespace llvm::object;24 25namespace {26 27// A struct to initialize a buffer to represent an ELF object file.28struct DataForTest {29  std::vector<uint8_t> Data;30 31  template <typename T>32  std::vector<uint8_t> makeElfData(uint8_t Class, uint8_t Encoding,33                                   uint16_t Machine, uint8_t OS,34                                   uint16_t Flags) {35    T Ehdr{}; // Zero-initialise the header.36    Ehdr.e_ident[ELF::EI_MAG0] = 0x7f;37    Ehdr.e_ident[ELF::EI_MAG1] = 'E';38    Ehdr.e_ident[ELF::EI_MAG2] = 'L';39    Ehdr.e_ident[ELF::EI_MAG3] = 'F';40    Ehdr.e_ident[ELF::EI_CLASS] = Class;41    Ehdr.e_ident[ELF::EI_DATA] = Encoding;42    Ehdr.e_ident[ELF::EI_VERSION] = 1;43    Ehdr.e_ident[ELF::EI_OSABI] = OS;44    Ehdr.e_type = ELF::ET_REL;45    Ehdr.e_machine = Machine;46    Ehdr.e_version = 1;47    Ehdr.e_flags = Flags;48    Ehdr.e_ehsize = sizeof(T);49 50    bool IsLittleEndian = Encoding == ELF::ELFDATA2LSB;51    if (sys::IsLittleEndianHost != IsLittleEndian) {52      sys::swapByteOrder(Ehdr.e_type);53      sys::swapByteOrder(Ehdr.e_machine);54      sys::swapByteOrder(Ehdr.e_version);55      sys::swapByteOrder(Ehdr.e_ehsize);56    }57 58    uint8_t *EhdrBytes = reinterpret_cast<uint8_t *>(&Ehdr);59    std::vector<uint8_t> Bytes;60    std::copy(EhdrBytes, EhdrBytes + sizeof(Ehdr), std::back_inserter(Bytes));61    return Bytes;62  }63 64  DataForTest(uint8_t Class, uint8_t Encoding, uint16_t Machine,65              uint8_t OS = ELF::ELFOSABI_NONE, uint16_t Flags = 0) {66    if (Class == ELF::ELFCLASS64)67      Data = makeElfData<ELF::Elf64_Ehdr>(Class, Encoding, Machine, OS, Flags);68    else {69      assert(Class == ELF::ELFCLASS32);70      Data = makeElfData<ELF::Elf32_Ehdr>(Class, Encoding, Machine, OS, Flags);71    }72  }73};74 75void checkFormatAndArch(const DataForTest &D, StringRef Fmt,76                        Triple::ArchType Arch) {77  Expected<std::unique_ptr<ObjectFile>> ELFObjOrErr =78      object::ObjectFile::createELFObjectFile(79          MemoryBufferRef(toStringRef(D.Data), "dummyELF"));80  ASSERT_THAT_EXPECTED(ELFObjOrErr, Succeeded());81 82  const ObjectFile &File = *(*ELFObjOrErr).get();83  EXPECT_EQ(Fmt, File.getFileFormatName());84  EXPECT_EQ(Arch, File.getArch());85}86 87std::array<DataForTest, 4> generateData(uint16_t Machine) {88  return {DataForTest(ELF::ELFCLASS32, ELF::ELFDATA2LSB, Machine),89          DataForTest(ELF::ELFCLASS32, ELF::ELFDATA2MSB, Machine),90          DataForTest(ELF::ELFCLASS64, ELF::ELFDATA2LSB, Machine),91          DataForTest(ELF::ELFCLASS64, ELF::ELFDATA2MSB, Machine)};92}93 94} // namespace95 96TEST(ELFObjectFileTest, MachineTestForNoneOrUnused) {97  std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown",98                                      "elf64-unknown", "elf64-unknown"};99  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_NONE)))100    checkFormatAndArch(Data, Formats[Idx], Triple::UnknownArch);101 102  // Test an arbitrary unused EM_* value (255).103  for (auto [Idx, Data] : enumerate(generateData(255)))104    checkFormatAndArch(Data, Formats[Idx], Triple::UnknownArch);105}106 107TEST(ELFObjectFileTest, MachineTestForVE) {108  std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown",109                                      "elf64-ve", "elf64-ve"};110  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_VE)))111    checkFormatAndArch(Data, Formats[Idx], Triple::ve);112}113 114TEST(ELFObjectFileTest, MachineTestForX86_64) {115  std::array<StringRef, 4> Formats = {"elf32-x86-64", "elf32-x86-64",116                                      "elf64-x86-64", "elf64-x86-64"};117  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_X86_64)))118    checkFormatAndArch(Data, Formats[Idx], Triple::x86_64);119}120 121TEST(ELFObjectFileTest, MachineTestFor386) {122  std::array<StringRef, 4> Formats = {"elf32-i386", "elf32-i386", "elf64-i386",123                                      "elf64-i386"};124  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_386)))125    checkFormatAndArch(Data, Formats[Idx], Triple::x86);126}127 128TEST(ELFObjectFileTest, MachineTestForMIPS) {129  std::array<StringRef, 4> Formats = {"elf32-mips", "elf32-mips", "elf64-mips",130                                      "elf64-mips"};131  std::array<Triple::ArchType, 4> Archs = {Triple::mipsel, Triple::mips,132                                           Triple::mips64el, Triple::mips64};133  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_MIPS)))134    checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);135}136 137TEST(ELFObjectFileTest, MachineTestForAMDGPU) {138  std::array<StringRef, 4> Formats = {"elf32-amdgpu", "elf32-amdgpu",139                                      "elf64-amdgpu", "elf64-amdgpu"};140  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_AMDGPU)))141    checkFormatAndArch(Data, Formats[Idx], Triple::UnknownArch);142}143 144TEST(ELFObjectFileTest, MachineTestForIAMCU) {145  std::array<StringRef, 4> Formats = {"elf32-iamcu", "elf32-iamcu",146                                      "elf64-unknown", "elf64-unknown"};147  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_IAMCU)))148    checkFormatAndArch(Data, Formats[Idx], Triple::x86);149}150 151TEST(ELFObjectFileTest, MachineTestForAARCH64) {152  std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown",153                                      "elf64-littleaarch64",154                                      "elf64-bigaarch64"};155  std::array<Triple::ArchType, 4> Archs = {Triple::aarch64, Triple::aarch64_be,156                                           Triple::aarch64, Triple::aarch64_be};157  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_AARCH64)))158    checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);159}160 161TEST(ELFObjectFileTest, MachineTestForPPC64) {162  std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown",163                                      "elf64-powerpcle", "elf64-powerpc"};164  std::array<Triple::ArchType, 4> Archs = {Triple::ppc64le, Triple::ppc64,165                                           Triple::ppc64le, Triple::ppc64};166  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_PPC64)))167    checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);168}169 170TEST(ELFObjectFileTest, MachineTestForPPC) {171  std::array<StringRef, 4> Formats = {"elf32-powerpcle", "elf32-powerpc",172                                      "elf64-unknown", "elf64-unknown"};173  std::array<Triple::ArchType, 4> Archs = {Triple::ppcle, Triple::ppc,174                                           Triple::ppcle, Triple::ppc};175  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_PPC)))176    checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);177}178 179TEST(ELFObjectFileTest, MachineTestForRISCV) {180  std::array<StringRef, 4> Formats = {"elf32-littleriscv", "elf32-bigriscv",181                                      "elf64-littleriscv", "elf64-bigriscv"};182  std::array<Triple::ArchType, 4> Archs = {Triple::riscv32, Triple::riscv32be,183                                           Triple::riscv64, Triple::riscv64be};184  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_RISCV)))185    checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);186}187 188TEST(ELFObjectFileTest, MachineTestForARM) {189  std::array<StringRef, 4> Formats = {"elf32-littlearm", "elf32-bigarm",190                                      "elf64-unknown", "elf64-unknown"};191  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_ARM)))192    checkFormatAndArch(Data, Formats[Idx], Triple::arm);193}194 195TEST(ELFObjectFileTest, MachineTestForS390) {196  std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown",197                                      "elf64-s390", "elf64-s390"};198  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_S390)))199    checkFormatAndArch(Data, Formats[Idx], Triple::systemz);200}201 202TEST(ELFObjectFileTest, MachineTestForSPARCV9) {203  std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown",204                                      "elf64-sparc", "elf64-sparc"};205  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_SPARCV9)))206    checkFormatAndArch(Data, Formats[Idx], Triple::sparcv9);207}208 209TEST(ELFObjectFileTest, MachineTestForSPARC) {210  std::array<StringRef, 4> Formats = {"elf32-sparc", "elf32-sparc",211                                      "elf64-unknown", "elf64-unknown"};212  std::array<Triple::ArchType, 4> Archs = {Triple::sparcel, Triple::sparc,213                                           Triple::sparcel, Triple::sparc};214  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_SPARC)))215    checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);216}217 218TEST(ELFObjectFileTest, MachineTestForSPARC32PLUS) {219  std::array<StringRef, 4> Formats = {"elf32-sparc", "elf32-sparc",220                                      "elf64-unknown", "elf64-unknown"};221  std::array<Triple::ArchType, 4> Archs = {Triple::sparcel, Triple::sparc,222                                           Triple::sparcel, Triple::sparc};223  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_SPARC32PLUS)))224    checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);225}226 227TEST(ELFObjectFileTest, MachineTestForBPF) {228  std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown",229                                      "elf64-bpf", "elf64-bpf"};230  std::array<Triple::ArchType, 4> Archs = {Triple::bpfel, Triple::bpfeb,231                                           Triple::bpfel, Triple::bpfeb};232  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_BPF)))233    checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);234}235 236TEST(ELFObjectFileTest, MachineTestForAVR) {237  std::array<StringRef, 4> Formats = {"elf32-avr", "elf32-avr", "elf64-unknown",238                                      "elf64-unknown"};239  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_AVR)))240    checkFormatAndArch(Data, Formats[Idx], Triple::avr);241}242 243TEST(ELFObjectFileTest, MachineTestForHEXAGON) {244  std::array<StringRef, 4> Formats = {"elf32-hexagon", "elf32-hexagon",245                                      "elf64-unknown", "elf64-unknown"};246  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_HEXAGON)))247    checkFormatAndArch(Data, Formats[Idx], Triple::hexagon);248}249 250TEST(ELFObjectFileTest, MachineTestForLANAI) {251  std::array<StringRef, 4> Formats = {"elf32-lanai", "elf32-lanai",252                                      "elf64-unknown", "elf64-unknown"};253  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_LANAI)))254    checkFormatAndArch(Data, Formats[Idx], Triple::lanai);255}256 257TEST(ELFObjectFileTest, MachineTestForMSP430) {258  std::array<StringRef, 4> Formats = {"elf32-msp430", "elf32-msp430",259                                      "elf64-unknown", "elf64-unknown"};260  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_MSP430)))261    checkFormatAndArch(Data, Formats[Idx], Triple::msp430);262}263 264TEST(ELFObjectFileTest, MachineTestForLoongArch) {265  std::array<StringRef, 4> Formats = {"elf32-loongarch", "elf32-loongarch",266                                      "elf64-loongarch", "elf64-loongarch"};267  std::array<Triple::ArchType, 4> Archs = {268      Triple::loongarch32, Triple::loongarch32, Triple::loongarch64,269      Triple::loongarch64};270  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_LOONGARCH)))271    checkFormatAndArch(Data, Formats[Idx], Archs[Idx]);272}273 274TEST(ELFObjectFileTest, MachineTestForCSKY) {275  std::array<StringRef, 4> Formats = {"elf32-csky", "elf32-csky",276                                      "elf64-unknown", "elf64-unknown"};277  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_CSKY)))278    checkFormatAndArch(Data, Formats[Idx], Triple::csky);279}280 281TEST(ELFObjectFileTest, MachineTestForXtensa) {282  std::array<StringRef, 4> Formats = {"elf32-xtensa", "elf32-xtensa",283                                      "elf64-unknown", "elf64-unknown"};284  for (auto [Idx, Data] : enumerate(generateData(ELF::EM_XTENSA)))285    checkFormatAndArch(Data, Formats[Idx], Triple::xtensa);286}287 288TEST(ELFObjectFileTest, CheckOSAndTriple) {289  std::tuple<uint16_t, uint8_t, StringRef> Formats[] = {290      {ELF::EM_AMDGPU, ELF::ELFOSABI_AMDGPU_HSA, "amdgcn-amd-amdhsa"},291      {ELF::EM_X86_64, ELF::ELFOSABI_LINUX, "x86_64--linux"},292      {ELF::EM_X86_64, ELF::ELFOSABI_NETBSD, "x86_64--netbsd"},293      {ELF::EM_X86_64, ELF::ELFOSABI_HURD, "x86_64--hurd"},294      {ELF::EM_X86_64, ELF::ELFOSABI_SOLARIS, "x86_64--solaris"},295      {ELF::EM_X86_64, ELF::ELFOSABI_AIX, "x86_64--aix"},296      {ELF::EM_X86_64, ELF::ELFOSABI_FREEBSD, "x86_64--freebsd"},297      {ELF::EM_X86_64, ELF::ELFOSABI_OPENBSD, "x86_64--openbsd"},298      {ELF::EM_CUDA, ELF::ELFOSABI_CUDA, "nvptx64-nvidia-cuda"}};299  for (auto [Machine, OS, Triple] : Formats) {300    const DataForTest D(ELF::ELFCLASS64, ELF::ELFDATA2LSB, Machine, OS,301                        ELF::EF_AMDGPU_MACH_AMDGCN_LAST);302    Expected<ELF64LEObjectFile> ELFObjOrErr = ELF64LEObjectFile::create(303        MemoryBufferRef(toStringRef(D.Data), "dummyELF"));304    ASSERT_THAT_EXPECTED(ELFObjOrErr, Succeeded());305 306    auto &ELFObj = *ELFObjOrErr;307    llvm::Triple TheTriple = ELFObj.makeTriple();308 309    // The AMDGPU architecture will be unknown on big-endian testers.310    if (TheTriple.getArch() == Triple::UnknownArch)311      continue;312 313    EXPECT_EQ(Triple, TheTriple.getTriple());314  }315}316 317// ELF relative relocation type test.318TEST(ELFObjectFileTest, RelativeRelocationTypeTest) {319  EXPECT_EQ(ELF::R_CKCORE_RELATIVE, getELFRelativeRelocationType(ELF::EM_CSKY));320}321 322template <class ELFT>323static Expected<ELFObjectFile<ELFT>> toBinary(SmallVectorImpl<char> &Storage,324                                              StringRef Yaml) {325  raw_svector_ostream OS(Storage);326  yaml::Input YIn(Yaml);327  if (!yaml::convertYAML(YIn, OS, [](const Twine &Msg) {}))328    return createStringError(std::errc::invalid_argument,329                             "unable to convert YAML");330  return ELFObjectFile<ELFT>::create(MemoryBufferRef(OS.str(), "dummyELF"));331}332 333// Check we are able to create an ELFObjectFile even when the content of the334// SHT_SYMTAB_SHNDX section can't be read properly.335TEST(ELFObjectFileTest, InvalidSymtabShndxTest) {336  SmallString<0> Storage;337  Expected<ELFObjectFile<ELF64LE>> ExpectedFile = toBinary<ELF64LE>(Storage, R"(338--- !ELF339FileHeader:340  Class: ELFCLASS64341  Data:  ELFDATA2LSB342  Type:  ET_REL343Sections:344  - Name:    .symtab_shndx345    Type:    SHT_SYMTAB_SHNDX346    Entries: [ 0 ]347    ShSize: 0xFFFFFFFF348)");349 350  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());351}352 353// Test that we are able to create an ELFObjectFile even when loadable segments354// are unsorted by virtual address.355// Test that ELFFile<ELFT>::toMappedAddr works properly in this case.356 357TEST(ELFObjectFileTest, InvalidLoadSegmentsOrderTest) {358  SmallString<0> Storage;359  Expected<ELFObjectFile<ELF64LE>> ExpectedFile = toBinary<ELF64LE>(Storage, R"(360--- !ELF361FileHeader:362  Class: ELFCLASS64363  Data:  ELFDATA2LSB364  Type:  ET_EXEC365Sections:366  - Name:         .foo367    Type:         SHT_PROGBITS368    Address:      0x1000369    Offset:       0x3000370    ContentArray: [ 0x11 ]371  - Name:         .bar372    Type:         SHT_PROGBITS373    Address:      0x2000374    Offset:       0x4000375    ContentArray: [ 0x99 ]376ProgramHeaders:377  - Type:     PT_LOAD378    VAddr:    0x2000379    FirstSec: .bar380    LastSec:  .bar381  - Type:     PT_LOAD382    VAddr:    0x1000383    FirstSec: .foo384    LastSec:  .foo385)");386 387  ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());388 389  std::string WarnString;390  auto ToMappedAddr = [&](uint64_t Addr) -> const uint8_t * {391    Expected<const uint8_t *> DataOrErr =392        ExpectedFile->getELFFile().toMappedAddr(Addr, [&](const Twine &Msg) {393          EXPECT_TRUE(WarnString.empty());394          WarnString = Msg.str();395          return Error::success();396        });397 398    if (!DataOrErr) {399      ADD_FAILURE() << toString(DataOrErr.takeError());400      return nullptr;401    }402 403    EXPECT_TRUE(WarnString ==404                "loadable segments are unsorted by virtual address");405    WarnString = "";406    return *DataOrErr;407  };408 409  const uint8_t *Data = ToMappedAddr(0x1000);410  ASSERT_TRUE(Data);411  MemoryBufferRef Buf = ExpectedFile->getMemoryBufferRef();412  EXPECT_EQ((const char *)Data - Buf.getBufferStart(), 0x3000);413  EXPECT_EQ(Data[0], 0x11);414 415  Data = ToMappedAddr(0x2000);416  ASSERT_TRUE(Data);417  Buf = ExpectedFile->getMemoryBufferRef();418  EXPECT_EQ((const char *)Data - Buf.getBufferStart(), 0x4000);419  EXPECT_EQ(Data[0], 0x99);420}421 422// This is a test for API that is related to symbols.423// We check that errors are properly reported here.424TEST(ELFObjectFileTest, InvalidSymbolTest) {425  SmallString<0> Storage;426  Expected<ELFObjectFile<ELF64LE>> ElfOrErr = toBinary<ELF64LE>(Storage, R"(427--- !ELF428FileHeader:429  Class:   ELFCLASS64430  Data:    ELFDATA2LSB431  Type:    ET_DYN432  Machine: EM_X86_64433Sections:434  - Name: .symtab435    Type: SHT_SYMTAB436)");437 438  ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());439  const ELFFile<ELF64LE> &Elf = ElfOrErr->getELFFile();440  const ELFObjectFile<ELF64LE> &Obj = *ElfOrErr;441 442  Expected<const typename ELF64LE::Shdr *> SymtabSecOrErr = Elf.getSection(1);443  ASSERT_THAT_EXPECTED(SymtabSecOrErr, Succeeded());444  ASSERT_EQ((*SymtabSecOrErr)->sh_type, ELF::SHT_SYMTAB);445 446  auto DoCheck = [&](unsigned BrokenSymIndex, const char *ErrMsg) {447    ELFSymbolRef BrokenSym = Obj.toSymbolRef(*SymtabSecOrErr, BrokenSymIndex);448 449    // 1) Check the behavior of ELFObjectFile<ELFT>::getSymbolName().450    //    SymbolRef::getName() calls it internally. We can't test it directly,451    //    because it is protected.452    EXPECT_THAT_ERROR(BrokenSym.getName().takeError(),453                      FailedWithMessage(ErrMsg));454 455    // 2) Check the behavior of ELFObjectFile<ELFT>::getSymbol().456    EXPECT_THAT_ERROR(Obj.getSymbol(BrokenSym.getRawDataRefImpl()).takeError(),457                      FailedWithMessage(ErrMsg));458 459    // 3) Check the behavior of ELFObjectFile<ELFT>::getSymbolSection().460    //    SymbolRef::getSection() calls it internally. We can't test it461    //    directly, because it is protected.462    EXPECT_THAT_ERROR(BrokenSym.getSection().takeError(),463                      FailedWithMessage(ErrMsg));464 465    // 4) Check the behavior of ELFObjectFile<ELFT>::getSymbolFlags().466    //    SymbolRef::getFlags() calls it internally. We can't test it directly,467    //    because it is protected.468    EXPECT_THAT_ERROR(BrokenSym.getFlags().takeError(),469                      FailedWithMessage(ErrMsg));470 471    // 5) Check the behavior of ELFObjectFile<ELFT>::getSymbolType().472    //    SymbolRef::getType() calls it internally. We can't test it directly,473    //    because it is protected.474    EXPECT_THAT_ERROR(BrokenSym.getType().takeError(),475                      FailedWithMessage(ErrMsg));476 477    // 6) Check the behavior of ELFObjectFile<ELFT>::getSymbolAddress().478    //    SymbolRef::getAddress() calls it internally. We can't test it479    //    directly, because it is protected.480    EXPECT_THAT_ERROR(BrokenSym.getAddress().takeError(),481                      FailedWithMessage(ErrMsg));482 483    // Finally, check the `ELFFile<ELFT>::getEntry` API. This is an underlying484    // method that generates errors for all cases above.485    EXPECT_THAT_EXPECTED(486        Elf.getEntry<typename ELF64LE::Sym>(**SymtabSecOrErr, 0), Succeeded());487    EXPECT_THAT_ERROR(488        Elf.getEntry<typename ELF64LE::Sym>(**SymtabSecOrErr, BrokenSymIndex)489            .takeError(),490        FailedWithMessage(ErrMsg));491  };492 493  // We create a symbol with an index that is too large to exist in the symbol494  // table.495  DoCheck(0x1, "can't read an entry at 0x18: it goes past the end of the "496               "section (0x18)");497 498  // We create a symbol with an index that is too large to exist in the object.499  DoCheck(0xFFFFFFFF, "can't read an entry at 0x17ffffffe8: it goes past the "500                      "end of the section (0x18)");501}502 503// Tests for error paths of the ELFFile::decodeBBAddrMap API.504TEST(ELFObjectFileTest, InvalidDecodeBBAddrMap) {505  StringRef CommonYamlString(R"(506--- !ELF507FileHeader:508  Class: ELFCLASS64509  Data:  ELFDATA2LSB510  Type:  ET_EXEC511Sections:512  - Type: SHT_LLVM_BB_ADDR_MAP513    Name: .llvm_bb_addr_map514    Entries:515)");516 517  auto DoCheck = [&](StringRef YamlString, const char *ErrMsg) {518    SmallString<0> Storage;519    Expected<ELFObjectFile<ELF64LE>> ElfOrErr =520        toBinary<ELF64LE>(Storage, YamlString);521    ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());522    const ELFFile<ELF64LE> &Elf = ElfOrErr->getELFFile();523 524    Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr =525        Elf.getSection(1);526    ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded());527    EXPECT_THAT_ERROR(Elf.decodeBBAddrMap(**BBAddrMapSecOrErr).takeError(),528                      FailedWithMessage(ErrMsg));529  };530 531  // Check that we can detect unsupported versions.532  SmallString<128> UnsupportedVersionYamlString(CommonYamlString);533  UnsupportedVersionYamlString += R"(534      - Version: 6535        BBRanges:536          - BaseAddress: 0x11111537            BBEntries:538              - AddressOffset: 0x0539                Size:          0x1540                Metadata:      0x2541)";542 543  {544    SCOPED_TRACE("unsupported version");545    DoCheck(UnsupportedVersionYamlString,546            "unsupported SHT_LLVM_BB_ADDR_MAP version: 6");547  }548 549  SmallString<128> ZeroBBRangesYamlString(CommonYamlString);550  ZeroBBRangesYamlString += R"(551      - Version: 3552        Feature: 0x8553        BBRanges: []554)";555  {556    SCOPED_TRACE("zero bb ranges");557    DoCheck(ZeroBBRangesYamlString,558            "invalid zero number of BB ranges at offset 3 in "559            "SHT_LLVM_BB_ADDR_MAP section with index 1");560  }561 562  SmallString<128> CommonVersionedYamlString(CommonYamlString);563  CommonVersionedYamlString += R"(564      - Version: 3565        BBRanges:566          - BaseAddress: 0x11111567            BBEntries:568              - AddressOffset: 0x0569                Size:          0x1570                Metadata:      0x2571)";572 573  // Check that we can detect the malformed encoding when the section is574  // truncated.575  SmallString<128> TruncatedYamlString(CommonVersionedYamlString);576  TruncatedYamlString += R"(577    ShSize: 0xb578)";579  {580    SCOPED_TRACE("truncated section");581    DoCheck(TruncatedYamlString,582            "unable to decode LEB128 at offset 0x0000000b: "583            "malformed uleb128, extends past end");584  }585 586  // Check that we can detect when the encoded BB entry fields exceed the UINT32587  // limit.588  SmallVector<SmallString<128>, 3> OverInt32LimitYamlStrings(589      3, CommonVersionedYamlString);590  OverInt32LimitYamlStrings[0] += R"(591              - ID:            1592                AddressOffset: 0x100000000593                Size:          0xFFFFFFFF594                Metadata:      0xFFFFFFFF595)";596 597  OverInt32LimitYamlStrings[1] += R"(598              - ID:            2599                AddressOffset: 0xFFFFFFFF600                Size:          0x100000000601                Metadata:      0xFFFFFFFF602)";603 604  OverInt32LimitYamlStrings[2] += R"(605              - ID:            3606                AddressOffset: 0xFFFFFFFF607                Size:          0xFFFFFFFF608                Metadata:      0x100000000609)";610 611  {612    SCOPED_TRACE("overlimit fields");613    DoCheck(OverInt32LimitYamlStrings[0],614            "ULEB128 value at offset 0x10 exceeds UINT32_MAX (0x100000000)");615    DoCheck(OverInt32LimitYamlStrings[1],616            "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000)");617    DoCheck(OverInt32LimitYamlStrings[2],618            "ULEB128 value at offset 0x1a exceeds UINT32_MAX (0x100000000)");619  }620 621  // Check the proper error handling when the section has fields exceeding622  // UINT32 and is also truncated. This is for checking that we don't generate623  // unhandled errors.624  SmallVector<SmallString<128>, 3> OverInt32LimitAndTruncated(625      3, OverInt32LimitYamlStrings[1]);626  // Truncate before the end of the 5-byte field.627  OverInt32LimitAndTruncated[0] += R"(628    ShSize: 0x19629)";630  // Truncate at the end of the 5-byte field.631  OverInt32LimitAndTruncated[1] += R"(632    ShSize: 0x1a633)";634  // Truncate after the end of the 5-byte field.635  OverInt32LimitAndTruncated[2] += R"(636    ShSize: 0x1b637)";638 639  {640    SCOPED_TRACE("overlimit fields, truncated section");641    DoCheck(OverInt32LimitAndTruncated[0],642            "unable to decode LEB128 at offset 0x00000015: malformed uleb128, "643            "extends past end");644    DoCheck(OverInt32LimitAndTruncated[1],645            "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000)");646    DoCheck(OverInt32LimitAndTruncated[2],647            "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000)");648  }649 650  // Check for proper error handling when the 'NumBlocks' field is overridden651  // with an out-of-range value.652  SmallString<128> OverLimitNumBlocks(CommonVersionedYamlString);653  OverLimitNumBlocks += R"(654            NumBlocks: 0x100000000655)";656 657  {658    SCOPED_TRACE("overlimit 'NumBlocks' field");659    DoCheck(OverLimitNumBlocks,660            "ULEB128 value at offset 0xa exceeds UINT32_MAX (0x100000000)");661  }662 663  // Check for proper error handling when the 'NumBBRanges' field is overridden664  // with an out-of-range value.665  SmallString<128> OverLimitNumBBRanges(CommonVersionedYamlString);666  OverLimitNumBBRanges += R"(667        NumBBRanges: 0x100000000668        Feature:     0x8669)";670  DoCheck(OverLimitNumBBRanges,671          "ULEB128 value at offset 0x2 exceeds UINT32_MAX (0x100000000)");672 673  // Check that we can detect unsupported version for callsite offsets.674  SmallString<128> UnsupportedLowVersionYamlString(CommonYamlString);675  UnsupportedLowVersionYamlString += R"(676      - Version: 2677        Feature: 0x20678        BBRanges:679          - BBEntries:680              - AddressOffset:   0x0681                Size:            0x1682                Metadata:        0x2683                CallsiteEndOffsets: [ 0x1 ]684)";685 686  {687    SCOPED_TRACE("unsupported version");688    DoCheck(UnsupportedLowVersionYamlString,689            "version should be >= 3 for SHT_LLVM_BB_ADDR_MAP when callsite"690            " offsets feature is enabled: version = 2 feature = 32");691  }692}693 694// Test for the ELFObjectFile::readBBAddrMap API.695TEST(ELFObjectFileTest, ReadBBAddrMap) {696  StringRef CommonYamlString(R"(697--- !ELF698FileHeader:699  Class: ELFCLASS64700  Data:  ELFDATA2LSB701  Type:  ET_EXEC702Sections:703  - Name: .llvm_bb_addr_map_1704    Type: SHT_LLVM_BB_ADDR_MAP705    Link: 1706    Entries:707      - Version: 3708        Feature: 0x20709        BBRanges:710          - BaseAddress: 0x11111711            BBEntries:712              - ID:              1713                AddressOffset:   0x0714                Size:            0x1715                Metadata:        0x2716                CallsiteEndOffsets: [ 0x1 , 0x1 ]717  - Name: .llvm_bb_addr_map_2718    Type: SHT_LLVM_BB_ADDR_MAP719    Link: 1720    Entries:721      - Version: 3722        Feature: 0x8723        BBRanges:724          - BaseAddress: 0x22222725            BBEntries:726              - ID:            2727                AddressOffset: 0x0728                Size:          0x2729                Metadata:      0x4730          - BaseAddress: 0xFFFFF731            BBEntries:732              - ID:            15733                AddressOffset: 0xF0734                Size:          0xF1735                Metadata:      0x1F736  - Name: .llvm_bb_addr_map_3737    Type: SHT_LLVM_BB_ADDR_MAP738    Link: 2739    Entries:740      - Version: 2741        BBRanges:742          - BaseAddress: 0x33333743            BBEntries:744              - ID:            0745                AddressOffset: 0x0746                Size:          0x3747                Metadata:      0x6748  - Name: .llvm_bb_addr_map_4749    Type: SHT_LLVM_BB_ADDR_MAP750  # Link: 0 (by default, can be overriden)751    Entries:752      - Version: 2753        BBRanges:754          - BaseAddress: 0x44444755            BBEntries:756              - ID:            0757                AddressOffset: 0x0758                Size:          0x4759                Metadata:      0x18760)");761 762  BBAddrMap E1 = {763      {{0x11111,764        {{1, 0x0, 0x3, {false, true, false, false, false}, {0x1, 0x2}, 0}}}}};765  BBAddrMap E2 = {766      {{0x22222, {{2, 0x0, 0x2, {false, false, true, false, false}, {}, 0}}},767       {0xFFFFF, {{15, 0xF0, 0xF1, {true, true, true, true, true}, {}, 0}}}}};768  BBAddrMap E3 = {769      {{0x33333, {{0, 0x0, 0x3, {false, true, true, false, false}, {}, 0}}}}};770  BBAddrMap E4 = {771      {{0x44444, {{0, 0x0, 0x4, {false, false, false, true, true}, {}, 0}}}}};772 773  std::vector<BBAddrMap> Section0BBAddrMaps = {E4};774  std::vector<BBAddrMap> Section1BBAddrMaps = {E3};775  std::vector<BBAddrMap> Section2BBAddrMaps = {E1, E2};776  std::vector<BBAddrMap> AllBBAddrMaps = {E1, E2, E3, E4};777 778  auto DoCheckSucceeds = [&](StringRef YamlString,779                             std::optional<unsigned> TextSectionIndex,780                             std::vector<BBAddrMap> ExpectedResult) {781    SCOPED_TRACE("for TextSectionIndex: " +782                 (TextSectionIndex ? llvm::Twine(*TextSectionIndex) : "{}") +783                 " and object yaml:\n" + YamlString);784    SmallString<0> Storage;785    Expected<ELFObjectFile<ELF64LE>> ElfOrErr =786        toBinary<ELF64LE>(Storage, YamlString);787    ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());788 789    Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr =790        ElfOrErr->getELFFile().getSection(1);791    ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded());792    auto BBAddrMaps = ElfOrErr->readBBAddrMap(TextSectionIndex);793    ASSERT_THAT_EXPECTED(BBAddrMaps, Succeeded());794    EXPECT_EQ(*BBAddrMaps, ExpectedResult);795  };796 797  auto DoCheckFails = [&](StringRef YamlString,798                          std::optional<unsigned> TextSectionIndex,799                          const char *ErrMsg) {800    SCOPED_TRACE("for TextSectionIndex: " +801                 (TextSectionIndex ? llvm::Twine(*TextSectionIndex) : "{}") +802                 " and object yaml:\n" + YamlString);803    SmallString<0> Storage;804    Expected<ELFObjectFile<ELF64LE>> ElfOrErr =805        toBinary<ELF64LE>(Storage, YamlString);806    ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());807 808    Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr =809        ElfOrErr->getELFFile().getSection(1);810    ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded());811    EXPECT_THAT_ERROR(ElfOrErr->readBBAddrMap(TextSectionIndex).takeError(),812                      FailedWithMessage(ErrMsg));813  };814 815  {816    SCOPED_TRACE("normal sections");817    // Check that we can retrieve the data in the normal case.818    DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/std::nullopt,819                    AllBBAddrMaps);820    DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/0,821                    Section0BBAddrMaps);822    DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/2,823                    Section1BBAddrMaps);824    DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/1,825                    Section2BBAddrMaps);826    // Check that when no bb-address-map section is found for a text section,827    // we return an empty result.828    DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/3, {});829  }830 831  // Check that we detect when a bb-addr-map section is linked to an invalid832  // (not present) section.833  SmallString<128> InvalidLinkedYamlString(CommonYamlString);834  InvalidLinkedYamlString += R"(835    Link: 121836)";837 838  DoCheckFails(InvalidLinkedYamlString, /*TextSectionIndex=*/4,839               "unable to get the linked-to section for "840               "SHT_LLVM_BB_ADDR_MAP section with index 4: invalid section "841               "index: 121");842  {843    SCOPED_TRACE("invalid linked section");844    // Linked sections are not checked when we don't target a specific text845    // section.846    DoCheckSucceeds(InvalidLinkedYamlString, /*TextSectionIndex=*/std::nullopt,847                    AllBBAddrMaps);848  }849 850  // Check that we can detect when bb-address-map decoding fails.851  SmallString<128> TruncatedYamlString(CommonYamlString);852  TruncatedYamlString += R"(853    ShSize: 0xa854)";855 856  {857    SCOPED_TRACE("truncated section");858    DoCheckFails(TruncatedYamlString, /*TextSectionIndex=*/std::nullopt,859                 "unable to read SHT_LLVM_BB_ADDR_MAP section with index 4: "860                 "unable to decode LEB128 at offset 0x0000000a: malformed "861                 "uleb128, extends past end");862 863    // Check that we can read the other section's bb-address-maps which are864    // valid.865    DoCheckSucceeds(TruncatedYamlString, /*TextSectionIndex=*/2,866                    Section1BBAddrMaps);867  }868}869 870// Tests for error paths of the ELFFile::decodeBBAddrMap with PGOAnalysisMap871// API.872TEST(ELFObjectFileTest, InvalidDecodePGOAnalysisMap) {873  StringRef CommonYamlString(R"(874--- !ELF875FileHeader:876  Class: ELFCLASS64877  Data:  ELFDATA2LSB878  Type:  ET_EXEC879Sections:880  - Type: SHT_LLVM_BB_ADDR_MAP881    Name: .llvm_bb_addr_map882    Entries:883)");884 885  auto DoCheck = [&](StringRef YamlString, const char *ErrMsg) {886    SmallString<0> Storage;887    Expected<ELFObjectFile<ELF64LE>> ElfOrErr =888        toBinary<ELF64LE>(Storage, YamlString);889    ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());890    const ELFFile<ELF64LE> &Elf = ElfOrErr->getELFFile();891 892    Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr =893        Elf.getSection(1);894    ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded());895 896    std::vector<PGOAnalysisMap> PGOAnalyses;897    EXPECT_THAT_ERROR(898        Elf.decodeBBAddrMap(**BBAddrMapSecOrErr, nullptr, &PGOAnalyses)899            .takeError(),900        FailedWithMessage(ErrMsg));901  };902 903  // Check that we can detect unsupported versions that are too old.904  SmallString<128> UnsupportedLowVersionYamlString(CommonYamlString);905  UnsupportedLowVersionYamlString += R"(906      - Version: 1907        Feature: 0x0908        BBRanges:909          - BBEntries:910              - AddressOffset: 0x0911                Size:          0x1912                Metadata:      0x2913)";914 915  {916    SCOPED_TRACE("unsupported version");917    DoCheck(UnsupportedLowVersionYamlString,918            "unsupported SHT_LLVM_BB_ADDR_MAP version: 1");919  }920 921  // Check that we fail when function entry count is enabled but not provided.922  SmallString<128> MissingFuncEntryCount(CommonYamlString);923  MissingFuncEntryCount += R"(924      - Version: 2925        Feature: 0x01926)";927 928  {929    SCOPED_TRACE("missing function entry count");930    DoCheck(MissingFuncEntryCount,931            "unexpected end of data at offset 0x2 while reading [0x2, 0xa)");932  }933 934  // Check that we fail when basic block frequency is enabled but not provided.935  SmallString<128> MissingBBFreq(CommonYamlString);936  MissingBBFreq += R"(937      - Version: 2938        Feature: 0x02939        BBRanges:940          - BBEntries:941              - ID:            1942                AddressOffset: 0x0943                Size:          0x1944                Metadata:      0x2945)";946 947  {948    SCOPED_TRACE("missing bb frequency");949    DoCheck(MissingBBFreq, "unable to decode LEB128 at offset 0x0000000f: "950                           "malformed uleb128, extends past end");951  }952 953  // Check that we fail when branch probability is enabled but not provided.954  SmallString<128> MissingBrProb(CommonYamlString);955  MissingBrProb += R"(956      - Version: 2957        Feature: 0x04958        BBRanges:959          - BBEntries:960              - ID:            1961                AddressOffset: 0x0962                Size:          0x1963                Metadata:      0x6964              - ID:            2965                AddressOffset: 0x1966                Size:          0x1967                Metadata:      0x2968              - ID:            3969                AddressOffset: 0x2970                Size:          0x1971                Metadata:      0x2972    PGOAnalyses:973      - PGOBBEntries:974         - Successors:975            - ID:          2976              BrProb:      0x80000000977            - ID:          3978              BrProb:      0x80000000979         - Successors:980            - ID:          3981              BrProb:      0xF0000000982)";983 984  {985    SCOPED_TRACE("missing branch probability");986    DoCheck(MissingBrProb, "unable to decode LEB128 at offset 0x00000017: "987                           "malformed uleb128, extends past end");988  }989}990 991// Test for the ELFObjectFile::readBBAddrMap API with BBHash.992TEST(ELFObjectFileTest, ReadBBHash) {993  StringRef CommonYamlString(R"(994--- !ELF995FileHeader:996  Class: ELFCLASS64997  Data:  ELFDATA2LSB998  Type:  ET_EXEC999Sections:1000  - Name: .llvm_bb_addr_map_11001    Type: SHT_LLVM_BB_ADDR_MAP1002    Link: 11003    Entries:1004      - Version: 41005        Feature: 0x601006        BBRanges:1007          - BaseAddress: 0x111111008            BBEntries:1009              - ID:              11010                AddressOffset:   0x01011                Size:            0x11012                Metadata:        0x21013                CallsiteEndOffsets: [ 0x1 , 0x1 ]1014                Hash:            0x11015  - Name: .llvm_bb_addr_map_21016    Type: SHT_LLVM_BB_ADDR_MAP1017    Link: 11018    Entries:1019      - Version: 41020        Feature: 0x481021        BBRanges:1022          - BaseAddress: 0x222221023            BBEntries:1024              - ID:            21025                AddressOffset: 0x01026                Size:          0x21027                Metadata:      0x41028                Hash:          0x21029          - BaseAddress: 0xFFFFF1030            BBEntries:1031              - ID:            151032                AddressOffset: 0xF01033                Size:          0xF11034                Metadata:      0x1F1035                Hash:          0xF1036  - Name: .llvm_bb_addr_map_31037    Type: SHT_LLVM_BB_ADDR_MAP1038    Link: 21039    Entries:1040      - Version: 41041        Feature: 0x401042        BBRanges:1043          - BaseAddress: 0x333331044            BBEntries:1045              - ID:            01046                AddressOffset: 0x01047                Size:          0x31048                Metadata:      0x61049                Hash:          0x31050  - Name: .llvm_bb_addr_map_41051    Type: SHT_LLVM_BB_ADDR_MAP1052  # Link: 0 (by default, can be overriden)1053    Entries:1054      - Version: 41055        Feature: 0x401056        BBRanges:1057          - BaseAddress: 0x444441058            BBEntries:1059              - ID:            01060                AddressOffset: 0x01061                Size:          0x41062                Metadata:      0x181063                Hash:          0x41064)");1065 1066  BBAddrMap E1 = {1067      {{0x11111,1068        {{1, 0x0, 0x3, {false, true, false, false, false}, {0x1, 0x2}, 0x1}}}}};1069  BBAddrMap E2 = {1070      {{0x22222, {{2, 0x0, 0x2, {false, false, true, false, false}, {}, 0x2}}},1071       {0xFFFFF, {{15, 0xF0, 0xF1, {true, true, true, true, true}, {}, 0xF}}}}};1072  BBAddrMap E3 = {1073      {{0x33333, {{0, 0x0, 0x3, {false, true, true, false, false}, {}, 0x3}}}}};1074  BBAddrMap E4 = {1075      {{0x44444, {{0, 0x0, 0x4, {false, false, false, true, true}, {}, 0x4}}}}};1076 1077  std::vector<BBAddrMap> Section0BBAddrMaps = {E4};1078  std::vector<BBAddrMap> Section1BBAddrMaps = {E3};1079  std::vector<BBAddrMap> Section2BBAddrMaps = {E1, E2};1080  std::vector<BBAddrMap> AllBBAddrMaps = {E1, E2, E3, E4};1081 1082  auto DoCheckSucceeds = [&](StringRef YamlString,1083                             std::optional<unsigned> TextSectionIndex,1084                             std::vector<BBAddrMap> ExpectedResult) {1085    SCOPED_TRACE("for TextSectionIndex: " +1086                 (TextSectionIndex ? llvm::Twine(*TextSectionIndex) : "{}") +1087                 " and object yaml:\n" + YamlString);1088    SmallString<0> Storage;1089    Expected<ELFObjectFile<ELF64LE>> ElfOrErr =1090        toBinary<ELF64LE>(Storage, YamlString);1091    ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());1092 1093    Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr =1094        ElfOrErr->getELFFile().getSection(1);1095    ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded());1096    auto BBAddrMaps = ElfOrErr->readBBAddrMap(TextSectionIndex);1097    ASSERT_THAT_EXPECTED(BBAddrMaps, Succeeded());1098    EXPECT_EQ(*BBAddrMaps, ExpectedResult);1099  };1100 1101  DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/std::nullopt,1102                  AllBBAddrMaps);1103  DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/0, Section0BBAddrMaps);1104  DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/2, Section1BBAddrMaps);1105  DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/1, Section2BBAddrMaps);1106}1107 1108// Test for the ELFObjectFile::readBBAddrMap API with PGOAnalysisMap.1109TEST(ELFObjectFileTest, ReadPGOAnalysisMap) {1110  StringRef CommonYamlString(R"(1111--- !ELF1112FileHeader:1113  Class: ELFCLASS641114  Data:  ELFDATA2LSB1115  Type:  ET_EXEC1116Sections:1117  - Name: .llvm_bb_addr_map_11118    Type: SHT_LLVM_BB_ADDR_MAP1119    Link: 11120    Entries:1121      - Version: 21122        Feature: 0x11123        BBRanges:1124          - BaseAddress: 0x111111125            BBEntries:1126              - ID:            11127                AddressOffset: 0x01128                Size:          0x11129                Metadata:      0x21130    PGOAnalyses:1131      - FuncEntryCount: 8921132  - Name: .llvm_bb_addr_map_21133    Type: SHT_LLVM_BB_ADDR_MAP1134    Link: 11135    Entries:1136      - Version: 21137        Feature: 0x21138        BBRanges:1139          - BaseAddress: 0x222221140            BBEntries:1141              - ID:            21142                AddressOffset: 0x01143                Size:          0x21144                Metadata:      0x41145    PGOAnalyses:1146      - PGOBBEntries:1147         - BBFreq:         3431148  - Name: .llvm_bb_addr_map_31149    Type: SHT_LLVM_BB_ADDR_MAP1150    Link: 21151    Entries:1152      - Version: 21153        Feature: 0x41154        BBRanges:1155          - BaseAddress: 0x333331156            BBEntries:1157              - ID:            01158                AddressOffset: 0x01159                Size:          0x31160                Metadata:      0x61161              - ID:            11162                AddressOffset: 0x01163                Size:          0x31164                Metadata:      0x41165              - ID:            21166                AddressOffset: 0x01167                Size:          0x31168                Metadata:      0x01169    PGOAnalyses:1170      - PGOBBEntries:1171         - Successors:1172            - ID:          11173              BrProb:      0x111111111174            - ID:          21175              BrProb:      0xeeeeeeee1176         - Successors:1177            - ID:          21178              BrProb:      0xffffffff1179         - Successors:     []1180  - Name: .llvm_bb_addr_map_41181    Type: SHT_LLVM_BB_ADDR_MAP1182  # Link: 0 (by default, can be overriden)1183    Entries:1184      - Version: 51185        Feature: 0x871186        BBRanges:1187          - BaseAddress: 0x444441188            BBEntries:1189              - ID:            01190                AddressOffset: 0x01191                Size:          0x41192                Metadata:      0x181193              - ID:            11194                AddressOffset: 0x01195                Size:          0x41196                Metadata:      0x01197              - ID:            21198                AddressOffset: 0x01199                Size:          0x41200                Metadata:      0x01201              - ID:            31202                AddressOffset: 0x01203                Size:          0x41204                Metadata:      0x01205    PGOAnalyses:1206      - FuncEntryCount: 10001207        PGOBBEntries:1208          - BBFreq:          10001209            PostLinkBBFreq:  501210            Successors:1211            - ID:          11212              BrProb:      0x222222221213            - ID:          21214              BrProb:      0x333333331215            - ID:          31216              BrProb:      0xaaaaaaaa1217          - BBFreq:         1331218            Successors:1219            - ID:          21220              BrProb:      0x111111111221            - ID:          31222              BrProb:      0xeeeeeeee1223          - BBFreq:         181224            Successors:1225            - ID:          31226              BrProb:      0xffffffff1227          - BBFreq:         10001228            Successors:    []1229  - Name: .llvm_bb_addr_map_51230    Type: SHT_LLVM_BB_ADDR_MAP1231  # Link: 0 (by default, can be overriden)1232    Entries:1233      - Version: 21234        Feature: 0x01235        BBRanges:1236          - BaseAddress: 0x555551237            BBEntries:1238              - ID:            21239                AddressOffset: 0x01240                Size:          0x21241                Metadata:      0x41242    PGOAnalyses: [{}]1243  - Name: .llvm_bb_addr_map_61244    Type: SHT_LLVM_BB_ADDR_MAP1245  # Link: 0 (by default, can be overriden)1246    Entries:1247      - Version: 51248        Feature: 0x8c1249        BBRanges:1250          - BaseAddress: 0x666661251            BBEntries:1252              - ID:            01253                AddressOffset: 0x01254                Size:          0x61255                Metadata:      0x61256              - ID:            11257                AddressOffset: 0x01258                Size:          0x61259                Metadata:      0x41260          - BaseAddress: 0x6666611261            BBEntries:1262              - ID:            21263                AddressOffset: 0x01264                Size:          0x61265                Metadata:      0x01266    PGOAnalyses:1267      - PGOBBEntries:1268         - Successors:1269            - ID:              11270              BrProb:          0x222222221271              PostLinkBrFreq:  71272            - ID:          21273              BrProb:      0xcccccccc1274         - Successors:1275            - ID:          21276              BrProb:      0x888888881277         - Successors:     []1278)");1279 1280  BBAddrMap E1 = {1281      {{0x11111, {{1, 0x0, 0x1, {false, true, false, false, false}, {}, 0}}}}};1282  PGOAnalysisMap P1 = {1283      892, {}, {true, false, false, false, false, false, false, false}};1284  BBAddrMap E2 = {1285      {{0x22222, {{2, 0x0, 0x2, {false, false, true, false, false}, {}, 0}}}}};1286  PGOAnalysisMap P2 = {{},1287                       {{BlockFrequency(343), 0, {}}},1288                       {false, true, false, false, false, false, false, false}};1289  BBAddrMap E3 = {1290      {{0x33333,1291        {{0, 0x0, 0x3, {false, true, true, false, false}, {}, 0},1292         {1, 0x3, 0x3, {false, false, true, false, false}, {}, 0},1293         {2, 0x6, 0x3, {false, false, false, false, false}, {}, 0}}}}};1294  PGOAnalysisMap P3 = {1295      {},1296      {{{},1297        0,1298        {{1, BranchProbability::getRaw(0x1111'1111), 0},1299         {2, BranchProbability::getRaw(0xeeee'eeee), 0}}},1300       {{}, 0, {{2, BranchProbability::getRaw(0xffff'ffff), 0}}},1301       {{}, 0, {}}},1302      {false, false, true, false, false, false, false, false}};1303  BBAddrMap E4 = {1304      {{0x44444,1305        {{0, 0x0, 0x4, {false, false, false, true, true}, {}, 0},1306         {1, 0x4, 0x4, {false, false, false, false, false}, {}, 0},1307         {2, 0x8, 0x4, {false, false, false, false, false}, {}, 0},1308         {3, 0xc, 0x4, {false, false, false, false, false}, {}, 0}}}}};1309  PGOAnalysisMap P4 = {1000,1310                       {{BlockFrequency(1000),1311                         50,1312                         {{1, BranchProbability::getRaw(0x2222'2222), 0},1313                          {2, BranchProbability::getRaw(0x3333'3333), 0},1314                          {3, BranchProbability::getRaw(0xaaaa'aaaa), 0}}},1315                        {BlockFrequency(133),1316                         0,1317                         {{2, BranchProbability::getRaw(0x1111'1111), 0},1318                          {3, BranchProbability::getRaw(0xeeee'eeee), 0}}},1319                        {BlockFrequency(18),1320                         0,1321                         {{3, BranchProbability::getRaw(0xffff'ffff), 0}}},1322                        {BlockFrequency(1000), 0, {}}},1323                       {true, true, true, false, false, false, false, true}};1324  BBAddrMap E5 = {1325      {{0x55555, {{2, 0x0, 0x2, {false, false, true, false, false}, {}, 0}}}}};1326  PGOAnalysisMap P5 = {1327      {}, {}, {false, false, false, false, false, false, false, false}};1328  BBAddrMap E6 = {1329      {{0x66666,1330        {{0, 0x0, 0x6, {false, true, true, false, false}, {}, 0},1331         {1, 0x6, 0x6, {false, false, true, false, false}, {}, 0}}},1332       {0x666661,1333        {{2, 0x0, 0x6, {false, false, false, false, false}, {}, 0}}}}};1334  PGOAnalysisMap P6 = {1335      {},1336      {{{},1337        0,1338        {{1, BranchProbability::getRaw(0x2222'2222), 7},1339         {2, BranchProbability::getRaw(0xcccc'cccc), 0}}},1340       {{}, 0, {{2, BranchProbability::getRaw(0x8888'8888), 0}}},1341       {{}, 0, {}}},1342      {false, false, true, true, false, false, false, true}};1343 1344  std::vector<BBAddrMap> Section0BBAddrMaps = {E4, E5, E6};1345  std::vector<BBAddrMap> Section1BBAddrMaps = {E3};1346  std::vector<BBAddrMap> Section2BBAddrMaps = {E1, E2};1347  std::vector<BBAddrMap> AllBBAddrMaps = {E1, E2, E3, E4, E5, E6};1348 1349  std::vector<PGOAnalysisMap> Section0PGOAnalysisMaps = {P4, P5, P6};1350  std::vector<PGOAnalysisMap> Section1PGOAnalysisMaps = {P3};1351  std::vector<PGOAnalysisMap> Section2PGOAnalysisMaps = {P1, P2};1352  std::vector<PGOAnalysisMap> AllPGOAnalysisMaps = {P1, P2, P3, P4, P5, P6};1353 1354  auto DoCheckSucceeds =1355      [&](StringRef YamlString, std::optional<unsigned> TextSectionIndex,1356          std::vector<BBAddrMap> ExpectedResult,1357          std::optional<std::vector<PGOAnalysisMap>> ExpectedPGO) {1358        SCOPED_TRACE(1359            "for TextSectionIndex: " +1360            (TextSectionIndex ? llvm::Twine(*TextSectionIndex) : "{}") +1361            " and object yaml:\n" + YamlString);1362        SmallString<0> Storage;1363        Expected<ELFObjectFile<ELF64LE>> ElfOrErr =1364            toBinary<ELF64LE>(Storage, YamlString);1365        ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());1366 1367        Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr =1368            ElfOrErr->getELFFile().getSection(1);1369        ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded());1370 1371        std::vector<PGOAnalysisMap> PGOAnalyses;1372        auto BBAddrMaps = ElfOrErr->readBBAddrMap(1373            TextSectionIndex, ExpectedPGO ? &PGOAnalyses : nullptr);1374        ASSERT_THAT_EXPECTED(BBAddrMaps, Succeeded());1375        EXPECT_EQ(*BBAddrMaps, ExpectedResult);1376        if (ExpectedPGO) {1377          EXPECT_EQ(BBAddrMaps->size(), PGOAnalyses.size());1378          for (const auto &PGO : PGOAnalyses) {1379            errs() << "FuncEntryCount: " << PGO.FuncEntryCount << "\n";1380            for (const auto &PGOBB : PGO.BBEntries)1381              errs() << "\tBB: " << PGOBB.BlockFreq.getFrequency() << "\n";1382          }1383          errs() << " To expected:\n";1384          for (const auto &PGO : *ExpectedPGO) {1385            errs() << "FuncEntryCount: " << PGO.FuncEntryCount << "\n";1386            for (const auto &PGOBB : PGO.BBEntries)1387              errs() << "\tBB: " << PGOBB.BlockFreq.getFrequency() << "\n";1388          }1389          EXPECT_EQ(PGOAnalyses, *ExpectedPGO);1390          for (auto &&[BB, PGO] : llvm::zip(*BBAddrMaps, PGOAnalyses)) {1391            if (PGO.FeatEnable.BBFreq || PGO.FeatEnable.BrProb)1392              EXPECT_EQ(BB.getNumBBEntries(), PGO.BBEntries.size());1393          }1394        }1395      };1396 1397  auto DoCheckFails = [&](StringRef YamlString,1398                          std::optional<unsigned> TextSectionIndex,1399                          const char *ErrMsg) {1400    SCOPED_TRACE("for TextSectionIndex: " +1401                 (TextSectionIndex ? llvm::Twine(*TextSectionIndex) : "{}") +1402                 " and object yaml:\n" + YamlString);1403    SmallString<0> Storage;1404    Expected<ELFObjectFile<ELF64LE>> ElfOrErr =1405        toBinary<ELF64LE>(Storage, YamlString);1406    ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());1407 1408    Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr =1409        ElfOrErr->getELFFile().getSection(1);1410    ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded());1411    std::vector<PGOAnalysisMap> PGOAnalyses;1412    EXPECT_THAT_ERROR(1413        ElfOrErr->readBBAddrMap(TextSectionIndex, &PGOAnalyses).takeError(),1414        FailedWithMessage(ErrMsg));1415  };1416 1417  {1418    SCOPED_TRACE("normal sections");1419    // Check that we can retrieve the data in the normal case.1420    DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/std::nullopt,1421                    AllBBAddrMaps, std::nullopt);1422    DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/0,1423                    Section0BBAddrMaps, std::nullopt);1424    DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/2,1425                    Section1BBAddrMaps, std::nullopt);1426    DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/1,1427                    Section2BBAddrMaps, std::nullopt);1428 1429    DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/std::nullopt,1430                    AllBBAddrMaps, AllPGOAnalysisMaps);1431    DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/0,1432                    Section0BBAddrMaps, Section0PGOAnalysisMaps);1433    DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/2,1434                    Section1BBAddrMaps, Section1PGOAnalysisMaps);1435    DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/1,1436                    Section2BBAddrMaps, Section2PGOAnalysisMaps);1437    // Check that when no bb-address-map section is found for a text section,1438    // we return an empty result.1439    DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/3, {}, std::nullopt);1440    DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/3, {},1441                    std::vector<PGOAnalysisMap>{});1442  }1443 1444  // Check that we detect when a bb-addr-map section is linked to an invalid1445  // (not present) section.1446  SmallString<128> InvalidLinkedYamlString(CommonYamlString);1447  InvalidLinkedYamlString += R"(1448    Link: 1211449)";1450 1451  {1452    SCOPED_TRACE("invalid linked section");1453    DoCheckFails(InvalidLinkedYamlString, /*TextSectionIndex=*/5,1454                 "unable to get the linked-to section for "1455                 "SHT_LLVM_BB_ADDR_MAP section with index 6: invalid section "1456                 "index: 121");1457 1458    // Linked sections are not checked when we don't target a specific text1459    // section.1460    DoCheckSucceeds(InvalidLinkedYamlString, /*TextSectionIndex=*/std::nullopt,1461                    AllBBAddrMaps, std::nullopt);1462    DoCheckSucceeds(InvalidLinkedYamlString, /*TextSectionIndex=*/std::nullopt,1463                    AllBBAddrMaps, AllPGOAnalysisMaps);1464  }1465 1466  // Check that we can detect when bb-address-map decoding fails.1467  SmallString<128> TruncatedYamlString(CommonYamlString);1468  TruncatedYamlString += R"(1469    ShSize: 0xa1470)";1471 1472  {1473    SCOPED_TRACE("truncated section");1474    DoCheckFails(1475        TruncatedYamlString, /*TextSectionIndex=*/std::nullopt,1476        "unable to read SHT_LLVM_BB_ADDR_MAP section with index 6: "1477        "unexpected end of data at offset 0xa while reading [0x4, 0xc)");1478    // Check that we can read the other section's bb-address-maps which are1479    // valid.1480    DoCheckSucceeds(TruncatedYamlString, /*TextSectionIndex=*/2,1481                    Section1BBAddrMaps, std::nullopt);1482    DoCheckSucceeds(TruncatedYamlString, /*TextSectionIndex=*/2,1483                    Section1BBAddrMaps, Section1PGOAnalysisMaps);1484  }1485}1486 1487// Test for ObjectFile::getRelocatedSection: check that it returns a relocated1488// section for executable and relocatable files.1489TEST(ELFObjectFileTest, ExecutableWithRelocs) {1490  StringRef HeaderString(R"(1491--- !ELF1492FileHeader:1493  Class: ELFCLASS641494  Data:  ELFDATA2LSB1495)");1496  StringRef ContentsString(R"(1497Sections:1498  - Name:  .text1499    Type:  SHT_PROGBITS1500    Flags: [ SHF_ALLOC, SHF_EXECINSTR ]1501  - Name:  .rela.text1502    Type:  SHT_RELA1503    Flags: [ SHF_INFO_LINK ]1504    Info:  .text1505)");1506 1507  auto DoCheck = [&](StringRef YamlString) {1508    SmallString<0> Storage;1509    Expected<ELFObjectFile<ELF64LE>> ElfOrErr =1510        toBinary<ELF64LE>(Storage, YamlString);1511    ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());1512    const ELFObjectFile<ELF64LE> &Obj = *ElfOrErr;1513 1514    bool FoundRela;1515 1516    for (SectionRef Sec : Obj.sections()) {1517      Expected<StringRef> SecNameOrErr = Sec.getName();1518      ASSERT_THAT_EXPECTED(SecNameOrErr, Succeeded());1519      StringRef SecName = *SecNameOrErr;1520      if (SecName != ".rela.text")1521        continue;1522      FoundRela = true;1523      Expected<section_iterator> RelSecOrErr = Sec.getRelocatedSection();1524      ASSERT_THAT_EXPECTED(RelSecOrErr, Succeeded());1525      section_iterator RelSec = *RelSecOrErr;1526      ASSERT_NE(RelSec, Obj.section_end());1527      Expected<StringRef> TextSecNameOrErr = RelSec->getName();1528      ASSERT_THAT_EXPECTED(TextSecNameOrErr, Succeeded());1529      StringRef TextSecName = *TextSecNameOrErr;1530      EXPECT_EQ(TextSecName, ".text");1531    }1532    ASSERT_TRUE(FoundRela);1533  };1534 1535  // Check ET_EXEC file (`ld --emit-relocs` use-case).1536  SmallString<128> ExecFileYamlString(HeaderString);1537  ExecFileYamlString += R"(1538  Type:  ET_EXEC1539)";1540  ExecFileYamlString += ContentsString;1541  DoCheck(ExecFileYamlString);1542 1543  // Check ET_REL file.1544  SmallString<128> RelocatableFileYamlString(HeaderString);1545  RelocatableFileYamlString += R"(1546  Type:  ET_REL1547)";1548  RelocatableFileYamlString += ContentsString;1549  DoCheck(RelocatableFileYamlString);1550}1551 1552TEST(ELFObjectFileTest, GetSectionAndRelocations) {1553  StringRef HeaderString(R"(1554--- !ELF1555FileHeader:1556  Class: ELFCLASS641557  Data:  ELFDATA2LSB1558  Type:  ET_EXEC1559)");1560 1561  using Elf_Shdr = Elf_Shdr_Impl<ELF64LE>;1562 1563  auto DoCheckSucceeds = [&](StringRef ContentsString,1564                             std::function<Expected<bool>(const Elf_Shdr &)>1565                                 Matcher) {1566    SmallString<0> Storage;1567    SmallString<128> FullYamlString(HeaderString);1568    FullYamlString += ContentsString;1569    Expected<ELFObjectFile<ELF64LE>> ElfOrErr =1570        toBinary<ELF64LE>(Storage, FullYamlString);1571    ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());1572 1573    Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SecToRelocMapOrErr =1574        ElfOrErr->getELFFile().getSectionAndRelocations(Matcher);1575    ASSERT_THAT_EXPECTED(SecToRelocMapOrErr, Succeeded());1576 1577    // Basic verification to make sure we have the correct section types.1578    for (auto const &[Sec, RelaSec] : *SecToRelocMapOrErr) {1579      ASSERT_EQ(Sec->sh_type, ELF::SHT_PROGBITS);1580      ASSERT_TRUE(RelaSec->sh_type == ELF::SHT_RELA ||1581                  RelaSec->sh_type == ELF::SHT_CREL);1582    }1583  };1584 1585  auto DoCheckFails = [&](StringRef ContentsString,1586                          std::function<Expected<bool>(const Elf_Shdr &)>1587                              Matcher,1588                          const char *ErrorMessage) {1589    SmallString<0> Storage;1590    SmallString<128> FullYamlString(HeaderString);1591    FullYamlString += ContentsString;1592    Expected<ELFObjectFile<ELF64LE>> ElfOrErr =1593        toBinary<ELF64LE>(Storage, FullYamlString);1594    ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());1595 1596    Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SecToRelocMapOrErr =1597        ElfOrErr->getELFFile().getSectionAndRelocations(Matcher);1598    ASSERT_THAT_ERROR(SecToRelocMapOrErr.takeError(),1599                      FailedWithMessage(ErrorMessage));1600  };1601 1602  auto DefaultMatcher = [](const Elf_Shdr &Sec) -> bool {1603    return Sec.sh_type == ELF::SHT_PROGBITS;1604  };1605 1606  StringRef TwoTextSections = R"(1607Sections:1608  - Name: .text1609    Type: SHT_PROGBITS1610    Flags: [ SHF_ALLOC, SHF_EXECINSTR ]1611  - Name: .rela.text1612    Type: SHT_RELA1613    Flags: [ SHF_INFO_LINK ]1614    Info: .text1615  - Name: .text21616    Type: SHT_PROGBITS1617    Flags: [ SHF_ALLOC, SHF_EXECINSTR ]1618  - Name: .rela.text21619    Type: SHT_RELA1620    Flags: [ SHF_INFO_LINK ]1621    Info: .text21622)";1623  DoCheckSucceeds(TwoTextSections, DefaultMatcher);1624 1625  StringRef OneTextSection = R"(1626Sections:1627  - Name: .text1628    Type: SHT_PROGBITS1629    Flags: [ SHF_ALLOC, SHF_EXECINSTR ]1630)";1631 1632  auto ErroringMatcher = [](const Elf_Shdr &Sec) -> Expected<bool> {1633    if (Sec.sh_type == ELF::SHT_PROGBITS)1634      return createError("This was supposed to fail.");1635    return false;1636  };1637 1638  DoCheckFails(OneTextSection, ErroringMatcher, "This was supposed to fail.");1639 1640  StringRef MissingRelocatableContent = R"(1641Sections:1642  - Name: .rela.text1643    Type: SHT_RELA1644    Flags: [ SHF_INFO_LINK ]1645    Info: 0xFF1646)";1647 1648  DoCheckFails(MissingRelocatableContent, DefaultMatcher,1649               "SHT_RELA section with index 1: failed to get a "1650               "relocated section: invalid section index: 255");1651 1652  StringRef OneTextSectionCREL = R"(1653Sections:1654  - Name: .text1655    Type: SHT_PROGBITS1656    Flags: [ SHF_ALLOC, SHF_EXECINSTR ]1657  - Name: .crel.tex1658    Type: SHT_CREL1659    Flags: [ SHF_INFO_LINK ]1660    Info: .text1661)";1662 1663  DoCheckSucceeds(OneTextSectionCREL, DefaultMatcher);1664}1665 1666TEST(ELFObjectFileTest, ELFSymbolRefLess) {1667  SmallString<0> Storage;1668  Expected<ELFObjectFile<ELF64LE>> ElfOrErr = toBinary<ELF64LE>(Storage, R"(1669--- !ELF1670FileHeader:1671  Class:   ELFCLASS641672  Data:    ELFDATA2LSB1673  Type:    ET_DYN1674  Machine: EM_X86_641675)");1676 1677  ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());1678  const ELFObjectFile<ELF64LE> &Obj = *ElfOrErr;1679 1680  const uint32_t ValLow = 0x00000001;1681  const uint32_t ValHigh = 0x00000100;1682 1683  auto MakeSymbol = [&Obj](size_t SymtabIndex, size_t SymbolIndex) {1684    DataRefImpl Data;1685    Data.d.a = SymtabIndex;1686    Data.d.b = SymbolIndex;1687    SymbolRef Sym(Data, &Obj);1688    return ELFSymbolRef(Sym);1689  };1690 1691  ELFSymbolRef ELFSymLowLow = MakeSymbol(ValLow, ValLow);1692  ELFSymbolRef ELFSymLowHigh = MakeSymbol(ValLow, ValHigh);1693  ELFSymbolRef ELFSymHighLow = MakeSymbol(ValHigh, ValLow);1694  ELFSymbolRef ELFSymHighHigh = MakeSymbol(ValHigh, ValHigh);1695 1696  EXPECT_TRUE(ELFSymLowLow < ELFSymLowHigh);1697  EXPECT_FALSE(ELFSymLowHigh < ELFSymLowLow);1698  EXPECT_FALSE(ELFSymLowLow < ELFSymLowLow);1699 1700  EXPECT_TRUE(ELFSymLowLow < ELFSymHighHigh);1701  EXPECT_TRUE(ELFSymLowHigh < ELFSymHighLow);1702  EXPECT_TRUE(ELFSymLowLow < ELFSymHighLow);1703 1704  EXPECT_FALSE(ELFSymHighLow < ELFSymLowHigh);1705  EXPECT_FALSE(ELFSymHighHigh < ELFSymLowLow);1706  EXPECT_FALSE(ELFSymHighLow < ELFSymLowLow);1707}1708