Skip to content

Commit

Permalink
cmd/link: move dwarf part of DWARF generation before type name mangling
Browse files Browse the repository at this point in the history
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 <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Heschi Kreinick <[email protected]>
  • Loading branch information
aarzilli authored and heschi committed Sep 4, 2018
1 parent 669fa8f commit 9c83383
Show file tree
Hide file tree
Showing 9 changed files with 276 additions and 164 deletions.
106 changes: 106 additions & 0 deletions misc/cgo/testplugin/src/checkdwarf/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// 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)
}
4 changes: 4 additions & 0 deletions misc/cgo/testplugin/test.bash
Original file line number Diff line number Diff line change
Expand Up @@ -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" 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

# Test that types and itabs get properly uniqified.
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/link/internal/ld/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -1602,7 +1602,7 @@ func (ctxt *Link) dodata() {
datap = append(datap, data[symn]...)
}

dwarfgeneratedebugsyms(ctxt)
dwarfGenerateDebugSyms(ctxt)

var i int
for ; i < len(dwarfp); i++ {
Expand Down
Loading

0 comments on commit 9c83383

Please sign in to comment.