]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: fix trampolines breaking DWARF line info
authorJeremy Quirke <qjeremy@uber.com>
Tue, 9 Aug 2022 17:20:33 +0000 (17:20 +0000)
committerThan McIntosh <thanm@google.com>
Thu, 11 Aug 2022 14:11:53 +0000 (14:11 +0000)
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 #54320

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>

src/cmd/link/internal/ld/dwarf_test.go
src/cmd/link/internal/loader/loader.go

index db5be74b9aefececea970dd61a2d61784c0f49e4..4ac3dbdcfded9f92e92ac073a16ed6a1d4624638 100644 (file)
@@ -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")
+       }
+}
index 52c7d72835c0fd9129f8e8f5c9eb425509f48675..c2baa20d8d20ec7c4e29370e84f223aaea0d8746 100644 (file)
@@ -1611,13 +1611,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() {