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