internal/gocore: fixes for DWARF5 support

Fix some DWARF-related test code to allow for subprogram DIE high_pc
attrs that are offsets from low_pc as opposed to addresses themselves
(this is what the Go compiler will be doing when it generates DWARF5).

Updates golang/go#26379.

Change-Id: I9d7bde7bbc305e01b0e8b61f3f2ed079c987274d
Reviewed-on: https://go-review.googlesource.com/c/debug/+/639177
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/internal/gocore/dwarf.go b/internal/gocore/dwarf.go
index e22766f..214c1ed 100644
--- a/internal/gocore/dwarf.go
+++ b/internal/gocore/dwarf.go
@@ -11,6 +11,7 @@
 	"reflect"
 	"strings"
 
+	"golang.org/x/debug/dwtest"
 	"golang.org/x/debug/internal/core"
 
 	"golang.org/x/debug/third_party/delve/dwarf/loclist"
@@ -395,22 +396,30 @@
 		}
 
 		if e.Tag == dwarf.TagSubprogram {
-			lowpc := e.AttrField(dwarf.AttrLowpc)
-			highpc := e.AttrField(dwarf.AttrHighpc)
-			if lowpc == nil || highpc == nil {
+			if e.AttrField(dwarf.AttrLowpc) == nil ||
+				e.AttrField(dwarf.AttrHighpc) == nil {
 				continue
 			}
-			min := core.Address(lowpc.Val.(uint64) + p.StaticBase())
-			max := core.Address(highpc.Val.(uint64) + p.StaticBase())
-			f := fns.find(min)
+
+			// Collect the start/end PC for the func. The format/class of
+			// the high PC attr may vary depending on which DWARF version
+			// we're generating; invoke a helper to handle the various
+			// possibilities.
+			lowpc, highpc, perr := dwtest.SubprogLoAndHighPc(e)
+			if perr != nil {
+				return nil, fmt.Errorf("subprog die malformed: %v", perr)
+			}
+			fmin := core.Address(lowpc + p.StaticBase())
+			fmax := core.Address(highpc + p.StaticBase())
+			f := fns.find(fmin)
 			if f == nil {
 				// some func Go doesn't know about. C?
 				curfn = nil
 			} else {
-				if f.entry != min {
+				if f.entry != fmin {
 					return nil, errors.New("dwarf and runtime don't agree about start of " + f.name)
 				}
-				if fns.find(max-1) != f {
+				if fns.find(fmax-1) != f {
 					return nil, errors.New("function ranges don't match for " + f.name)
 				}
 				curfn = f