diff --git a/src/cmd/compile/internal/dwarfgen/dwarf.go b/src/cmd/compile/internal/dwarfgen/dwarf.go index 95bfcf5c586787..2205372cf80d79 100644 --- a/src/cmd/compile/internal/dwarfgen/dwarf.go +++ b/src/cmd/compile/internal/dwarfgen/dwarf.go @@ -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())) } } @@ -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) @@ -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(), @@ -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 { @@ -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(), @@ -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() { @@ -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 @@ -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]}) } diff --git a/src/cmd/compile/internal/gc/obj.go b/src/cmd/compile/internal/gc/obj.go index 474d718525f5b8..f177ac83eab1f1 100644 --- a/src/cmd/compile/internal/gc/obj.go +++ b/src/cmd/compile/internal/gc/obj.go @@ -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" @@ -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) { @@ -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) { diff --git a/src/cmd/go/internal/work/init.go b/src/cmd/go/internal/work/init.go index 37a3e2d0ffd123..db8f2d8aa0942f 100644 --- a/src/cmd/go/internal/work/init.go +++ b/src/cmd/go/internal/work/init.go @@ -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 != "" { diff --git a/src/cmd/internal/dwarf/dwarf.go b/src/cmd/internal/dwarf/dwarf.go index d8c66fdea3e3a6..ac8fc1719785bf 100644 --- a/src/cmd/internal/dwarf/dwarf.go +++ b/src/cmd/internal/dwarf/dwarf.go @@ -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) } @@ -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 } diff --git a/src/cmd/internal/obj/dwarf.go b/src/cmd/internal/obj/dwarf.go index 45baad2da9d74e..ffdf44b83a548a 100644 --- a/src/cmd/internal/obj/dwarf.go +++ b/src/cmd/internal/obj/dwarf.go @@ -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) @@ -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()) } @@ -445,7 +465,7 @@ 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 } @@ -453,12 +473,12 @@ func (ctxt *Link) DwarfIntConst(myimportpath, name, typename string, val int64) 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 } @@ -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) } @@ -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 @@ -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) + } } } @@ -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 } @@ -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") + } } } diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index b48ccfb1536b43..fd6fca7ca0c7b5 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -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 diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go index 48e6dee9d29700..6004851c4bc519 100644 --- a/src/cmd/link/internal/ld/dwarf.go +++ b/src/cmd/link/internal/ld/dwarf.go @@ -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) @@ -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. @@ -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)