[llvm] r307975 - [DWARF] Introduce verification for the unit header chain in .debug_info section to llvm-dwarfdump.
Eric Christopher via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 13 18:41:20 PDT 2017
This included some unused variables :)
I've gone ahead and removed them in r307987
On Thu, Jul 13, 2017 at 4:25 PM Spyridoula Gravani via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: sgravani
> Date: Thu Jul 13 16:25:24 2017
> New Revision: 307975
>
> URL: http://llvm.org/viewvc/llvm-project?rev=307975&view=rev
> Log:
> [DWARF] Introduce verification for the unit header chain in .debug_info
> section to llvm-dwarfdump.
>
> This patch adds verification checks for the unit header chain in the
> .debug_info section.
> Specifically, for each unit in the .debug_info section, the verifier
> checks that:
>
> The unit length is valid (i.e. the unit can actually fit in the
> .debug_info section)
> The dwarf version of the unit is valid
> The address size is valid (4 or 8)
> The unit type (if the unit is in dwarf5) is valid
> The debug_abbrev_offset is valid
>
> Added:
> llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_unit_header_chain.s
> Modified:
> llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
> llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
> llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
> llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
>
> Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h?rev=307975&r1=307974&r2=307975&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h (original)
> +++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h Thu Jul 13
> 16:25:24 2017
> @@ -238,6 +238,34 @@ public:
>
> uint8_t getUnitType() const { return UnitType; }
>
> + static bool isValidUnitType(uint8_t UnitType) {
> + return UnitType == dwarf::DW_UT_compile || UnitType ==
> dwarf::DW_UT_type ||
> + UnitType == dwarf::DW_UT_partial ||
> + UnitType == dwarf::DW_UT_skeleton ||
> + UnitType == dwarf::DW_UT_split_compile ||
> + UnitType == dwarf::DW_UT_split_type;
> + }
> +
> + /// \brief Return the number of bytes for the header of a unit of
> + /// UnitType type.
> + ///
> + /// This function must be called with a valid unit type which in
> + /// DWARF5 is defined as one of the following six types.
> + static uint32_t getDWARF5HeaderSize(uint8_t UnitType) {
> + switch (UnitType) {
> + case dwarf::DW_UT_compile:
> + case dwarf::DW_UT_partial:
> + return 12;
> + case dwarf::DW_UT_skeleton:
> + case dwarf::DW_UT_split_compile:
> + return 20;
> + case dwarf::DW_UT_type:
> + case dwarf::DW_UT_split_type:
> + return 24;
> + }
> + llvm_unreachable("Invalid UnitType.");
> + }
> +
> uint64_t getBaseAddress() const { return BaseAddr; }
>
> void setBaseAddress(uint64_t base_addr) {
>
> Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h?rev=307975&r1=307974&r2=307975&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h (original)
> +++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h Thu Jul 13
> 16:25:24 2017
> @@ -21,6 +21,7 @@ class DWARFContext;
> class DWARFDie;
> class DWARFUnit;
> class DWARFAcceleratorTable;
> +class DWARFDataExtractor;
>
> /// A class that verifies DWARF debug information given a DWARF Context.
> class DWARFVerifier {
> @@ -34,6 +35,29 @@ class DWARFVerifier {
> uint32_t NumDebugLineErrors = 0;
> uint32_t NumAppleNamesErrors = 0;
>
> + /// Verifies the header of a unit in the .debug_info section.
> + ///
> + /// This function currently checks for:
> + /// - Unit is in 32-bit DWARF format. The function can be modified to
> + /// support 64-bit format.
> + /// - The DWARF version is valid
> + /// - The unit type is valid (if unit is in version >=5)
> + /// - The unit doesn't extend beyond .debug_info section
> + /// - The address size is valid
> + /// - The offset in the .debug_abbrev section is valid
> + ///
> + /// \param DebugInfoData The .debug_info section data
> + /// \param Offset A reference to the offset start of the unit. The
> offset will
> + /// be updated to point to the next unit in .debug_info
> + /// \param UnitIndex The index of the unit to be verified
> + /// \param isUnitDWARF64 A reference to a flag that shows whether the
> unit is
> + /// in 64-bit format.
> + ///
> + /// \returns true if the header is verified successfully, false
> otherwise.
> + bool verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
> + uint32_t *Offset, unsigned UnitIndex,
> + bool &isUnitDWARF64);
> +
> /// Verifies the attribute's DWARF attribute and its value.
> ///
> /// This function currently checks for:
> @@ -78,6 +102,14 @@ class DWARFVerifier {
> public:
> DWARFVerifier(raw_ostream &S, DWARFContext &D)
> : OS(S), DCtx(D) {}
> + /// Verify the unit header chain in the .debug_info section.
> + ///
> + /// Any errors are reported to the stream that this object was
> + /// constructed with.
> + ///
> + /// \returns true if the unit header chain verifies successfully, false
> + /// otherwise.
> + bool handleDebugInfoUnitHeaderChain();
> /// Verify the information in the .debug_info section.
> ///
> /// Any errors are reported to the stream that was this object was
>
> Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=307975&r1=307974&r2=307975&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp (original)
> +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp Thu Jul 13 16:25:24
> 2017
> @@ -414,6 +414,8 @@ DWARFDie DWARFContext::getDIEForOffset(u
> bool DWARFContext::verify(raw_ostream &OS, DIDumpType DumpType) {
> bool Success = true;
> DWARFVerifier verifier(OS, *this);
> + if (!verifier.handleDebugInfoUnitHeaderChain())
> + Success = false;
> if (DumpType == DIDT_All || DumpType == DIDT_Info) {
> if (!verifier.handleDebugInfo())
> Success = false;
>
> Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp?rev=307975&r1=307974&r2=307975&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp (original)
> +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp Thu Jul 13 16:25:24
> 2017
> @@ -24,6 +24,98 @@ using namespace llvm;
> using namespace dwarf;
> using namespace object;
>
> +bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor
> DebugInfoData,
> + uint32_t *Offset, unsigned UnitIndex,
> + bool &isUnitDWARF64) {
> + uint32_t AbbrOffset, Length;
> + uint8_t AddrSize = 0, UnitType = 0;
> + uint16_t Version;
> + bool Success = true;
> + uint32_t HeaderSize =
> + 11; // means that we have only compile units in .debug_info
> +
> + bool ValidLength = false;
> + bool ValidVersion = false;
> + bool ValidAddrSize = false;
> + bool ValidType = true;
> + bool ValidAbbrevOffset = true;
> +
> + uint32_t OffsetStart = *Offset;
> + Length = DebugInfoData.getU32(Offset);
> + if (Length == UINT32_MAX) {
> + isUnitDWARF64 = true;
> + OS << format(
> + "Unit[%d] is in 64-bit DWARF format; cannot verify from this
> point.\n",
> + UnitIndex);
> + return false;
> + }
> + Version = DebugInfoData.getU16(Offset);
> +
> + if (Version >= 5) {
> + UnitType = DebugInfoData.getU8(Offset);
> + AddrSize = DebugInfoData.getU8(Offset);
> + AbbrOffset = DebugInfoData.getU32(Offset);
> + ValidType = DWARFUnit::isValidUnitType(UnitType);
> + if (ValidType)
> + HeaderSize = DWARFUnit::getDWARF5HeaderSize(UnitType);
> + } else {
> + AbbrOffset = DebugInfoData.getU32(Offset);
> + AddrSize = DebugInfoData.getU8(Offset);
> + }
> +
> + if (!DCtx.getDebugAbbrev()->getAbbreviationDeclarationSet(AbbrOffset))
> + ValidAbbrevOffset = false;
> +
> + ValidLength = DebugInfoData.isValidOffset(OffsetStart + Length + 3);
> + ValidVersion = DWARFContext::isSupportedVersion(Version);
> + ValidAddrSize = AddrSize == 4 || AddrSize == 8;
> + if (!ValidLength || !ValidVersion || !ValidAddrSize ||
> !ValidAbbrevOffset ||
> + !ValidType) {
> + Success = false;
> + OS << format("Units[%d] - start offset: 0x%08x \n", UnitIndex,
> OffsetStart);
> + if (!ValidLength)
> + OS << "\tError: The length for this unit is too "
> + "large for the .debug_info provided.\n";
> + if (!ValidVersion)
> + OS << "\tError: The 16 bit unit header version is not valid.\n";
> + if (!ValidType)
> + OS << "\tError: The unit type encoding is not valid.\n";
> + if (!ValidAbbrevOffset)
> + OS << "\tError: The offset into the .debug_abbrev section is "
> + "not valid.\n";
> + if (!ValidAddrSize)
> + OS << "\tError: The address size is unsupported.\n";
> + }
> + *Offset = OffsetStart + Length + 4;
> + return Success;
> +}
> +
> +bool DWARFVerifier::handleDebugInfoUnitHeaderChain() {
> + OS << "Verifying .debug_info Unit Header Chain...\n";
> +
> + DWARFDataExtractor DebugInfoData(DCtx.getInfoSection(),
> DCtx.isLittleEndian(),
> + 0);
> + uint32_t OffsetStart, Offset = 0, UnitIdx = 0;
> + bool isUnitDWARF64 = false;
> + bool Success = true;
> + bool hasDIE = DebugInfoData.isValidOffset(Offset);
> + while (hasDIE) {
> + OffsetStart = Offset;
> + if (!verifyUnitHeader(DebugInfoData, &Offset, UnitIdx,
> isUnitDWARF64)) {
> + Success = false;
> + if (isUnitDWARF64)
> + break;
> + }
> + hasDIE = DebugInfoData.isValidOffset(Offset);
> + ++UnitIdx;
> + }
> + if (UnitIdx == 0 && !hasDIE) {
> + OS << "Warning: .debug_info is empty.\n";
> + Success = true;
> + }
> + return Success;
> +}
> +
> void DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
> DWARFAttribute &AttrValue) {
> const auto Attr = AttrValue.Attr;
>
> Added: llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_unit_header_chain.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_unit_header_chain.s?rev=307975&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_unit_header_chain.s
> (added)
> +++ llvm/trunk/test/tools/llvm-dwarfdump/X86/verify_unit_header_chain.s
> Thu Jul 13 16:25:24 2017
> @@ -0,0 +1,81 @@
> +# RUN: llvm-mc %s -filetype obj -triple x86_64-apple-darwin -o - \
> +# RUN: | not llvm-dwarfdump -verify - \
> +# RUN: | FileCheck %s
> +
> +# CHECK: Verifying .debug_info Unit Header Chain...
> +# CHECK-NEXT: Units[1] - start offset: 0x0000000d
> +# CHECK-NEXT: Error: The unit type encoding is not valid.
> +# CHECK-NEXT: Error: The address size is unsupported.
> +# CHECK-NEXT: Units[2] - start offset: 0x00000026
> +# CHECK-NEXT: Error: The 16 bit unit header version is not valid.
> +# CHECK-NEXT: Error: The offset into the .debug_abbrev section is not
> valid.
> +# CHECK-NEXT: Units[4] - start offset: 0x00000041
> +# CHECK-NEXT: Error: The length for this unit is too large for the
> .debug_info provided.
> +
> + .section __TEXT,__text,regular,pure_instructions
> + .file 1 "basic.c"
> + .comm _i,4,2 ## @i
> + .comm _j,4,2 ## @j
> + .section __DWARF,__debug_str,regular,debug
> +Linfo_string:
> + .asciz "clang version 5.0.0 (trunk 307232) (llvm/trunk 307042)"
> ## string offset=0
> + .asciz "basic.c" ## string offset=55
> + .asciz "/Users/sgravani/Development/tests" ## string offset=63
> + .asciz "i" ## string offset=97
> + .asciz "int" ## string offset=99
> + .asciz "j" ## string offset=103
> + .section __DWARF,__debug_abbrev,regular,debug
> +Lsection_abbrev:
> + .byte 1 ## Abbreviation Code
> + .byte 17 ## DW_TAG_compile_unit
> + .byte 0 ## EOM(1)
> + .byte 0 ## EOM(2)
> + .byte 0 ## EOM(3)
> + .section __DWARF,__debug_info,regular,debug
> +Lsection_info:
> +Lcu_begin0:
> + .long 9 ## Length of Unit
> + .short 4 ## DWARF version number
> +Lset0 = Lsection_abbrev-Lsection_abbrev ## Offset Into Abbrev. Section
> + .long Lset0
> + .byte 4 ## Address Size (in bytes)
> + .byte 1 ## Abbrev [1] 0xc:0x45
> DW_TAG_compile_unit
> + .byte 0 ## End Of Children Mark
> +Ltu_begin0:
> + .long 21 ## Length of Unit
> + .short 5 ## DWARF version number
> + .byte 0 ## DWARF Unit Type -- Error: The
> unit type encoding is not valid.
> + .byte 3 ## Address Size (in bytes) --
> Error: The address size is unsupported.
> + .long 0
> + .quad 0
> + .long 0
> + .byte 0
> +Lcu_begin1:
> + .long 10 ## Length of Unit
> + .short 6 ## DWARF version number -- Error:
> The 16 bit unit header version is not valid.
> + .byte 1 ## DWARF Unit Type
> + .byte 4 ## Address Size (in bytes) -- The
> offset into the .debug_abbrev section is not valid.
> + .long Lline_table_start0
> + .byte 1 ## Abbrev [1] 0xc:0x45
> DW_TAG_compile_unit
> + .byte 0 ## End Of Children Mark
> +Lcu_begin2:
> + .long 9 ## Length of Unit
> + .short 5 ## DWARF version number
> + .byte 1 ## DWARF Unit Type
> + .byte 4 ## Address Size (in bytes)
> + .long 0 ## Abbrev
> offset
> + .byte 0
> +Ltu_begin1:
> + .long 26 ## Length of Unit -- Error: The
> length for this unit is too large for the .debug_info provided.
> + .short 5 ## DWARF version number
> + .byte 2 ## DWARF Unit Type
> + .byte 4 ## Address Size (in bytes)
> + .long 0
> + .quad 0
> + .long 0
> + .byte 0
> +
> +.subsections_via_symbols
> + .section __DWARF,__debug_line,regular,debug
> +Lsection_line:
> +Lline_table_start0:
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170714/e41040ff/attachment.html>
More information about the llvm-commits
mailing list