Skip to content

Commit

Permalink
[release-branch.go1.17] cmd/compile,link: support generating dwarf in…
Browse files Browse the repository at this point in the history
…fo when -linkshared

Now, all the dwarf type can be generated by compiler, when using static link, every compiler unit generate its own dwarf type die. when using -linkshared, all the types current compile unit need can be collected. So we can generate corresponding dwarf type info for it and subtypes of it.
For synthesizetype, we also need to keep the type info of them when linkshared

For golang#52209

Change-Id: Ia70ba39708ce710c45d923d5b86dac91d7e9d616
  • Loading branch information
zhouguangyuan0718 committed Apr 20, 2022
1 parent 9bebd5d commit 38703b5
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 36 deletions.
20 changes: 14 additions & 6 deletions src/cmd/compile/internal/dwarfgen/dwarf.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ func Info(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.Scope,
continue
}
apdecls = append(apdecls, n)
CreateDwarfType(n.Type())
fnsym.Func().RecordAutoType(reflectdata.TypeLinksym(n.Type()))
}
}
Expand Down Expand Up @@ -185,7 +186,7 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir
decls = append(decls, n)
continue
}
typename := dwarf.InfoPrefix + types.TypeSymName(n.Type())

decls = append(decls, n)
abbrev := dwarf.DW_ABRV_AUTO_LOCLIST
isReturnValue := (n.Class == ir.PPARAMOUT)
Expand All @@ -206,13 +207,14 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir
}
}
}

declpos := base.Ctxt.InnermostPos(n.Pos())
vars = append(vars, &dwarf.Var{
Name: n.Sym().Name,
IsReturnValue: isReturnValue,
Abbrev: abbrev,
StackOffset: int32(n.FrameOffset()),
Type: base.Ctxt.Lookup(typename),
Type: CreateDwarfType(n.Type()),
DeclFile: declpos.RelFilename(),
DeclLine: declpos.RelLine(),
DeclCol: declpos.Col(),
Expand Down Expand Up @@ -351,7 +353,6 @@ func createSimpleVar(fnsym *obj.LSym, n *ir.Name) *dwarf.Var {
base.Fatalf("createSimpleVar unexpected class %v for node %v", n.Class, n)
}

typename := dwarf.InfoPrefix + types.TypeSymName(n.Type())
delete(fnsym.Func().Autot, reflectdata.TypeLinksym(n.Type()))
inlIndex := 0
if base.Flag.GenDwarfInl > 1 {
Expand All @@ -369,7 +370,7 @@ func createSimpleVar(fnsym *obj.LSym, n *ir.Name) *dwarf.Var {
IsInlFormal: n.InlFormal(),
Abbrev: abbrev,
StackOffset: int32(offs),
Type: base.Ctxt.Lookup(typename),
Type: CreateDwarfType(n.Type()),
DeclFile: declpos.RelFilename(),
DeclLine: declpos.RelLine(),
DeclCol: declpos.Col(),
Expand Down Expand Up @@ -452,7 +453,7 @@ func createComplexVar(fnsym *obj.LSym, fn *ir.Func, varID ssa.VarID) *dwarf.Var

gotype := reflectdata.TypeLinksym(n.Type())
delete(fnsym.Func().Autot, gotype)
typename := dwarf.InfoPrefix + gotype.Name[len("type."):]

inlIndex := 0
if base.Flag.GenDwarfInl > 1 {
if n.InlFormal() || n.InlLocal() {
Expand All @@ -468,7 +469,7 @@ func createComplexVar(fnsym *obj.LSym, fn *ir.Func, varID ssa.VarID) *dwarf.Var
IsReturnValue: n.Class == ir.PPARAMOUT,
IsInlFormal: n.InlFormal(),
Abbrev: abbrev,
Type: base.Ctxt.Lookup(typename),
Type: CreateDwarfType(n.Type()),
// The stack offset is used as a sorting key, so for decomposed
// variables just give it the first one. It's not used otherwise.
// This won't work well if the first slot hasn't been assigned a stack
Expand Down Expand Up @@ -569,6 +570,13 @@ func lookupRuntime(name string) dwarf.Type {
return reflectdata.DwarfType{Type: t.Type()}
}

func CreateDwarfType(t *types.Type) *obj.LSym {
if base.Ctxt.Flag_linkshared && base.Flag.Dwarf {
base.Ctxt.PopulateDWARFType(reflectdata.DwarfType{Type: t}, true)
}
return base.Ctxt.Lookup(dwarf.InfoPrefix + types.TypeSymName(t))
}

func DumpDwarfTypes() {
base.Ctxt.DumpDwarfTypes(lookupRuntime, reflectdata.DwarfType{Type: types.Types[types.TUINTPTR]})
}
5 changes: 3 additions & 2 deletions src/cmd/compile/internal/gc/obj.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package gc

import (
"cmd/compile/internal/base"
"cmd/compile/internal/dwarfgen"
"cmd/compile/internal/ir"
"cmd/compile/internal/objw"
"cmd/compile/internal/reflectdata"
Expand Down Expand Up @@ -196,7 +197,7 @@ func dumpGlobal(n *ir.Name) {
}
types.CalcSize(n.Type())
ggloblnod(n)
base.Ctxt.DwarfGlobal(base.Ctxt.Pkgpath, types.TypeSymName(n.Type()), n.Linksym())
base.Ctxt.DwarfGlobal(base.Ctxt.Pkgpath, dwarfgen.CreateDwarfType(n.Type()), n.Linksym())
}

func dumpGlobalConst(n ir.Node) {
Expand All @@ -220,7 +221,7 @@ func dumpGlobalConst(n ir.Node) {
return
}
}
base.Ctxt.DwarfIntConst(base.Ctxt.Pkgpath, n.Sym().Name, types.TypeSymName(t), ir.IntVal(t, v))
base.Ctxt.DwarfIntConst(base.Ctxt.Pkgpath, n.Sym().Name, dwarfgen.CreateDwarfType(t), ir.IntVal(t, v))
}

func dumpglobls(externs []ir.Node) {
Expand Down
3 changes: 1 addition & 2 deletions src/cmd/go/internal/work/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,7 @@ func buildModeInit() {
"-linkshared")
codegenArg = "-dynlink"
forcedGcflags = append(forcedGcflags, "-linkshared")
// TODO(mwhudson): remove -w when that gets fixed in linker.
forcedLdflags = append(forcedLdflags, "-linkshared", "-w")
forcedLdflags = append(forcedLdflags, "-linkshared")
}
}
if codegenArg != "" {
Expand Down
5 changes: 4 additions & 1 deletion src/cmd/internal/dwarf/dwarf.go
Original file line number Diff line number Diff line change
Expand Up @@ -1733,6 +1733,9 @@ type TypeContext interface {
// LookupDwarfSym will create a sym that type is SDWARFTYPE.
LookupDwarfSym(name string) (s Sym, exist bool)

// LookupDwarfSymDupOk will create or lookup a dupok sym that type is SDWARFTYPE.
LookupDwarfSymDupOk(name string) (s Sym, exist bool)

// DiagLog is used to report error
DiagLog(info string)
}
Expand Down Expand Up @@ -2078,7 +2081,7 @@ func mkInternalTypename(base string, arg1 string, arg2 string) string {

func MkInternalType(parent *DWDie, ctx TypeContext, abbrev int, typename, keyname, valname string, f func(*DWDie)) Sym {
name := mkInternalTypename(typename, keyname, valname)
s, exist := ctx.LookupDwarfSym(name)
s, exist := ctx.LookupDwarfSymDupOk(name)
if exist {
return s
}
Expand Down
55 changes: 47 additions & 8 deletions src/cmd/internal/obj/dwarf.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,16 @@ func (c dwCtxt) CurrentOffset(s dwarf.Sym) int64 {
return ls.Size
}

func (c dwCtxt) LookupDwarfSymDupOk(name string) (s dwarf.Sym, exist bool) {
ds := c.Link.Lookup(dwarf.InfoPrefix + name)
if ds.Type == objabi.SDWARFTYPE {
return ds, true
}
ds.Set(AttrDuplicateOK, true)
ds.Type = objabi.SDWARFTYPE
return ds, false
}

func (c dwCtxt) LookupDwarfSym(name string) (s dwarf.Sym, exist bool) {
if len(name) != 0 {
ds := c.Link.Lookup(dwarf.InfoPrefix + name)
Expand All @@ -300,6 +310,16 @@ func (c dwCtxt) LookupDwarfSym(name string) (s dwarf.Sym, exist bool) {
}

func (c dwCtxt) Reference(t dwarf.Type) dwarf.Sym {
if c.Flag_linkshared {
if c.Pkgpath != "runtime" {
name := t.DwarfName()
if name == "*runtime.g" || name == "*runtime._type" ||
name == "*runtime.mapextra" || name == "*runtime.itab" {
return c.Link.Lookup(dwarf.InfoPrefix + "uintptr")
}
}
return c.PopulateDWARFType(t, true)
}
return c.Link.Lookup(dwarf.InfoPrefix + t.Name())
}

Expand Down Expand Up @@ -445,20 +465,20 @@ func (ctxt *Link) populateDWARF(curfn interface{}, s *LSym, myimportpath string)

// DwarfIntConst creates a link symbol for an integer constant with the
// given name, type and value.
func (ctxt *Link) DwarfIntConst(myimportpath, name, typename string, val int64) {
func (ctxt *Link) DwarfIntConst(myimportpath, name string, typeSym *LSym, val int64) {
if myimportpath == "" {
return
}
s := ctxt.LookupInit(dwarf.ConstInfoPrefix+myimportpath, func(s *LSym) {
s.Type = objabi.SDWARFCONST
ctxt.Data = append(ctxt.Data, s)
})
dwarf.PutIntConst(dwCtxt{ctxt}, s, ctxt.Lookup(dwarf.InfoPrefix+typename), myimportpath+"."+name, val)
dwarf.PutIntConst(dwCtxt{ctxt}, s, typeSym, myimportpath+"."+name, val)
}

// DwarfGlobal creates a link symbol containing a DWARF entry for
// a global variable.
func (ctxt *Link) DwarfGlobal(myimportpath, typename string, varSym *LSym) {
func (ctxt *Link) DwarfGlobal(myimportpath string, typeSym, varSym *LSym) {
if myimportpath == "" || varSym.Local() {
return
}
Expand All @@ -477,7 +497,6 @@ func (ctxt *Link) DwarfGlobal(myimportpath, typename string, varSym *LSym) {
s.Set(AttrDuplicateOK, true) // needed for shared linkage
ctxt.Data = append(ctxt.Data, s)
})
typeSym := ctxt.Lookup(dwarf.InfoPrefix + typename)
dwarf.PutGlobal(dwCtxt{ctxt}, dieSym, typeSym, varSym, varname)
}

Expand Down Expand Up @@ -791,7 +810,7 @@ func (ctxt *Link) PopulateDWARFType(typ dwarf.Type, dupok bool) dwarf.Sym {
dwsym.Set(AttrDuplicateOK, dupok)

dwctxt := dwCtxt{ctxt}
def, _, err := dwarf.NewType(typ, dwctxt, &ctxt.dwtypes)
def, typedef, err := dwarf.NewType(typ, dwctxt, &ctxt.dwtypes)
if err != nil {
ctxt.Diag(err.Error())
return nil
Expand All @@ -800,6 +819,10 @@ func (ctxt *Link) PopulateDWARFType(typ dwarf.Type, dupok bool) dwarf.Sym {
name := typ.DwarfName()
if _, ok := prototypes[name]; ok {
prototypes[name] = def
if ctxt.Flag_linkshared {
//other packages will emit prototype,too. make it dupok
typedef.Sym.(*LSym).Set(AttrDuplicateOK, true)
}
}
}

Expand All @@ -811,18 +834,31 @@ func (ctxt *Link) DumpDwarfTypes(lookupRuntime func(name string) dwarf.Type, Uin

// We don't expect this type in the package out of runtime.
// So use another temp root, we can avoid dumping them when dwtypes is traversed.
prototypeRoot := new(dwarf.DWDie)
var prototypeRoot *dwarf.DWDie
if ctxt.Flag_linkshared {
uintptrSym.Set(AttrDuplicateOK, true)
dwarf.NewType(Uintptr, dwCtxt{ctxt}, &ctxt.dwtypes)
prototypeRoot = &ctxt.dwtypes
} else {
prototypeRoot = new(dwarf.DWDie)
}

lookupPrototype := func(name string) *dwarf.DWDie {

die := prototypes[name]
if die != nil {
return die
}
t := lookupRuntime(name)
die, _, err := dwarf.NewType(t, dwCtxt{ctxt}, prototypeRoot)
die, typedef, err := dwarf.NewType(t, dwCtxt{ctxt}, prototypeRoot)
if err != nil {
ctxt.Diag(err.Error())
return nil
}
if ctxt.Flag_linkshared {
// only be emitted when using -linkshared
typedef.Sym.(*LSym).Set(AttrDuplicateOK, true)
}
prototypes[name] = die
return die
}
Expand All @@ -837,7 +873,10 @@ func (ctxt *Link) DumpDwarfTypes(lookupRuntime func(name string) dwarf.Type, Uin
case dwarf.DW_ABRV_CHANTYPE:
dwarf.SynthesizeChanTypes(dwCtxt{ctxt}, die, &ctxt.dwtypes, lookupPrototype)
case dwarf.DW_ABRV_IFACETYPE:
// runtime must dump iface and eface, do anything
if ctxt.Flag_linkshared {
lookupPrototype("runtime.eface")
lookupPrototype("runtime.iface")
}
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/cmd/link/internal/ld/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,13 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
if weak && !ldr.AttrReachable(rs) {
continue
}

if ldr.SymType(s) == sym.SDWARFTYPE && strings.HasPrefix(ldr.SymName(rs), "type.") && rst == sym.SDYNIMPORT {
// The relocation of dwarf type die which reference the gotype is generated by compiler,
// it does not know the gotype is dynamic symbol or not. Skip it.
continue
}

if ldr.SymSect(rs) == nil {
st.err.Errorf(s, "unreachable sym in relocation: %s", ldr.SymName(rs))
continue
Expand Down
41 changes: 24 additions & 17 deletions src/cmd/link/internal/ld/dwarf.go
Original file line number Diff line number Diff line change
Expand Up @@ -1023,22 +1023,6 @@ func dwarfGenerateDebugInfo(ctxt *Link) {
dwsectCUSize = make(map[string]uint64)
}

// Needed by the prettyprinter code for interface inspection.
for _, typ := range []string{
"type.runtime._type",
"type.runtime.arraytype",
"type.runtime.chantype",
"type.runtime.functype",
"type.runtime.maptype",
"type.runtime.ptrtype",
"type.runtime.slicetype",
"type.runtime.structtype",
"type.runtime.interfacetype",
"type.runtime.itab",
"type.runtime.imethod"} {
d.markTypeInfo(d.lookupOrDiag(typ))
}

// fake root DIE for compile unit DIEs
var dwroot dwarf.DWDie
flagVariants := make(map[string]bool)
Expand Down Expand Up @@ -1110,6 +1094,24 @@ func dwarfGenerateDebugInfo(ctxt *Link) {
}
}

if !ctxt.IsSharedGoLink() || ctxt.runtimeCU != nil {
// Needed by the prettyprinter code for interface inspection.
for _, typ := range []string{
"type.runtime._type",
"type.runtime.arraytype",
"type.runtime.chantype",
"type.runtime.functype",
"type.runtime.maptype",
"type.runtime.ptrtype",
"type.runtime.slicetype",
"type.runtime.structtype",
"type.runtime.interfacetype",
"type.runtime.itab",
"type.runtime.imethod"} {
d.markTypeInfo(d.lookupOrDiag(typ))
}
}

// Fix for 31034: if the objects feeding into this link were compiled
// with different sets of flags, then don't issue an error if
// the -strictdups checks fail.
Expand Down Expand Up @@ -1243,7 +1245,12 @@ func (d *dwctxt) dwarfGenerateDebugSyms() {
dwarf.ReverseTree(&u.DWInfo.Child)
}

d.linkctxt.runtimeCU.TypeDIES = keeptypeinfo
if d.linkctxt.IsSharedGoLink() && d.linkctxt.runtimeCU == nil {
d.linkctxt.compUnits[0].TypeDIES = keeptypeinfo
} else {
d.linkctxt.runtimeCU.TypeDIES = keeptypeinfo
}

mkSecSym := func(name string) loader.Sym {
s := d.ldr.CreateSymForUpdate(name, 0)
s.SetType(sym.SDWARFSECT)
Expand Down

0 comments on commit 38703b5

Please sign in to comment.