From: Rob Pike Date: Wed, 16 Jul 2014 18:26:50 +0000 (+0000) Subject: cmd/ld: use count, not upper bound, in type of array X-Git-Tag: go1.4beta1~1087 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=74c9cc8394049f68f711e25df413a813dc21f174;p=gostls13.git cmd/ld: use count, not upper bound, in type of array DWARF says only one is necessary. The count is preferable because it admits 0-length arrays. Update debug/dwarf to handle either form. LGTM=rsc R=rsc CC=golang-codereviews https://golang.org/cl/111230044 --- diff --git a/src/cmd/ld/dwarf.c b/src/cmd/ld/dwarf.c index c2fd07702d..c9bb1bd8f0 100644 --- a/src/cmd/ld/dwarf.c +++ b/src/cmd/ld/dwarf.c @@ -266,7 +266,7 @@ static struct DWAbbrev { DW_TAG_subrange_type, DW_CHILDREN_no, // No name! DW_AT_type, DW_FORM_ref_addr, - DW_AT_upper_bound, DW_FORM_udata, + DW_AT_count, DW_FORM_udata, 0, 0 }, @@ -992,7 +992,8 @@ defgotype(LSym *gotype) s = decodetype_arrayelem(gotype); newrefattr(die, DW_AT_type, defgotype(s)); fld = newdie(die, DW_ABRV_ARRAYRANGE, "range"); - newattr(fld, DW_AT_upper_bound, DW_CLS_CONSTANT, decodetype_arraylen(gotype)-1, 0); // -1: want upper bound, not count. + // use actual length not upper bound; correct for 0-length arrays. + newattr(fld, DW_AT_count, DW_CLS_CONSTANT, decodetype_arraylen(gotype), 0); newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr")); break; @@ -1256,7 +1257,7 @@ synthesizemaptypes(DWDie *die) newattr(dwhk, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize * keysize, 0); newrefattr(dwhk, DW_AT_type, indirect_key ? defptrto(keytype) : keytype); fld = newdie(dwhk, DW_ABRV_ARRAYRANGE, "size"); - newattr(fld, DW_AT_upper_bound, DW_CLS_CONSTANT, BucketSize, 0); + newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0); newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr")); // Construct type to represent an array of BucketSize values @@ -1266,7 +1267,7 @@ synthesizemaptypes(DWDie *die) newattr(dwhv, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize * valsize, 0); newrefattr(dwhv, DW_AT_type, indirect_val ? defptrto(valtype) : valtype); fld = newdie(dwhv, DW_ABRV_ARRAYRANGE, "size"); - newattr(fld, DW_AT_upper_bound, DW_CLS_CONSTANT, BucketSize, 0); + newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0); newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr")); // Construct bucket diff --git a/src/pkg/debug/dwarf/type.go b/src/pkg/debug/dwarf/type.go index 68866d0b7b..7b5f1cf7b9 100644 --- a/src/pkg/debug/dwarf/type.go +++ b/src/pkg/debug/dwarf/type.go @@ -370,16 +370,22 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off // but haven't seen that in the wild yet. switch kid.Tag { case TagSubrangeType: - max, ok := kid.Val(AttrUpperBound).(int64) + count, ok := kid.Val(AttrCount).(int64) if !ok { - max = -2 // Count == -1, as in x[]. + // Old binaries may have an upper bound instead. + count, ok = kid.Val(AttrUpperBound).(int64) + if ok { + count++ // Length is one more than upper bound. + } else { + count = -1 // As in x[]. + } } if ndim == 0 { - t.Count = max + 1 + t.Count = count } else { // Multidimensional array. // Create new array type underneath this one. - t.Type = &ArrayType{Type: t.Type, Count: max + 1} + t.Type = &ArrayType{Type: t.Type, Count: count} } ndim++ case TagEnumerationType: