142 lines · cpp
1//===----------------------- ELFTypesTest.cpp -----------------------------===//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#include "llvm/Object/ELFTypes.h"9#include "llvm/Testing/Support/Error.h"10#include "gtest/gtest.h"11#include <iostream>12 13using namespace llvm;14using namespace llvm::object;15 16template <typename ELFT> using Elf_Note = typename ELFT::Note;17 18template <class ELFT> struct NoteTestData {19 std::vector<uint8_t> Data;20 21 const Elf_Note_Impl<ELFT> getElfNote(StringRef Name, uint32_t Type,22 ArrayRef<uint8_t> Desc) {23 constexpr uint64_t Align = 4;24 Data.resize(alignTo(sizeof(Elf_Nhdr_Impl<ELFT>) + Name.size(), Align) +25 alignTo(Desc.size(), Align),26 0);27 28 Elf_Nhdr_Impl<ELFT> *Nhdr =29 reinterpret_cast<Elf_Nhdr_Impl<ELFT> *>(Data.data());30 Nhdr->n_namesz = (Name == "") ? 0 : Name.size() + 1;31 Nhdr->n_descsz = Desc.size();32 Nhdr->n_type = Type;33 34 auto NameOffset = Data.begin() + sizeof(*Nhdr);35 llvm::copy(Name, NameOffset);36 37 auto DescOffset =38 Data.begin() + alignTo(sizeof(*Nhdr) + Nhdr->n_namesz, Align);39 std::copy(Desc.begin(), Desc.end(), DescOffset);40 41 return Elf_Note_Impl<ELFT>(*Nhdr);42 }43};44 45TEST(ELFTypesTest, NoteTest) {46 static const uint8_t Random[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};47 ArrayRef<uint8_t> RandomData = ArrayRef(Random);48 NoteTestData<ELF64LE> TestData;49 50 auto Note1 = TestData.getElfNote(StringRef("AMD"), ELF::NT_AMDGPU_METADATA,51 RandomData);52 EXPECT_EQ(Note1.getName(), "AMD");53 EXPECT_EQ(Note1.getType(), ELF::NT_AMDGPU_METADATA);54 EXPECT_EQ(Note1.getDesc(4), RandomData);55 EXPECT_EQ(Note1.getDescAsStringRef(4),56 StringRef(reinterpret_cast<const char *>(Random), sizeof(Random)));57 58 auto Note2 = TestData.getElfNote("", ELF::NT_AMDGPU_METADATA, RandomData);59 EXPECT_EQ(Note2.getName(), "");60 61 auto Note3 =62 TestData.getElfNote("AMD", ELF::NT_AMDGPU_METADATA, ArrayRef<uint8_t>());63 EXPECT_EQ(Note3.getDescAsStringRef(4), StringRef(""));64}65 66TEST(ELFTypesTest, BBEntryMetadataEncodingTest) {67 const std::array<BBAddrMap::BBEntry::Metadata, 7> Decoded = {68 {{false, false, false, false, false},69 {true, false, false, false, false},70 {false, true, false, false, false},71 {false, false, true, false, false},72 {false, false, false, true, false},73 {false, false, false, false, true},74 {true, true, true, true, true}}};75 const std::array<uint32_t, 7> Encoded = {{0, 1, 2, 4, 8, 16, 31}};76 for (size_t i = 0; i < Decoded.size(); ++i)77 EXPECT_EQ(Decoded[i].encode(), Encoded[i]);78 for (size_t i = 0; i < Encoded.size(); ++i) {79 Expected<BBAddrMap::BBEntry::Metadata> MetadataOrError =80 BBAddrMap::BBEntry::Metadata::decode(Encoded[i]);81 ASSERT_THAT_EXPECTED(MetadataOrError, Succeeded());82 EXPECT_EQ(*MetadataOrError, Decoded[i]);83 }84}85 86TEST(ELFTypesTest, BBEntryMetadataInvalidEncodingTest) {87 const std::array<std::string, 2> Errors = {88 "invalid encoding for BBEntry::Metadata: 0xffff",89 "invalid encoding for BBEntry::Metadata: 0x100001"};90 const std::array<uint32_t, 2> Values = {{0xFFFF, 0x100001}};91 for (size_t i = 0; i < Values.size(); ++i) {92 EXPECT_THAT_ERROR(93 BBAddrMap::BBEntry::Metadata::decode(Values[i]).takeError(),94 FailedWithMessage(Errors[i]));95 }96}97 98static_assert(99 std::is_same_v<decltype(PGOAnalysisMap::PGOBBEntry::SuccessorEntry::ID),100 decltype(BBAddrMap::BBEntry::ID)>,101 "PGOAnalysisMap should use the same type for basic block ID as BBAddrMap");102 103TEST(ELFTypesTest, BBAddrMapFeaturesEncodingTest) {104 const std::array<BBAddrMap::Features, 14> Decoded = {105 {{false, false, false, false, false, false, false, false},106 {true, false, false, false, false, false, false, false},107 {false, true, false, false, false, false, false, false},108 {false, false, true, false, false, false, false, false},109 {false, false, false, true, false, false, false, false},110 {true, true, false, false, false, false, false, false},111 {false, true, true, false, false, false, false, false},112 {false, true, true, true, false, false, false, false},113 {true, true, true, true, false, false, false, false},114 {false, false, false, false, true, false, false, false},115 {false, false, false, false, false, true, false, false},116 {false, false, false, false, false, false, true, false},117 {false, false, false, false, false, false, false, true},118 {false, false, false, false, false, false, true, true}}};119 const std::array<uint16_t, 14> Encoded = {120 {0b0000, 0b0001, 0b0010, 0b0100, 0b1000, 0b0011, 0b0110, 0b1110, 0b1111,121 0b1'0000, 0b10'0000, 0b100'0000, 0b1000'0000, 0b1100'0000}};122 for (const auto &[Feat, EncodedVal] : llvm::zip(Decoded, Encoded))123 EXPECT_EQ(Feat.encode(), EncodedVal);124 for (const auto &[Feat, EncodedVal] : llvm::zip(Decoded, Encoded)) {125 Expected<BBAddrMap::Features> FeatEnableOrError =126 BBAddrMap::Features::decode(EncodedVal);127 ASSERT_THAT_EXPECTED(FeatEnableOrError, Succeeded());128 EXPECT_EQ(*FeatEnableOrError, Feat);129 }130}131 132TEST(ELFTypesTest, BBAddrMapFeaturesInvalidEncodingTest) {133 const std::array<std::string, 2> Errors = {134 "invalid encoding for BBAddrMap::Features: 0x100",135 "invalid encoding for BBAddrMap::Features: 0x1000"};136 const std::array<uint16_t, 2> Values = {{0b1'0000'0000, 0b1'0000'0000'0000}};137 for (const auto &[Val, Error] : llvm::zip(Values, Errors)) {138 EXPECT_THAT_ERROR(BBAddrMap::Features::decode(Val).takeError(),139 FailedWithMessage(Error));140 }141}142