diff options
| author | Shenghou Ma <minux@golang.org> | 2014-07-26 17:46:51 -0400 |
|---|---|---|
| committer | Shenghou Ma <minux@golang.org> | 2014-07-26 17:46:51 -0400 |
| commit | 20a5de9eb6e363d22a7594146cf9b2d634ff24a0 (patch) | |
| tree | d8773a1367137f01c11087f5fb28cc1e35aa3a92 /src/liblink/obj5.c | |
| parent | faa223459a931a3fcd94264ba586120f6bd1ad97 (diff) | |
| download | go-20a5de9eb6e363d22a7594146cf9b2d634ff24a0.tar.xz | |
liblink: warn about TLS base MRC instruction that does not write into R0.
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
Diffstat (limited to 'src/liblink/obj5.c')
| -rw-r--r-- | src/liblink/obj5.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/src/liblink/obj5.c b/src/liblink/obj5.c index 0c3358cef8..348401930b 100644 --- a/src/liblink/obj5.c +++ b/src/liblink/obj5.c @@ -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); + // 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); - // 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; + 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; } |
