1
0
mirror of https://github.com/golang/go synced 2024-11-26 23:51:29 -07:00

runtime: fix GOARM<7 build

Update #8690

If liblink determines that the host doesn't support TLS it replaces the MRC call with a BL runtime.tls_read_fallback. The problem is save_g doesn't expect anyone to make any BL calls and hasn't setup its own link register properly so when runtime.tls_read_fallback returns the LR points to save_g, not save_g's caller so the RET at the end of the function turns into an infinite loop.

This fix is only a proof of concept, I think the real fix should go into liblink as its MRC substitution is not as transparent as expected.

LGTM=rsc
R=rsc, minux
CC=golang-codereviews
https://golang.org/cl/143050043
This commit is contained in:
Dave Cheney 2014-09-19 02:02:21 +00:00
parent 54b63f0647
commit 66795e8ba1

View File

@ -29,7 +29,13 @@ TEXT runtime·save_g(SB),NOSPLIT,$-4
MOVW g, R0 // preserve R0 across call to setg<> MOVW g, R0 // preserve R0 across call to setg<>
RET RET
#endif #endif
// If the host does not support MRC the linker will replace it with
// a call to runtime.read_tls_fallback which jumps to __kuser_get_tls.
// Both functions are written to only disturb R0 so it should be safe to
// use R11 here to temporarily store LR.
MOVW LR, R11
MRC 15, 0, R0, C13, C0, 3 // fetch TLS base pointer MRC 15, 0, R0, C13, C0, 3 // fetch TLS base pointer
MOVW R11, LR
// $runtime.tlsg(SB) is a special linker symbol. // $runtime.tlsg(SB) is a special linker symbol.
// It is the offset from the TLS base pointer to our // It is the offset from the TLS base pointer to our
// thread-local storage for g. // thread-local storage for g.
@ -51,7 +57,10 @@ TEXT runtime·load_g(SB),NOSPLIT,$0
// nothing to do as nacl/arm does not use TLS at all. // nothing to do as nacl/arm does not use TLS at all.
RET RET
#endif #endif
// See comment in save_g.
MOVW LR, R11
MRC 15, 0, R0, C13, C0, 3 // fetch TLS base pointer MRC 15, 0, R0, C13, C0, 3 // fetch TLS base pointer
MOVW R11, LR
// $runtime.tlsg(SB) is a special linker symbol. // $runtime.tlsg(SB) is a special linker symbol.
// It is the offset from the TLS base pointer to our // It is the offset from the TLS base pointer to our
// thread-local storage for g. // thread-local storage for g.