Skip to content

Commit 5b48fca

Browse files
aarzillithanm
authored andcommitted
cmd/compile: mark wrapper functions with DW_AT_trampoline
Change DWARF generation to tag wrapper functions with the "DW_AT_trampoline attribute". The intent is that debuggers can pick up on this attr so as to skip through the wrapper to the eventual target. DWARF standard allows for a couple of different possible variants of the trampoline attr; this is the simplest variant (all it tells the debugger is that the function is a wrapper, doesn't include a reference to the wrapper routine). This implementation keys off the WRAPPER LSym attribute, which is set for method wrappers, ABI wrappers, and a selected set of runtime assembly routines (ex: "runtime.call32"). Change-Id: Ib53e1bc56c02b86ca3ac5e7da1a541ec262726cf Reviewed-on: https://go-review.googlesource.com/c/go/+/347352 Reviewed-by: Than McIntosh <[email protected]> Run-TryBot: Than McIntosh <[email protected]> TryBot-Result: Go Bot <[email protected]> Trust: Jeremy Faller <[email protected]>
1 parent e4dfd78 commit 5b48fca

File tree

2 files changed

+53
-12
lines changed

2 files changed

+53
-12
lines changed

src/cmd/internal/dwarf/dwarf.go

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,10 @@ const (
325325
DW_ABRV_COMPUNIT
326326
DW_ABRV_COMPUNIT_TEXTLESS
327327
DW_ABRV_FUNCTION
328+
DW_ABRV_WRAPPER
328329
DW_ABRV_FUNCTION_ABSTRACT
329330
DW_ABRV_FUNCTION_CONCRETE
331+
DW_ABRV_WRAPPER_CONCRETE
330332
DW_ABRV_INLINED_SUBROUTINE
331333
DW_ABRV_INLINED_SUBROUTINE_RANGES
332334
DW_ABRV_VARIABLE
@@ -455,6 +457,19 @@ var abbrevs = [DW_NABRV]dwAbbrev{
455457
},
456458
},
457459

460+
/* WRAPPER */
461+
{
462+
DW_TAG_subprogram,
463+
DW_CHILDREN_yes,
464+
[]dwAttrForm{
465+
{DW_AT_name, DW_FORM_string},
466+
{DW_AT_low_pc, DW_FORM_addr},
467+
{DW_AT_high_pc, DW_FORM_addr},
468+
{DW_AT_frame_base, DW_FORM_block1},
469+
{DW_AT_trampoline, DW_FORM_flag},
470+
},
471+
},
472+
458473
/* FUNCTION_ABSTRACT */
459474
{
460475
DW_TAG_subprogram,
@@ -478,6 +493,19 @@ var abbrevs = [DW_NABRV]dwAbbrev{
478493
},
479494
},
480495

496+
/* WRAPPER_CONCRETE */
497+
{
498+
DW_TAG_subprogram,
499+
DW_CHILDREN_yes,
500+
[]dwAttrForm{
501+
{DW_AT_abstract_origin, DW_FORM_ref_addr},
502+
{DW_AT_low_pc, DW_FORM_addr},
503+
{DW_AT_high_pc, DW_FORM_addr},
504+
{DW_AT_frame_base, DW_FORM_block1},
505+
{DW_AT_trampoline, DW_FORM_flag},
506+
},
507+
},
508+
481509
/* INLINED_SUBROUTINE */
482510
{
483511
DW_TAG_inlined_subroutine,
@@ -1329,11 +1357,14 @@ func putInlinedFunc(ctxt Context, s *FnState, callIdx int) error {
13291357
// for the function (which holds location-independent attributes such
13301358
// as name, type), then the remainder of the attributes are specific
13311359
// to this instance (location, frame base, etc).
1332-
func PutConcreteFunc(ctxt Context, s *FnState) error {
1360+
func PutConcreteFunc(ctxt Context, s *FnState, isWrapper bool) error {
13331361
if logDwarf {
13341362
ctxt.Logf("PutConcreteFunc(%v)\n", s.Info)
13351363
}
13361364
abbrev := DW_ABRV_FUNCTION_CONCRETE
1365+
if isWrapper {
1366+
abbrev = DW_ABRV_WRAPPER_CONCRETE
1367+
}
13371368
Uleb128put(ctxt, s.Info, int64(abbrev))
13381369

13391370
// Abstract origin.
@@ -1346,6 +1377,10 @@ func PutConcreteFunc(ctxt Context, s *FnState) error {
13461377
// cfa / frame base
13471378
putattr(ctxt, s.Info, abbrev, DW_FORM_block1, DW_CLS_BLOCK, 1, []byte{DW_OP_call_frame_cfa})
13481379

1380+
if isWrapper {
1381+
putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, int64(1), 0)
1382+
}
1383+
13491384
// Scopes
13501385
if err := putPrunedScopes(ctxt, s, abbrev); err != nil {
13511386
return err
@@ -1368,11 +1403,14 @@ func PutConcreteFunc(ctxt Context, s *FnState) error {
13681403
// when its containing package was compiled (hence there is no need to
13691404
// emit an abstract version for it to use as a base for inlined
13701405
// routine records).
1371-
func PutDefaultFunc(ctxt Context, s *FnState) error {
1406+
func PutDefaultFunc(ctxt Context, s *FnState, isWrapper bool) error {
13721407
if logDwarf {
13731408
ctxt.Logf("PutDefaultFunc(%v)\n", s.Info)
13741409
}
13751410
abbrev := DW_ABRV_FUNCTION
1411+
if isWrapper {
1412+
abbrev = DW_ABRV_WRAPPER
1413+
}
13761414
Uleb128put(ctxt, s.Info, int64(abbrev))
13771415

13781416
// Expand '"".' to import path.
@@ -1385,13 +1423,16 @@ func PutDefaultFunc(ctxt Context, s *FnState) error {
13851423
putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, 0, s.StartPC)
13861424
putattr(ctxt, s.Info, abbrev, DW_FORM_addr, DW_CLS_ADDRESS, s.Size, s.StartPC)
13871425
putattr(ctxt, s.Info, abbrev, DW_FORM_block1, DW_CLS_BLOCK, 1, []byte{DW_OP_call_frame_cfa})
1388-
ctxt.AddFileRef(s.Info, s.Filesym)
1389-
1390-
var ev int64
1391-
if s.External {
1392-
ev = 1
1426+
if isWrapper {
1427+
putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, int64(1), 0)
1428+
} else {
1429+
ctxt.AddFileRef(s.Info, s.Filesym)
1430+
var ev int64
1431+
if s.External {
1432+
ev = 1
1433+
}
1434+
putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, ev, 0)
13931435
}
1394-
putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, ev, 0)
13951436

13961437
// Scopes
13971438
if err := putPrunedScopes(ctxt, s, abbrev); err != nil {
@@ -1489,10 +1530,10 @@ func determineVarAbbrev(v *Var, fnabbrev int) (int, bool, bool) {
14891530
// Determine whether to use a concrete variable or regular variable DIE.
14901531
concrete := true
14911532
switch fnabbrev {
1492-
case DW_ABRV_FUNCTION:
1533+
case DW_ABRV_FUNCTION, DW_ABRV_WRAPPER:
14931534
concrete = false
14941535
break
1495-
case DW_ABRV_FUNCTION_CONCRETE:
1536+
case DW_ABRV_FUNCTION_CONCRETE, DW_ABRV_WRAPPER_CONCRETE:
14961537
// If we're emitting a concrete subprogram DIE and the variable
14971538
// in question is not part of the corresponding abstract function DIE,
14981539
// then use the default (non-concrete) abbrev for this param.

src/cmd/internal/obj/dwarf.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -378,9 +378,9 @@ func (ctxt *Link) populateDWARF(curfn interface{}, s *LSym, myimportpath string)
378378
if err != nil {
379379
ctxt.Diag("emitting DWARF for %s failed: %v", s.Name, err)
380380
}
381-
err = dwarf.PutConcreteFunc(dwctxt, fnstate)
381+
err = dwarf.PutConcreteFunc(dwctxt, fnstate, s.Wrapper())
382382
} else {
383-
err = dwarf.PutDefaultFunc(dwctxt, fnstate)
383+
err = dwarf.PutDefaultFunc(dwctxt, fnstate, s.Wrapper())
384384
}
385385
if err != nil {
386386
ctxt.Diag("emitting DWARF for %s failed: %v", s.Name, err)

0 commit comments

Comments
 (0)