From 3a43ff1a77d64be009add9eda36ce5ef01081e25 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 11 Jan 2011 13:56:47 -0800 Subject: [PATCH] ld: Fix exported dynamic symbols on Mach-O. * 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 | 20 ++++++++++---------- src/cmd/ld/go.c | 1 - src/cmd/ld/lib.h | 2 ++ src/cmd/ld/macho.c | 14 ++++---------- 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c index 26293454bf6..9726d227cdb 100644 --- a/src/cmd/6l/asm.c +++ b/src/cmd/6l/asm.c @@ -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) { diff --git a/src/cmd/ld/go.c b/src/cmd/ld/go.c index 00318fe1154..8966b2a1fc4 100644 --- a/src/cmd/ld/go.c +++ b/src/cmd/ld/go.c @@ -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 diff --git a/src/cmd/ld/lib.h b/src/cmd/ld/lib.h index 450135a7f55..bcf29711681 100644 --- a/src/cmd/ld/lib.h +++ b/src/cmd/ld/lib.h @@ -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*); diff --git a/src/cmd/ld/macho.c b/src/cmd/ld/macho.c index 45bdd4cefcd..402e0ec63dd 100644 --- a/src/cmd/ld/macho.c +++ b/src/cmd/ld/macho.c @@ -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);