]> Cypherpunks repositories - gostls13.git/commitdiff
liblink, cmd/5l: restore flag_shared
authorElias Naur <elias.naur@gmail.com>
Mon, 3 Feb 2014 22:49:57 +0000 (14:49 -0800)
committerIan Lance Taylor <iant@golang.org>
Mon, 3 Feb 2014 22:49:57 +0000 (14:49 -0800)
CL 56120043 fixed and cleaned up TLS on ARM after introducing liblink, but
left flag_shared broken. This CL restores the (unsupported) flag_shared
behaviour by simply rewriting access to $runtime.tlsgm(SB) with
runtime.tlsgm(SB), to compensate for the extra indirection when going from
the R_ARM_TLS_LE32 relocation to the R_ARM_TLS_IE32 relocation.

Also, remove unnecessary symbol lookup left after 56120043.

LGTM=iant
R=iant, rsc
CC=golang-codereviews
https://golang.org/cl/57000043

src/cmd/5l/5.out.h
src/liblink/asm5.c
src/liblink/obj5.c

index 99836cb7fffdb4cb0b0739ebfca0dab2065a6cf5..16348a457e14032f02daa228619a2c1f1ba7e953 100644 (file)
@@ -279,7 +279,7 @@ enum
        D_PLT1 = (D_NONE+44), // R_ARM_PLT32, 2nd inst: add ip, ip, #0xNN000
        D_PLT2 = (D_NONE+45), // R_ARM_PLT32, 3rd inst: ldr pc, [ip, #0xNNN]!
        D_CALL = (D_NONE+46), // R_ARM_PLT32/R_ARM_CALL/R_ARM_JUMP24, bl xxxxx or b yyyyy
-       D_TLS = (D_NONE+47), // R_ARM_TLS_LE32
+       D_TLS = (D_NONE+47), // R_ARM_TLS_LE32/R_ARM_TLS_IE32
 };
 
 /*
index d19283a1974981a962deff332ba1c8b0a10f4fd9..02b6e8e46508056b73b2d767408f779376d032d9 100644 (file)
@@ -1371,11 +1371,10 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                        // Its "address" is the offset from the TLS thread pointer
                        // to the thread-local g and m pointers.
                        // Emit a TLS relocation instead of a standard one.
-                       // The TLS flag_shared case is not tested and probably now wrong.
                        if(rel->sym == ctxt->gmsym) {
                                rel->type = D_TLS;
                                if(ctxt->flag_shared)
-                                       rel->add += ctxt->pc - p->pcrel->pc - 8 - rel->siz; // TODO: probably wrong
+                                       rel->add += ctxt->pc - p->pcrel->pc - 8 - rel->siz;
                                rel->xadd = rel->add;
                                rel->xsym = rel->sym;
                        } else if(ctxt->flag_shared) {
index cda00b6432590b7201da0eb12355f8f9b4341980..2af23358fdf221e37ff94f792a867768ee34c298 100644 (file)
@@ -167,6 +167,21 @@ progedit(Link *ctxt, Prog *p)
                }
                break;
        }
+
+       if(ctxt->flag_shared) {
+               // Shared libraries use R_ARM_TLS_IE32 instead of 
+               // R_ARM_TLS_LE32, replacing the link time constant TLS offset in
+               // runtime.tlsgm with an address to a GOT entry containing the 
+               // offset. Rewrite $runtime.tlsgm(SB) to runtime.tlsgm(SB) to
+               // compensate.
+               if(ctxt->gmsym == nil)
+                       ctxt->gmsym = linklookup(ctxt, "runtime.tlsgm", 0);
+
+               if(p->from.type == D_CONST && p->from.name == D_EXTERN && p->from.sym == ctxt->gmsym)
+                       p->from.type = D_OREG;
+               if(p->to.type == D_CONST && p->to.name == D_EXTERN && p->to.sym == ctxt->gmsym)
+                       p->to.type = D_OREG;
+       }
 }
 
 static Prog*
@@ -225,8 +240,6 @@ addstacksplit(Link *ctxt, LSym *cursym)
        if(ctxt->symmorestack[0] == nil)
                ctxt->symmorestack[0] = linklookup(ctxt, "runtime.morestack", 0);
        
-       if(ctxt->gmsym == nil)
-               ctxt->gmsym = linklookup(ctxt, "runtime.tlsgm", 0);
        q = nil;
        
        ctxt->cursym = cursym;
@@ -302,7 +315,6 @@ addstacksplit(Link *ctxt, LSym *cursym)
         * strip NOPs
         * expand RET
         * expand BECOME pseudo
-        * fixup TLS
         */
 
        for(p = cursym->text; p != nil; p = p->link) {