mirror of
https://github.com/golang/go
synced 2024-11-20 05:54:43 -07: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:
parent
821897bc96
commit
b63d40a53e
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user