proc: for optimized functions allow .closureptr to not exist (#3808)

* proc: flag variables correctly when range-over-func stmts are used

Argument variables of a range-over-func body closure should be returned
flagged as normal local variables, not as function arguments.

Updates #3806

* proc: for optimized functions allow .closureptr to not exist

For optimized functions .closureptr is sometimes omitted from DWARF,
allow it to be 0 and try to recover the range-over-func stack by best
effort.

Fixes #3806
This commit is contained in:
Alessandro Arzilli
2024-09-18 23:16:34 +02:00
committed by GitHub
parent b9fadbae9b
commit 582305a813
6 changed files with 143 additions and 13 deletions

View File

@ -463,7 +463,7 @@ type compileUnit struct {
entry *dwarf.Entry // debug_info entry describing this compile unit
isgo bool // true if this is the go compile unit
lineInfo *line.DebugLineInfo // debug_line segment associated with this compile unit
optimized bool // this compile unit is optimized
optimized optimizedFlags // this compile unit is optimized
producer string // producer attribute
offset dwarf.Offset // offset of the entry describing the compile unit
@ -471,6 +471,13 @@ type compileUnit struct {
image *Image // parent image of this compilation unit.
}
type optimizedFlags uint8
const (
optimizedInlined optimizedFlags = 1 << iota
optimizedOptimized
)
type fileLine struct {
file string
line int
@ -605,7 +612,7 @@ func (fn *Function) NameWithoutTypeParams() string {
// Optimized returns true if the function was optimized by the compiler.
func (fn *Function) Optimized() bool {
return fn.cu.optimized
return fn.cu.optimized != 0
}
// PrologueEndPC returns the PC just after the function prologue
@ -2472,9 +2479,18 @@ func (bi *BinaryInfo) loadDebugInfoMaps(image *Image, debugInfoBytes, debugLineB
if cu.isgo && cu.producer != "" {
semicolon := strings.Index(cu.producer, ";")
if semicolon < 0 {
cu.optimized = goversion.ProducerAfterOrEqual(cu.producer, 1, 10)
cu.optimized = 0
if goversion.ProducerAfterOrEqual(cu.producer, 1, 10) {
cu.optimized = optimizedInlined | optimizedOptimized
}
} else {
cu.optimized = !strings.Contains(cu.producer[semicolon:], "-N") || !strings.Contains(cu.producer[semicolon:], "-l")
cu.optimized = optimizedInlined | optimizedOptimized
if strings.Contains(cu.producer[semicolon:], "-N") {
cu.optimized &^= optimizedOptimized
}
if strings.Contains(cu.producer[semicolon:], "-l") {
cu.optimized &^= optimizedInlined
}
const regabi = " regabi"
if i := strings.Index(cu.producer[semicolon:], regabi); i > 0 {
i += semicolon