aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Quirke <qjeremy@uber.com>2022-08-09 17:20:33 +0000
committerHeschi Kreinick <heschi@google.com>2022-08-29 20:10:29 +0000
commit62aa93010dd2e49ed1b98d54c088a875558fed56 (patch)
tree022b4aa3f8f9b2ba4d79bb23927cd78c0e6fc70e
parent15b234b83021ec254a85e79b241a1b4af8ba9b1a (diff)
downloadgo-62aa93010dd2e49ed1b98d54c088a875558fed56.tar.gz
go-62aa93010dd2e49ed1b98d54c088a875558fed56.zip
[release-branch.go1.19] cmd/link: fix trampolines breaking DWARF line info
When trampolines are needed (e.g. Darwin ARM64), the DWARF LPT (Line Program Table - see DWARF section 6.1) generation fails because the replacement symbols are marked as external symbols and skipped during the DWARF LPT generation phase. Fixes #54406 Change-Id: I6c93f5378f50e5edf30d5121402a48214abb1ce2 GitHub-Last-Rev: 085bbc55dbc95d55456cc2acc46a0d02416c2848 GitHub-Pull-Request: golang/go#54321 Reviewed-on: https://go-review.googlesource.com/c/go/+/422154 Reviewed-by: Cherry Mui <cherryyz@google.com> Run-TryBot: Than McIntosh <thanm@google.com> Reviewed-by: Than McIntosh <thanm@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> (cherry picked from commit 2340d371796f95acdcc399e60f9ecefec2add8df) Reviewed-on: https://go-review.googlesource.com/c/go/+/423214 Run-TryBot: Cherry Mui <cherryyz@google.com>
-rw-r--r--src/cmd/link/internal/ld/dwarf_test.go79
-rw-r--r--src/cmd/link/internal/loader/loader.go9
2 files changed, 81 insertions, 7 deletions
diff --git a/src/cmd/link/internal/ld/dwarf_test.go b/src/cmd/link/internal/ld/dwarf_test.go
index db5be74b9a..4ac3dbdcfd 100644
--- a/src/cmd/link/internal/ld/dwarf_test.go
+++ b/src/cmd/link/internal/ld/dwarf_test.go
@@ -1842,3 +1842,82 @@ func main() {
}
}
}
+func TestIssue54320(t *testing.T) {
+ // Check that when trampolines are used, the DWARF LPT is correctly
+ // emitted in the final binary
+ testenv.MustHaveGoBuild(t)
+
+ if runtime.GOOS == "plan9" {
+ t.Skip("skipping on plan9; no DWARF symbol table in executables")
+ }
+
+ t.Parallel()
+
+ const prog = `
+package main
+
+import "fmt"
+
+func main() {
+ fmt.Printf("Hello world\n");
+}
+`
+
+ dir := t.TempDir()
+ f := gobuild(t, dir, prog, "-ldflags=-debugtramp=2")
+ defer f.Close()
+
+ d, err := f.DWARF()
+ if err != nil {
+ t.Fatalf("error reading DWARF: %v", err)
+ }
+
+ rdr := d.Reader()
+ found := false
+ var entry *dwarf.Entry
+ for entry, err = rdr.Next(); entry != nil; entry, err = rdr.Next() {
+ if err != nil {
+ t.Fatalf("error reading DWARF: %v", err)
+ }
+ if entry.Tag != dwarf.TagCompileUnit {
+ continue
+ }
+ name, _ := entry.Val(dwarf.AttrName).(string)
+ if name == "main" {
+ found = true
+ break
+ }
+ rdr.SkipChildren()
+ }
+
+ if !found {
+ t.Fatalf("could not find main compile unit")
+ }
+ lr, err := d.LineReader(entry)
+ if err != nil {
+ t.Fatalf("error obtaining linereader: %v", err)
+ }
+
+ var le dwarf.LineEntry
+ found = false
+ for {
+ if err := lr.Next(&le); err != nil {
+ if err == io.EOF {
+ break
+ }
+ t.Fatalf("error reading linentry: %v", err)
+ }
+ // check LE contains an entry to test.go
+ if le.File == nil {
+ continue
+ }
+ file := filepath.Base(le.File.Name)
+ if file == "test.go" {
+ found = true
+ break
+ }
+ }
+ if !found {
+ t.Errorf("no LPT entries for test.go")
+ }
+}
diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go
index 0cf9551fae..e40e1a7ef9 100644
--- a/src/cmd/link/internal/loader/loader.go
+++ b/src/cmd/link/internal/loader/loader.go
@@ -1610,13 +1610,8 @@ func (l *Loader) GetFuncDwarfAuxSyms(fnSymIdx Sym) (auxDwarfInfo, auxDwarfLoc, a
if l.SymType(fnSymIdx) != sym.STEXT {
log.Fatalf("error: non-function sym %d/%s t=%s passed to GetFuncDwarfAuxSyms", fnSymIdx, l.SymName(fnSymIdx), l.SymType(fnSymIdx).String())
}
- if l.IsExternal(fnSymIdx) {
- // Current expectation is that any external function will
- // not have auxsyms.
- return
- }
- r, li := l.toLocal(fnSymIdx)
- auxs := r.Auxs(li)
+ r, auxs := l.auxs(fnSymIdx)
+
for i := range auxs {
a := &auxs[i]
switch a.Type() {