elfstr[ElfStrRelPlt] = addstring(shstrtab, ".rel.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 */
s = lookup(".dynsym", 0);
s->type = SELFROSECT;
sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC;
sh->addralign = 1;
- shsym(sh, lookup(".interp", 0));
+ if(interpreter == nil)
+ interpreter = linuxdynld;
+ elfinterp(sh, startva, interpreter);
ph = newElfPhdr();
ph->type = PT_INTERP;
a += elfwritephdrs();
a += elfwriteshdrs();
cflush();
- if(a > ELFRESERVE)
+ if(a+elfwriteinterp() > ELFRESERVE)
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
break;
}
elfstr[ElfStrGnuVersion] = addstring(shstrtab, ".gnu.version");
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 */
s = lookup(".dynsym", 0);
s->type = SELFROSECT;
break;
}
}
- shsym(sh, lookup(".interp", 0));
+ elfinterp(sh, startva, interpreter);
ph = newElfPhdr();
ph->type = PT_INTERP;
a += elfwritephdrs();
a += elfwriteshdrs();
cflush();
- if(a > ELFRESERVE)
+ if(a+elfwriteinterp() > ELFRESERVE)
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
break;
case Hwindows:
elfstr[ElfStrGnuVersion] = addstring(shstrtab, ".gnu.version");
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 */
s = lookup(".dynsym", 0);
s->type = SELFROSECT;
sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC;
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->type = PT_INTERP;
a += elfwritephdrs();
a += elfwriteshdrs();
cflush();
- if(a > ELFRESERVE)
+ if(a+elfwriteinterp() > ELFRESERVE)
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
break;
/* data */
sect = addsection(&segdata, ".data", 06);
- sect->vaddr = 0;
+ sect->vaddr = datsize;
for(; s != nil && s->type < SBSS; s = s->next) {
s->type = SDATA;
t = s->size;
static ElfEhdr hdr;
static ElfPhdr *phdr[NSECT];
static ElfShdr *shdr[NSECT];
+static char *interp;
typedef struct Elfstring Elfstring;
struct Elfstring
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;
int elfverneed;