mirror of
https://github.com/golang/go
synced 2024-11-25 23:58:02 -07:00
FFI step 2: can ask for libc.so.6.
introduced explicit "data" symbol instead of etext to mark beginning of data, so that using larger alignment (i.e. 4MB like GNU loader) doesn't confuse garbage collector. split dodata into dodata and dobss in preparation for putting the dynamic data + headers in the data segment instead of stuffed at the beginning of the binary. R=r DELTA=52 (37 added, 3 deleted, 12 changed) OCL=33610 CL=33618
This commit is contained in:
parent
5bd266d1ee
commit
bd4161fcba
@ -128,7 +128,7 @@ asmb(void)
|
|||||||
int32 v, magic;
|
int32 v, magic;
|
||||||
int a, nl;
|
int a, nl;
|
||||||
uchar *op1;
|
uchar *op1;
|
||||||
vlong vl, va, startva, fo, w, symo, hashoff;
|
vlong vl, va, startva, fo, w, symo, hashoff, dstrtab, off;
|
||||||
vlong symdatva = 0x99LL<<32;
|
vlong symdatva = 0x99LL<<32;
|
||||||
Elf64Hdr *eh;
|
Elf64Hdr *eh;
|
||||||
Elf64PHdr *ph, *pph;
|
Elf64PHdr *ph, *pph;
|
||||||
@ -431,6 +431,7 @@ asmb(void)
|
|||||||
sh = newElf64SHdr("");
|
sh = newElf64SHdr("");
|
||||||
|
|
||||||
pph = nil; /* silence compiler */
|
pph = nil; /* silence compiler */
|
||||||
|
dstrtab = 0;
|
||||||
|
|
||||||
/* Dynamic linking sections */
|
/* Dynamic linking sections */
|
||||||
if (!debug['d']) { /* -d suppresses dynamic loader format */
|
if (!debug['d']) { /* -d suppresses dynamic loader format */
|
||||||
@ -443,7 +444,7 @@ asmb(void)
|
|||||||
pph->off = ELF64HDRSIZE;
|
pph->off = ELF64HDRSIZE;
|
||||||
pph->vaddr = startva + pph->off;
|
pph->vaddr = startva + pph->off;
|
||||||
pph->paddr = startva + pph->off;
|
pph->paddr = startva + pph->off;
|
||||||
pph->align = 8;
|
pph->align = INITRND;
|
||||||
|
|
||||||
/* interpreter */
|
/* interpreter */
|
||||||
ph = newElf64PHdr();
|
ph = newElf64PHdr();
|
||||||
@ -503,13 +504,19 @@ asmb(void)
|
|||||||
sh->addr = startva + sh->off;
|
sh->addr = startva + sh->off;
|
||||||
sh->off = startelf();
|
sh->off = startelf();
|
||||||
elf64writedynent(DT_HASH, startva+hashoff);
|
elf64writedynent(DT_HASH, startva+hashoff);
|
||||||
elf64writedynent(DT_STRTAB, startva+ELF64FULLHDRSIZE-STRTABSIZE);
|
|
||||||
elf64writedynent(DT_SYMTAB, startva);
|
elf64writedynent(DT_SYMTAB, startva);
|
||||||
elf64writedynent(DT_RELA, startva);
|
elf64writedynent(DT_RELA, startva);
|
||||||
elf64writedynent(DT_RELASZ, 0); // size of the whole rela in bytes
|
elf64writedynent(DT_RELASZ, 0); // size of the whole rela in bytes
|
||||||
elf64writedynent(DT_RELAENT, ELF64RELASIZE);
|
elf64writedynent(DT_RELAENT, ELF64RELASIZE);
|
||||||
elf64writedynent(DT_STRSZ, STRTABSIZE);
|
|
||||||
elf64writedynent(DT_SYMENT, 0);
|
elf64writedynent(DT_SYMENT, 0);
|
||||||
|
// elf64writedynent(DT_NEEDED, elf64addstr("libc.so.6"));
|
||||||
|
|
||||||
|
/* make space for these now but fill them in later */
|
||||||
|
cflush();
|
||||||
|
dstrtab = seek(cout, 0, 1);
|
||||||
|
elf64writedynent(DT_STRTAB, -1);
|
||||||
|
elf64writedynent(DT_STRSZ, -1);
|
||||||
|
|
||||||
elf64writedynent(DT_NULL, 0);
|
elf64writedynent(DT_NULL, 0);
|
||||||
sh->size = endelf() - sh->off;
|
sh->size = endelf() - sh->off;
|
||||||
sh->addralign = 8;
|
sh->addralign = 8;
|
||||||
@ -534,7 +541,7 @@ asmb(void)
|
|||||||
ph->paddr = startva + ph->off;
|
ph->paddr = startva + ph->off;
|
||||||
ph->filesz = sh->off + sh->size - ph->off;
|
ph->filesz = sh->off + sh->size - ph->off;
|
||||||
ph->memsz = ph->filesz;
|
ph->memsz = ph->filesz;
|
||||||
ph->align = 8;
|
ph->align = INITRND;
|
||||||
}
|
}
|
||||||
|
|
||||||
ph = newElf64PHdr();
|
ph = newElf64PHdr();
|
||||||
@ -644,6 +651,17 @@ asmb(void)
|
|||||||
elf64writestrtable();
|
elf64writestrtable();
|
||||||
sh->size = endelf() - sh->off;
|
sh->size = endelf() - sh->off;
|
||||||
|
|
||||||
|
if(dstrtab != 0) {
|
||||||
|
// update DT_STRTAB entry
|
||||||
|
cflush();
|
||||||
|
off = seek(cout, 0, 1);
|
||||||
|
seek(cout, dstrtab, 0);
|
||||||
|
elf64writedynent(DT_STRTAB, sh->addr);
|
||||||
|
elf64writedynent(DT_STRSZ, sh->size);
|
||||||
|
cflush();
|
||||||
|
seek(cout, off, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Main header */
|
/* Main header */
|
||||||
eh = getElf64Hdr();
|
eh = getElf64Hdr();
|
||||||
eh->ident[EI_MAG0] = '\177';
|
eh->ident[EI_MAG0] = '\177';
|
||||||
|
@ -390,6 +390,7 @@ double cputime(void);
|
|||||||
void datblk(int32, int32);
|
void datblk(int32, int32);
|
||||||
void deadcode(void);
|
void deadcode(void);
|
||||||
void diag(char*, ...);
|
void diag(char*, ...);
|
||||||
|
void dobss(void);
|
||||||
void dodata(void);
|
void dodata(void);
|
||||||
void doinit(void);
|
void doinit(void);
|
||||||
void doprof1(void);
|
void doprof1(void);
|
||||||
|
@ -390,6 +390,7 @@ main(int argc, char *argv[])
|
|||||||
patch();
|
patch();
|
||||||
follow();
|
follow();
|
||||||
dodata();
|
dodata();
|
||||||
|
dobss();
|
||||||
dostkoff();
|
dostkoff();
|
||||||
paramspace = "SP"; /* (FP) now (SP) on output */
|
paramspace = "SP"; /* (FP) now (SP) on output */
|
||||||
if(debug['p'])
|
if(debug['p'])
|
||||||
|
@ -124,6 +124,14 @@ dodata(void)
|
|||||||
}
|
}
|
||||||
datsize += u;
|
datsize += u;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dobss(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Sym *s;
|
||||||
|
int32 t;
|
||||||
|
|
||||||
/* now the bss */
|
/* now the bss */
|
||||||
bsssize = 0;
|
bsssize = 0;
|
||||||
@ -137,6 +145,7 @@ dodata(void)
|
|||||||
s->value = bsssize + datsize;
|
s->value = bsssize + datsize;
|
||||||
bsssize += t;
|
bsssize += t;
|
||||||
}
|
}
|
||||||
|
xdefine("data", SBSS, 0);
|
||||||
xdefine("edata", SBSS, datsize);
|
xdefine("edata", SBSS, datsize);
|
||||||
xdefine("end", SBSS, bsssize + datsize);
|
xdefine("end", SBSS, bsssize + datsize);
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ static Elf64Hdr hdr;
|
|||||||
static Elf64PHdr *phdr[NSECT];
|
static Elf64PHdr *phdr[NSECT];
|
||||||
static Elf64SHdr *shdr[NSECT];
|
static Elf64SHdr *shdr[NSECT];
|
||||||
static char *sname[NSECT];
|
static char *sname[NSECT];
|
||||||
static char *str[NSECT];
|
static char *str[20];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Initialize the global variable that describes the ELF header. It will be updated as
|
Initialize the global variable that describes the ELF header. It will be updated as
|
||||||
@ -80,15 +80,19 @@ elf64writestrtable(void)
|
|||||||
diag("elf64 string table overflow");
|
diag("elf64 string table overflow");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
uint32
|
||||||
e64addstr(char *name)
|
elf64addstr(char *name)
|
||||||
{
|
{
|
||||||
if (numstr >= NSECT) {
|
int r;
|
||||||
|
|
||||||
|
if (numstr >= nelem(str)) {
|
||||||
diag("too many elf strings");
|
diag("too many elf strings");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
str[numstr++] = strdup(name);
|
str[numstr++] = strdup(name);
|
||||||
|
r = stroffset;
|
||||||
stroffset += strlen(name)+1;
|
stroffset += strlen(name)+1;
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
@ -135,11 +139,10 @@ newElf64SHdr(char *name)
|
|||||||
hdr.shstrndx = hdr.shnum;
|
hdr.shstrndx = hdr.shnum;
|
||||||
e = malloc(sizeof *e);
|
e = malloc(sizeof *e);
|
||||||
memset(e, 0, sizeof *e);
|
memset(e, 0, sizeof *e);
|
||||||
e->name = stroffset;
|
e->name = elf64addstr(name);
|
||||||
if (hdr.shnum >= NSECT) {
|
if (hdr.shnum >= NSECT) {
|
||||||
diag("too many shdrs");
|
diag("too many shdrs");
|
||||||
} else {
|
} else {
|
||||||
e64addstr(name);
|
|
||||||
shdr[hdr.shnum++] = e;
|
shdr[hdr.shnum++] = e;
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
@ -152,7 +155,7 @@ getElf64Hdr(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
elf64writehdr()
|
elf64writehdr(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -274,6 +274,7 @@ Elf64PHdr *newElf64PHdr();
|
|||||||
uint32 elf64writehdr(void);
|
uint32 elf64writehdr(void);
|
||||||
uint32 elf64writephdrs(void);
|
uint32 elf64writephdrs(void);
|
||||||
uint32 elf64writeshdrs(void);
|
uint32 elf64writeshdrs(void);
|
||||||
|
uint32 elf64addstr(char*);
|
||||||
void elf64writestrtable(void);
|
void elf64writestrtable(void);
|
||||||
void elf64writedynent(int, uint64);
|
void elf64writedynent(int, uint64);
|
||||||
uint32 elf64_hash(uchar*);
|
uint32 elf64_hash(uchar*);
|
||||||
|
@ -19,6 +19,7 @@ enum {
|
|||||||
Debug = 0
|
Debug = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern byte data[];
|
||||||
extern byte etext[];
|
extern byte etext[];
|
||||||
extern byte end[];
|
extern byte end[];
|
||||||
|
|
||||||
@ -84,7 +85,7 @@ mark(void)
|
|||||||
G *gp;
|
G *gp;
|
||||||
|
|
||||||
// mark data+bss
|
// mark data+bss
|
||||||
scanblock(0, etext, end - etext);
|
scanblock(0, data, end - data);
|
||||||
|
|
||||||
// mark stacks
|
// mark stacks
|
||||||
for(gp=allg; gp!=nil; gp=gp->alllink) {
|
for(gp=allg; gp!=nil; gp=gp->alllink) {
|
||||||
|
Loading…
Reference in New Issue
Block a user