From 3ba818c894a1aa1e616a8531a1262d4f9d54f02a Mon Sep 17 00:00:00 2001 From: Heschi Kreinick Date: Wed, 18 Oct 2017 13:45:03 -0400 Subject: [PATCH] cmd/compile: distinguish args and return values in DWARF Set DW_AT_variable_parameter on DW_TAG_formal_parameters that are actually return values. variable_parameter is supposed to indicate inout parameters, but Go doesn't really have those, and DWARF doesn't have explicit support for multiple return values. This seems to be the best compromise, especially since the implementation of the two is very similar -- both are stack slots. Fixes #21100 Change-Id: Icebabc92b7b397e0aa00a7237478cce84ad1a670 Reviewed-on: https://go-review.googlesource.com/71670 Run-TryBot: Heschi Kreinick TryBot-Result: Gobot Gobot Reviewed-by: David Chase --- src/cmd/compile/internal/gc/pgen.go | 11 ++++++----- src/cmd/internal/dwarf/dwarf.go | 28 ++++++++++++++++++---------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go index 84d06a00e7..9a91fe40ce 100644 --- a/src/cmd/compile/internal/gc/pgen.go +++ b/src/cmd/compile/internal/gc/pgen.go @@ -400,11 +400,12 @@ func createSimpleVars(automDecls []*Node) ([]*Node, []*dwarf.Var) { typename := dwarf.InfoPrefix + typesymname(n.Type) decls = append(decls, n) vars = append(vars, &dwarf.Var{ - Name: n.Sym.Name, - Abbrev: abbrev, - StackOffset: int32(offs), - Type: Ctxt.Lookup(typename), - DeclLine: n.Pos.Line(), + Name: n.Sym.Name, + IsReturnValue: n.Class() == PPARAMOUT, + Abbrev: abbrev, + StackOffset: int32(offs), + Type: Ctxt.Lookup(typename), + DeclLine: n.Pos.Line(), }) } return decls, vars diff --git a/src/cmd/internal/dwarf/dwarf.go b/src/cmd/internal/dwarf/dwarf.go index f840828b62..149cfc790d 100644 --- a/src/cmd/internal/dwarf/dwarf.go +++ b/src/cmd/internal/dwarf/dwarf.go @@ -49,13 +49,14 @@ type Piece struct { // A Var represents a local variable or a function parameter. type Var struct { - Name string - Abbrev int // Either DW_ABRV_AUTO or DW_ABRV_PARAM - StackOffset int32 - LocationList []Location - Scope int32 - Type Sym - DeclLine uint + Name string + Abbrev int // Either DW_ABRV_AUTO[_LOCLIST] or DW_ABRV_PARAM[_LOCLIST] + IsReturnValue bool + StackOffset int32 + LocationList []Location + Scope int32 + Type Sym + DeclLine uint } // A Scope represents a lexical scope. All variables declared within a @@ -355,6 +356,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{ DW_CHILDREN_no, []dwAttrForm{ {DW_AT_name, DW_FORM_string}, + {DW_AT_variable_parameter, DW_FORM_flag}, {DW_AT_decl_line, DW_FORM_udata}, {DW_AT_location, DW_FORM_block1}, {DW_AT_type, DW_FORM_ref_addr}, @@ -367,6 +369,7 @@ var abbrevs = [DW_NABRV]dwAbbrev{ DW_CHILDREN_no, []dwAttrForm{ {DW_AT_name, DW_FORM_string}, + {DW_AT_variable_parameter, DW_FORM_flag}, {DW_AT_decl_line, DW_FORM_udata}, {DW_AT_location, DW_FORM_sec_offset}, {DW_AT_type, DW_FORM_ref_addr}, @@ -833,8 +836,6 @@ func putscope(ctxt Context, info, loc, ranges, startPC Sym, curscope int32, scop } func putvar(ctxt Context, info, loc Sym, v *Var, startPC Sym, encbuf []byte) { - n := v.Name - // If the variable was entirely optimized out, don't emit a location list; // convert to an inline abbreviation and emit an empty location. missing := false @@ -848,7 +849,14 @@ func putvar(ctxt Context, info, loc Sym, v *Var, startPC Sym, encbuf []byte) { } Uleb128put(ctxt, info, int64(v.Abbrev)) - putattr(ctxt, info, v.Abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(n)), n) + putattr(ctxt, info, v.Abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(v.Name)), v.Name) + if v.Abbrev == DW_ABRV_PARAM || v.Abbrev == DW_ABRV_PARAM_LOCLIST { + var isReturn int64 + if v.IsReturnValue { + isReturn = 1 + } + putattr(ctxt, info, v.Abbrev, DW_FORM_flag, DW_CLS_FLAG, isReturn, nil) + } putattr(ctxt, info, v.Abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(v.DeclLine), nil) if v.Abbrev == DW_ABRV_AUTO_LOCLIST || v.Abbrev == DW_ABRV_PARAM_LOCLIST { putattr(ctxt, info, v.Abbrev, DW_FORM_sec_offset, DW_CLS_PTR, int64(loc.Len()), loc) -- 2.48.1