1
0
mirror of https://github.com/golang/go synced 2024-11-26 00:07:57 -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:
Russ Cox 2009-08-20 16:09:38 -07:00
parent 5bd266d1ee
commit bd4161fcba
7 changed files with 48 additions and 14 deletions

View File

@ -128,7 +128,7 @@ asmb(void)
int32 v, magic;
int a, nl;
uchar *op1;
vlong vl, va, startva, fo, w, symo, hashoff;
vlong vl, va, startva, fo, w, symo, hashoff, dstrtab, off;
vlong symdatva = 0x99LL<<32;
Elf64Hdr *eh;
Elf64PHdr *ph, *pph;
@ -431,6 +431,7 @@ asmb(void)
sh = newElf64SHdr("");
pph = nil; /* silence compiler */
dstrtab = 0;
/* Dynamic linking sections */
if (!debug['d']) { /* -d suppresses dynamic loader format */
@ -443,7 +444,7 @@ asmb(void)
pph->off = ELF64HDRSIZE;
pph->vaddr = startva + pph->off;
pph->paddr = startva + pph->off;
pph->align = 8;
pph->align = INITRND;
/* interpreter */
ph = newElf64PHdr();
@ -503,13 +504,19 @@ asmb(void)
sh->addr = startva + sh->off;
sh->off = startelf();
elf64writedynent(DT_HASH, startva+hashoff);
elf64writedynent(DT_STRTAB, startva+ELF64FULLHDRSIZE-STRTABSIZE);
elf64writedynent(DT_SYMTAB, startva);
elf64writedynent(DT_RELA, startva);
elf64writedynent(DT_RELASZ, 0); // size of the whole rela in bytes
elf64writedynent(DT_RELAENT, ELF64RELASIZE);
elf64writedynent(DT_STRSZ, STRTABSIZE);
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);
sh->size = endelf() - sh->off;
sh->addralign = 8;
@ -534,7 +541,7 @@ asmb(void)
ph->paddr = startva + ph->off;
ph->filesz = sh->off + sh->size - ph->off;
ph->memsz = ph->filesz;
ph->align = 8;
ph->align = INITRND;
}
ph = newElf64PHdr();
@ -644,6 +651,17 @@ asmb(void)
elf64writestrtable();
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 */
eh = getElf64Hdr();
eh->ident[EI_MAG0] = '\177';

View File

@ -390,6 +390,7 @@ double cputime(void);
void datblk(int32, int32);
void deadcode(void);
void diag(char*, ...);
void dobss(void);
void dodata(void);
void doinit(void);
void doprof1(void);

View File

@ -390,6 +390,7 @@ main(int argc, char *argv[])
patch();
follow();
dodata();
dobss();
dostkoff();
paramspace = "SP"; /* (FP) now (SP) on output */
if(debug['p'])

View File

@ -124,6 +124,14 @@ dodata(void)
}
datsize += u;
}
}
void
dobss(void)
{
int i;
Sym *s;
int32 t;
/* now the bss */
bsssize = 0;
@ -137,6 +145,7 @@ dodata(void)
s->value = bsssize + datsize;
bsssize += t;
}
xdefine("data", SBSS, 0);
xdefine("edata", SBSS, datsize);
xdefine("end", SBSS, bsssize + datsize);
}

View File

@ -13,7 +13,7 @@ static Elf64Hdr hdr;
static Elf64PHdr *phdr[NSECT];
static Elf64SHdr *shdr[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
@ -80,15 +80,19 @@ elf64writestrtable(void)
diag("elf64 string table overflow");
}
void
e64addstr(char *name)
uint32
elf64addstr(char *name)
{
if (numstr >= NSECT) {
int r;
if (numstr >= nelem(str)) {
diag("too many elf strings");
return;
return 0;
}
str[numstr++] = strdup(name);
r = stroffset;
stroffset += strlen(name)+1;
return r;
}
uint32
@ -135,11 +139,10 @@ newElf64SHdr(char *name)
hdr.shstrndx = hdr.shnum;
e = malloc(sizeof *e);
memset(e, 0, sizeof *e);
e->name = stroffset;
e->name = elf64addstr(name);
if (hdr.shnum >= NSECT) {
diag("too many shdrs");
} else {
e64addstr(name);
shdr[hdr.shnum++] = e;
}
return e;
@ -152,7 +155,7 @@ getElf64Hdr(void)
}
uint32
elf64writehdr()
elf64writehdr(void)
{
int i;

View File

@ -274,6 +274,7 @@ Elf64PHdr *newElf64PHdr();
uint32 elf64writehdr(void);
uint32 elf64writephdrs(void);
uint32 elf64writeshdrs(void);
uint32 elf64addstr(char*);
void elf64writestrtable(void);
void elf64writedynent(int, uint64);
uint32 elf64_hash(uchar*);

View File

@ -19,6 +19,7 @@ enum {
Debug = 0
};
extern byte data[];
extern byte etext[];
extern byte end[];
@ -84,7 +85,7 @@ mark(void)
G *gp;
// mark data+bss
scanblock(0, etext, end - etext);
scanblock(0, data, end - data);
// mark stacks
for(gp=allg; gp!=nil; gp=gp->alllink) {