From: Dave Cheney Date: Fri, 19 Sep 2014 02:02:21 +0000 (+0000) Subject: runtime: fix GOARM<7 build X-Git-Tag: go1.4beta1~344 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=66795e8ba101fc20916196db6d343b0d927e7dd5;p=gostls13.git 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 --- diff --git a/src/runtime/tls_arm.s b/src/runtime/tls_arm.s index 7a247ab195..039b013833 100644 --- a/src/runtime/tls_arm.s +++ b/src/runtime/tls_arm.s @@ -29,7 +29,13 @@ TEXT runtime·save_g(SB),NOSPLIT,$-4 MOVW g, R0 // preserve R0 across call to setg<> RET #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 + MOVW R11, LR // $runtime.tlsg(SB) is a special linker symbol. // It is the offset from the TLS base pointer to our // 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. RET #endif + // See comment in save_g. + MOVW LR, R11 MRC 15, 0, R0, C13, C0, 3 // fetch TLS base pointer + MOVW R11, LR // $runtime.tlsg(SB) is a special linker symbol. // It is the offset from the TLS base pointer to our // thread-local storage for g.