From 7cbfb46ab9a118c5048a39f2cb153e19832c19be Mon Sep 17 00:00:00 2001 From: Wolfgang Pieb Date: Tue, 9 May 2017 19:38:38 +0000 Subject: [PATCH] [DWARF] Fix a parsing issue with type unit headers. Reviewers: dblaikie Differential Revision: https://reviews.llvm.org/D32987 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302574 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/DebugInfo/DWARF/DWARFTypeUnit.cpp | 6 ++- .../Inputs/typeunit-header.elf-x86-64 | Bin 0 -> 840 bytes test/DebugInfo/Inputs/typeunit-header.s | 49 ++++++++++++++++++ test/DebugInfo/typeunit-header.test | 15 ++++++ 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 test/DebugInfo/Inputs/typeunit-header.elf-x86-64 create mode 100644 test/DebugInfo/Inputs/typeunit-header.s create mode 100644 test/DebugInfo/typeunit-header.test diff --git a/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp index e0f81938328..25824f6eb83 100644 --- a/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp +++ b/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp @@ -24,7 +24,11 @@ bool DWARFTypeUnit::extractImpl(DataExtractor debug_info, return false; TypeHash = debug_info.getU64(offset_ptr); TypeOffset = debug_info.getU32(offset_ptr); - return TypeOffset < getLength(); + // TypeOffset is relative to the beginning of the header, + // so we have to account for the leading length field. + // FIXME: The size of the length field is 12 in DWARF64. + unsigned SizeOfLength = 4; + return TypeOffset < getLength() + SizeOfLength; } void DWARFTypeUnit::dump(raw_ostream &OS, bool SummarizeTypes) { diff --git a/test/DebugInfo/Inputs/typeunit-header.elf-x86-64 b/test/DebugInfo/Inputs/typeunit-header.elf-x86-64 new file mode 100644 index 0000000000000000000000000000000000000000..26fb0a5177d05ce6dd9605f7e2ab88c35d1b25c5 GIT binary patch literal 840 zcmbtSJ5R$f5dItjtzbY1AIP_jHaPInA{>+yRn(aKaJ2sh9g7v&qfyWY1H^ zBvHNB)iCxr#j)ZKgjY01!t;c2TzZhoB4P#Dphw4+5ZjbDV=iwxGtE#aJWX^s% zJWPs`vACJ`H@9uzs zoO`XN(ATj`I&wG@FSVqaSvU;0!8O9iU0rr literal 0 HcmV?d00001 diff --git a/test/DebugInfo/Inputs/typeunit-header.s b/test/DebugInfo/Inputs/typeunit-header.s new file mode 100644 index 00000000000..802eb01c552 --- /dev/null +++ b/test/DebugInfo/Inputs/typeunit-header.s @@ -0,0 +1,49 @@ +# Test object with an artifically constructed type unit header to verify +# that the length field is correctly used to verify the validity of the +# type_offset field. +# +# To generate the test object: +# llvm-mc -triple x86_64-unknown-linux typeunit-header.s -filetype=obj \ +# -o typeunit-header.elf-x86-64 +# +# We only have an abbreviation for the type unit die which is all we need. +# Real type unit dies have quite different attributes of course, but we +# just need to demonstrate an issue with validating length, so we just give it +# a single visibility attribute. + .section .debug_abbrev,"",@progbits + .byte 0x01 # Abbrev code + .byte 0x41 # DW_TAG_type_unit + .byte 0x01 # DW_CHILDREN_yes + .byte 0x17 # DW_AT_visibility + .byte 0x0b # DW_FORM_data1 + .byte 0x00 # EOM(1) + .byte 0x00 # EOM(2) + .byte 0x02 # Abbrev code + .byte 0x13 # DW_TAG_structure_type + .byte 0x00 # DW_CHILDREN_no (no members) + .byte 0x17 # DW_AT_visibility + .byte 0x0b # DW_FORM_data1 + .byte 0x00 # EOM(1) + .byte 0x00 # EOM(2) + .byte 0x00 # EOM(3) + + .section .debug_types,"",@progbits +# DWARF v4 Type unit header - DWARF32 format. +TU_4_32_start: + .long TU_4_32_end-TU_4_32_version # Length of Unit +TU_4_32_version: + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .quad 0x0011223344556677 # Type Signature + .long TU_4_32_type-TU_4_32_start # Type offset +# The type-unit DIE, which has just a visibility attribute. + .byte 1 # Abbreviation code + .byte 1 # DW_VIS_local +# The type DIE, which also just has a one-byte visibility attribute. +TU_4_32_type: + .byte 2 # Abbreviation code + .byte 1 # DW_VIS_local + .byte 0 # NULL + .byte 0 # NULL +TU_4_32_end: diff --git a/test/DebugInfo/typeunit-header.test b/test/DebugInfo/typeunit-header.test new file mode 100644 index 00000000000..c16156b91e6 --- /dev/null +++ b/test/DebugInfo/typeunit-header.test @@ -0,0 +1,15 @@ +RUN: llvm-dwarfdump %p/Inputs/typeunit-header.elf-x86-64 | FileCheck %s + +This is testing a bugfix where parsing the type unit header was not +taking the unit's intial length field into account when validating. + +The input file is hand-coded assembler to generate a type unit stub, +which only contains a type unit DIE with a sole visibility attribute. + +We make sure that llvm-dwarfdump is parsing the type unit header correctly +and displays it. + +CHECK: .debug_types contents: +CHECK: 0x00000000: Type Unit: length = 0x00000019 version = 0x0004 abbr_offset = 0x0000 addr_size = 0x08 name = '' type_signature = 0x0011223344556677 type_offset = 0x0019 (next unit at 0x0000001d) +CHECK: 0x00000017: DW_TAG_type_unit [1] * +CHECK: DW_AT_visibility [DW_FORM_data1] (DW_VIS_local) -- 2.40.0