]> Cypherpunks repositories - gostls13.git/commitdiff
liblink: warn about TLS base MRC instruction that does not write into R0.
authorShenghou Ma <minux@golang.org>
Sat, 26 Jul 2014 21:46:51 +0000 (17:46 -0400)
committerShenghou Ma <minux@golang.org>
Sat, 26 Jul 2014 21:46:51 +0000 (17:46 -0400)
While we're here, make it lookup the tlsfallback symbol only once.

LGTM=crawshaw
R=golang-codereviews, crawshaw, dave
CC=golang-codereviews
https://golang.org/cl/107430044

src/liblink/obj5.c

index 0c3358cef89abb9b0df1adcee4d0217aa12b2f4a..348401930bead81bf3c8cf0013d9c0a931e4960b 100644 (file)
@@ -92,7 +92,7 @@ progedit(Link *ctxt, Prog *p)
 {
        char literal[64];
        LSym *s;
-       LSym *tlsfallback;
+       static LSym *tlsfallback;
 
        p->from.class = 0;
        p->to.class = 0;
@@ -111,19 +111,27 @@ progedit(Link *ctxt, Prog *p)
        // Replace TLS register fetches on older ARM procesors.
        switch(p->as) {
        case AMRC:
-               // If the instruction matches MRC 15, 0, <reg>, C13, C0, 3, replace it.
-               if(ctxt->goarm < 7 && (p->to.offset & 0xffff0fff) == 0xee1d0f70) {
-                       tlsfallback = linklookup(ctxt, "runtime.read_tls_fallback", 0);
-
-                       // BL runtime.read_tls_fallback(SB)
-                       p->as = ABL;
-                       p->to.type = D_BRANCH;
-                       p->to.sym = tlsfallback;
-                       p->to.offset = 0;
-               } else {
-                       // Otherwise, MRC/MCR instructions need no further treatment.
-                       p->as = AWORD;
+               // Treat MRC 15, 0, <reg>, C13, C0, 3 specially.
+               if((p->to.offset & 0xffff0fff) == 0xee1d0f70) {
+                       // Because the instruction might be rewriten to a BL which returns in R0
+                       // the register must be zero.
+                       if ((p->to.offset & 0xf000) != 0)
+                               ctxt->diag("%L: TLS MRC instruction must write to R0 as it might get translated into a BL instruction", p->lineno);
+
+                       if(ctxt->goarm < 7) {
+                               // Replace it with BL runtime.read_tls_fallback(SB).
+                               if(tlsfallback == nil)
+                                       tlsfallback = linklookup(ctxt, "runtime.read_tls_fallback", 0);
+                               // BL runtime.read_tls_fallback(SB)
+                               p->as = ABL;
+                               p->to.type = D_BRANCH;
+                               p->to.sym = tlsfallback;
+                               p->to.offset = 0;
+                               break;
+                       }
                }
+               // Otherwise, MRC/MCR instructions need no further treatment.
+               p->as = AWORD;
                break;
        }