mirror of
https://github.com/golang/go
synced 2024-11-24 12:20:17 -07:00
runtime: make static/dynamic startup detection work with musl on ppc64le
The glibc loader explicitly sets the first doubleword on the stack (R1) to $0 to indicate it was dynamically loaded. An ELFv2 ABI compliant loader will set R3/R4 to argc/argv when starting the process, and R13 to TLS. musl is not compliant. Instead it passes argc/argv like the kernel, but R3/R4 are in an undefined state and R13 is valid. With the knowledge above, the startup code can be modified to dynamically handle all three cases when linked internally. Fixes #51787 Change-Id: I5de33862c161900d9161817388bbc13a65fdc69c Reviewed-on: https://go-review.googlesource.com/c/go/+/394654 Reviewed-by: Cherry Mui <cherryyz@google.com> Run-TryBot: Paul Murphy <murp@ibm.com> TryBot-Result: Gopher Robot <gobot@golang.org> Trust: Paul Murphy <murp@ibm.com> Trust: Lynn Boger <laboger@linux.vnet.ibm.com>
This commit is contained in:
parent
817d6ea2b3
commit
946167906e
@ -147,25 +147,35 @@ TEXT _main<>(SB),NOSPLIT,$-8
|
||||
// In a statically linked binary, the stack contains argc,
|
||||
// argv as argc string pointers followed by a NULL, envv as a
|
||||
// sequence of string pointers followed by a NULL, and auxv.
|
||||
// There is no TLS base pointer.
|
||||
// The TLS pointer should be initialized to 0.
|
||||
//
|
||||
// In a dynamically linked binary, r3 contains argc, r4
|
||||
// contains argv, r5 contains envp, r6 contains auxv, and r13
|
||||
// In an ELFv2 compliant dynamically linked binary, R3 contains argc,
|
||||
// R4 contains argv, R5 contains envp, R6 contains auxv, and R13
|
||||
// contains the TLS pointer.
|
||||
//
|
||||
// Figure out which case this is by looking at r4: if it's 0,
|
||||
// we're statically linked; otherwise we're dynamically
|
||||
// linked.
|
||||
CMP R0, R4
|
||||
BNE dlink
|
||||
// When loading via glibc, the first doubleword on the stack points
|
||||
// to NULL a value. (that is *(uintptr)(R1) == 0). This is used to
|
||||
// differentiate static vs dynamicly linked binaries.
|
||||
//
|
||||
// If loading with the musl loader, it doesn't follow the ELFv2 ABI. It
|
||||
// passes argc/argv similar to the linux kernel, R13 (TLS) is
|
||||
// initialized, and R3/R4 are undefined.
|
||||
MOVD (R1), R12
|
||||
CMP R0, R12
|
||||
BEQ tls_and_argcv_in_reg
|
||||
|
||||
// Statically linked
|
||||
// Arguments are passed via the stack (musl loader or a static binary)
|
||||
MOVD 0(R1), R3 // argc
|
||||
ADD $8, R1, R4 // argv
|
||||
|
||||
// Did the TLS pointer get set? If so, don't change it (e.g musl).
|
||||
CMP R0, R13
|
||||
BNE tls_and_argcv_in_reg
|
||||
|
||||
MOVD $runtime·m0+m_tls(SB), R13 // TLS
|
||||
ADD $0x7000, R13
|
||||
|
||||
dlink:
|
||||
tls_and_argcv_in_reg:
|
||||
BR main(SB)
|
||||
|
||||
TEXT main(SB),NOSPLIT,$-8
|
||||
|
Loading…
Reference in New Issue
Block a user