diff --git a/llvm/lib/DebugInfo/CodeView/Formatters.cpp b/llvm/lib/DebugInfo/CodeView/Formatters.cpp --- a/llvm/lib/DebugInfo/CodeView/Formatters.cpp +++ b/llvm/lib/DebugInfo/CodeView/Formatters.cpp @@ -23,6 +23,17 @@ GuidAdapter::GuidAdapter(ArrayRef Guid) : FormatAdapter(std::move(Guid)) {} +// From https://docs.microsoft.com/en-us/windows/win32/msi/guid documentation: +// The GUID data type is a text string representing a Class identifier (ID). +// All GUIDs must be authored in uppercase. +// The valid format for a GUID is {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} where +// X is a hex digit (0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F). +// +// The individual string components must be padded to comply with the specific +// lengths of {8-4-4-4-12} characters. +// The llvm-yaml2obj tool checks that a GUID follow that format: +// - the total length to be 38 (including the curly braces. +// - there is a dash at the positions: 8, 13, 18 and 23. void GuidAdapter::format(raw_ostream &Stream, StringRef Style) { assert(Item.size() == 16 && "Expected 16-byte GUID"); struct MSGuid { @@ -33,11 +44,11 @@ }; const MSGuid *G = reinterpret_cast(Item.data()); Stream - << '{' << format_hex_no_prefix(G->Data1, sizeof(G->Data1), /*Upper=*/true) - << '-' << format_hex_no_prefix(G->Data2, sizeof(G->Data2), /*Upper=*/true) - << '-' << format_hex_no_prefix(G->Data3, sizeof(G->Data3), /*Upper=*/true) - << '-' << format_hex_no_prefix(G->Data4 >> 48, 2, /*Upper=*/true) << '-' - << format_hex_no_prefix(G->Data4 & ((1ULL << 48) - 1), 6, /*Upper=*/true) + << '{' << format_hex_no_prefix(G->Data1, 8, /*Upper=*/true) + << '-' << format_hex_no_prefix(G->Data2, 4, /*Upper=*/true) + << '-' << format_hex_no_prefix(G->Data3, 4, /*Upper=*/true) + << '-' << format_hex_no_prefix(G->Data4 >> 48, 4, /*Upper=*/true) << '-' + << format_hex_no_prefix(G->Data4 & ((1ULL << 48) - 1), 12, /*Upper=*/true) << '}'; } diff --git a/llvm/test/tools/obj2yaml/COFF/Inputs/test-1.o b/llvm/test/tools/obj2yaml/COFF/Inputs/test-1.o new file mode 100755 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@; +using GuidData = SmallVector; + +void checkData(GuidData &Data) { + for (auto Item : Data) { + std::string GuidText(formatv("{0}", Item.second).str()); + StringRef Scalar(GuidText); + + // GUID strings are 38 characters long. + EXPECT_EQ(Scalar.size(), size_t(38)); + + // GUID must be enclosed in {} + EXPECT_EQ(Scalar.front(), '{'); + EXPECT_EQ(Scalar.back(), '}'); + + Scalar = Scalar.substr(1, Scalar.size() - 2); + SmallVector Component; + Scalar.split(Component, '-', 5); + + // GUID must have 5 components. + EXPECT_EQ(Component.size(), size_t(5)); + + // GUID components are properly delineated with dashes. + EXPECT_EQ(Scalar[8], '-'); + EXPECT_EQ(Scalar[13], '-'); + EXPECT_EQ(Scalar[18], '-'); + EXPECT_EQ(Scalar[23], '-'); + + // GUID only contains hex digits. + struct { + support::ulittle32_t Data0; + support::ulittle16_t Data1; + support::ulittle16_t Data2; + support::ubig16_t Data3; + support::ubig64_t Data4; + } G = {}; + EXPECT_TRUE(to_integer(Component[0], G.Data0, 16)); + EXPECT_TRUE(to_integer(Component[1], G.Data1, 16)); + EXPECT_TRUE(to_integer(Component[2], G.Data2, 16)); + EXPECT_TRUE(to_integer(Component[3], G.Data3, 16)); + EXPECT_TRUE(to_integer(Component[4], G.Data4, 16)); + + // Check the values are the same. + EXPECT_EQ(Scalar, Item.first); + } +} + +TEST(GUIDFormatTest, ValidateFormat) { + // Shifting 2 (0x00) + GuidData Data = { + // Non-zero values in all components. + {"11223344-5566-7788-99AA-BBCCDDEEFFAA", + {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc, + 0xdd, 0xee, 0xff, 0xaa}}, + + // Zero values in all components. + {"00000000-0000-0000-0000-000000000000", + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}}, + + // Shift 2 (0x00) across all components + {"00003344-5566-7788-99AA-BBCCDDEEFFAA", + {0x44, 0x33, 0x00, 0x00, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc, + 0xdd, 0xee, 0xff, 0xaa}}, + {"11000044-5566-7788-99AA-BBCCDDEEFFAA", + {0x44, 0x00, 0x00, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc, + 0xdd, 0xee, 0xff, 0xaa}}, + {"11220000-5566-7788-99AA-BBCCDDEEFFAA", + {0x00, 0x00, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc, + 0xdd, 0xee, 0xff, 0xaa}}, + {"11223300-0066-7788-99AA-BBCCDDEEFFAA", + {0x00, 0x33, 0x22, 0x11, 0x66, 0x00, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc, + 0xdd, 0xee, 0xff, 0xaa}}, + {"11223344-0000-7788-99AA-BBCCDDEEFFAA", + {0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc, + 0xdd, 0xee, 0xff, 0xaa}}, + {"11223344-5500-0088-99AA-BBCCDDEEFFAA", + {0x44, 0x33, 0x22, 0x11, 0x00, 0x55, 0x88, 0x00, 0x99, 0xaa, 0xbb, 0xcc, + 0xdd, 0xee, 0xff, 0xaa}}, + {"11223344-5566-0000-99AA-BBCCDDEEFFAA", + {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x00, 0x00, 0x99, 0xaa, 0xbb, 0xcc, + 0xdd, 0xee, 0xff, 0xaa}}, + {"11223344-5566-7700-00AA-BBCCDDEEFFAA", + {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x00, 0x77, 0x00, 0xaa, 0xbb, 0xcc, + 0xdd, 0xee, 0xff, 0xaa}}, + {"11223344-5566-7788-0000-BBCCDDEEFFAA", + {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x00, 0x00, 0xbb, 0xcc, + 0xdd, 0xee, 0xff, 0xaa}}, + {"11223344-5566-7788-9900-00CCDDEEFFAA", + {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0x00, 0x00, 0xcc, + 0xdd, 0xee, 0xff, 0xaa}}, + {"11223344-5566-7788-99AA-0000DDEEFFAA", + {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0x00, 0x00, + 0xdd, 0xee, 0xff, 0xaa}}, + {"11223344-5566-7788-99AA-BB0000EEFFAA", + {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0x00, + 0x00, 0xee, 0xff, 0xaa}}, + {"11223344-5566-7788-99AA-BBCC0000FFAA", + {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc, + 0x00, 0x00, 0xff, 0xaa}}, + {"11223344-5566-7788-99AA-BBCCDD0000AA", + {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc, + 0xdd, 0x00, 0x00, 0xaa}}, + {"11223344-5566-7788-99AA-BBCCDDEE0000", + {0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x88, 0x77, 0x99, 0xaa, 0xbb, 0xcc, + 0xdd, 0xee, 0x00, 0x00}}, + }; + + checkData(Data); +} +} // namespace