ld: fix freebsd build reverting .interp move

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/4794046
This commit is contained in:
Gustavo Niemeyer 2011-07-21 03:48:56 -03:00
parent 8cdee891d7
commit 14eba969d8
5 changed files with 46 additions and 47 deletions

View File

@ -185,14 +185,6 @@ doelf(void)
elfstr[ElfStrRelPlt] = addstring(shstrtab, ".rel.plt"); elfstr[ElfStrRelPlt] = addstring(shstrtab, ".rel.plt");
elfstr[ElfStrPlt] = addstring(shstrtab, ".plt"); elfstr[ElfStrPlt] = addstring(shstrtab, ".plt");
/* interpreter string */
if(interpreter == nil)
interpreter = linuxdynld;
s = lookup(".interp", 0);
s->type = SELFROSECT;
s->reachable = 1;
addstring(s, interpreter);
/* dynamic symbol table - first entry all zeros */ /* dynamic symbol table - first entry all zeros */
s = lookup(".dynsym", 0); s = lookup(".dynsym", 0);
s->type = SELFROSECT; s->type = SELFROSECT;
@ -492,7 +484,9 @@ asmb(void)
sh->type = SHT_PROGBITS; sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC; sh->flags = SHF_ALLOC;
sh->addralign = 1; sh->addralign = 1;
shsym(sh, lookup(".interp", 0)); if(interpreter == nil)
interpreter = linuxdynld;
elfinterp(sh, startva, interpreter);
ph = newElfPhdr(); ph = newElfPhdr();
ph->type = PT_INTERP; ph->type = PT_INTERP;
@ -638,7 +632,7 @@ asmb(void)
a += elfwritephdrs(); a += elfwritephdrs();
a += elfwriteshdrs(); a += elfwriteshdrs();
cflush(); cflush();
if(a > ELFRESERVE) if(a+elfwriteinterp() > ELFRESERVE)
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE); diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
break; break;
} }

View File

@ -591,22 +591,6 @@ doelf(void)
elfstr[ElfStrGnuVersion] = addstring(shstrtab, ".gnu.version"); elfstr[ElfStrGnuVersion] = addstring(shstrtab, ".gnu.version");
elfstr[ElfStrGnuVersionR] = addstring(shstrtab, ".gnu.version_r"); elfstr[ElfStrGnuVersionR] = addstring(shstrtab, ".gnu.version_r");
/* interpreter string */
if(interpreter == nil) {
switch(HEADTYPE) {
case Hlinux:
interpreter = linuxdynld;
break;
case Hfreebsd:
interpreter = freebsddynld;
break;
}
}
s = lookup(".interp", 0);
s->type = SELFROSECT;
s->reachable = 1;
addstring(s, interpreter);
/* dynamic symbol table - first entry all zeros */ /* dynamic symbol table - first entry all zeros */
s = lookup(".dynsym", 0); s = lookup(".dynsym", 0);
s->type = SELFROSECT; s->type = SELFROSECT;
@ -909,7 +893,7 @@ asmb(void)
break; break;
} }
} }
shsym(sh, lookup(".interp", 0)); elfinterp(sh, startva, interpreter);
ph = newElfPhdr(); ph = newElfPhdr();
ph->type = PT_INTERP; ph->type = PT_INTERP;
@ -1088,7 +1072,7 @@ asmb(void)
a += elfwritephdrs(); a += elfwritephdrs();
a += elfwriteshdrs(); a += elfwriteshdrs();
cflush(); cflush();
if(a > ELFRESERVE) if(a+elfwriteinterp() > ELFRESERVE)
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE); diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
break; break;
case Hwindows: case Hwindows:

View File

@ -551,22 +551,6 @@ doelf(void)
elfstr[ElfStrGnuVersion] = addstring(shstrtab, ".gnu.version"); elfstr[ElfStrGnuVersion] = addstring(shstrtab, ".gnu.version");
elfstr[ElfStrGnuVersionR] = addstring(shstrtab, ".gnu.version_r"); elfstr[ElfStrGnuVersionR] = addstring(shstrtab, ".gnu.version_r");
/* interpreter string */
if(interpreter == nil) {
switch(HEADTYPE) {
case Hlinux:
interpreter = linuxdynld;
break;
case Hfreebsd:
interpreter = freebsddynld;
break;
}
}
s = lookup(".interp", 0);
s->type = SELFROSECT;
s->reachable = 1;
addstring(s, interpreter);
/* dynamic symbol table - first entry all zeros */ /* dynamic symbol table - first entry all zeros */
s = lookup(".dynsym", 0); s = lookup(".dynsym", 0);
s->type = SELFROSECT; s->type = SELFROSECT;
@ -964,7 +948,17 @@ asmb(void)
sh->type = SHT_PROGBITS; sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC; sh->flags = SHF_ALLOC;
sh->addralign = 1; sh->addralign = 1;
shsym(sh, lookup(".interp", 0)); if(interpreter == nil) {
switch(HEADTYPE) {
case Hlinux:
interpreter = linuxdynld;
break;
case Hfreebsd:
interpreter = freebsddynld;
break;
}
}
elfinterp(sh, startva, interpreter);
ph = newElfPhdr(); ph = newElfPhdr();
ph->type = PT_INTERP; ph->type = PT_INTERP;
@ -1148,7 +1142,7 @@ asmb(void)
a += elfwritephdrs(); a += elfwritephdrs();
a += elfwriteshdrs(); a += elfwriteshdrs();
cflush(); cflush();
if(a > ELFRESERVE) if(a+elfwriteinterp() > ELFRESERVE)
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE); diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
break; break;

View File

@ -871,7 +871,7 @@ dodata(void)
/* data */ /* data */
sect = addsection(&segdata, ".data", 06); sect = addsection(&segdata, ".data", 06);
sect->vaddr = 0; sect->vaddr = datsize;
for(; s != nil && s->type < SBSS; s = s->next) { for(; s != nil && s->type < SBSS; s = s->next) {
s->type = SDATA; s->type = SDATA;
t = s->size; t = s->size;

View File

@ -19,6 +19,7 @@ static int elf64;
static ElfEhdr hdr; static ElfEhdr hdr;
static ElfPhdr *phdr[NSECT]; static ElfPhdr *phdr[NSECT];
static ElfShdr *shdr[NSECT]; static ElfShdr *shdr[NSECT];
static char *interp;
typedef struct Elfstring Elfstring; typedef struct Elfstring Elfstring;
struct Elfstring struct Elfstring
@ -303,6 +304,32 @@ elfwritedynentsymsize(Sym *s, int tag, Sym *t)
addsize(s, t); addsize(s, t);
} }
int
elfwriteinterp(void)
{
int n;
if(interp == nil)
return 0;
n = strlen(interp)+1;
cseek(ELFRESERVE-n);
cwrite(interp, n);
return n;
}
void
elfinterp(ElfShdr *sh, uint64 startva, char *p)
{
int n;
interp = p;
n = strlen(interp)+1;
sh->addr = startva + ELFRESERVE - n;
sh->off = ELFRESERVE - n;
sh->size = n;
}
extern int nelfsym; extern int nelfsym;
int elfverneed; int elfverneed;