Commit 9c833831 authored by Alessandro Arzilli's avatar Alessandro Arzilli Committed by Heschi Kreinick

cmd/link: move dwarf part of DWARF generation before type name mangling

Splits part of dwarfgeneratedebugsyms into a new function,
dwarfGenerateDebugInfo which is called between deadcode elimination
and type name mangling.
This function takes care of collecting and processing the DIEs for
all functions and package-level variables and also generates DIEs
for all types used in the program.

Fixes #23733

Change-Id: I75ef0608fbed2dffc3be7a477f1b03e7e740ec61
Reviewed-on: https://go-review.googlesource.com/111237
Run-TryBot: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarHeschi Kreinick <heschi@google.com>
parent 669fa8f3
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Usage:
//
// checkdwarf <exe> <suffix>
//
// Opens <exe>, which must be an executable or a library and checks that
// there is an entry in .debug_info whose name ends in <suffix>
package main
import (
"debug/dwarf"
"debug/elf"
"debug/macho"
"debug/pe"
"fmt"
"os"
"strings"
)
func usage() {
fmt.Fprintf(os.Stderr, "checkdwarf executable-or-library DIE-suffix\n")
}
type dwarfer interface {
DWARF() (*dwarf.Data, error)
}
func openElf(path string) dwarfer {
exe, err := elf.Open(path)
if err != nil {
return nil
}
return exe
}
func openMacho(path string) dwarfer {
exe, err := macho.Open(path)
if err != nil {
return nil
}
return exe
}
func openPE(path string) dwarfer {
exe, err := pe.Open(path)
if err != nil {
return nil
}
return exe
}
func main() {
if len(os.Args) != 3 {
usage()
}
exePath := os.Args[1]
dieSuffix := os.Args[2]
var exe dwarfer
for _, openfn := range []func(string) dwarfer{openMacho, openPE, openElf} {
exe = openfn(exePath)
if exe != nil {
break
}
}
if exe == nil {
fmt.Fprintf(os.Stderr, "could not open %s", exePath)
os.Exit(1)
}
data, err := exe.DWARF()
if err != nil {
fmt.Fprintf(os.Stderr, "error opening DWARF: %v", err)
os.Exit(1)
}
rdr := data.Reader()
for {
e, err := rdr.Next()
if err != nil {
fmt.Fprintf(os.Stderr, "error reading DWARF: %v", err)
os.Exit(1)
}
if e == nil {
break
}
name, hasname := e.Val(dwarf.AttrName).(string)
if !hasname {
continue
}
if strings.HasSuffix(name, dieSuffix) {
// found
os.Exit(0)
}
}
fmt.Fprintf(os.Stderr, "no entry with a name ending in %q was found", dieSuffix)
os.Exit(1)
}
...@@ -32,6 +32,10 @@ GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o=unnamed1.so u ...@@ -32,6 +32,10 @@ GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o=unnamed1.so u
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o=unnamed2.so unnamed2/main.go GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o=unnamed2.so unnamed2/main.go
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" host GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" host
# test that DWARF sections are emitted for plugins and programs importing "plugin"
go run src/checkdwarf/main.go plugin2.so plugin2.UnexportedNameReuse
go run src/checkdwarf/main.go host main.main
LD_LIBRARY_PATH=$(pwd) ./host LD_LIBRARY_PATH=$(pwd) ./host
# Test that types and itabs get properly uniqified. # Test that types and itabs get properly uniqified.
......
...@@ -1602,7 +1602,7 @@ func (ctxt *Link) dodata() { ...@@ -1602,7 +1602,7 @@ func (ctxt *Link) dodata() {
datap = append(datap, data[symn]...) datap = append(datap, data[symn]...)
} }
dwarfgeneratedebugsyms(ctxt) dwarfGenerateDebugSyms(ctxt)
var i int var i int
for ; i < len(dwarfp); i++ { for ; i < len(dwarfp); i++ {
......
This diff is collapsed.
...@@ -654,7 +654,6 @@ func (ctxt *Link) mangleTypeSym() { ...@@ -654,7 +654,6 @@ func (ctxt *Link) mangleTypeSym() {
return return
} }
*FlagW = true // disable DWARF generation
for _, s := range ctxt.Syms.Allsym { for _, s := range ctxt.Syms.Allsym {
newName := typeSymbolMangle(s.Name) newName := typeSymbolMangle(s.Name)
if newName != s.Name { if newName != s.Name {
......
...@@ -89,6 +89,9 @@ type Link struct { ...@@ -89,6 +89,9 @@ type Link struct {
// Used to implement field tracking. // Used to implement field tracking.
Reachparent map[*sym.Symbol]*sym.Symbol Reachparent map[*sym.Symbol]*sym.Symbol
compUnits []*compilationUnit // DWARF compilation units
compUnitByPackage map[*sym.Library]*compilationUnit
} }
type unresolvedSymKey struct { type unresolvedSymKey struct {
......
...@@ -208,6 +208,7 @@ func Main(arch *sys.Arch, theArch Arch) { ...@@ -208,6 +208,7 @@ func Main(arch *sys.Arch, theArch Arch) {
ctxt.dostrdata() ctxt.dostrdata()
deadcode(ctxt) deadcode(ctxt)
dwarfGenerateDebugInfo(ctxt)
if objabi.Fieldtrack_enabled != 0 { if objabi.Fieldtrack_enabled != 0 {
fieldtrack(ctxt) fieldtrack(ctxt)
} }
......
...@@ -318,6 +318,8 @@ overwrite: ...@@ -318,6 +318,8 @@ overwrite:
pc.InlTree[i].Func = r.readSymIndex() pc.InlTree[i].Func = r.readSymIndex()
} }
s.FuncInfo.IsStmtSym = r.syms.Lookup(dwarf.IsStmtPrefix+s.Name, int(s.Version))
s.Lib = r.lib s.Lib = r.lib
if !dupok { if !dupok {
if s.Attr.OnList() { if s.Attr.OnList() {
......
...@@ -478,6 +478,7 @@ type FuncInfo struct { ...@@ -478,6 +478,7 @@ type FuncInfo struct {
Pcline Pcdata Pcline Pcdata
Pcinline Pcdata Pcinline Pcdata
Pcdata []Pcdata Pcdata []Pcdata
IsStmtSym *Symbol
Funcdata []*Symbol Funcdata []*Symbol
Funcdataoff []int64 Funcdataoff []int64
File []*Symbol File []*Symbol
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment