diff options
-rw-r--r-- | src/cmd/internal/dwarf/dwarf.go | 61 | ||||
-rw-r--r-- | src/cmd/internal/obj/dwarf.go | 4 |
2 files changed, 53 insertions, 12 deletions
diff --git a/src/cmd/internal/dwarf/dwarf.go b/src/cmd/internal/dwarf/dwarf.go index 4e163db020..69aafaf986 100644 --- a/src/cmd/internal/dwarf/dwarf.go +++ b/src/cmd/internal/dwarf/dwarf.go @@ -325,8 +325,10 @@ const ( DW_ABRV_COMPUNIT DW_ABRV_COMPUNIT_TEXTLESS DW_ABRV_FUNCTION + DW_ABRV_WRAPPER DW_ABRV_FUNCTION_ABSTRACT DW_ABRV_FUNCTION_CONCRETE + DW_ABRV_WRAPPER_CONCRETE DW_ABRV_INLINED_SUBROUTINE DW_ABRV_INLINED_SUBROUTINE_RANGES DW_ABRV_VARIABLE @@ -455,6 +457,19 @@ var abbrevs = [DW_NABRV]dwAbbrev{ }, }, + /* WRAPPER */ + { + DW_TAG_subprogram, + DW_CHILDREN_yes, + []dwAttrForm{ + {DW_AT_name, DW_FORM_string}, + {DW_AT_low_pc, DW_FORM_addr}, + {DW_AT_high_pc, DW_FORM_addr}, + {DW_AT_frame_base, DW_FORM_block1}, + {DW_AT_trampoline, DW_FORM_flag}, + }, + }, + /* FUNCTION_ABSTRACT */ { DW_TAG_subprogram, @@ -478,6 +493,19 @@ var abbrevs = [DW_NABRV]dwAbbrev{ }, }, + /* WRAPPER_CONCRETE */ + { + DW_TAG_subprogram, + DW_CHILDREN_yes, + []dwAttrForm{ + {DW_AT_abstract_origin, DW_FORM_ref_addr}, + {DW_AT_low_pc, DW_FORM_addr}, + {DW_AT_high_pc, DW_FORM_addr}, + {DW_AT_frame_base, DW_FORM_block1}, + {DW_AT_trampoline, DW_FORM_flag}, + }, + }, + /* INLINED_SUBROUTINE */ { DW_TAG_inlined_subroutine, @@ -1329,11 +1357,14 @@ func putInlinedFunc(ctxt Context, s *FnState, callIdx int) error { // for the function (which holds location-independent attributes such // as name, type), then the remainder of the attributes are specific // to this instance (location, frame base, etc). -func PutConcreteFunc(ctxt Context, s *FnState) error { +func PutConcreteFunc(ctxt Context, s *FnState, isWrapper bool) error { if logDwarf { ctxt.Logf("PutConcreteFunc(%v)\n", s.Info) } abbrev := DW_ABRV_FUNCTION_CONCRETE + if isWrapper { + abbrev = DW_ABRV_WRAPPER_CONCRETE + } Uleb128put(ctxt, s.Info, int64(abbrev)) // Abstract origin. @@ -1346,6 +1377,10 @@ func PutConcreteFunc(ctxt Context, s *FnState) error { // cfa / frame base putattr(ctxt, s.Info, abbrev, DW_FORM_block1, DW_CLS_BLOCK, 1, []byte{DW_OP_call_frame_cfa}) + if isWrapper { + putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, int64(1), 0) + } + // Scopes if err := putPrunedScopes(ctxt, s, abbrev); err != nil { return err @@ -1368,11 +1403,14 @@ func PutConcreteFunc(ctxt Context, s *FnState) error { // when its containing package was compiled (hence there is no need to // emit an abstract version for it to use as a base for inlined // routine records). -func PutDefaultFunc(ctxt Context, s *FnState) error { +func PutDefaultFunc(ctxt Context, s *FnState, isWrapper bool) error { if logDwarf { ctxt.Logf("PutDefaultFunc(%v)\n", s.Info) } abbrev := DW_ABRV_FUNCTION + if isWrapper { + abbrev = DW_ABRV_WRAPPER + } Uleb128put(ctxt, s.Info, int64(abbrev)) // Expand '"".' to import path. @@ -1385,13 +1423,16 @@ func PutDefaultFunc(ctxt Context, s *FnState) error { putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, 0, s.StartPC) putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, s.Size, s.StartPC) putattr(ctxt, s.Info, abbrev, DW_FORM_block1, DW_CLS_BLOCK, 1, []byte{DW_OP_call_frame_cfa}) - ctxt.AddFileRef(s.Info, s.Filesym) - - var ev int64 - if s.External { - ev = 1 + if isWrapper { + putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, int64(1), 0) + } else { + ctxt.AddFileRef(s.Info, s.Filesym) + var ev int64 + if s.External { + ev = 1 + } + putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, ev, 0) } - putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, ev, 0) // Scopes if err := putPrunedScopes(ctxt, s, abbrev); err != nil { @@ -1489,10 +1530,10 @@ func determineVarAbbrev(v *Var, fnabbrev int) (int, bool, bool) { // Determine whether to use a concrete variable or regular variable DIE. concrete := true switch fnabbrev { - case DW_ABRV_FUNCTION: + case DW_ABRV_FUNCTION, DW_ABRV_WRAPPER: concrete = false break - case DW_ABRV_FUNCTION_CONCRETE: + case DW_ABRV_FUNCTION_CONCRETE, DW_ABRV_WRAPPER_CONCRETE: // If we're emitting a concrete subprogram DIE and the variable // in question is not part of the corresponding abstract function DIE, // then use the default (non-concrete) abbrev for this param. diff --git a/src/cmd/internal/obj/dwarf.go b/src/cmd/internal/obj/dwarf.go index 6dd53ffd12..29e367aa4c 100644 --- a/src/cmd/internal/obj/dwarf.go +++ b/src/cmd/internal/obj/dwarf.go @@ -378,9 +378,9 @@ func (ctxt *Link) populateDWARF(curfn interface{}, s *LSym, myimportpath string) if err != nil { ctxt.Diag("emitting DWARF for %s failed: %v", s.Name, err) } - err = dwarf.PutConcreteFunc(dwctxt, fnstate) + err = dwarf.PutConcreteFunc(dwctxt, fnstate, s.Wrapper()) } else { - err = dwarf.PutDefaultFunc(dwctxt, fnstate) + err = dwarf.PutDefaultFunc(dwctxt, fnstate, s.Wrapper()) } if err != nil { ctxt.Diag("emitting DWARF for %s failed: %v", s.Name, err) |