]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix GOARM<7 build
authorDave Cheney <dave@cheney.net>
Fri, 19 Sep 2014 02:02:21 +0000 (02:02 +0000)
committerDave Cheney <dave@cheney.net>
Fri, 19 Sep 2014 02:02:21 +0000 (02:02 +0000)
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

src/runtime/tls_arm.s

index 7a247ab1954be39408b5b0cd1a9bdd48f9daddb3..039b0138338cb7015780e011ae142f65b4f683b0 100644 (file)
@@ -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.