diff --git a/llvm/docs/Extensions.rst b/llvm/docs/Extensions.rst --- a/llvm/docs/Extensions.rst +++ b/llvm/docs/Extensions.rst @@ -401,11 +401,22 @@ metadata. This information can be used to map binary profiles (like perf profiles) directly to machine basic blocks. This section is emitted with ``-basic-block-sections=labels`` and will contain -a BB address map table for every function which may be constructed as follows: +a BB address map table for every function. + +This feature provides backward compatibility to allow reading older versions of +the BB address map generated by older compilers. +The section name will include a version suffix (`.v#{version-number}`) which +specifies the version to use. The follwoing versioning schemes are currently +supported. + +Version 1 (newest): basic block address offsets are computed relative to end of +previous blocks. + +Example: .. code-block:: gas - .section ".llvm_bb_addr_map","",@llvm_bb_addr_map + .section ".llvm_bb_addr_map.v1","",@llvm_bb_addr_map .quad .Lfunc_begin0 # address of the function .byte 2 # number of basic blocks # BB record for BB_0 @@ -413,11 +424,28 @@ .uleb128 .LBB_END0_0-.Lfunc_begin0 # BB_0 size .byte x # BB_0 metadata # BB record for BB_1 - .uleb128 .LBB0_1-.Lfunc_begin0 # BB_1 offset relative to function entry - .uleb128 .LBB_END0_1-.Lfunc_begin0 # BB_1 size + .uleb128 .LBB0_1-.LBB_END0_0 # BB_1 offset relative to the end of last block (BB_0). + .uleb128 .LBB_END0_1-.LBB0_1 # BB_1 size .byte y # BB_1 metadata -This creates a BB address map table for a function with two basic blocks. +Version 0: basic block address offsets are computed relative to the function +address. + +Example: + +.. code-block:: gas + + .section ".llvm_bb_addr_map.v0","",@llvm_bb_addr_map + .quad .Lfunc_begin0 # address of the function + .byte 2 # number of basic blocks + # BB record for BB_0 + .uleb128 .Lfunc_beign0-.Lfunc_begin0 # BB_0 offset relative to function entry (always zero) + .uleb128 .LBB_END0_0-.Lfunc_begin0 # BB_0 size + .byte x # BB_0 metadata + # BB record for BB_1 + .uleb128 .LBB0_1-.Lfunc_begin0 # BB_1 offset relative to function entry + .uleb128 .LBB_END0_1-.LBB0_1 # BB_1 size + .byte y # BB_1 metadata CodeView-Dependent ------------------ diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1312,16 +1312,19 @@ OutStreamer->emitSymbolValue(FunctionSymbol, getPointerSize()); // Emit the total number of basic blocks in this function. OutStreamer->emitULEB128IntValue(MF.size()); + const MCSymbol *PrevMBBEndSymbol = FunctionSymbol; // Emit BB Information for each basic block in the funciton. for (const MachineBasicBlock &MBB : MF) { const MCSymbol *MBBSymbol = MBB.isEntryBlock() ? FunctionSymbol : MBB.getSymbol(); - // Emit the basic block offset. - emitLabelDifferenceAsULEB128(MBBSymbol, FunctionSymbol); + // Emit the basic block offset relative to the end of the previous block. + // This is zero unless the block is padded due to alignment. + emitLabelDifferenceAsULEB128(MBBSymbol, PrevMBBEndSymbol); // Emit the basic block size. When BBs have alignments, their size cannot // always be computed from their offsets. emitLabelDifferenceAsULEB128(MBB.getEndSymbol(), MBBSymbol); OutStreamer->emitULEB128IntValue(getBBAddrMapMetadata(MBB)); + PrevMBBEndSymbol = MBB.getEndSymbol(); } OutStreamer->PopSection(); } diff --git a/llvm/lib/CodeGen/BasicBlockSections.cpp b/llvm/lib/CodeGen/BasicBlockSections.cpp --- a/llvm/lib/CodeGen/BasicBlockSections.cpp +++ b/llvm/lib/CodeGen/BasicBlockSections.cpp @@ -60,7 +60,7 @@ // Basic Block Labels // ================== // -// With -fbasic-block-sections=labels, we emit the offsets of BB addresses of +// With -fbasic-block-sections=labels, we encode the offsets of BB addresses of // every function into the .llvm_bb_addr_map section. Along with the function // symbols, this allows for mapping of virtual addresses in PMU profiles back to // the corresponding basic blocks. This logic is implemented in AsmPrinter. This diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -1111,7 +1111,7 @@ // Use the text section's begin symbol and unique ID to create a separate // .llvm_bb_addr_map section associated with every unique text section. - return Ctx->getELFSection(".llvm_bb_addr_map", ELF::SHT_LLVM_BB_ADDR_MAP, + return Ctx->getELFSection(".llvm_bb_addr_map.v1", ELF::SHT_LLVM_BB_ADDR_MAP, Flags, 0, GroupName, true, ElfSec.getUniqueID(), cast(TextSec.getBeginSymbol())); } diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -631,6 +631,21 @@ template Expected> ELFFile::decodeBBAddrMap(const Elf_Shdr &Sec) const { + Expected SectionNameOrErr = getSectionName(Sec); + if (!SectionNameOrErr) + return SectionNameOrErr.takeError(); + StringRef VersionStr = SectionNameOrErr->rsplit('.').second; + // Without a version suffix we assume version=0. + // TODO: Report error in this case when version 0 becomes obsolete. + int Version = 0; + if (!VersionStr.empty() && VersionStr.startswith("v")) { + if (VersionStr.substr(1).getAsInteger(10, Version)) + return createError("Unable to parse bb-address-map version suffix: " + + VersionStr); + if (Version > 1) + return createError("Unsupported bb-address-map version: " + + Twine(Version)); + } Expected> ContentsOrErr = getSectionContents(Sec); if (!ContentsOrErr) return ContentsOrErr.takeError(); @@ -664,11 +679,17 @@ uintX_t Address = static_cast(Data.getAddress(Cur)); uint32_t NumBlocks = ReadULEB128AsUInt32(); std::vector BBEntries; + uint32_t PrevBBEndOffset = 0; for (uint32_t BlockID = 0; !ULEBSizeErr && Cur && (BlockID < NumBlocks); ++BlockID) { uint32_t Offset = ReadULEB128AsUInt32(); uint32_t Size = ReadULEB128AsUInt32(); uint32_t Metadata = ReadULEB128AsUInt32(); + if (Version >= 1) { + // Offset is calculated relative to the end of the previous BB. + Offset += PrevBBEndOffset; + PrevBBEndOffset = Offset + Size; + } BBEntries.push_back({Offset, Size, Metadata}); } FunctionEntries.push_back({Address, BBEntries}); diff --git a/llvm/test/CodeGen/X86/basic-block-sections-labels-empty-function.ll b/llvm/test/CodeGen/X86/basic-block-sections-labels-empty-function.ll --- a/llvm/test/CodeGen/X86/basic-block-sections-labels-empty-function.ll +++ b/llvm/test/CodeGen/X86/basic-block-sections-labels-empty-function.ll @@ -17,5 +17,5 @@ ; CHECK: func: ; CHECK: .Lfunc_begin1: -; CHECK: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text{{$}} +; CHECK: .section .llvm_bb_addr_map.v1,"o",@llvm_bb_addr_map,.text{{$}} ; CHECK: .quad .Lfunc_begin1 diff --git a/llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll b/llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll --- a/llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll +++ b/llvm/test/CodeGen/X86/basic-block-sections-labels-functions-sections.ll @@ -9,7 +9,7 @@ ; CHECK: .section .text._Z3barv,"ax",@progbits ; CHECK-LABEL: _Z3barv: ; CHECK-NEXT: [[BAR_BEGIN:.Lfunc_begin[0-9]+]]: -; CHECK: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text._Z3barv{{$}} +; CHECK: .section .llvm_bb_addr_map.v1,"o",@llvm_bb_addr_map,.text._Z3barv{{$}} ; CHECK-NEXT: .quad [[BAR_BEGIN]] @@ -20,7 +20,7 @@ ; CHECK: .section .text._Z3foov,"ax",@progbits ; CHECK-LABEL: _Z3foov: ; CHECK-NEXT: [[FOO_BEGIN:.Lfunc_begin[0-9]+]]: -; CHECK: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text._Z3foov{{$}} +; CHECK: .section .llvm_bb_addr_map.v1,"o",@llvm_bb_addr_map,.text._Z3foov{{$}} ; CHECK-NEXT: .quad [[FOO_BEGIN]] @@ -31,5 +31,5 @@ ; CHECK: .section .text._Z4fooTIiET_v,"axG",@progbits,_Z4fooTIiET_v,comdat ; CHECK-LABEL: _Z4fooTIiET_v: ; CHECK-NEXT: [[FOOCOMDAT_BEGIN:.Lfunc_begin[0-9]+]]: -; CHECK: .section .llvm_bb_addr_map,"Go",@llvm_bb_addr_map,_Z4fooTIiET_v,comdat,.text._Z4fooTIiET_v{{$}} +; CHECK: .section .llvm_bb_addr_map.v1,"Go",@llvm_bb_addr_map,_Z4fooTIiET_v,comdat,.text._Z4fooTIiET_v{{$}} ; CHECK-NEXT: .quad [[FOOCOMDAT_BEGIN]] diff --git a/llvm/test/CodeGen/X86/basic-block-sections-labels.ll b/llvm/test/CodeGen/X86/basic-block-sections-labels.ll --- a/llvm/test/CodeGen/X86/basic-block-sections-labels.ll +++ b/llvm/test/CodeGen/X86/basic-block-sections-labels.ll @@ -43,20 +43,20 @@ ; CHECK-LABEL: .LBB_END0_3: ; CHECK-LABEL: .Lfunc_end0: -; UNIQ: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text._Z3bazb{{$}} +; UNIQ: .section .llvm_bb_addr_map.v1,"o",@llvm_bb_addr_map,.text._Z3bazb{{$}} ;; Verify that with -unique-section-names=false, the unique id of the text section gets assigned to the llvm_bb_addr_map section. -; NOUNIQ: .section .llvm_bb_addr_map,"o",@llvm_bb_addr_map,.text,unique,1 +; NOUNIQ: .section .llvm_bb_addr_map.v1,"o",@llvm_bb_addr_map,.text,unique,1 ; CHECK-NEXT: .quad .Lfunc_begin0 ; CHECK-NEXT: .byte 4 ; CHECK-NEXT: .uleb128 .Lfunc_begin0-.Lfunc_begin0 ; CHECK-NEXT: .uleb128 .LBB_END0_0-.Lfunc_begin0 ; CHECK-NEXT: .byte 8 -; CHECK-NEXT: .uleb128 .LBB0_1-.Lfunc_begin0 +; CHECK-NEXT: .uleb128 .LBB0_1-.LBB_END0_0 ; CHECK-NEXT: .uleb128 .LBB_END0_1-.LBB0_1 ; CHECK-NEXT: .byte 8 -; CHECK-NEXT: .uleb128 .LBB0_2-.Lfunc_begin0 +; CHECK-NEXT: .uleb128 .LBB0_2-.LBB_END0_1 ; CHECK-NEXT: .uleb128 .LBB_END0_2-.LBB0_2 ; CHECK-NEXT: .byte 1 -; CHECK-NEXT: .uleb128 .LBB0_3-.Lfunc_begin0 +; CHECK-NEXT: .uleb128 .LBB0_3-.LBB_END0_2 ; CHECK-NEXT: .uleb128 .LBB_END0_3-.LBB0_3 ; CHECK-NEXT: .byte 5 diff --git a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test --- a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test +++ b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test @@ -1,75 +1,87 @@ ## This test checks how we handle the --bb-addr-map option. -# Check 64-bit: +## Check 64-bit (version #0 encoding): # RUN: yaml2obj %s -DBITS=64 -DADDR=0x999999999 -o %t1.x64.o -# RUN: llvm-readobj %t1.x64.o --bb-addr-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.x64.o --check-prefix=LLVM - +# RUN: llvm-readobj %t1.x64.o --bb-addr-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.x64.o --check-prefixes=CHECK,V0 # RUN: llvm-readelf %t1.x64.o --bb-addr-map | FileCheck %s --check-prefix=GNU +## Check 64-bit (version #1 encoding): +# RUN: yaml2obj %s -DBITS=64 -DVERSION=1 -DADDR=0x999999999 -o %t1.v1.x64.o +# RUN: llvm-readobj %t1.v1.x64.o --bb-addr-map 2>&1 | FileCheck %s -DADDR=0x999999999 -DFILE=%t1.v1.x64.o --check-prefixes=CHECK,V1 + ## Check 32-bit: # RUN: yaml2obj %s -DBITS=32 -o %t1.x32.o -# RUN: llvm-readobj %t1.x32.o --bb-addr-map 2>&1 | FileCheck -DADDR=0x11111 %s -DFILE=%t1.x32.o --check-prefix=LLVM +# RUN: llvm-readobj %t1.x32.o --bb-addr-map 2>&1 | FileCheck -DADDR=0x11111 %s -DFILE=%t1.x32.o --check-prefixes=CHECK,V0 # RUN: llvm-readelf %t1.x32.o --bb-addr-map | FileCheck %s --check-prefix=GNU ## Check that a malformed section can be handled. # RUN: yaml2obj %s -DBITS=32 -DSIZE=4 -o %t2.o # RUN: llvm-readobj %t2.o --bb-addr-map 2>&1 | FileCheck %s -DOFFSET=0x00000004 -DFILE=%t2.o --check-prefix=TRUNCATED -# LLVM: BBAddrMap [ -# LLVM-NEXT: Function { -# LLVM-NEXT: At: [[ADDR]] -# LLVM-NEXT: warning: '[[FILE]]': could not identify function symbol for address ([[ADDR]]) in SHT_LLVM_BB_ADDR_MAP section with index 3 -# LLVM-NEXT: Name: -# LLVM-NEXT: BB entries [ -# LLVM-NEXT: { -# LLVM-NEXT: Offset: 0x0 -# LLVM-NEXT: Size: 0x1 -# LLVM-NEXT: HasReturn: No -# LLVM-NEXT: HasTailCall: Yes -# LLVM-NEXT: IsEHPad: No -# LLVM-NEXT: CanFallThrough: No -# LLVM-NEXT: } -# LLVM-NEXT: { -# LLVM-NEXT: Offset: 0x3 -# LLVM-NEXT: Size: 0x4 -# LLVM-NEXT: HasReturn: Yes -# LLVM-NEXT: HasTailCall: No -# LLVM-NEXT: IsEHPad: Yes -# LLVM-NEXT: CanFallThrough: No -# LLVM-NEXT: } -# LLVM-NEXT: ] -# LLVM-NEXT: } -# LLVM-NEXT: Function { -# LLVM-NEXT: At: 0x22222 -# LLVM-NEXT: Name: foo -# LLVM-NEXT: BB entries [ -# LLVM-NEXT: { -# LLVM-NEXT: Offset: 0x6 -# LLVM-NEXT: Size: 0x7 -# LLVM-NEXT: HasReturn: No -# LLVM-NEXT: HasTailCall: No -# LLVM-NEXT: IsEHPad: No -# LLVM-NEXT: CanFallThrough: Yes -# LLVM-NEXT: } -# LLVM-NEXT: ] -# LLVM-NEXT: } -# LLVM-NEXT: ] -# LLVM-NEXT: BBAddrMap [ -# LLVM-NEXT: Function { -# LLVM-NEXT: At: 0x33333 -# LLVM-NEXT: Name: bar -# LLVM-NEXT: BB entries [ -# LLVM-NEXT: { -# LLVM-NEXT: Offset: 0x9 -# LLVM-NEXT: Size: 0xA -# LLVM-NEXT: HasReturn: Yes -# LLVM-NEXT: HasTailCall: Yes -# LLVM-NEXT: IsEHPad: No -# LLVM-NEXT: CanFallThrough: Yes -# LLVM-NEXT: } -# LLVM-NEXT: ] -# LLVM-NEXT: } -# LLVM-NEXT: ] +# CHECK: BBAddrMap [ +# CHECK-NEXT: Function { +# CHECK-NEXT: At: [[ADDR]] +# CHECK-NEXT: warning: '[[FILE]]': could not identify function symbol for address ([[ADDR]]) in SHT_LLVM_BB_ADDR_MAP section with index 3 +# CHECK-NEXT: Name: +# CHECK-NEXT: BB entries [ +# CHECK-NEXT: { +# CHECK-NEXT: Offset: 0x0 +# CHECK-NEXT: Size: 0x1 +# CHECK-NEXT: HasReturn: No +# CHECK-NEXT: HasTailCall: Yes +# CHECK-NEXT: IsEHPad: No +# CHECK-NEXT: CanFallThrough: No +# CHECK-NEXT: } +# CHECK-NEXT: { +# CHECK-NEXT: Offset: 0x3 +# CHECK-NEXT: Size: 0x4 +# CHECK-NEXT: HasReturn: Yes +# CHECK-NEXT: HasTailCall: No +# CHECK-NEXT: IsEHPad: Yes +# CHECK-NEXT: CanFallThrough: No +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: Function { +# CHECK-NEXT: At: 0x22222 +# CHECK-NEXT: Name: foo +# CHECK-NEXT: BB entries [ +# CHECK-NEXT: { +# CHECK-NEXT: Offset: 0x6 +# CHECK-NEXT: Size: 0x7 +# CHECK-NEXT: HasReturn: No +# CHECK-NEXT: HasTailCall: No +# CHECK-NEXT: IsEHPad: No +# CHECK-NEXT: CanFallThrough: Yes +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: BBAddrMap [ +# CHECK-NEXT: Function { +# CHECK-NEXT: At: 0x33333 +# CHECK-NEXT: Name: bar +# CHECK-NEXT: BB entries [ +# CHECK-NEXT: { +# CHECK-NEXT: Offset: 0x9 +# CHECK-NEXT: Size: 0xA +# CHECK-NEXT: HasReturn: Yes +# CHECK-NEXT: HasTailCall: Yes +# CHECK-NEXT: IsEHPad: No +# CHECK-NEXT: CanFallThrough: Yes +# CHECK-NEXT: } +# CHECK-NEXT: { +# V0-NEXT: Offset: 0xC +# V1-NEXT: Offset: 0x1F +# CHECK-NEXT: Size: 0xD +# CHECK-NEXT: HasReturn: No +# CHECK-NEXT: HasTailCall: Yes +# CHECK-NEXT: IsEHPad: Yes +# CHECK-NEXT: CanFallThrough: Yes +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: ] # GNU: GNUStyle::printBBAddrMaps not implemented @@ -90,6 +102,14 @@ # TRUNCATED-NEXT: IsEHPad: No # TRUNCATED-NEXT: CanFallThrough: Yes # TRUNCATED-NEXT: } +# TRUNCATED-NEXT: { +# TRUNCATED-NEXT: Offset: 0xC +# TRUNCATED-NEXT: Size: 0xD +# TRUNCATED-NEXT: HasReturn: No +# TRUNCATED-NEXT: HasTailCall: Yes +# TRUNCATED-NEXT: IsEHPad: Yes +# TRUNCATED-NEXT: CanFallThrough: Yes +# TRUNCATED-NEXT: } # TRUNCATED-NEXT: ] # TRUNCATED-NEXT: } # TRUNCATED-NEXT: ] @@ -106,7 +126,7 @@ - Name: .text.bar Type: SHT_PROGBITS Flags: [SHF_ALLOC] - - Name: bb_addr_map_1 + - Name: .llvm_bb_addr_map Type: SHT_LLVM_BB_ADDR_MAP ShSize: [[SIZE=]] Link: .text @@ -127,7 +147,7 @@ - Name: dummy_section Type: SHT_PROGBITS Size: 16 - - Name: bb_addr_map_2 + - Name: .llvm_bb_addr_map.v[[VERSION=0]] Type: SHT_LLVM_BB_ADDR_MAP Link: .text.bar Entries: @@ -136,6 +156,9 @@ - AddressOffset: 0x9 Size: 0xa Metadata: 0xb + - AddressOffset: 0xc + Size: 0xd + Metadata: 0xe Symbols: - Name: foo Section: .text diff --git a/llvm/unittests/Object/ELFObjectFileTest.cpp b/llvm/unittests/Object/ELFObjectFileTest.cpp --- a/llvm/unittests/Object/ELFObjectFileTest.cpp +++ b/llvm/unittests/Object/ELFObjectFileTest.cpp @@ -505,14 +505,7 @@ Data: ELFDATA2LSB Type: ET_EXEC Sections: - - Name: .llvm_bb_addr_map - Type: SHT_LLVM_BB_ADDR_MAP - Entries: - - Address: 0x11111 - BBEntries: - - AddressOffset: 0x0 - Size: 0x1 - Metadata: 0x2 + - Type: SHT_LLVM_BB_ADDR_MAP )"); auto DoCheck = [&](StringRef YamlString, const char *ErrMsg) { @@ -529,9 +522,35 @@ FailedWithMessage(ErrMsg)); }; + // Check that we can detect invalid and unsupported versions. + SmallVector, 2> InvalidVersionYamlStrings(2, + CommonYamlString); + InvalidVersionYamlStrings[0] += R"( + Name: .llvm_bb_addr_map.vx +)"; + InvalidVersionYamlStrings[1] += R"( + Name: .llvm_bb_addr_map.v2 +)"; + + DoCheck(InvalidVersionYamlStrings[0], + "Unable to parse bb-address-map version suffix: vx"); + DoCheck(InvalidVersionYamlStrings[1], + "Unsupported bb-address-map version: 2"); + + SmallString<128> CommonValidYamlString(CommonYamlString); + CommonValidYamlString += R"( + Name: .llvm_bb_addr_map.v1 + Entries: + - Address: 0x11111 + BBEntries: + - AddressOffset: 0x0 + Size: 0x1 + Metadata: 0x2 +)"; + // Check that we can detect the malformed encoding when the section is // truncated. - SmallString<128> TruncatedYamlString(CommonYamlString); + SmallString<128> TruncatedYamlString(CommonValidYamlString); TruncatedYamlString += R"( ShSize: 0x8 )"; @@ -540,8 +559,8 @@ // Check that we can detect when the encoded BB entry fields exceed the UINT32 // limit. - SmallVector, 3> OverInt32LimitYamlStrings(3, - CommonYamlString); + SmallVector, 3> OverInt32LimitYamlStrings( + 3, CommonValidYamlString); OverInt32LimitYamlStrings[0] += R"( - AddressOffset: 0x100000000 Size: 0xFFFFFFFF @@ -595,7 +614,7 @@ // Check for proper error handling when the 'NumBlocks' field is overridden // with an out-of-range value. - SmallString<128> OverLimitNumBlocks(CommonYamlString); + SmallString<128> OverLimitNumBlocks(CommonValidYamlString); OverLimitNumBlocks += R"( NumBlocks: 0x100000000 )";