summaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-11-18 13:51:05 -0800
committerRuss Cox <rsc@golang.org>2009-11-18 13:51:05 -0800
commitc0153e764ab8d53abed51087988140a797e168f0 (patch)
tree8727eaf3e5e42d7a9e34c07b88e86694c8706d2e /src/cmd
parent6d311ea60e06920efe0301e123ddf409e0254ffa (diff)
downloadgolang-c0153e764ab8d53abed51087988140a797e168f0.tar.gz
ld: move interpreter string into first block of ELF file
necessary on freebsd. R=r, dho CC=golang-dev http://codereview.appspot.com/157069
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/6l/asm.c25
-rw-r--r--src/cmd/8l/asm.c22
-rw-r--r--src/cmd/ld/elf.c27
-rw-r--r--src/cmd/ld/elf.h5
4 files changed, 51 insertions, 28 deletions
diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c
index 3679e5cf4..4f7f6e22f 100644
--- a/src/cmd/6l/asm.c
+++ b/src/cmd/6l/asm.c
@@ -315,19 +315,6 @@ doelf(void)
elfstr[ElfStrDynstr] = addstring(shstrtab, ".dynstr");
elfstr[ElfStrRela] = addstring(shstrtab, ".rela");
- /* interpreter string */
- s = lookup(".interp", 0);
- s->reachable = 1;
- s->type = SDATA; // TODO: rodata
- switch(HEADTYPE) {
- case 7:
- addstring(lookup(".interp", 0), linuxdynld);
- break;
- case 9:
- addstring(lookup(".interp", 0), freebsddynld);
- break;
- }
-
/*
* hash table.
* only entries that other objects need to find when
@@ -688,7 +675,14 @@ asmb(void)
sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC;
sh->addralign = 1;
- shsym(sh, lookup(".interp", 0));
+ switch(HEADTYPE) {
+ case 7:
+ elfinterp(sh, startva, linuxdynld);
+ break;
+ case 9:
+ elfinterp(sh, startva, freebsddynld);
+ break;
+ }
ph = newElfPhdr();
ph->type = PT_INTERP;
@@ -903,7 +897,8 @@ asmb(void)
a += elfwritehdr();
a += elfwritephdrs();
a += elfwriteshdrs();
- if (a > ELFRESERVE)
+ cflush();
+ if(a+elfwriteinterp() > ELFRESERVE)
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
break;
}
diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c
index e496672e5..689ba12d9 100644
--- a/src/cmd/8l/asm.c
+++ b/src/cmd/8l/asm.c
@@ -304,14 +304,6 @@ doelf(void)
s = lookup(".interp", 0);
s->reachable = 1;
s->type = SDATA; // TODO: rodata
- switch(HEADTYPE) {
- case 7:
- addstring(lookup(".interp", 0), linuxdynld);
- break;
- case 9:
- addstring(lookup(".interp", 0), freebsddynld);
- break;
- }
/*
* hash table - empty for now.
@@ -794,7 +786,14 @@ asmb(void)
sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC;
sh->addralign = 1;
- shsym(sh, lookup(".interp", 0));
+ switch(HEADTYPE) {
+ case 7:
+ elfinterp(sh, startva, linuxdynld);
+ break;
+ case 9:
+ elfinterp(sh, startva, freebsddynld);
+ break;
+ }
ph = newElfPhdr();
ph->type = PT_INTERP;
@@ -1012,10 +1011,9 @@ asmb(void)
a += elfwritehdr();
a += elfwritephdrs();
a += elfwriteshdrs();
- if (a > ELFRESERVE) {
- diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
- }
cflush();
+ if(a+elfwriteinterp() > ELFRESERVE)
+ diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
break;
}
cflush();
diff --git a/src/cmd/ld/elf.c b/src/cmd/ld/elf.c
index f4809e07c..c57630e80 100644
--- a/src/cmd/ld/elf.c
+++ b/src/cmd/ld/elf.c
@@ -17,6 +17,7 @@ static int elf64;
static ElfEhdr hdr;
static ElfPhdr *phdr[NSECT];
static ElfShdr *shdr[NSECT];
+static char *interp;
/*
Initialize the global variable that describes the ELF header. It will be updated as
@@ -278,3 +279,29 @@ elfwritedynentsymsize(Sym *s, int tag, Sym *t)
adduint32(s, tag);
addsize(s, t);
}
+
+int
+elfwriteinterp(void)
+{
+ int n;
+
+ if(interp == nil)
+ return 0;
+
+ n = strlen(interp)+1;
+ seek(cout, ELFRESERVE-n, 0);
+ write(cout, 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;
+}
diff --git a/src/cmd/ld/elf.h b/src/cmd/ld/elf.h
index e0c2bd1b6..9f18ec3dd 100644
--- a/src/cmd/ld/elf.h
+++ b/src/cmd/ld/elf.h
@@ -961,11 +961,14 @@ uint64 startelf(void);
uint64 endelf(void);
extern int numelfphdr;
extern int numelfshdr;
+int elfwriteinterp(void);
+void elfinterp(ElfShdr*, uint64, char*);
/*
* Total amount of space to reserve at the start of the file
- * for Header, PHeaders, and SHeaders.
+ * for Header, PHeaders, SHeaders, and interp.
* May waste some.
+ * On FreeBSD, cannot be larger than a page.
*/
#define ELFRESERVE 2048