From 6044dd098d93d12c26ae8378a6c99338350e8280 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Sun, 13 Sep 2015 12:12:13 -0400 Subject: [PATCH] debug/dwarf: return ClassUnknown if attribute class cannot be determined Currently, if the .debug_abbrev section of an ELF file contains attributes that aren't known to the dwarf package and that have form formSecOffset, the dwarf package will fail to open the DWARF data with an error like "decoding dwarf section abbrev at offset 0x17: cannot determine class of unknown attribute with formSecOffset". For the most part, the class is implied by the form encoded in the abbrev section, but formSecOffset can imply many different DWARF classes. Hence, debug/dwarf disambiguates these using a table of known attributes. However, it will reject the entire image if it encounters an attribute it can't determine the class of. This is particularly unfortunate because the caller may never even uses the offending attribute. Fix this by introducing a ClassUnknown attribute class to use as a fallback in these cases. This allows the dwarf package to load the DWARF data and isolates the problem to just the affected attributes. Fixes #12592. Change-Id: I766227b136e9757f8b89c0b3ab8e9ddea899d94f Reviewed-on: https://go-review.googlesource.com/14541 Reviewed-by: Ian Lance Taylor Reviewed-by: jcd . --- src/debug/dwarf/class_string.go | 7 +++---- src/debug/dwarf/entry.go | 11 ++++++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/debug/dwarf/class_string.go b/src/debug/dwarf/class_string.go index 0b1206b9f3..d57d9f71c4 100644 --- a/src/debug/dwarf/class_string.go +++ b/src/debug/dwarf/class_string.go @@ -4,14 +4,13 @@ package dwarf import "fmt" -const _Class_name = "ClassAddressClassBlockClassConstantClassExprLocClassFlagClassLinePtrClassLocListPtrClassMacPtrClassRangeListPtrClassReferenceClassReferenceSigClassStringClassReferenceAltClassStringAlt" +const _Class_name = "ClassUnknownClassAddressClassBlockClassConstantClassExprLocClassFlagClassLinePtrClassLocListPtrClassMacPtrClassRangeListPtrClassReferenceClassReferenceSigClassStringClassReferenceAltClassStringAlt" -var _Class_index = [...]uint8{0, 12, 22, 35, 47, 56, 68, 83, 94, 111, 125, 142, 153, 170, 184} +var _Class_index = [...]uint8{0, 12, 24, 34, 47, 59, 68, 80, 95, 106, 123, 137, 154, 165, 182, 196} func (i Class) String() string { - i -= 1 if i < 0 || i+1 >= Class(len(_Class_index)) { - return fmt.Sprintf("Class(%d)", i+1) + return fmt.Sprintf("Class(%d)", i) } return _Class_name[_Class_index[i]:_Class_index[i+1]] } diff --git a/src/debug/dwarf/entry.go b/src/debug/dwarf/entry.go index d607e5b4a3..5ca86679fa 100644 --- a/src/debug/dwarf/entry.go +++ b/src/debug/dwarf/entry.go @@ -193,8 +193,7 @@ func formToClass(form format, attr Attr, vers int, b *buf) Class { if class, ok := attrPtrClass[attr]; ok { return class } - b.error("cannot determine class of unknown attribute with formSecOffset") - return 0 + return ClassUnknown case formExprloc: return ClassExprLoc @@ -235,6 +234,9 @@ type Entry struct { // loclistptr int64 ClassLocListPtr // macptr int64 ClassMacPtr // rangelistptr int64 ClassRangeListPtr +// +// For unrecognized or vendor-defined attributes, Class may be +// ClassUnknown. type Field struct { Attr Attr Val interface{} @@ -258,9 +260,12 @@ type Field struct { type Class int const ( + // ClassUnknown represents values of unknown DWARF class. + ClassUnknown Class = iota + // ClassAddress represents values of type uint64 that are // addresses on the target machine. - ClassAddress Class = 1 + iota + ClassAddress // ClassBlock represents values of type []byte whose // interpretation depends on the attribute. -- 2.48.1