Skip to content

Commit be23819

Browse files
jquirkebradfitz
authored andcommitted
[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 golang#54406 Change-Id: I6c93f5378f50e5edf30d5121402a48214abb1ce2 GitHub-Last-Rev: 085bbc5 GitHub-Pull-Request: golang#54321 Reviewed-on: https://go-review.googlesource.com/c/go/+/422154 Reviewed-by: Cherry Mui <[email protected]> Run-TryBot: Than McIntosh <[email protected]> Reviewed-by: Than McIntosh <[email protected]> TryBot-Result: Gopher Robot <[email protected]> (cherry picked from commit 2340d37) Reviewed-on: https://go-review.googlesource.com/c/go/+/423214 Run-TryBot: Cherry Mui <[email protected]>
1 parent a65a1aa commit be23819

File tree

2 files changed

+81
-7
lines changed

2 files changed

+81
-7
lines changed

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

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1842,3 +1842,82 @@ func main() {
18421842
}
18431843
}
18441844
}
1845+
func TestIssue54320(t *testing.T) {
1846+
// Check that when trampolines are used, the DWARF LPT is correctly
1847+
// emitted in the final binary
1848+
testenv.MustHaveGoBuild(t)
1849+
1850+
if runtime.GOOS == "plan9" {
1851+
t.Skip("skipping on plan9; no DWARF symbol table in executables")
1852+
}
1853+
1854+
t.Parallel()
1855+
1856+
const prog = `
1857+
package main
1858+
1859+
import "fmt"
1860+
1861+
func main() {
1862+
fmt.Printf("Hello world\n");
1863+
}
1864+
`
1865+
1866+
dir := t.TempDir()
1867+
f := gobuild(t, dir, prog, "-ldflags=-debugtramp=2")
1868+
defer f.Close()
1869+
1870+
d, err := f.DWARF()
1871+
if err != nil {
1872+
t.Fatalf("error reading DWARF: %v", err)
1873+
}
1874+
1875+
rdr := d.Reader()
1876+
found := false
1877+
var entry *dwarf.Entry
1878+
for entry, err = rdr.Next(); entry != nil; entry, err = rdr.Next() {
1879+
if err != nil {
1880+
t.Fatalf("error reading DWARF: %v", err)
1881+
}
1882+
if entry.Tag != dwarf.TagCompileUnit {
1883+
continue
1884+
}
1885+
name, _ := entry.Val(dwarf.AttrName).(string)
1886+
if name == "main" {
1887+
found = true
1888+
break
1889+
}
1890+
rdr.SkipChildren()
1891+
}
1892+
1893+
if !found {
1894+
t.Fatalf("could not find main compile unit")
1895+
}
1896+
lr, err := d.LineReader(entry)
1897+
if err != nil {
1898+
t.Fatalf("error obtaining linereader: %v", err)
1899+
}
1900+
1901+
var le dwarf.LineEntry
1902+
found = false
1903+
for {
1904+
if err := lr.Next(&le); err != nil {
1905+
if err == io.EOF {
1906+
break
1907+
}
1908+
t.Fatalf("error reading linentry: %v", err)
1909+
}
1910+
// check LE contains an entry to test.go
1911+
if le.File == nil {
1912+
continue
1913+
}
1914+
file := filepath.Base(le.File.Name)
1915+
if file == "test.go" {
1916+
found = true
1917+
break
1918+
}
1919+
}
1920+
if !found {
1921+
t.Errorf("no LPT entries for test.go")
1922+
}
1923+
}

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

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1610,13 +1610,8 @@ func (l *Loader) GetFuncDwarfAuxSyms(fnSymIdx Sym) (auxDwarfInfo, auxDwarfLoc, a
16101610
if l.SymType(fnSymIdx) != sym.STEXT {
16111611
log.Fatalf("error: non-function sym %d/%s t=%s passed to GetFuncDwarfAuxSyms", fnSymIdx, l.SymName(fnSymIdx), l.SymType(fnSymIdx).String())
16121612
}
1613-
if l.IsExternal(fnSymIdx) {
1614-
// Current expectation is that any external function will
1615-
// not have auxsyms.
1616-
return
1617-
}
1618-
r, li := l.toLocal(fnSymIdx)
1619-
auxs := r.Auxs(li)
1613+
r, auxs := l.auxs(fnSymIdx)
1614+
16201615
for i := range auxs {
16211616
a := &auxs[i]
16221617
switch a.Type() {

0 commit comments

Comments
 (0)