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 19:11:15 +0000
commit569d949eeab8b16ae2548a3132ca6f1b8657262b (patch)
treeb402c300350a49900ff4022d81313325429e958d
parentdb2685159346c582cf8ff4cdf8d3632c3b4b1bf6 (diff)
downloadgo-569d949eeab8b16ae2548a3132ca6f1b8657262b.tar.gz
go-569d949eeab8b16ae2548a3132ca6f1b8657262b.zip
[release-branch.go1.18] 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 #54502 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/+/424536 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 2f9bf25d10..c1f60f0289 100644
--- a/src/cmd/link/internal/ld/dwarf_test.go
+++ b/src/cmd/link/internal/ld/dwarf_test.go
@@ -1843,3 +1843,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 371a84ab2e..2a9435b96d 100644
--- a/src/cmd/link/internal/loader/loader.go
+++ b/src/cmd/link/internal/loader/loader.go
@@ -1630,13 +1630,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() {