Index: llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -410,22 +410,28 @@ 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 char *D, size_t Length) { + DWARFUnit *U = Die.getDwarfUnit(); + DataExtractor Data(StringRef(D, Length), 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()) { + // Verify inlined location. + VerifyLocation(reinterpret_cast(Expr->data()), + Expr->size()); + } else if (auto LocOffset = AttrValue.Value.getAsUnsignedConstant()) { + // Verify 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/dsymutil/X86/verify.test =================================================================== --- llvm/test/tools/dsymutil/X86/verify.test +++ llvm/test/tools/dsymutil/X86/verify.test @@ -1,8 +1,23 @@ -# Multiple inputs in flat mode -RUN: not llvm-dsymutil -verify -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 %p/../Inputs/basic-archive.macho.x86_64 %p/../Inputs/basic-lto.macho.x86_64 %p/../Inputs/basic-lto-dw4.macho.x86_64 -o %t 2>&1 | FileCheck %s --check-prefix=QUIET -RUN: not llvm-dsymutil -verify -verbose -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 %p/../Inputs/basic-archive.macho.x86_64 %p/../Inputs/basic-lto.macho.x86_64 %p/../Inputs/basic-lto-dw4.macho.x86_64 -o %t 2>&1 | FileCheck %s --check-prefix=QUIET --check-prefix=VERBOSE - -VERBOSE: Verifying DWARF for architecture: x86_64 -VERBOSE: error: DIE has invalid DW_AT_location encoding: -VERBOSE: error: DIE has invalid DW_AT_location encoding: -QUIET: error: verification failed +# Positive tests in regular and verbose mode. +# RUN: llvm-dsymutil -verify -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 %p/../Inputs/basic-archive.macho.x86_64 %p/../Inputs/basic-lto.macho.x86_64 %p/../Inputs/basic-lto-dw4.macho.x86_64 -o %t 2>&1 | FileCheck %s --allow-empty --check-prefix=QUIET-SUCCESS +# RUN: llvm-dsymutil -verify -verbose -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 %p/../Inputs/basic-archive.macho.x86_64 %p/../Inputs/basic-lto.macho.x86_64 %p/../Inputs/basic-lto-dw4.macho.x86_64 -o %t 2>&1 | FileCheck %s --check-prefix=QUIET-SUCCESS --check-prefix=VERBOSE + +# VERBOSE: Verifying DWARF for architecture: x86_64 +# QUIET-SUCCESS-NOT: error: verification failed + +# Negative tests in regular and verbose mode. +# (Invalid object generated from ../Inputs/invalid.s by modified the low PC.) +# RUN: not llvm-dsymutil -verify -oso-prepend-path=%p/../Inputs -y %s -o %t 2>&1 | FileCheck %s --check-prefix=QUIET-FAIL +# RUN: not llvm-dsymutil -verify -verbose -oso-prepend-path=%p/../Inputs -y %s -o %t 2>&1 | FileCheck %s --check-prefix=QUIET-FAIL --check-prefix=VERBOSE + +# QUIET-FAIL: error: verification failed + +--- +triple: 'x86_64-apple-darwin' +objects: + - filename: invalid.o + timestamp: 1518197670 + symbols: + - { sym: _main, objAddr: 0x0000000000000010, binAddr: 0x0000000100000FB0, size: 0x00000008 } + - { sym: _g, objAddr: 0x0000000000000000, binAddr: 0x0000000100000FA0, size: 0x00000010 } +... 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; }