<div dir="ltr">Hey - could we revisit the review for this (I've followed up there too) - I feel like the crux of my concerns was never really resolved? <br><br>(if I recall correctly, the original version of this code was non-recursive (& only walked a fixed set of levels (one abstract, one specification)) - I'm not sure how/why it became recursive & would like to revisit/reexamine that decision before we add more complexity to handle that route)</div><br><div class="gmail_quote"><div dir="ltr">On Mon, Apr 30, 2018 at 10:06 AM Jonas Devlieghere via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: jdevlieghere<br>
Date: Mon Apr 30 10:02:41 2018<br>
New Revision: 331200<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=331200&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=331200&view=rev</a><br>
Log:<br>
[DebugInfo] Prevent infinite recursion for malformed DWARF<br>
<br>
This prevents infinite recursion in DWARFDie::findRecursively for<br>
malformed DWARF where a DIE references itself.<br>
<br>
This fixes PR36257.<br>
<br>
Differential revision: <a href="https://reviews.llvm.org/D43092" rel="noreferrer" target="_blank">https://reviews.llvm.org/D43092</a><br>
<br>
Added:<br>
llvm/trunk/test/tools/llvm-dwarfdump/X86/invalid_abstract_origin.s<br>
Modified:<br>
llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp?rev=331200&r1=331199&r2=331200&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp?rev=331200&r1=331199&r2=331200&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp Mon Apr 30 10:02:41 2018<br>
@@ -10,6 +10,7 @@<br>
#include "llvm/DebugInfo/DWARF/DWARFDie.h"<br>
#include "llvm/ADT/None.h"<br>
#include "llvm/ADT/Optional.h"<br>
+#include "llvm/ADT/SmallSet.h"<br>
#include "llvm/ADT/StringRef.h"<br>
#include "llvm/BinaryFormat/Dwarf.h"<br>
#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"<br>
@@ -295,18 +296,37 @@ DWARFDie::find(ArrayRef<dwarf::Attribute<br>
<br>
Optional<DWARFFormValue><br>
DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const {<br>
- if (!isValid())<br>
- return None;<br>
- if (auto Value = find(Attrs))<br>
- return Value;<br>
- if (auto Die = getAttributeValueAsReferencedDie(DW_AT_abstract_origin)) {<br>
- if (auto Value = Die.findRecursively(Attrs))<br>
- return Value;<br>
- }<br>
- if (auto Die = getAttributeValueAsReferencedDie(DW_AT_specification)) {<br>
- if (auto Value = Die.findRecursively(Attrs))<br>
+ std::vector<DWARFDie> Worklist;<br>
+ Worklist.push_back(*this);<br>
+<br>
+ // Keep track if DIEs already seen to prevent infinite recursion.<br>
+ // Empirically we rarely see a depth of more than 3 when dealing with valid<br>
+ // DWARF. This corresponds to following the DW_AT_abstract_origin and<br>
+ // DW_AT_specification just once.<br>
+ SmallSet<DWARFDie, 3> Seen;<br>
+<br>
+ while (!Worklist.empty()) {<br>
+ DWARFDie Die = Worklist.back();<br>
+ Worklist.pop_back();<br>
+<br>
+ if (!Die.isValid())<br>
+ continue;<br>
+<br>
+ if (Seen.count(Die))<br>
+ continue;<br>
+<br>
+ Seen.insert(Die);<br>
+<br>
+ if (auto Value = Die.find(Attrs))<br>
return Value;<br>
+<br>
+ if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))<br>
+ Worklist.push_back(D);<br>
+<br>
+ if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_specification))<br>
+ Worklist.push_back(D);<br>
}<br>
+<br>
return None;<br>
}<br>
<br>
<br>
Added: llvm/trunk/test/tools/llvm-dwarfdump/X86/invalid_abstract_origin.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/invalid_abstract_origin.s?rev=331200&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/invalid_abstract_origin.s?rev=331200&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/invalid_abstract_origin.s (added)<br>
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/invalid_abstract_origin.s Mon Apr 30 10:02:41 2018<br>
@@ -0,0 +1,296 @@<br>
+# This test ensures that dwarfdump doesn't crash for malformed DWARF where a<br>
+# DIE references itself.<br>
+#<br>
+# Source:<br>
+# void f();<br>
+# __attribute__((always_inline)) void g() {<br>
+# f();<br>
+# }<br>
+# void h() {<br>
+# g();<br>
+# };<br>
+#<br>
+# Compile with:<br>
+# clang inlined.c -S -g -o inlined.s<br>
+#<br>
+# RUN: llvm-mc %s -filetype obj -triple x86_64-apple-darwin -o - \<br>
+# RUN: | llvm-dwarfdump -debug-info - \<br>
+# RUN: | FileCheck %s<br>
+<br>
+# CHECK: 0x0000005a: DW_TAG_inlined_subroutine<br>
+# CHECK-NEXT: DW_AT_abstract_origin (0x0000005a)<br>
+<br>
+ .section __TEXT,__text,regular,pure_instructions<br>
+ .macosx_version_min 10, 13<br>
+ .globl _g ## -- Begin function g<br>
+ .p2align 4, 0x90<br>
+_g: ## @g<br>
+Lfunc_begin0:<br>
+ .file 1 "inlined.c"<br>
+ .loc 1 2 0 ## inlined.c:2:0<br>
+ .cfi_startproc<br>
+## %bb.0: ## %entry<br>
+ pushq %rbp<br>
+ .cfi_def_cfa_offset 16<br>
+ .cfi_offset %rbp, -16<br>
+ movq %rsp, %rbp<br>
+ .cfi_def_cfa_register %rbp<br>
+Ltmp0:<br>
+ .loc 1 3 3 prologue_end ## inlined.c:3:3<br>
+ movb $0, %al<br>
+ callq _f<br>
+ .loc 1 4 1 ## inlined.c:4:1<br>
+ popq %rbp<br>
+ retq<br>
+Ltmp1:<br>
+Lfunc_end0:<br>
+ .cfi_endproc<br>
+ ## -- End function<br>
+ .globl _h ## -- Begin function h<br>
+ .p2align 4, 0x90<br>
+_h: ## @h<br>
+Lfunc_begin1:<br>
+ .loc 1 5 0 ## inlined.c:5:0<br>
+ .cfi_startproc<br>
+## %bb.0: ## %entry<br>
+ pushq %rbp<br>
+ .cfi_def_cfa_offset 16<br>
+ .cfi_offset %rbp, -16<br>
+ movq %rsp, %rbp<br>
+ .cfi_def_cfa_register %rbp<br>
+Ltmp2:<br>
+ .loc 1 3 3 prologue_end ## inlined.c:3:3<br>
+ movb $0, %al<br>
+ callq _f<br>
+Ltmp3:<br>
+ .loc 1 7 1 ## inlined.c:7:1<br>
+ popq %rbp<br>
+ retq<br>
+Ltmp4:<br>
+Lfunc_end1:<br>
+ .cfi_endproc<br>
+ ## -- End function<br>
+ .section __DWARF,__debug_str,regular,debug<br>
+Linfo_string:<br>
+ .asciz "clang version 7.0.0 " ## string offset=0<br>
+ .asciz "inlined.c" ## string offset=21<br>
+ .asciz "/private/tmp" ## string offset=31<br>
+ .asciz "g" ## string offset=44<br>
+ .asciz "h" ## string offset=46<br>
+ .section __DWARF,__debug_abbrev,regular,debug<br>
+Lsection_abbrev:<br>
+ .byte 1 ## Abbreviation Code<br>
+ .byte 17 ## DW_TAG_compile_unit<br>
+ .byte 1 ## DW_CHILDREN_yes<br>
+ .byte 37 ## DW_AT_producer<br>
+ .byte 14 ## DW_FORM_strp<br>
+ .byte 19 ## DW_AT_language<br>
+ .byte 5 ## DW_FORM_data2<br>
+ .byte 3 ## DW_AT_name<br>
+ .byte 14 ## DW_FORM_strp<br>
+ .byte 16 ## DW_AT_stmt_list<br>
+ .byte 23 ## DW_FORM_sec_offset<br>
+ .byte 27 ## DW_AT_comp_dir<br>
+ .byte 14 ## DW_FORM_strp<br>
+ .byte 17 ## DW_AT_low_pc<br>
+ .byte 1 ## DW_FORM_addr<br>
+ .byte 18 ## DW_AT_high_pc<br>
+ .byte 6 ## DW_FORM_data4<br>
+ .byte 0 ## EOM(1)<br>
+ .byte 0 ## EOM(2)<br>
+ .byte 2 ## Abbreviation Code<br>
+ .byte 46 ## DW_TAG_subprogram<br>
+ .byte 0 ## DW_CHILDREN_no<br>
+ .byte 17 ## DW_AT_low_pc<br>
+ .byte 1 ## DW_FORM_addr<br>
+ .byte 18 ## DW_AT_high_pc<br>
+ .byte 6 ## DW_FORM_data4<br>
+ .byte 64 ## DW_AT_frame_base<br>
+ .byte 24 ## DW_FORM_exprloc<br>
+ .byte 49 ## DW_AT_abstract_origin<br>
+ .byte 19 ## DW_FORM_ref4<br>
+ .byte 0 ## EOM(1)<br>
+ .byte 0 ## EOM(2)<br>
+ .byte 3 ## Abbreviation Code<br>
+ .byte 46 ## DW_TAG_subprogram<br>
+ .byte 0 ## DW_CHILDREN_no<br>
+ .byte 3 ## DW_AT_name<br>
+ .byte 14 ## DW_FORM_strp<br>
+ .byte 58 ## DW_AT_decl_file<br>
+ .byte 11 ## DW_FORM_data1<br>
+ .byte 59 ## DW_AT_decl_line<br>
+ .byte 11 ## DW_FORM_data1<br>
+ .byte 63 ## DW_AT_external<br>
+ .byte 25 ## DW_FORM_flag_present<br>
+ .byte 32 ## DW_AT_inline<br>
+ .byte 11 ## DW_FORM_data1<br>
+ .byte 0 ## EOM(1)<br>
+ .byte 0 ## EOM(2)<br>
+ .byte 4 ## Abbreviation Code<br>
+ .byte 46 ## DW_TAG_subprogram<br>
+ .byte 1 ## DW_CHILDREN_yes<br>
+ .byte 17 ## DW_AT_low_pc<br>
+ .byte 1 ## DW_FORM_addr<br>
+ .byte 18 ## DW_AT_high_pc<br>
+ .byte 6 ## DW_FORM_data4<br>
+ .byte 64 ## DW_AT_frame_base<br>
+ .byte 24 ## DW_FORM_exprloc<br>
+ .byte 3 ## DW_AT_name<br>
+ .byte 14 ## DW_FORM_strp<br>
+ .byte 58 ## DW_AT_decl_file<br>
+ .byte 11 ## DW_FORM_data1<br>
+ .byte 59 ## DW_AT_decl_line<br>
+ .byte 11 ## DW_FORM_data1<br>
+ .byte 63 ## DW_AT_external<br>
+ .byte 25 ## DW_FORM_flag_present<br>
+ .byte 0 ## EOM(1)<br>
+ .byte 0 ## EOM(2)<br>
+ .byte 5 ## Abbreviation Code<br>
+ .byte 29 ## DW_TAG_inlined_subroutine<br>
+ .byte 0 ## DW_CHILDREN_no<br>
+ .byte 49 ## DW_AT_abstract_origin<br>
+ .byte 19 ## DW_FORM_ref4<br>
+ .byte 17 ## DW_AT_low_pc<br>
+ .byte 1 ## DW_FORM_addr<br>
+ .byte 18 ## DW_AT_high_pc<br>
+ .byte 6 ## DW_FORM_data4<br>
+ .byte 88 ## DW_AT_call_file<br>
+ .byte 11 ## DW_FORM_data1<br>
+ .byte 89 ## DW_AT_call_line<br>
+ .byte 11 ## DW_FORM_data1<br>
+ .byte 0 ## EOM(1)<br>
+ .byte 0 ## EOM(2)<br>
+ .byte 0 ## EOM(3)<br>
+ .section __DWARF,__debug_info,regular,debug<br>
+Lsection_info:<br>
+Lcu_begin0:<br>
+ .long 107 ## Length of Unit<br>
+ .short 4 ## DWARF version number<br>
+Lset0 = Lsection_abbrev-Lsection_abbrev ## Offset Into Abbrev. Section<br>
+ .long Lset0<br>
+ .byte 8 ## Address Size (in bytes)<br>
+ .byte 1 ## Abbrev [1] 0xb:0x64 DW_TAG_compile_unit<br>
+ .long 0 ## DW_AT_producer<br>
+ .short 12 ## DW_AT_language<br>
+ .long 21 ## DW_AT_name<br>
+Lset1 = Lline_table_start0-Lsection_line ## DW_AT_stmt_list<br>
+ .long Lset1<br>
+ .long 31 ## DW_AT_comp_dir<br>
+ .quad Lfunc_begin0 ## DW_AT_low_pc<br>
+Lset2 = Lfunc_end1-Lfunc_begin0 ## DW_AT_high_pc<br>
+ .long Lset2<br>
+ .byte 2 ## Abbrev [2] 0x2a:0x13 DW_TAG_subprogram<br>
+ .quad Lfunc_begin0 ## DW_AT_low_pc<br>
+Lset3 = Lfunc_end0-Lfunc_begin0 ## DW_AT_high_pc<br>
+ .long Lset3<br>
+ .byte 1 ## DW_AT_frame_base<br>
+ .byte 86<br>
+ .long 61 ## DW_AT_abstract_origin<br>
+ .byte 3 ## Abbrev [3] 0x3d:0x8 DW_TAG_subprogram<br>
+ .long 44 ## DW_AT_name<br>
+ .byte 1 ## DW_AT_decl_file<br>
+ .byte 2 ## DW_AT_decl_line<br>
+ ## DW_AT_external<br>
+ .byte 1 ## DW_AT_inline<br>
+ .byte 4 ## Abbrev [4] 0x45:0x29 DW_TAG_subprogram<br>
+ .quad Lfunc_begin1 ## DW_AT_low_pc<br>
+Lset4 = Lfunc_end1-Lfunc_begin1 ## DW_AT_high_pc<br>
+ .long Lset4<br>
+ .byte 1 ## DW_AT_frame_base<br>
+ .byte 86<br>
+ .long 46 ## DW_AT_name<br>
+ .byte 1 ## DW_AT_decl_file<br>
+ .byte 5 ## DW_AT_decl_line<br>
+ ## DW_AT_external<br>
+ .byte 5 ## Abbrev [5] 0x5a:0x13 DW_TAG_inlined_subroutine<br>
+ .long 90 ## DW_AT_abstract_origin <- We modified the value so the DIE references itself.<br>
+ .quad Ltmp2 ## DW_AT_low_pc<br>
+Lset5 = Ltmp3-Ltmp2 ## DW_AT_high_pc<br>
+ .long Lset5<br>
+ .byte 1 ## DW_AT_call_file<br>
+ .byte 6 ## DW_AT_call_line<br>
+ .byte 0 ## End Of Children Mark<br>
+ .byte 0 ## End Of Children Mark<br>
+ .section __DWARF,__debug_ranges,regular,debug<br>
+Ldebug_range:<br>
+ .section __DWARF,__debug_macinfo,regular,debug<br>
+Ldebug_macinfo:<br>
+Lcu_macro_begin0:<br>
+ .byte 0 ## End Of Macro List Mark<br>
+ .section __DWARF,__apple_names,regular,debug<br>
+Lnames_begin:<br>
+ .long 1212240712 ## Header Magic<br>
+ .short 1 ## Header Version<br>
+ .short 0 ## Header Hash Function<br>
+ .long 2 ## Header Bucket Count<br>
+ .long 2 ## Header Hash Count<br>
+ .long 12 ## Header Data Length<br>
+ .long 0 ## HeaderData Die Offset Base<br>
+ .long 1 ## HeaderData Atom Count<br>
+ .short 1 ## DW_ATOM_die_offset<br>
+ .short 6 ## DW_FORM_data4<br>
+ .long 0 ## Bucket 0<br>
+ .long 1 ## Bucket 1<br>
+ .long 177676 ## Hash in Bucket 0<br>
+ .long 177677 ## Hash in Bucket 1<br>
+ .long LNames0-Lnames_begin ## Offset in Bucket 0<br>
+ .long LNames1-Lnames_begin ## Offset in Bucket 1<br>
+LNames0:<br>
+ .long 44 ## g<br>
+ .long 2 ## Num DIEs<br>
+ .long 42<br>
+ .long 90<br>
+ .long 0<br>
+LNames1:<br>
+ .long 46 ## h<br>
+ .long 1 ## Num DIEs<br>
+ .long 69<br>
+ .long 0<br>
+ .section __DWARF,__apple_objc,regular,debug<br>
+Lobjc_begin:<br>
+ .long 1212240712 ## Header Magic<br>
+ .short 1 ## Header Version<br>
+ .short 0 ## Header Hash Function<br>
+ .long 1 ## Header Bucket Count<br>
+ .long 0 ## Header Hash Count<br>
+ .long 12 ## Header Data Length<br>
+ .long 0 ## HeaderData Die Offset Base<br>
+ .long 1 ## HeaderData Atom Count<br>
+ .short 1 ## DW_ATOM_die_offset<br>
+ .short 6 ## DW_FORM_data4<br>
+ .long -1 ## Bucket 0<br>
+ .section __DWARF,__apple_namespac,regular,debug<br>
+Lnamespac_begin:<br>
+ .long 1212240712 ## Header Magic<br>
+ .short 1 ## Header Version<br>
+ .short 0 ## Header Hash Function<br>
+ .long 1 ## Header Bucket Count<br>
+ .long 0 ## Header Hash Count<br>
+ .long 12 ## Header Data Length<br>
+ .long 0 ## HeaderData Die Offset Base<br>
+ .long 1 ## HeaderData Atom Count<br>
+ .short 1 ## DW_ATOM_die_offset<br>
+ .short 6 ## DW_FORM_data4<br>
+ .long -1 ## Bucket 0<br>
+ .section __DWARF,__apple_types,regular,debug<br>
+Ltypes_begin:<br>
+ .long 1212240712 ## Header Magic<br>
+ .short 1 ## Header Version<br>
+ .short 0 ## Header Hash Function<br>
+ .long 1 ## Header Bucket Count<br>
+ .long 0 ## Header Hash Count<br>
+ .long 20 ## Header Data Length<br>
+ .long 0 ## HeaderData Die Offset Base<br>
+ .long 3 ## HeaderData Atom Count<br>
+ .short 1 ## DW_ATOM_die_offset<br>
+ .short 6 ## DW_FORM_data4<br>
+ .short 3 ## DW_ATOM_die_tag<br>
+ .short 5 ## DW_FORM_data2<br>
+ .short 4 ## DW_ATOM_type_flags<br>
+ .short 11 ## DW_FORM_data1<br>
+ .long -1 ## Bucket 0<br>
+<br>
+.subsections_via_symbols<br>
+ .section __DWARF,__debug_line,regular,debug<br>
+Lsection_line:<br>
+Lline_table_start0:<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>