1
0
mirror of https://github.com/golang/go synced 2024-10-03 08:21:21 -06:00

count SHdrs and PHdrs and write them out as a unit

R=rsc
DELTA=181  (93 added, 63 deleted, 25 changed)
OCL=31802
CL=31812
This commit is contained in:
Rob Pike 2009-07-17 16:34:58 -07:00
parent 821897bc96
commit b63d40a53e
3 changed files with 115 additions and 85 deletions

View File

@ -122,16 +122,13 @@ asmb(void)
{ {
Prog *p; Prog *p;
int32 v, magic; int32 v, magic;
int a, nl, np; int a, nl;
uchar *op1; uchar *op1;
vlong vl, va, fo, w, symo; vlong vl, va, fo, w, symo;
int strtabsize;
vlong symdatva = 0x99LL<<32; vlong symdatva = 0x99LL<<32;
Elf64PHdr *ph; Elf64PHdr *ph;
Elf64SHdr *sh; Elf64SHdr *sh;
strtabsize = 0;
if(debug['v']) if(debug['v'])
Bprint(&bso, "%5.2f asmb\n", cputime()); Bprint(&bso, "%5.2f asmb\n", cputime());
Bflush(&bso); Bflush(&bso);
@ -196,9 +193,6 @@ asmb(void)
case 7: case 7:
debug['8'] = 1; /* 64-bit addresses */ debug['8'] = 1; /* 64-bit addresses */
seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0);
strtabsize = elf64strtable();
cflush();
v = rnd(HEADR+textsize, INITRND); v = rnd(HEADR+textsize, INITRND);
seek(cout, v, 0); seek(cout, v, 0);
break; break;
@ -241,7 +235,7 @@ asmb(void)
symo = rnd(HEADR+textsize, INITRND)+rnd(datsize, INITRND); symo = rnd(HEADR+textsize, INITRND)+rnd(datsize, INITRND);
break; break;
case 7: case 7:
symo = rnd(HEADR+textsize, INITRND)+datsize+strtabsize; symo = rnd(HEADR+textsize, INITRND)+datsize+STRTABSIZE;
symo = rnd(symo, INITRND); symo = rnd(symo, INITRND);
break; break;
} }
@ -421,31 +415,6 @@ asmb(void)
break; break;
case 7: case 7:
/* elf amd-64 */ /* elf amd-64 */
strnput("\177ELF", 4); /* e_ident */
cput(2); /* class = 64 bit */
cput(1); /* data = LSB */
cput(1); /* version = CURRENT */
strnput("", 9);
wputl(2); /* type = EXEC */
wputl(62); /* machine = AMD64 */
lputl(1L); /* version = CURRENT */
vputl(entryvalue()); /* entry vaddr */
vputl(64L); /* offset to first phdr */
np = 3;
if(!debug['s'])
np++;
vputl(64L+56*np); /* offset to first shdr */
lputl(0L); /* processor specific flags */
wputl(64); /* Ehdr size */
wputl(56); /* Phdr size */
wputl(np); /* # of Phdrs */
wputl(64); /* Shdr size */
if (!debug['s'])
wputl(7); /* # of Shdrs */
else
wputl(5); /* # of Shdrs */
wputl(4); /* Shdr with strings */
fo = 0; fo = 0;
va = INITTEXT & ~((vlong)INITRND - 1); va = INITTEXT & ~((vlong)INITRND - 1);
@ -459,7 +428,6 @@ asmb(void)
ph->filesz = w; ph->filesz = w;
ph->memsz = w; ph->memsz = w;
ph->align = INITRND; ph->align = INITRND;
elf64phdr(ph);
fo = rnd(fo+w, INITRND); fo = rnd(fo+w, INITRND);
va = rnd(va+w, INITRND); va = rnd(va+w, INITRND);
@ -474,7 +442,6 @@ asmb(void)
ph->filesz = w; ph->filesz = w;
ph->memsz = w+bsssize; ph->memsz = w+bsssize;
ph->align = INITRND; ph->align = INITRND;
elf64phdr(ph);
if(!debug['s']) { if(!debug['s']) {
ph = newElf64PHdr(); ph = newElf64PHdr();
@ -486,66 +453,59 @@ asmb(void)
ph->filesz = 8+symsize+lcsize; ph->filesz = 8+symsize+lcsize;
ph->memsz = 8+symsize+lcsize; ph->memsz = 8+symsize+lcsize;
ph->align = INITRND; ph->align = INITRND;
elf64phdr(ph);
} }
ph = newElf64PHdr(); ph = newElf64PHdr();
ph->type = 0x6474e551; /* gok */ ph->type = 0x6474e551; /* gok */
ph->flags = PF_X+PF_W+PF_R; ph->flags = PF_X+PF_W+PF_R;
ph->align = 8; ph->align = 8;
elf64phdr(ph);
sh = newElf64SHdr(); sh = newElf64SHdr("");
elf64shdr(nil, sh);
stroffset = 1; /* 0 means no name, so start at 1 */ stroffset = 1; /* 0 means no name, so start at 1 */
fo = HEADR; fo = HEADR;
va = (INITTEXT & ~((vlong)INITRND - 1)) + HEADR; va = (INITTEXT & ~((vlong)INITRND - 1)) + HEADR;
w = textsize; w = textsize;
sh = newElf64SHdr(); sh = newElf64SHdr(".text");
sh->type = SHT_PROGBITS; sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC+SHF_EXECINSTR; sh->flags = SHF_ALLOC+SHF_EXECINSTR;
sh->addr = va; sh->addr = va;
sh->off = fo; sh->off = fo;
sh->size = w; sh->size = w;
sh->addralign = 8; sh->addralign = 8;
elf64shdr(".text", sh);
fo = rnd(fo+w, INITRND); fo = rnd(fo+w, INITRND);
va = rnd(va+w, INITRND); va = rnd(va+w, INITRND);
w = datsize; w = datsize;
sh = newElf64SHdr(); sh = newElf64SHdr(".data");
sh->type = SHT_PROGBITS; sh->type = SHT_PROGBITS;
sh->flags = SHF_WRITE+SHF_ALLOC; sh->flags = SHF_WRITE+SHF_ALLOC;
sh->addr = va; sh->addr = va;
sh->off = fo; sh->off = fo;
sh->size = w; sh->size = w;
sh->addralign = 8; sh->addralign = 8;
elf64shdr(".data", sh);
fo += w; fo += w;
va += w; va += w;
w = bsssize; w = bsssize;
sh = newElf64SHdr(); sh = newElf64SHdr(".bss");
sh->type = SHT_NOBITS; sh->type = SHT_NOBITS;
sh->flags = SHF_WRITE+SHF_ALLOC; sh->flags = SHF_WRITE+SHF_ALLOC;
sh->addr = va; sh->addr = va;
sh->off = fo; sh->off = fo;
sh->size = w; sh->size = w;
sh->addralign = 8; sh->addralign = 8;
elf64shdr(".bss", sh);
w = strtabsize; w = STRTABSIZE;
sh = newElf64SHdr(); sh = newElf64SHdr(".shstrtab");
sh->type = SHT_STRTAB; sh->type = SHT_STRTAB;
sh->off = fo; sh->off = fo;
sh->size = w; sh->size = w;
sh->addralign = 1; sh->addralign = 1;
elf64shdr(".shstrtab", sh);
if (debug['s']) if (debug['s'])
break; break;
@ -553,24 +513,52 @@ asmb(void)
fo = symo+8; fo = symo+8;
w = symsize; w = symsize;
sh = newElf64SHdr(); sh = newElf64SHdr(".gosymtab");
sh->type = SHT_PROGBITS; sh->type = SHT_PROGBITS;
sh->off = fo; sh->off = fo;
sh->size = w; sh->size = w;
sh->addralign = 1; sh->addralign = 1;
sh->entsize = 24; sh->entsize = 24;
elf64shdr(".gosymtab", sh);
fo += w; fo += w;
w = lcsize; w = lcsize;
sh = newElf64SHdr(); sh = newElf64SHdr(".gopclntab");
sh->type = SHT_PROGBITS; sh->type = SHT_PROGBITS;
sh->off = fo; sh->off = fo;
sh->size = w; sh->size = w;
sh->addralign = 1; sh->addralign = 1;
sh->entsize = 24; sh->entsize = 24;
elf64shdr(".gopclntab", sh);
// write out the main header */
strnput("\177ELF", 4); /* e_ident */
cput(2); /* class = 64 bit */
cput(1); /* data = LSB */
cput(1); /* version = CURRENT */
strnput("", 9);
wputl(2); /* type = EXEC */
wputl(62); /* machine = AMD64 */
lputl(1L); /* version = CURRENT */
vputl(entryvalue()); /* entry vaddr */
vputl(64L); /* offset to first phdr */
vputl(64L+56*nume64phdr); /* offset to first shdr */
lputl(0L); /* processor specific flags */
wputl(64); /* Ehdr size */
wputl(56); /* Phdr size */
wputl(nume64phdr); /* # of Phdrs */
wputl(64); /* Shdr size */
wputl(nume64shdr); /* # of Shdrs */
wputl(4); /* Shdr with strings */
elf64writephdrs();
elf64writeshdrs();
cflush();
/* string table */
seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0);
elf64writestrtable();
cflush();
break; break;
} }

View File

@ -6,6 +6,15 @@
#include "../ld/elf64.h" #include "../ld/elf64.h"
#define NSECT 16
int nume64phdr;
int nume64shdr;
int nume64str;
static Elf64PHdr *phdr[NSECT];
static Elf64SHdr *shdr[NSECT];
static char *sname[NSECT];
static char *str[NSECT];
void void
elf64phdr(Elf64PHdr *e) elf64phdr(Elf64PHdr *e)
{ {
@ -32,9 +41,6 @@ elf64shdr(char *name, Elf64SHdr *e)
lputl(e->info); lputl(e->info);
vputl(e->addralign); vputl(e->addralign);
vputl(e->entsize); vputl(e->entsize);
if(name != nil)
stroffset += strlen(name)+1;
} }
int int
@ -47,25 +53,29 @@ putelf64strtab(char* name)
return w; return w;
} }
void
int elf64writestrtable(void)
elf64strtable(void)
{ {
int i;
int size; int size;
size = 0; size = 0;
size += putelf64strtab(""); for (i = 0; i < nume64str; i++)
size += putelf64strtab(".text"); size += putelf64strtab(str[i]);
size += putelf64strtab(".data"); if (size > STRTABSIZE)
size += putelf64strtab(".bss"); diag("elf64 string table overflow");
size += putelf64strtab(".shstrtab");
if (!debug['s']) {
size += putelf64strtab(".gosymtab");
size += putelf64strtab(".gopclntab");
}
return size;
} }
void
e64addstr(char *name)
{
if (nume64str >= NSECT) {
diag("too many elf strings");
return;
}
str[nume64str++] = strdup(name);
stroffset += strlen(name)+1;
}
uint32 uint32
elf64headr(void) elf64headr(void)
@ -74,6 +84,7 @@ elf64headr(void)
a = 64; /* a.out header */ a = 64; /* a.out header */
/* TODO: calculate these byte counts properly */
a += 56; /* page zero seg */ a += 56; /* page zero seg */
a += 56; /* text seg */ a += 56; /* text seg */
a += 56; /* stack seg */ a += 56; /* stack seg */
@ -92,25 +103,51 @@ elf64headr(void)
return a; return a;
} }
void
elf64writeshdrs(void)
{
int i;
for (i = 0; i < nume64shdr; i++)
elf64shdr(sname[i], shdr[i]);
}
void
elf64writephdrs(void)
{
int i;
for (i = 0; i < nume64phdr; i++)
elf64phdr(phdr[i]);
}
Elf64PHdr*
newElf64PHdr(void)
{
Elf64PHdr *e;
e = malloc(sizeof *e);
memset(e, 0, sizeof *e);
if (nume64phdr >= NSECT)
diag("too many phdrs");
else
phdr[nume64phdr++] = e;
return e;
}
Elf64SHdr* Elf64SHdr*
newElf64SHdr() newElf64SHdr(char *name)
{ {
Elf64SHdr *e; Elf64SHdr *e;
e = malloc(sizeof *e); e = malloc(sizeof *e);
memset(e, 0, sizeof *e); memset(e, 0, sizeof *e);
e->name = stroffset; e->name = stroffset;
if (nume64shdr >= NSECT) {
diag("too many shdrs");
} else {
e64addstr(name);
shdr[nume64shdr++] = e;
}
return e; return e;
} }
Elf64PHdr*
newElf64PHdr()
{
Elf64PHdr *e;
e = malloc(sizeof *e);
memset(e, 0, sizeof *e);
return e;
}

View File

@ -132,9 +132,14 @@ struct Elf64SHdr
#define SHF_MASKOS 0x0F000000 /* Environment-specific use */ #define SHF_MASKOS 0x0F000000 /* Environment-specific use */
#define SHF_MASKPROC 0xF0000000 /* Processor-specific use */ #define SHF_MASKPROC 0xF0000000 /* Processor-specific use */
Elf64SHdr *newElf64SHdr(); Elf64SHdr *newElf64SHdr(char*);
Elf64PHdr *newElf64PHdr(); Elf64PHdr *newElf64PHdr();
uint32 elf64headr(void); uint32 elf64headr(void);
void elf64phdr(Elf64PHdr*); void elf64writephdrs(void);
void elf64shdr(char*, Elf64SHdr*); void elf64writeshdrs(void);
int elf64strtable(void); void elf64writestrtable(void);
extern int nume64phdr;
extern int nume64shdr;
#define STRTABSIZE 256