aboutsummaryrefslogtreecommitdiff
path: root/src/liblink/obj5.c
diff options
context:
space:
mode:
authorElias Naur <elias.naur@gmail.com>2014-02-03 14:07:54 -0800
committerIan Lance Taylor <iant@golang.org>2014-02-03 14:07:54 -0800
commit1dd4da14591a25748f90a42ef35fa360ff8edde2 (patch)
tree2d1c3e79d0afb5fc12f2ff4a5208b7b5a1c7838a /src/liblink/obj5.c
parente6d8bfe218a5f387d7aceddcaee5067a59181838 (diff)
downloadgo-1dd4da14591a25748f90a42ef35fa360ff8edde2.tar.xz
liblink, cmd/5a, cmd/5l: restore cgo on older ARM processors
CL 56120043 fixed TLS handling on ARM after the introduction of liblink but left older ARM processors broken. Before liblink, the MRC instruction was replaced with a fallback on older ARMs. CL 56120043 removed that, because the rewrite matched bit patterns on the AWORD pseudo-instruction and could therefore change unrelated AWORDs that happened to match. This CL adds an AMRC instruction to encode both MRC and MCR previously encoded as AWORDs. Then, in liblink, the AMRC instructions are either rewritten to AWORD, or, on goarm < 7, replaced with a branch to the fallback. ./all.bash completes successfully on an ARMv7 with either GOARM=7 or GOARM=5. I have verified that the fallback is indeed present in both runtime.save_gm and runtime.load_gm when GOARM=5 but not when GOARM=7. If all goes well, this should fix the armv5 builders. LGTM=iant R=iant, rsc CC=golang-codereviews https://golang.org/cl/55540044
Diffstat (limited to 'src/liblink/obj5.c')
-rw-r--r--src/liblink/obj5.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/liblink/obj5.c b/src/liblink/obj5.c
index da688066a6..cda00b6432 100644
--- a/src/liblink/obj5.c
+++ b/src/liblink/obj5.c
@@ -92,6 +92,7 @@ progedit(Link *ctxt, Prog *p)
{
char literal[64];
LSym *s;
+ LSym *tlsfallback;
p->from.class = 0;
p->to.class = 0;
@@ -105,6 +106,25 @@ progedit(Link *ctxt, Prog *p)
break;
}
+ // 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;
+ }
+ break;
+ }
+
// Rewrite float constants to values stored in memory.
switch(p->as) {
case AMOVF: