cmd/link: scope test to linux & net.sendFile

This commit is contained in:
Derek Parker
2025-07-23 10:37:40 -07:00
parent 71c2bf5513
commit add2b2e209
2 changed files with 17 additions and 23 deletions

View File

@@ -278,7 +278,7 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir
base.Fatalf("invalid heap allocated var without Heapaddr")
}
debug := fn.DebugInfo.(*ssa.FuncDebug)
list := createHeapDerefLocationList(n, fnsym, debug.EntryID, ssa.FuncEnd.ID)
list := createHeapDerefLocationList(n, debug.EntryID)
dvar.PutLocationList = func(listSym, startPC dwarf.Sym) {
debug.PutLocationList(list, base.Ctxt, listSym.(*obj.LSym), startPC.(*obj.LSym))
}
@@ -558,7 +558,7 @@ func createComplexVar(fnsym *obj.LSym, fn *ir.Func, varID ssa.VarID, closureVars
// createHeapDerefLocationList creates a location list for a heap-escaped variable
// that describes "dereference pointer at stack offset"
func createHeapDerefLocationList(n *ir.Name, fnsym *obj.LSym, entryID, prologEndID ssa.ID) []byte {
func createHeapDerefLocationList(n *ir.Name, entryID ssa.ID) []byte {
// Get the stack offset where the heap pointer is stored
heapPtrOffset := n.Heapaddr.FrameOffset()
if base.Ctxt.Arch.FixedFrameSize == 0 {

View File

@@ -257,7 +257,18 @@ func TestDWARFiOS(t *testing.T) {
})
}
// This test ensures that variables promoted to the heap, specifically
// function return parameters, have correct location lists generated.
//
// TODO(deparker): This test is intentionally limited to GOOS=="linux"
// and scoped to net.sendFile, which was the function reported originally in
// issue #65405. There is relevant discussion in https://go-review.googlesource.com/c/go/+/684377
// pertaining to these limitations. There are other missing location lists which must be fixed
// particularly in functions where `linkname` is involved.
func TestDWARFLocationList(t *testing.T) {
if runtime.GOOS != "linux" {
t.Skip("skipping test on non-linux OS")
}
testenv.MustHaveCGO(t)
testenv.MustHaveGoBuild(t)
@@ -305,22 +316,10 @@ func TestDWARFLocationList(t *testing.T) {
// Look for the net.sendFile subprogram
if entry.Tag == dwarf.TagSubprogram {
fnName, ok := entry.Val(dwarf.AttrName).(string)
if !ok {
if !ok || fnName != "net.sendFile" {
reader.SkipChildren()
continue
}
if strings.Contains(fnName, ".eq") || // Ignore autogenerated equality funcs
strings.HasPrefix(fnName, "internal/") || // Ignore internal/runtime package TODO(deparker): Fix these too (likely same issue as other ignored packages below).
strings.HasPrefix(fnName, "runtime.") || // Ignore runtime package which contain funcs implemented in assembly or exposed through linkname which seems to not generate location lists correctly (most likely linkname causing this). TODO(deparker) Fix these too.
strings.HasPrefix(fnName, "reflect.") || // Ignore reflect package. TODO(deparker) Fix these too.
strings.HasPrefix(fnName, "time.") { // Ignore funcs in time package which are exposed through linkname and seem to not generate location lists correctly TODO(deparker) Fix these too.
continue
}
if fnName == "syscall.compileCallback" || fnName == "maps.clone" {
continue // Ignore for now, possibly caused by linkname usage. TODO(deparker) Fix this too.
}
if runtime.GOOS == "windows" && strings.HasPrefix(fnName, "syscall.") {
continue // Ignore, caused by linkname usage. TODO(deparker) Fix these too.
}
for {
paramEntry, err := reader.Next()
@@ -332,13 +331,8 @@ func TestDWARFLocationList(t *testing.T) {
}
if paramEntry.Tag == dwarf.TagFormalParameter {
paramName, hasName := paramEntry.Val(dwarf.AttrName).(string)
if !hasName {
continue
}
if paramName[0] == '~' {
continue
}
paramName, _ := paramEntry.Val(dwarf.AttrName).(string)
// Check if this parameter has a location attribute
if loc := paramEntry.Val(dwarf.AttrLocation); loc != nil {
switch locData := loc.(type) {