mirror of
https://github.com/golang/go
synced 2024-11-02 09:28:34 +00:00
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 #54320
This commit is contained in:
parent
d75e186e2c
commit
085bbc55db
2 changed files with 81 additions and 7 deletions
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in a new issue