]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/ld, cmd/6l: part 2 of solaris/amd64 linker changes.
authorShenghou Ma <minux.ma@gmail.com>
Tue, 11 Feb 2014 23:43:05 +0000 (18:43 -0500)
committerShenghou Ma <minux.ma@gmail.com>
Tue, 11 Feb 2014 23:43:05 +0000 (18:43 -0500)
Second part of the solaris/amd64 linker changes: relocation and symbol table.

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

src/cmd/6l/asm.c
src/cmd/ld/data.c
src/cmd/ld/symtab.c

index 813bdc8485fc84ebb622f2a0658621b9124f3a32..08209c4e0b7a189450708babd065b9deade92f3f 100644 (file)
@@ -207,6 +207,15 @@ adddynrel(LSym *s, Reloc *r)
                return;
        
        case D_ADDR:
+               if(s->type == STEXT && iself) {
+                       // The code is asking for the address of an external
+                       // function.  We provide it with the address of the
+                       // correspondent GOT symbol.
+                       addgotsym(targ);
+                       r->sym = linklookup(ctxt, ".got", 0);
+                       r->add += targ->got;
+                       return;
+               }
                if(s->type != SDATA)
                        break;
                if(iself) {
@@ -273,9 +282,12 @@ elfreloc1(Reloc *r, vlong sectoff)
                break;
 
        case D_PCREL:
-               if(r->siz == 4)
-                       VPUT(R_X86_64_PC32 | (uint64)elfsym<<32);
-               else
+               if(r->siz == 4) {
+                       if(r->xsym->type == SDYNIMPORT)
+                               VPUT(R_X86_64_GOTPCREL | (uint64)elfsym<<32);
+                       else
+                               VPUT(R_X86_64_PC32 | (uint64)elfsym<<32);
+               } else
                        return -1;
                break;
        
index 640fd6d6ef2b3d63788b564c5527c0da88c466f3..8acb72331c23cea124ef0f5b39ac731a1a8ff559 100644 (file)
@@ -154,9 +154,9 @@ relocsym(LSym *s)
                if(r->type >= 256)
                        continue;
 
-               if(r->sym != S && r->sym->type == SDYNIMPORT)
+               // Solaris needs the ability to reference dynimport symbols.
+               if(HEADTYPE != Hsolaris && r->sym != S && r->sym->type == SDYNIMPORT)
                        diag("unhandled relocation for %s (type %d rtype %d)", r->sym->name, r->sym->type, r->type);
-
                if(r->sym != S && r->sym->type != STLSBSS && !r->sym->reachable)
                        diag("unreachable sym in relocation: %s %s", s->name, r->sym->name);
 
@@ -194,7 +194,7 @@ relocsym(LSym *s)
                                        r->xadd += symaddr(rs) - symaddr(rs->outer);
                                        rs = rs->outer;
                                }
-                               if(rs->type != SHOSTOBJ && rs->sect == nil)
+                               if(rs->type != SHOSTOBJ && rs->type != SDYNIMPORT && rs->sect == nil)
                                        diag("missing section for %s", rs->name);
                                r->xsym = rs;
 
@@ -225,7 +225,7 @@ relocsym(LSym *s)
                                        rs = rs->outer;
                                }
                                r->xadd -= r->siz; // relative to address after the relocated chunk
-                               if(rs->type != SHOSTOBJ && rs->sect == nil)
+                               if(rs->type != SHOSTOBJ && rs->type != SDYNIMPORT && rs->sect == nil)
                                        diag("missing section for %s", rs->name);
                                r->xsym = rs;
 
index 54e6041483b06c449c57eb3301c50d0b4da0e479..0789c8a3eb4f9b96783839fc6bd37612b0fe2205 100644 (file)
@@ -171,6 +171,7 @@ void
 asmelfsym(void)
 {
        LSym *s;
+       char *name;
 
        // the first symbol entry is reserved
        putelfsyment(0, 0, 0, (STB_LOCAL<<4)|STT_NOTYPE, 0, 0);
@@ -196,9 +197,13 @@ asmelfsym(void)
        genasmsym(putelfsym);
        
        for(s=ctxt->allsym; s!=S; s=s->allsym) {
-               if(s->type != SHOSTOBJ)
+               if(s->type != SHOSTOBJ && s->type != SDYNIMPORT)
                        continue;
-               putelfsyment(putelfstr(s->name), 0, 0, (STB_GLOBAL<<4)|STT_NOTYPE, 0, 0);
+               if(s->type == SDYNIMPORT)
+                       name = s->extname;
+               else
+                       name = s->name;
+               putelfsyment(putelfstr(name), 0, 0, (STB_GLOBAL<<4)|STT_NOTYPE, 0, 0);
                s->elfsym = numelfsym++;
        }
 }