1*d0a5d861SCarlosAlbertoEnciso //===- unittest/DebugInfo/CodeView/GUIDFormatTest.cpp - GUID formatting ---===//
2*d0a5d861SCarlosAlbertoEnciso //
3*d0a5d861SCarlosAlbertoEnciso // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*d0a5d861SCarlosAlbertoEnciso // See https://llvm.org/LICENSE.txt for license information.
5*d0a5d861SCarlosAlbertoEnciso // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*d0a5d861SCarlosAlbertoEnciso //
7*d0a5d861SCarlosAlbertoEnciso //===----------------------------------------------------------------------===//
8*d0a5d861SCarlosAlbertoEnciso 
9*d0a5d861SCarlosAlbertoEnciso #include "llvm/ADT/SmallVector.h"
10*d0a5d861SCarlosAlbertoEnciso #include "llvm/ADT/StringRef.h"
11*d0a5d861SCarlosAlbertoEnciso #include "llvm/DebugInfo/CodeView/Formatters.h"
12*d0a5d861SCarlosAlbertoEnciso #include "llvm/DebugInfo/CodeView/GUID.h"
13*d0a5d861SCarlosAlbertoEnciso #include "llvm/Support/FormatVariadic.h"
14*d0a5d861SCarlosAlbertoEnciso #include "gtest/gtest.h"
15*d0a5d861SCarlosAlbertoEnciso 
16*d0a5d861SCarlosAlbertoEnciso using namespace llvm;
17*d0a5d861SCarlosAlbertoEnciso using namespace llvm::codeview;
18*d0a5d861SCarlosAlbertoEnciso 
19*d0a5d861SCarlosAlbertoEnciso // Variant 1 UUIDs, nowadays the most common variant, are encoded in a
20*d0a5d861SCarlosAlbertoEnciso // big-endian format.
21*d0a5d861SCarlosAlbertoEnciso // For example, 00112233-4455-6677-8899-aabbccddeeff is encoded as the bytes
22*d0a5d861SCarlosAlbertoEnciso // 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff
23*d0a5d861SCarlosAlbertoEnciso //
24*d0a5d861SCarlosAlbertoEnciso // Variant 2 UUIDs, historically used in Microsoft's COM/OLE libraries, use a
25*d0a5d861SCarlosAlbertoEnciso // mixed-endian format, whereby the first three components of the UUID are
26*d0a5d861SCarlosAlbertoEnciso // little-endian, and the last two are big-endian.
27*d0a5d861SCarlosAlbertoEnciso // For example, 00112233-4455-6677-8899-aabbccddeeff is encoded as the bytes
28*d0a5d861SCarlosAlbertoEnciso // 33 22 11 00 55 44 77 66 88 99 aa bb cc dd ee ff.
29*d0a5d861SCarlosAlbertoEnciso //
30*d0a5d861SCarlosAlbertoEnciso // Note: Only Variant 2 UUIDs are tested.
31*d0a5d861SCarlosAlbertoEnciso namespace {
32*d0a5d861SCarlosAlbertoEnciso 
33*d0a5d861SCarlosAlbertoEnciso using GuidPair = std::pair<StringRef, GUID>;
34*d0a5d861SCarlosAlbertoEnciso using GuidData = SmallVector<GuidPair>;
35*d0a5d861SCarlosAlbertoEnciso 
checkData(GuidData & Data)36*d0a5d861SCarlosAlbertoEnciso void checkData(GuidData &Data) {
37*d0a5d861SCarlosAlbertoEnciso   for (auto Item : Data) {
38*d0a5d861SCarlosAlbertoEnciso     std::string GuidText(formatv("{0}", Item.second).str());
39*d0a5d861SCarlosAlbertoEnciso     StringRef Scalar(GuidText);
40*d0a5d861SCarlosAlbertoEnciso 
41*d0a5d861SCarlosAlbertoEnciso     // GUID strings are 38 characters long.
42*d0a5d861SCarlosAlbertoEnciso     EXPECT_EQ(Scalar.size(), size_t(38));
43*d0a5d861SCarlosAlbertoEnciso 
44*d0a5d861SCarlosAlbertoEnciso     // GUID must be enclosed in {}
45*d0a5d861SCarlosAlbertoEnciso     EXPECT_EQ(Scalar.front(), '{');
46*d0a5d861SCarlosAlbertoEnciso     EXPECT_EQ(Scalar.back(), '}');
47*d0a5d861SCarlosAlbertoEnciso 
48*d0a5d861SCarlosAlbertoEnciso     Scalar = Scalar.substr(1, Scalar.size() - 2);
49*d0a5d861SCarlosAlbertoEnciso     SmallVector<StringRef, 6> Component;
50*d0a5d861SCarlosAlbertoEnciso     Scalar.split(Component, '-', 5);
51*d0a5d861SCarlosAlbertoEnciso 
52*d0a5d861SCarlosAlbertoEnciso     // GUID must have 5 components.
53*d0a5d861SCarlosAlbertoEnciso     EXPECT_EQ(Component.size(), size_t(5));
54*d0a5d861SCarlosAlbertoEnciso 
55*d0a5d861SCarlosAlbertoEnciso     // GUID components are properly delineated with dashes.
56*d0a5d861SCarlosAlbertoEnciso     EXPECT_EQ(Scalar[8], '-');
57*d0a5d861SCarlosAlbertoEnciso     EXPECT_EQ(Scalar[13], '-');
58*d0a5d861SCarlosAlbertoEnciso     EXPECT_EQ(Scalar[18], '-');
59*d0a5d861SCarlosAlbertoEnciso     EXPECT_EQ(Scalar[23], '-');
60*d0a5d861SCarlosAlbertoEnciso 
61*d0a5d861SCarlosAlbertoEnciso     // GUID only contains hex digits.
62*d0a5d861SCarlosAlbertoEnciso     struct {
63*d0a5d861SCarlosAlbertoEnciso       support::ulittle32_t Data0;
64*d0a5d861SCarlosAlbertoEnciso       support::ulittle16_t Data1;
65*d0a5d861SCarlosAlbertoEnciso       support::ulittle16_t Data2;
66*d0a5d861SCarlosAlbertoEnciso       support::ubig16_t Data3;
67*d0a5d861SCarlosAlbertoEnciso       support::ubig64_t Data4;
68*d0a5d861SCarlosAlbertoEnciso     } G = {};
69*d0a5d861SCarlosAlbertoEnciso     EXPECT_TRUE(to_integer(Component[0], G.Data0, 16));
70*d0a5d861SCarlosAlbertoEnciso     EXPECT_TRUE(to_integer(Component[1], G.Data1, 16));
71*d0a5d861SCarlosAlbertoEnciso     EXPECT_TRUE(to_integer(Component[2], G.Data2, 16));
72*d0a5d861SCarlosAlbertoEnciso     EXPECT_TRUE(to_integer(Component[3], G.Data3, 16));
73*d0a5d861SCarlosAlbertoEnciso     EXPECT_TRUE(to_integer(Component[4], G.Data4, 16));
74*d0a5d861SCarlosAlbertoEnciso 
75*d0a5d861SCarlosAlbertoEnciso     // Check the values are the same.
76*d0a5d861SCarlosAlbertoEnciso     EXPECT_EQ(Scalar, Item.first);
77*d0a5d861SCarlosAlbertoEnciso   }
78*d0a5d861SCarlosAlbertoEnciso }
79*d0a5d861SCarlosAlbertoEnciso 
TEST(GUIDFormatTest,ValidateFormat)80*d0a5d861SCarlosAlbertoEnciso TEST(GUIDFormatTest, ValidateFormat) {
81*d0a5d861SCarlosAlbertoEnciso   // Shifting 2 (0x00)
82*d0a5d861SCarlosAlbertoEnciso   GuidData Data = {
83*d0a5d861SCarlosAlbertoEnciso       // Non-zero values in all components.
84*d0a5d861SCarlosAlbertoEnciso       {"11223344-5566-7788-99AA-BBCCDDEEFFAA",
85*d0a5d861SCarlosAlbertoEnciso        {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc,
86*d0a5d861SCarlosAlbertoEnciso         0xdd, 0xee, 0xff, 0xaa}},
87*d0a5d861SCarlosAlbertoEnciso 
88*d0a5d861SCarlosAlbertoEnciso       // Zero values in all components.
89*d0a5d861SCarlosAlbertoEnciso       {"00000000-0000-0000-0000-000000000000",
90*d0a5d861SCarlosAlbertoEnciso        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91*d0a5d861SCarlosAlbertoEnciso         0x00, 0x00, 0x00, 0x00}},
92*d0a5d861SCarlosAlbertoEnciso 
93*d0a5d861SCarlosAlbertoEnciso       // Shift 2 (0x00) across all components
94*d0a5d861SCarlosAlbertoEnciso       {"00003344-5566-7788-99AA-BBCCDDEEFFAA",
95*d0a5d861SCarlosAlbertoEnciso        {0x44, 0x33, 0x00, 0x00, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc,
96*d0a5d861SCarlosAlbertoEnciso         0xdd, 0xee, 0xff, 0xaa}},
97*d0a5d861SCarlosAlbertoEnciso       {"11000044-5566-7788-99AA-BBCCDDEEFFAA",
98*d0a5d861SCarlosAlbertoEnciso        {0x44, 0x00, 0x00, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc,
99*d0a5d861SCarlosAlbertoEnciso         0xdd, 0xee, 0xff, 0xaa}},
100*d0a5d861SCarlosAlbertoEnciso       {"11220000-5566-7788-99AA-BBCCDDEEFFAA",
101*d0a5d861SCarlosAlbertoEnciso        {0x00, 0x00, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc,
102*d0a5d861SCarlosAlbertoEnciso         0xdd, 0xee, 0xff, 0xaa}},
103*d0a5d861SCarlosAlbertoEnciso       {"11223300-0066-7788-99AA-BBCCDDEEFFAA",
104*d0a5d861SCarlosAlbertoEnciso        {0x00, 0x33, 0x22, 0x11, 0x66, 0x00, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc,
105*d0a5d861SCarlosAlbertoEnciso         0xdd, 0xee, 0xff, 0xaa}},
106*d0a5d861SCarlosAlbertoEnciso       {"11223344-0000-7788-99AA-BBCCDDEEFFAA",
107*d0a5d861SCarlosAlbertoEnciso        {0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc,
108*d0a5d861SCarlosAlbertoEnciso         0xdd, 0xee, 0xff, 0xaa}},
109*d0a5d861SCarlosAlbertoEnciso       {"11223344-5500-0088-99AA-BBCCDDEEFFAA",
110*d0a5d861SCarlosAlbertoEnciso        {0x44, 0x33, 0x22, 0x11, 0x00, 0x55, 0x88, 0x00, 0x99, 0xaa, 0xbb, 0xcc,
111*d0a5d861SCarlosAlbertoEnciso         0xdd, 0xee, 0xff, 0xaa}},
112*d0a5d861SCarlosAlbertoEnciso       {"11223344-5566-0000-99AA-BBCCDDEEFFAA",
113*d0a5d861SCarlosAlbertoEnciso        {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x00, 0x00, 0x99, 0xaa, 0xbb, 0xcc,
114*d0a5d861SCarlosAlbertoEnciso         0xdd, 0xee, 0xff, 0xaa}},
115*d0a5d861SCarlosAlbertoEnciso       {"11223344-5566-7700-00AA-BBCCDDEEFFAA",
116*d0a5d861SCarlosAlbertoEnciso        {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x00, 0x77, 0x00, 0xaa, 0xbb, 0xcc,
117*d0a5d861SCarlosAlbertoEnciso         0xdd, 0xee, 0xff, 0xaa}},
118*d0a5d861SCarlosAlbertoEnciso       {"11223344-5566-7788-0000-BBCCDDEEFFAA",
119*d0a5d861SCarlosAlbertoEnciso        {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x00, 0x00, 0xbb, 0xcc,
120*d0a5d861SCarlosAlbertoEnciso         0xdd, 0xee, 0xff, 0xaa}},
121*d0a5d861SCarlosAlbertoEnciso       {"11223344-5566-7788-9900-00CCDDEEFFAA",
122*d0a5d861SCarlosAlbertoEnciso        {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0x00, 0x00, 0xcc,
123*d0a5d861SCarlosAlbertoEnciso         0xdd, 0xee, 0xff, 0xaa}},
124*d0a5d861SCarlosAlbertoEnciso       {"11223344-5566-7788-99AA-0000DDEEFFAA",
125*d0a5d861SCarlosAlbertoEnciso        {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0x00, 0x00,
126*d0a5d861SCarlosAlbertoEnciso         0xdd, 0xee, 0xff, 0xaa}},
127*d0a5d861SCarlosAlbertoEnciso       {"11223344-5566-7788-99AA-BB0000EEFFAA",
128*d0a5d861SCarlosAlbertoEnciso        {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0x00,
129*d0a5d861SCarlosAlbertoEnciso         0x00, 0xee, 0xff, 0xaa}},
130*d0a5d861SCarlosAlbertoEnciso       {"11223344-5566-7788-99AA-BBCC0000FFAA",
131*d0a5d861SCarlosAlbertoEnciso        {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc,
132*d0a5d861SCarlosAlbertoEnciso         0x00, 0x00, 0xff, 0xaa}},
133*d0a5d861SCarlosAlbertoEnciso       {"11223344-5566-7788-99AA-BBCCDD0000AA",
134*d0a5d861SCarlosAlbertoEnciso        {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc,
135*d0a5d861SCarlosAlbertoEnciso         0xdd, 0x00, 0x00, 0xaa}},
136*d0a5d861SCarlosAlbertoEnciso       {"11223344-5566-7788-99AA-BBCCDDEE0000",
137*d0a5d861SCarlosAlbertoEnciso        {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc,
138*d0a5d861SCarlosAlbertoEnciso         0xdd, 0xee, 0x00, 0x00}},
139*d0a5d861SCarlosAlbertoEnciso   };
140*d0a5d861SCarlosAlbertoEnciso 
141*d0a5d861SCarlosAlbertoEnciso   checkData(Data);
142*d0a5d861SCarlosAlbertoEnciso }
143*d0a5d861SCarlosAlbertoEnciso } // namespace
144