diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1980,8 +1980,14 @@ Asm->OutStreamer->AddComment("Loc expr size"); if (getDwarfVersion() >= 5) Asm->EmitULEB128(DebugLocs.getBytes(Entry).size()); - else + else if (DebugLocs.getBytes(Entry).size() <= std::numeric_limits::max()) Asm->emitInt16(DebugLocs.getBytes(Entry).size()); + else { + // The entry is too big to fit into 16 bit, drop it as there is nothing we + // can do. + Asm->emitInt16(0); + return; + } // Emit the entry. APByteStreamer Streamer(*Asm); emitDebugLocEntry(Streamer, Entry); diff --git a/llvm/test/MC/X86/dwarf-size-field-overflow.test b/llvm/test/MC/X86/dwarf-size-field-overflow.test new file mode 100644 --- /dev/null +++ b/llvm/test/MC/X86/dwarf-size-field-overflow.test @@ -0,0 +1,49 @@ +# This test generates too many debug location entries to fit into 65KB required +# by DWARF < 5. Check that the location is set to 0 instead of crashing. +# +# RUN: %python %s 4000 | llc -filetype=obj -o - +# RUN: llvm-dwarfdump %t | FileCheck %s +# +# CHECK: 0x0000004d: DW_TAG_formal_parameter +# CHECK-NEXT: DW_AT_location (0x00000000 +# CHECK-NEXT: [0x0000000000000000, 0x0000000000000008): ) +# CHECK-NEXT: DW_AT_name ("self") + +import sys + +SKELETON = """define void @test() !dbg !24 {{ + {} + call void @foo(), !dbg !34 + ret void, !dbg !34 +}} + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #0 + +declare void @foo() + +attributes #0 = {{ nounwind readnone speculatable }} + +!llvm.dbg.cu = !{{!0}} +!llvm.module.flags = !{{!22}} + +!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 4, emissionKind: FullDebug) +!1 = !DIFile(filename: "asdf.c", directory: "bar") +!2 = !{{}} +!6 = !DIModule(scope: null, name: "dag", includePath: "/") +!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !6, file: !1, line: 36, size: 2384384, elements: !2, runtimeLang: DW_LANG_C) +!22 = !{{i32 2, !"Debug Info Version", i32 3}} +!24 = distinct !DISubprogram(name: "main", linkageName: "main", scope: !6, file: !1, line: 1, type: !25, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) +!25 = !DISubroutineType(types: !2) +!30 = !DILocalVariable(name: "self", arg: 1, scope: !24, file: !1, line: 12, type: !8, flags: DIFlagArtificial) +!34 = !DILocation(line: 12, column: 8, scope: !24) +""" + +CALL = "call void @llvm.dbg.value(metadata i64 {0}, metadata !30, metadata !DIExpression(DW_OP_LLVM_fragment, {0}, 64)), !dbg !34" + +if __name__ == '__main__': + N = int(sys.argv[1]) + calls = [] + for i in range(0, N): + calls.append(CALL.format(i * 10**12)) + print(SKELETON.format('\n'.join(calls)))