[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