]> Cypherpunks repositories - gostls13.git/commitdiff
ld: Fix exported dynamic symbols on Mach-O.
authorIan Lance Taylor <iant@golang.org>
Tue, 11 Jan 2011 21:56:47 +0000 (13:56 -0800)
committerIan Lance Taylor <iant@golang.org>
Tue, 11 Jan 2011 21:56:47 +0000 (13:56 -0800)
* Avoid confusion between imported and exported symbols.
* Record number of imported and exported symbols correctly.
* Explictly relocate SMACHOSYM section, since it is not in datap.

R=rsc
CC=golang-dev
https://golang.org/cl/3920042

src/cmd/6l/asm.c
src/cmd/ld/go.c
src/cmd/ld/lib.h
src/cmd/ld/macho.c

index 26293454bf6013bcccb3acbc69ad973cbed0eee6..9726d227cdb7d63b883916940186eb4f79980f64 100644 (file)
@@ -184,7 +184,7 @@ adddynrel(Sym *s, Reloc *r)
 
        // Handle relocations found in ELF object files.
        case 256 + R_X86_64_PC32:
-               if(targ->dynimpname)
+               if(targ->dynimpname != nil && !targ->dynexport)
                        diag("unexpected R_X86_64_PC32 relocation for dynamic symbol %s", targ->name);
                if(targ->type == 0 || targ->type == SXREF)
                        diag("unknown symbol %s in pcrel", targ->name);
@@ -195,7 +195,7 @@ adddynrel(Sym *s, Reloc *r)
        case 256 + R_X86_64_PLT32:
                r->type = D_PCREL;
                r->add += 4;
-               if(targ->dynimpname != nil) {
+               if(targ->dynimpname != nil && !targ->dynexport) {
                        addpltsym(targ);
                        r->sym = lookup(".plt", 0);
                        r->add += targ->plt;
@@ -203,7 +203,7 @@ adddynrel(Sym *s, Reloc *r)
                return;
        
        case 256 + R_X86_64_GOTPCREL:
-               if(targ->dynimpname == nil) {
+               if(targ->dynimpname == nil || targ->dynexport) {
                        // have symbol
                        // turn MOVQ of GOT entry into LEAQ of symbol itself
                        if(r->off < 2 || s->p[r->off-2] != 0x8b) {
@@ -223,7 +223,7 @@ adddynrel(Sym *s, Reloc *r)
                return;
        
        case 256 + R_X86_64_64:
-               if(targ->dynimpname)
+               if(targ->dynimpname != nil && !targ->dynexport)
                        diag("unexpected R_X86_64_64 relocation for dynamic symbol %s", targ->name);
                r->type = D_ADDR;
                return;
@@ -234,12 +234,12 @@ adddynrel(Sym *s, Reloc *r)
        case 512 + MACHO_X86_64_RELOC_BRANCH*2 + 0:
                // TODO: What is the difference between all these?
                r->type = D_ADDR;
-               if(targ->dynimpname)
+               if(targ->dynimpname != nil && !targ->dynexport)
                        diag("unexpected reloc for dynamic symbol %s", targ->name);
                return;
 
        case 512 + MACHO_X86_64_RELOC_BRANCH*2 + 1:
-               if(targ->dynimpname) {
+               if(targ->dynimpname != nil && !targ->dynexport) {
                        addpltsym(targ);
                        r->sym = lookup(".plt", 0);
                        r->add = targ->plt;
@@ -253,12 +253,12 @@ adddynrel(Sym *s, Reloc *r)
        case 512 + MACHO_X86_64_RELOC_SIGNED_2*2 + 1:
        case 512 + MACHO_X86_64_RELOC_SIGNED_4*2 + 1:
                r->type = D_PCREL;
-               if(targ->dynimpname)
+               if(targ->dynimpname != nil && !targ->dynexport)
                        diag("unexpected pc-relative reloc for dynamic symbol %s", targ->name);
                return;
 
        case 512 + MACHO_X86_64_RELOC_GOT_LOAD*2 + 1:
-               if(targ->dynimpname == nil) {
+               if(targ->dynimpname == nil || targ->dynexport) {
                        // have symbol
                        // turn MOVQ of GOT entry into LEAQ of symbol itself
                        if(r->off < 2 || s->p[r->off-2] != 0x8b) {
@@ -271,7 +271,7 @@ adddynrel(Sym *s, Reloc *r)
                }
                // fall through
        case 512 + MACHO_X86_64_RELOC_GOT*2 + 1:
-               if(targ->dynimpname == nil)
+               if(targ->dynimpname == nil || targ->dynexport)
                        diag("unexpected GOT reloc for non-dynamic symbol %s", targ->name);
                addgotsym(targ);
                r->type = D_PCREL;
@@ -281,7 +281,7 @@ adddynrel(Sym *s, Reloc *r)
        }
        
        // Handle references to ELF symbols from our own object files.
-       if(targ->dynimpname == nil)
+       if(targ->dynimpname == nil || targ->dynexport)
                return;
 
        switch(r->type) {
index 00318fe1154d555c43cd103f9b1b81a2e1befa35..8966b2a1fc4587b3f9f60848e3a09a56a51a40f7 100644 (file)
@@ -71,7 +71,6 @@ static void loaddynexport(char*, char*, char*, int);
 static int parsemethod(char**, char*, char**);
 static int parsepkgdata(char*, char*, char**, char*, char**, char**, char**);
 
-static int ndynexp;
 static Sym **dynexp;
 
 void
index 450135a7f55136d29995e9680a3f60051d3b5dcd..bcf297116819e7b9f9fd37fbf561ff4e38a07436 100644 (file)
@@ -92,6 +92,7 @@ EXTERN        uchar   inuxi8[8];
 EXTERN char*   outfile;
 EXTERN int32   nsymbol;
 EXTERN char*   thestring;
+EXTERN int     ndynexp;
 
 EXTERN Segment segtext;
 EXTERN Segment segdata;
@@ -140,6 +141,7 @@ void        codeblk(int32, int32);
 void   datblk(int32, int32);
 Sym*   datsort(Sym*);
 void   reloc(void);
+void   relocsym(Sym*);
 void   savedata(Sym*, Prog*);
 void   symgrow(Sym*, int32);
 vlong  addstring(Sym*, char*);
index 45bdd4cefcd790262d4d8d73462dd57d98df41b8..402e0ec63dd17f1b2cbd430c20bef72639ddf080 100644 (file)
@@ -102,13 +102,6 @@ newMachoDebug(void)
 
 // Generic linking code.
 
-struct Expsym
-{
-       int     off;
-       Sym*    s;
-} *expsym;
-static int nexpsym;
-
 static char **dylib;
 static int ndylib;
 
@@ -415,9 +408,9 @@ asmbmacho(void)
                ml->data[0] = 0;        /* ilocalsym */
                ml->data[1] = 0;        /* nlocalsym */
                ml->data[2] = 0;        /* iextdefsym */
-               ml->data[3] = 0;        /* nextdefsym */        // TODO nexpsym
-               ml->data[4] = 0;        /* iundefsym */ // TODO nexpsym
-               ml->data[5] = s1->size / (macho64 ? 16 : 12);   /* nundefsym */
+               ml->data[3] = ndynexp;  /* nextdefsym */
+               ml->data[4] = ndynexp;  /* iundefsym */
+               ml->data[5] = (s1->size / (macho64 ? 16 : 12)) - ndynexp;       /* nundefsym */
                ml->data[6] = 0;        /* tocoffset */
                ml->data[7] = 0;        /* ntoc */
                ml->data[8] = 0;        /* modtaboff */
@@ -480,6 +473,7 @@ domacholink(void)
 
        // write data that will be linkedit section
        s1 = lookup(".dynsym", 0);
+       relocsym(s1);
        s2 = lookup(".dynstr", 0);
        s3 = lookup(".linkedit.plt", 0);
        s4 = lookup(".linkedit.got", 0);