1 //===----------------------- ELFTypesTest.cpp -----------------------------===//
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-exception
7 //===----------------------------------------------------------------------===//
8 #include "llvm/Object/ELFTypes.h"
9 #include "llvm/Testing/Support/Error.h"
10 #include "gtest/gtest.h"
14 using namespace llvm::object
;
16 template <typename ELFT
> using Elf_Note
= typename
ELFT::Note
;
18 template <class ELFT
> struct NoteTestData
{
19 std::vector
<uint8_t> Data
;
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
),
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();
34 auto NameOffset
= Data
.begin() + sizeof(*Nhdr
);
35 std::copy(Name
.begin(), Name
.end(), NameOffset
);
38 Data
.begin() + alignTo(sizeof(*Nhdr
) + Nhdr
->n_namesz
, Align
);
39 std::copy(Desc
.begin(), Desc
.end(), DescOffset
);
41 return Elf_Note_Impl
<ELFT
>(*Nhdr
);
45 TEST(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
;
50 auto Note1
= TestData
.getElfNote(StringRef("AMD"), ELF::NT_AMDGPU_METADATA
,
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
)));
58 auto Note2
= TestData
.getElfNote("", ELF::NT_AMDGPU_METADATA
, RandomData
);
59 EXPECT_EQ(Note2
.getName(), "");
62 TestData
.getElfNote("AMD", ELF::NT_AMDGPU_METADATA
, ArrayRef
<uint8_t>());
63 EXPECT_EQ(Note3
.getDescAsStringRef(4), StringRef(""));
66 TEST(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
]);
86 TEST(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
) {
93 BBAddrMap::BBEntry::Metadata::decode(Values
[i
]).takeError(),
94 FailedWithMessage(Errors
[i
]));
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");
103 TEST(ELFTypesTest
, BBAddrMapFeaturesEncodingTest
) {
104 const std::array
<BBAddrMap::Features
, 9> Decoded
= {
105 {{false, false, false, false},
106 {true, false, false, false},
107 {false, true, false, false},
108 {false, false, true, false},
109 {false, false, false, true},
110 {true, true, false, false},
111 {false, true, true, false},
112 {false, true, true, true},
113 {true, true, true, true}}};
114 const std::array
<uint8_t, 9> Encoded
= {
115 {0b0000, 0b0001, 0b0010, 0b0100, 0b1000, 0b0011, 0b0110, 0b1110, 0b1111}};
116 for (const auto &[Feat
, EncodedVal
] : llvm::zip(Decoded
, Encoded
))
117 EXPECT_EQ(Feat
.encode(), EncodedVal
);
118 for (const auto &[Feat
, EncodedVal
] : llvm::zip(Decoded
, Encoded
)) {
119 Expected
<BBAddrMap::Features
> FeatEnableOrError
=
120 BBAddrMap::Features::decode(EncodedVal
);
121 ASSERT_THAT_EXPECTED(FeatEnableOrError
, Succeeded());
122 EXPECT_EQ(*FeatEnableOrError
, Feat
);
126 TEST(ELFTypesTest
, BBAddrMapFeaturesInvalidEncodingTest
) {
127 const std::array
<std::string
, 2> Errors
= {
128 "invalid encoding for BBAddrMap::Features: 0x10",
129 "invalid encoding for BBAddrMap::Features: 0xff"};
130 const std::array
<uint8_t, 2> Values
= {{0b10000, 0b1111'1111}};
131 for (const auto &[Val
, Error
] : llvm::zip(Values
, Errors
)) {
132 EXPECT_THAT_ERROR(BBAddrMap::Features::decode(Val
).takeError(),
133 FailedWithMessage(Error
));