Skip to content

cmd/internal/obj: prologue end marker in arm64 is in the wrong place #74357

Open
@ajwerner

Description

@ajwerner

Go version

go1.24.4

Output of go env in your module/workspace:

AR='ar'                                                                                                                                                       
CC='gcc'                                                                                                                                                      
CGO_CFLAGS='-O2 -g'                                                                                                                                           
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/andrew/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/andrew/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1743267656=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/home/andrew/src/github.com/DataDog/datadog-agent/go.mod'
GOMODCACHE='/home/andrew/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/andrew/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/andrew/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.4.linux-amd64'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/andrew/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/andrew/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.4.linux-amd64/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.24.4'
GOWORK='/home/andrew/src/github.com/DataDog/datadog-agent/go.work'
PKG_CONFIG='pkg-config

What did you do?

I looked at dwarf and disassembled code for an arm64 binary.

What did you see happen?

I saw that the debug_line section for the program marks the prologue_end as occurring before the stack pointer and frame pointer are updated and the function frame has been set up.

What did you expect to see?

I expected to see the prologue_end marker after the stack pointer and frame pointer have been set up.

My best guess is that when the prologue_end marker was introduced (a88c26e), it was more or less in the right place. Since them, several changes around that code to manage the frame pointer and what not have merged (09e059a, c6d9b38). It seems obvious from the message and review of the latter commit that this adjustment is part of the "prologue".

I think that the issue is that the bookkeeping of the prologueEnd code around here hasn't kept up with other code changes.

To make this explicit, in this commit we have this discussion:

For frame size <= 240B,
  prologue:
    STP		(R29, R30), -(offset+8)(RSP)
    SUB		$offset, RSP, RSP

If you look at some generated go code:

00000000000b5490 <main.stringArrayArg>:
   # <stack growth check>
   b549c: fe 0f 1b f8   str     x30, [sp, #-80]!
   b54a0: fd 83 1f f8   stur    x29, [sp, #-8]
   b54a4: fd 23 00 d1   sub     x29, sp, #8

If we then look at the debug_line table for this code:

0x00000000000b5490     66      0      2   0             0  is_stmt
0x00000000000b549c     66      0      2   0             0  is_stmt prologue_end

This says that the prologue ends at 0xb549c -- but that's where the stack adjustment part of the prologue starts!

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.arch-arm64compiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    Status

    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions