Index: llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -410,22 +410,30 @@ ReportError("DIE has invalid DW_AT_stmt_list encoding:"); break; case DW_AT_location: { - Optional> Expr = AttrValue.Value.getAsBlock(); - if (!Expr) { - ReportError("DIE has invalid DW_AT_location encoding:"); - break; + auto VerifyLocation = [&](const void *data, size_t len) { + DWARFUnit *U = Die.getDwarfUnit(); + DataExtractor Data(StringRef(reinterpret_cast(data), len), + DCtx.isLittleEndian(), 0); + DWARFExpression Expression(Data, U->getVersion(), + U->getAddressByteSize()); + bool Error = llvm::any_of(Expression, [](DWARFExpression::Operation &Op) { + return Op.isError(); + }); + if (Error) + ReportError("DIE contains invalid DWARF expression:"); + }; + if (Optional> Expr = AttrValue.Value.getAsBlock()) { + // Inlined location + VerifyLocation(Expr->data(), Expr->size()); + } else if (auto LocOffset = AttrValue.Value.getAsUnsignedConstant()) { + // Location list + if (auto DebugLoc = DCtx.getDebugLoc()) { + if (auto LocList = DebugLoc->getLocationListAtOffset(*LocOffset)) { + for (const auto &Entry : LocList->Entries) + VerifyLocation(Entry.Loc.data(), Entry.Loc.size()); + } + } } - - DWARFUnit *U = Die.getDwarfUnit(); - DataExtractor Data( - StringRef(reinterpret_cast(Expr->data()), Expr->size()), - DCtx.isLittleEndian(), 0); - DWARFExpression Expression(Data, U->getVersion(), U->getAddressByteSize()); - bool Error = llvm::any_of(Expression, [](DWARFExpression::Operation &Op) { - return Op.isError(); - }); - if (Error) - ReportError("DIE contains invalid DWARF expression:"); break; } Index: llvm/test/tools/llvm-dwarfdump/X86/debugloc.s =================================================================== --- llvm/test/tools/llvm-dwarfdump/X86/debugloc.s +++ llvm/test/tools/llvm-dwarfdump/X86/debugloc.s @@ -2,6 +2,10 @@ # RUN: | llvm-dwarfdump --debug-loc - \ # RUN: | FileCheck %s +# RUN: llvm-mc %s -filetype obj -triple x86_64-linux-elf -o - \ +# RUN: | llvm-dwarfdump --verify - \ +# RUN: | FileCheck %s --check-prefix VERIFY + # CHECK: .debug_loc contents: # CHECK: 0x00000000: @@ -12,6 +16,9 @@ # CHECK-NEXT: [0x0000000000000010, 0x0000000000000013): DW_OP_reg5 RDI # CHECK-NEXT: [0x0000000000000013, 0x0000000000000014): DW_OP_reg0 RAX +# VERIFY: Verifying .debug_info Unit Header Chain +# VERIFY-NOT: DIE has invalid DW_AT_location encoding + # Source: # int* foo(int* i) { return i; } # int* bar(int* i) { return i; }