404 lines · cpp
1//===- llvm/unittest/DebugInfo/DWARFFormValueTest.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 9#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"10#include "llvm/ADT/ArrayRef.h"11#include "llvm/ADT/SmallString.h"12#include "llvm/ADT/StringExtras.h"13#include "llvm/BinaryFormat/Dwarf.h"14#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"15#include "llvm/Support/FormatVariadic.h"16#include "llvm/Support/LEB128.h"17#include "llvm/TargetParser/Host.h"18#include "gtest/gtest.h"19#include <climits>20using namespace llvm;21using namespace dwarf;22 23namespace {24 25bool isFormClass(dwarf::Form Form, DWARFFormValue::FormClass FC) {26 return DWARFFormValue(Form).isFormClass(FC);27}28 29TEST(DWARFFormValue, FormClass) {30 EXPECT_TRUE(isFormClass(DW_FORM_addr, DWARFFormValue::FC_Address));31 EXPECT_FALSE(isFormClass(DW_FORM_data8, DWARFFormValue::FC_Address));32 EXPECT_TRUE(isFormClass(DW_FORM_data8, DWARFFormValue::FC_Constant));33 EXPECT_TRUE(isFormClass(DW_FORM_data8, DWARFFormValue::FC_SectionOffset));34 EXPECT_TRUE(doesFormBelongToClass(DW_FORM_data8,35 DWARFFormValue::FC_SectionOffset, 3));36 EXPECT_FALSE(doesFormBelongToClass(DW_FORM_data8,37 DWARFFormValue::FC_SectionOffset, 5));38 EXPECT_TRUE(39 isFormClass(DW_FORM_sec_offset, DWARFFormValue::FC_SectionOffset));40 EXPECT_TRUE(isFormClass(DW_FORM_GNU_str_index, DWARFFormValue::FC_String));41 EXPECT_TRUE(isFormClass(DW_FORM_GNU_addr_index, DWARFFormValue::FC_Address));42 EXPECT_FALSE(isFormClass(DW_FORM_ref_addr, DWARFFormValue::FC_Address));43 EXPECT_TRUE(isFormClass(DW_FORM_ref_addr, DWARFFormValue::FC_Reference));44 EXPECT_TRUE(isFormClass(DW_FORM_ref_sig8, DWARFFormValue::FC_Reference));45}46 47template<typename RawTypeT>48DWARFFormValue createDataXFormValue(dwarf::Form Form, RawTypeT Value) {49 char Raw[sizeof(RawTypeT)];50 memcpy(Raw, &Value, sizeof(RawTypeT));51 uint64_t Offset = 0;52 DWARFFormValue Result(Form);53 DWARFDataExtractor Data(StringRef(Raw, sizeof(RawTypeT)),54 sys::IsLittleEndianHost, sizeof(void *));55 Result.extractValue(Data, &Offset, {0, 0, dwarf::DwarfFormat::DWARF32});56 return Result;57}58 59DWARFFormValue createULEBFormValue(uint64_t Value) {60 SmallString<10> RawData;61 raw_svector_ostream OS(RawData);62 encodeULEB128(Value, OS);63 uint64_t Offset = 0;64 DWARFFormValue Result(DW_FORM_udata);65 DWARFDataExtractor Data(OS.str(), sys::IsLittleEndianHost, sizeof(void *));66 Result.extractValue(Data, &Offset, {0, 0, dwarf::DwarfFormat::DWARF32});67 return Result;68}69 70DWARFFormValue createSLEBFormValue(int64_t Value) {71 SmallString<10> RawData;72 raw_svector_ostream OS(RawData);73 encodeSLEB128(Value, OS);74 uint64_t Offset = 0;75 DWARFFormValue Result(DW_FORM_sdata);76 DWARFDataExtractor Data(OS.str(), sys::IsLittleEndianHost, sizeof(void *));77 Result.extractValue(Data, &Offset, {0, 0, dwarf::DwarfFormat::DWARF32});78 return Result;79}80 81TEST(DWARFFormValue, SignedConstantForms) {82 // Check that we correctly sign extend fixed size forms.83 auto Sign1 = createDataXFormValue<uint8_t>(DW_FORM_data1, -123);84 auto Sign2 = createDataXFormValue<uint16_t>(DW_FORM_data2, -12345);85 auto Sign4 = createDataXFormValue<uint32_t>(DW_FORM_data4, -123456789);86 auto Sign8 = createDataXFormValue<uint64_t>(DW_FORM_data8, -1);87 EXPECT_EQ(*Sign1.getAsSignedConstant(), -123);88 EXPECT_EQ(*Sign2.getAsSignedConstant(), -12345);89 EXPECT_EQ(*Sign4.getAsSignedConstant(), -123456789);90 EXPECT_EQ(*Sign8.getAsSignedConstant(), -1);91 92 // Check that we can handle big positive values, but that we return93 // an error just over the limit.94 auto UMax = createULEBFormValue(LLONG_MAX);95 auto TooBig = createULEBFormValue(uint64_t(LLONG_MAX) + 1);96 EXPECT_EQ(*UMax.getAsSignedConstant(), LLONG_MAX);97 EXPECT_EQ(TooBig.getAsSignedConstant().has_value(), false);98 99 // Sanity check some other forms.100 auto Data1 = createDataXFormValue<uint8_t>(DW_FORM_data1, 120);101 auto Data2 = createDataXFormValue<uint16_t>(DW_FORM_data2, 32000);102 auto Data4 = createDataXFormValue<uint32_t>(DW_FORM_data4, 2000000000);103 auto Data8 = createDataXFormValue<uint64_t>(DW_FORM_data8, 0x1234567812345678LL);104 auto LEBMin = createSLEBFormValue(LLONG_MIN);105 auto LEBMax = createSLEBFormValue(LLONG_MAX);106 auto LEB1 = createSLEBFormValue(-42);107 auto LEB2 = createSLEBFormValue(42);108 EXPECT_EQ(*Data1.getAsSignedConstant(), 120);109 EXPECT_EQ(*Data2.getAsSignedConstant(), 32000);110 EXPECT_EQ(*Data4.getAsSignedConstant(), 2000000000);111 EXPECT_EQ(*Data8.getAsSignedConstant(), 0x1234567812345678LL);112 EXPECT_EQ(*LEBMin.getAsSignedConstant(), LLONG_MIN);113 EXPECT_EQ(*LEBMax.getAsSignedConstant(), LLONG_MAX);114 EXPECT_EQ(*LEB1.getAsSignedConstant(), -42);115 EXPECT_EQ(*LEB2.getAsSignedConstant(), 42);116 117 // Data16 is a little tricky.118 char Cksum[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};119 DWARFFormValue Data16(DW_FORM_data16);120 DWARFDataExtractor DE16(StringRef(Cksum, 16), sys::IsLittleEndianHost,121 sizeof(void *));122 uint64_t Offset = 0;123 Data16.extractValue(DE16, &Offset, {0, 0, dwarf::DwarfFormat::DWARF32});124 SmallString<32> Str;125 raw_svector_ostream Res(Str);126 Data16.dump(Res, DIDumpOptions());127 EXPECT_EQ(memcmp(Str.data(), "000102030405060708090a0b0c0d0e0f", 32), 0);128}129 130using ParamType = std::tuple<Form, uint16_t, uint8_t, DwarfFormat,131 ArrayRef<uint8_t>, uint64_t, bool>;132 133struct FormSkipValueFixtureBase : public testing::TestWithParam<ParamType> {134 void SetUp() override {135 std::tie(Fm, Version, AddrSize, Dwarf, InitialData, ExpectedSkipped,136 ExpectedResult) = GetParam();137 }138 139 void doSkipValueTest() {140 SCOPED_TRACE("Inputs: Form = " + std::to_string(Fm) +141 ", Version = " + std::to_string(Version) +142 ", AddrSize = " + std::to_string(uint32_t(AddrSize)) +143 ", DwarfFormat = " + std::to_string(Dwarf));144 std::vector<uint8_t> Buf(InitialData.data(),145 InitialData.data() + InitialData.size());146 // The data extractor only adjusts the offset to the end of the buffer when147 // attempting to read past the end, so the buffer must be bigger than the148 // expected amount to be skipped to identify cases where more data than149 // expected is skipped.150 Buf.resize(ExpectedSkipped + 1);151 DWARFDataExtractor Data(Buf, sys::IsLittleEndianHost, AddrSize);152 uint64_t Offset = 0;153 EXPECT_EQ(DWARFFormValue::skipValue(Fm, Data, &Offset,154 {Version, AddrSize, Dwarf}),155 ExpectedResult);156 EXPECT_EQ(Offset, ExpectedSkipped);157 }158 159 Form Fm;160 uint16_t Version;161 uint8_t AddrSize;162 DwarfFormat Dwarf;163 ArrayRef<uint8_t> InitialData;164 uint64_t ExpectedSkipped;165 bool ExpectedResult;166};167 168template <typename T> static ArrayRef<uint8_t> toBytes(const T &Input) {169 return ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&Input),170 sizeof(Input));171}172 173const uint8_t LEBData[] = {0x80, 0x1};174ArrayRef<uint8_t> SampleLEB(LEBData, sizeof(LEBData));175const uint8_t SampleLength8 = 0x80;176const uint16_t SampleLength16 = 0x80;177const uint32_t SampleLength = 0x80;178ArrayRef<uint8_t> SampleU8 = toBytes(SampleLength8);179ArrayRef<uint8_t> SampleU16 = toBytes(SampleLength16);180ArrayRef<uint8_t> SampleU32 = toBytes(SampleLength);181const uint8_t StringData[] = "abcdef";182ArrayRef<uint8_t> SampleString(StringData, sizeof(StringData));183const uint8_t IndirectData8[] = {DW_FORM_data8};184const uint8_t IndirectData16[] = {DW_FORM_data16};185const uint8_t IndirectAddr[] = {DW_FORM_addr};186const uint8_t IndirectIndirectData1[] = {DW_FORM_indirect, DW_FORM_data1};187const uint8_t IndirectIndirectEnd[] = {DW_FORM_indirect};188 189// Gtest's paramterised tests only allow a maximum of 50 cases, so split the190// test into multiple identical parts to share the cases.191struct FormSkipValueFixture1 : FormSkipValueFixtureBase {};192struct FormSkipValueFixture2 : FormSkipValueFixtureBase {};193TEST_P(FormSkipValueFixture1, skipValuePart1) { doSkipValueTest(); }194TEST_P(FormSkipValueFixture2, skipValuePart2) { doSkipValueTest(); }195 196INSTANTIATE_TEST_SUITE_P(197 SkipValueTestParams1, FormSkipValueFixture1,198 testing::Values(199 // Form, Version, AddrSize, DwarfFormat, InitialData, ExpectedSize,200 // ExpectedResult.201 ParamType(DW_FORM_exprloc, 0, 0, DWARF32, SampleLEB,202 SampleLength + SampleLEB.size(), true),203 ParamType(DW_FORM_block, 0, 0, DWARF32, SampleLEB,204 SampleLength + SampleLEB.size(), true),205 ParamType(DW_FORM_block1, 0, 0, DWARF32, SampleU8, SampleLength8 + 1,206 true),207 ParamType(DW_FORM_block2, 0, 0, DWARF32, SampleU16, SampleLength16 + 2,208 true),209 ParamType(DW_FORM_block4, 0, 0, DWARF32, SampleU32, SampleLength + 4,210 true),211 ParamType(DW_FORM_string, 0, 0, DWARF32, SampleString,212 SampleString.size(), true),213 ParamType(DW_FORM_addr, 0, 42, DWARF32, SampleU32, 0, false),214 ParamType(DW_FORM_addr, 4, 0, DWARF32, SampleU32, 0, false),215 ParamType(DW_FORM_addr, 4, 42, DWARF32, SampleU32, 42, true),216 ParamType(DW_FORM_ref_addr, 0, 1, DWARF32, SampleU32, 0, false),217 ParamType(DW_FORM_ref_addr, 1, 0, DWARF32, SampleU32, 0, false),218 ParamType(DW_FORM_ref_addr, 1, 1, DWARF32, SampleU32, 4, true),219 ParamType(DW_FORM_ref_addr, 1, 1, DWARF64, SampleU32, 8, true),220 ParamType(DW_FORM_ref_addr, 2, 42, DWARF32, SampleU32, 42, true),221 ParamType(DW_FORM_ref_addr, 2, 42, DWARF64, SampleU32, 42, true),222 ParamType(DW_FORM_ref_addr, 3, 3, DWARF32, SampleU32, 4, true),223 ParamType(DW_FORM_ref_addr, 3, 3, DWARF64, SampleU32, 8, true),224 ParamType(DW_FORM_flag_present, 4, 4, DWARF32, SampleU32, 0, true),225 ParamType(DW_FORM_data1, 0, 0, DWARF32, SampleU32, 1, true),226 ParamType(DW_FORM_data2, 0, 0, DWARF32, SampleU32, 2, true),227 ParamType(DW_FORM_data4, 0, 0, DWARF32, SampleU32, 4, true),228 ParamType(DW_FORM_data8, 0, 0, DWARF32, SampleU32, 8, true),229 ParamType(DW_FORM_data16, 0, 0, DWARF32, SampleU32, 16, true),230 ParamType(DW_FORM_flag, 0, 0, DWARF32, SampleU32, 1, true),231 ParamType(DW_FORM_ref1, 0, 0, DWARF32, SampleU32, 1, true),232 ParamType(DW_FORM_ref2, 0, 0, DWARF32, SampleU32, 2, true),233 ParamType(DW_FORM_ref4, 0, 0, DWARF32, SampleU32, 4, true),234 ParamType(DW_FORM_ref8, 0, 0, DWARF32, SampleU32, 8, true),235 ParamType(DW_FORM_ref_sig8, 0, 0, DWARF32, SampleU32, 8, true),236 ParamType(DW_FORM_ref_sup4, 0, 0, DWARF32, SampleU32, 4, true),237 ParamType(DW_FORM_ref_sup8, 0, 0, DWARF32, SampleU32, 8, true),238 ParamType(DW_FORM_strx1, 0, 0, DWARF32, SampleU32, 1, true),239 ParamType(DW_FORM_strx2, 0, 0, DWARF32, SampleU32, 2, true),240 ParamType(DW_FORM_strx3, 0, 0, DWARF32, SampleU32, 3, true),241 ParamType(DW_FORM_strx4, 0, 0, DWARF32, SampleU32, 4, true),242 ParamType(DW_FORM_addrx1, 0, 0, DWARF32, SampleU32, 1, true),243 ParamType(DW_FORM_addrx2, 0, 0, DWARF32, SampleU32, 2, true),244 ParamType(DW_FORM_addrx3, 0, 0, DWARF32, SampleU32, 3, true),245 ParamType(DW_FORM_addrx4, 0, 0, DWARF32, SampleU32, 4, true),246 ParamType(DW_FORM_sec_offset, 0, 1, DWARF32, SampleU32, 0, false),247 ParamType(DW_FORM_sec_offset, 1, 0, DWARF32, SampleU32, 0, false),248 ParamType(DW_FORM_sec_offset, 1, 1, DWARF32, SampleU32, 4, true),249 ParamType(DW_FORM_sec_offset, 1, 1, DWARF64, SampleU32, 8, true),250 ParamType(DW_FORM_strp, 0, 1, DWARF32, SampleU32, 0, false),251 ParamType(DW_FORM_strp, 1, 0, DWARF32, SampleU32, 0, false),252 ParamType(DW_FORM_strp, 1, 1, DWARF32, SampleU32, 4, true),253 ParamType(DW_FORM_strp, 1, 1, DWARF64, SampleU32, 8, true),254 ParamType(DW_FORM_strp_sup, 0, 1, DWARF32, SampleU32, 0, false),255 ParamType(DW_FORM_strp_sup, 1, 0, DWARF32, SampleU32, 0, false),256 ParamType(DW_FORM_strp_sup, 1, 1, DWARF32, SampleU32, 4, true),257 ParamType(DW_FORM_strp_sup, 1, 1, DWARF64, SampleU32, 8, true)));258 259INSTANTIATE_TEST_SUITE_P(260 SkipValueTestParams2, FormSkipValueFixture2,261 testing::Values(262 ParamType(DW_FORM_line_strp, 0, 1, DWARF32, SampleU32, 0, false),263 ParamType(DW_FORM_line_strp, 1, 0, DWARF32, SampleU32, 0, false),264 ParamType(DW_FORM_line_strp, 1, 1, DWARF32, SampleU32, 4, true),265 ParamType(DW_FORM_line_strp, 1, 1, DWARF64, SampleU32, 8, true),266 ParamType(DW_FORM_GNU_ref_alt, 0, 1, DWARF32, SampleU32, 0, false),267 ParamType(DW_FORM_GNU_ref_alt, 1, 0, DWARF32, SampleU32, 0, false),268 ParamType(DW_FORM_GNU_ref_alt, 1, 1, DWARF32, SampleU32, 4, true),269 ParamType(DW_FORM_GNU_ref_alt, 1, 1, DWARF64, SampleU32, 8, true),270 ParamType(DW_FORM_GNU_strp_alt, 0, 1, DWARF32, SampleU32, 0, false),271 ParamType(DW_FORM_GNU_strp_alt, 1, 0, DWARF32, SampleU32, 0, false),272 ParamType(DW_FORM_GNU_strp_alt, 1, 1, DWARF32, SampleU32, 4, true),273 ParamType(DW_FORM_GNU_strp_alt, 1, 1, DWARF64, SampleU32, 8, true),274 ParamType(DW_FORM_sdata, 0, 0, DWARF32, SampleLEB, SampleLEB.size(),275 true),276 ParamType(DW_FORM_udata, 0, 0, DWARF32, SampleLEB, SampleLEB.size(),277 true),278 ParamType(DW_FORM_ref_udata, 0, 0, DWARF32, SampleLEB, SampleLEB.size(),279 true),280 ParamType(DW_FORM_strx, 0, 0, DWARF32, SampleLEB, SampleLEB.size(),281 true),282 ParamType(DW_FORM_addrx, 0, 0, DWARF32, SampleLEB, SampleLEB.size(),283 true),284 ParamType(DW_FORM_loclistx, 0, 0, DWARF32, SampleLEB, SampleLEB.size(),285 true),286 ParamType(DW_FORM_rnglistx, 0, 0, DWARF32, SampleLEB, SampleLEB.size(),287 true),288 ParamType(DW_FORM_GNU_addr_index, 0, 0, DWARF32, SampleLEB,289 SampleLEB.size(), true),290 ParamType(DW_FORM_GNU_str_index, 0, 0, DWARF32, SampleLEB,291 SampleLEB.size(), true),292 ParamType(DW_FORM_indirect, 0, 0, DWARF32,293 ArrayRef<uint8_t>(IndirectData8, sizeof(IndirectData8)), 9,294 true),295 ParamType(DW_FORM_indirect, 0, 0, DWARF32,296 ArrayRef<uint8_t>(IndirectData16, sizeof(IndirectData16)), 17,297 true),298 ParamType(DW_FORM_indirect, 4, 0, DWARF32,299 ArrayRef<uint8_t>(IndirectAddr, sizeof(IndirectAddr)), 1,300 false),301 ParamType(DW_FORM_indirect, 4, 4, DWARF32,302 ArrayRef<uint8_t>(IndirectAddr, sizeof(IndirectAddr)), 5,303 true),304 ParamType(DW_FORM_indirect, 4, 4, DWARF32,305 ArrayRef<uint8_t>(IndirectIndirectData1,306 sizeof(IndirectIndirectData1)),307 3, true),308 ParamType(DW_FORM_indirect, 4, 4, DWARF32,309 ArrayRef<uint8_t>(IndirectIndirectEnd,310 sizeof(IndirectIndirectEnd)),311 2, false),312 ParamType(/*Unknown=*/Form(0xff), 4, 4, DWARF32, SampleU32, 0, false)));313 314using ErrorParams = std::tuple<Form, std::vector<uint8_t>>;315struct ExtractValueErrorFixture : public testing::TestWithParam<ErrorParams> {316 void SetUp() override { std::tie(Fm, InitialData) = GetParam(); }317 318 Form Fm;319 ArrayRef<uint8_t> InitialData;320};321 322TEST_P(ExtractValueErrorFixture, Test) {323 SCOPED_TRACE(formatv("Fm = {0}, InitialData = {1}", Fm,324 make_range(InitialData.begin(), InitialData.end()))325 .str());326 327 DWARFDataExtractor Data(InitialData, sys::IsLittleEndianHost, 4);328 DWARFFormValue Form(Fm);329 uint64_t Offset = 0;330 EXPECT_FALSE(Form.extractValue(Data, &Offset, {0, 0, DWARF32}));331}332 333INSTANTIATE_TEST_SUITE_P(334 ExtractValueErrorParams, ExtractValueErrorFixture,335 testing::Values(336 ErrorParams{DW_FORM_ref_addr, {}}, ErrorParams{DW_FORM_block, {}},337 ErrorParams{DW_FORM_block, {1}}, ErrorParams{DW_FORM_block, {2, 0}},338 ErrorParams{DW_FORM_block1, {}}, ErrorParams{DW_FORM_block2, {}},339 ErrorParams{DW_FORM_block4, {}}, ErrorParams{DW_FORM_data1, {}},340 ErrorParams{DW_FORM_data2, {}}, ErrorParams{DW_FORM_strx3, {}},341 ErrorParams{DW_FORM_data4, {}}, ErrorParams{DW_FORM_data8, {}},342 ErrorParams{DW_FORM_data16, {}}, ErrorParams{DW_FORM_sdata, {}},343 ErrorParams{DW_FORM_udata, {}}, ErrorParams{DW_FORM_string, {}},344 ErrorParams{DW_FORM_indirect, {}},345 ErrorParams{DW_FORM_indirect, {DW_FORM_data1}},346 ErrorParams{DW_FORM_strp_sup, {}}, ErrorParams{DW_FORM_ref_sig8, {}}));347 348using DumpValueParams =349 std::tuple<Form, ArrayRef<uint8_t>, DwarfFormat, StringRef>;350struct DumpValueFixture : public testing::TestWithParam<DumpValueParams> {351 void SetUp() override {352 std::tie(Fm, InitialData, Format, ExpectedResult) = GetParam();353 }354 355 Form Fm;356 ArrayRef<uint8_t> InitialData;357 DwarfFormat Format;358 StringRef ExpectedResult;359};360 361TEST_P(DumpValueFixture, Test) {362 SCOPED_TRACE(formatv("Fm = {0}, InitialData = [{1}], Format = {2}", Fm,363 toHex(InitialData),364 Format == DWARF64 ? "DWARF64" : "DWARF32"));365 DWARFDataExtractor Data(InitialData, sys::IsLittleEndianHost, 8);366 DWARFFormValue Form(Fm);367 uint64_t Offset = 0;368 Form.extractValue(Data, &Offset, {0, 0, Format});369 370 std::string Output;371 raw_string_ostream OS(Output);372 373 DIDumpOptions Opts;374 Opts.Verbose = true;375 Opts.ShowAddresses = true;376 377 Form.dump(OS, Opts);378 379 EXPECT_EQ(Output, ExpectedResult);380}381 382const uint32_t DumpTestSample32Val = 0x112233;383ArrayRef<uint8_t> DumpTestSample32 = toBytes(DumpTestSample32Val);384const uint64_t DumpTestSample64Val = 0x11223344556677;385ArrayRef<uint8_t> DumpTestSample64 = toBytes(DumpTestSample64Val);386 387INSTANTIATE_TEST_SUITE_P(388 DumpValueParams, DumpValueFixture,389 testing::Values(DumpValueParams{DW_FORM_strp, DumpTestSample32, DWARF32,390 " .debug_str[0x00112233] = "},391 DumpValueParams{DW_FORM_strp, DumpTestSample64, DWARF64,392 " .debug_str[0x0011223344556677] = "},393 DumpValueParams{DW_FORM_line_strp, DumpTestSample32,394 DWARF32, " .debug_line_str[0x00112233] = "},395 DumpValueParams{DW_FORM_line_strp, DumpTestSample64,396 DWARF64,397 " .debug_line_str[0x0011223344556677] = "},398 DumpValueParams{DW_FORM_sec_offset, DumpTestSample32,399 DWARF32, "0x00112233"},400 DumpValueParams{DW_FORM_sec_offset, DumpTestSample64,401 DWARF64, "0x0011223344556677"}));402 403} // end anonymous namespace404