diff options
author | Russ Cox <rsc@golang.org> | 2009-09-24 12:53:35 -0700 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2009-09-24 12:53:35 -0700 |
commit | 5599b7bebffa3a5e22d3d8727ea1ea2b5888665d (patch) | |
tree | b7d237241100cfb25e209b5c6f85a833d9543fb9 /src/cmd | |
parent | caa629b7c2fd518a6e813c01cb2c6a31b03824d6 (diff) | |
download | golang-5599b7bebffa3a5e22d3d8727ea1ea2b5888665d.tar.gz |
convert 8l to new ELF code.
mostly cut and paste from 6l.
R=r
DELTA=930 (525 added, 182 deleted, 223 changed)
OCL=34976
CL=34976
Diffstat (limited to 'src/cmd')
-rw-r--r-- | src/cmd/6l/asm.c | 125 | ||||
-rw-r--r-- | src/cmd/8l/8.out.h | 1 | ||||
-rw-r--r-- | src/cmd/8l/Makefile | 3 | ||||
-rw-r--r-- | src/cmd/8l/asm.c | 769 | ||||
-rw-r--r-- | src/cmd/8l/l.h | 20 | ||||
-rw-r--r-- | src/cmd/8l/obj.c | 6 | ||||
-rw-r--r-- | src/cmd/8l/pass.c | 8 | ||||
-rw-r--r-- | src/cmd/8l/span.c | 12 | ||||
-rw-r--r-- | src/cmd/ld/elf.c | 124 | ||||
-rw-r--r-- | src/cmd/ld/elf.h | 33 |
10 files changed, 722 insertions, 379 deletions
diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c index 87d3b19b4..48a7bae4e 100644 --- a/src/cmd/6l/asm.c +++ b/src/cmd/6l/asm.c @@ -399,7 +399,7 @@ doelf(void) } void -shsym(Elf64_Shdr *sh, Sym *s) +shsym(ElfShdr *sh, Sym *s) { sh->addr = symaddr(s); sh->off = datoff(sh->addr); @@ -407,7 +407,7 @@ shsym(Elf64_Shdr *sh, Sym *s) } void -phsh(Elf64_Phdr *ph, Elf64_Shdr *sh) +phsh(ElfPhdr *ph, ElfShdr *sh) { ph->vaddr = sh->addr; ph->paddr = ph->vaddr; @@ -426,9 +426,9 @@ asmb(void) uchar *op1; vlong vl, va, startva, fo, w, symo; vlong symdatva = 0x99LL<<32; - Elf64_Ehdr *eh; - Elf64_Phdr *ph, *pph; - Elf64_Shdr *sh; + ElfEhdr *eh; + ElfPhdr *ph, *pph; + ElfShdr *sh; if(debug['v']) Bprint(&bso, "%5.2f asmb\n", cputime()); @@ -600,53 +600,6 @@ asmb(void) lputb(spsize); /* sp offsets */ lputb(lcsize); /* line offsets */ break; - case 5: - strnput("\177ELF", 4); /* e_ident */ - cput(1); /* class = 32 bit */ - cput(1); /* data = LSB */ - cput(1); /* version = CURRENT */ - strnput("", 9); - wputl(2); /* type = EXEC */ - wputl(62); /* machine = AMD64 */ - lputl(1L); /* version = CURRENT */ - lputl(PADDR(entryvalue())); /* entry vaddr */ - lputl(52L); /* offset to first phdr */ - lputl(0L); /* offset to first shdr */ - lputl(0L); /* processor specific flags */ - wputl(52); /* Ehdr size */ - wputl(32); /* Phdr size */ - wputl(3); /* # of Phdrs */ - wputl(40); /* Shdr size */ - wputl(0); /* # of Shdrs */ - wputl(0); /* Shdr string size */ - - lputl(1L); /* text - type = PT_LOAD */ - lputl(HEADR); /* file offset */ - lputl(INITTEXT); /* vaddr */ - lputl(PADDR(INITTEXT)); /* paddr */ - lputl(textsize); /* file size */ - lputl(textsize); /* memory size */ - lputl(0x05L); /* protections = RX */ - lputl(INITRND); /* alignment */ - - lputl(1L); /* data - type = PT_LOAD */ - lputl(HEADR+textsize); /* file offset */ - lputl(INITDAT); /* vaddr */ - lputl(PADDR(INITDAT)); /* paddr */ - lputl(datsize); /* file size */ - lputl(datsize+bsssize); /* memory size */ - lputl(0x06L); /* protections = RW */ - lputl(INITRND); /* alignment */ - - lputl(0L); /* data - type = PT_NULL */ - lputl(HEADR+textsize+datsize); /* file offset */ - lputl(0L); - lputl(0L); - lputl(symsize); /* symbol table size */ - lputl(lcsize); /* line number size */ - lputl(0x04L); /* protections = R */ - lputl(0x04L); /* alignment */ - break; case 6: /* apple MACH */ va = 4096; @@ -717,44 +670,44 @@ asmb(void) case 7: /* elf amd-64 */ - eh = getElf64_Ehdr(); - fo = 0; + eh = getElfEhdr(); + fo = HEADR; startva = INITTEXT - HEADR; - va = startva; - w = HEADR+textsize; + va = startva + fo; + w = textsize; /* This null SHdr must appear before all others */ - sh = newElf64_Shdr(elfstr[ElfStrEmpty]); + sh = newElfShdr(elfstr[ElfStrEmpty]); /* program header info */ - pph = newElf64_Phdr(); + pph = newElfPhdr(); pph->type = PT_PHDR; pph->flags = PF_R + PF_X; pph->off = eh->ehsize; - pph->vaddr = startva + pph->off; - pph->paddr = startva + pph->off; + pph->vaddr = INITTEXT - HEADR + pph->off; + pph->paddr = INITTEXT - HEADR + pph->off; pph->align = INITRND; if(!debug['d']) { /* interpreter */ - sh = newElf64_Shdr(elfstr[ElfStrInterp]); + sh = newElfShdr(elfstr[ElfStrInterp]); sh->type = SHT_PROGBITS; sh->flags = SHF_ALLOC; sh->addralign = 1; shsym(sh, lookup(".interp", 0)); - ph = newElf64_Phdr(); + ph = newElfPhdr(); ph->type = PT_INTERP; ph->flags = PF_R; phsh(ph, sh); } - ph = newElf64_Phdr(); + ph = newElfPhdr(); ph->type = PT_LOAD; ph->flags = PF_X+PF_R; ph->vaddr = va; ph->paddr = va; - ph->off = 0; + ph->off = fo; ph->filesz = w; ph->memsz = w; ph->align = INITRND; @@ -763,7 +716,7 @@ asmb(void) va = rnd(va+w, INITRND); w = datsize; - ph = newElf64_Phdr(); + ph = newElfPhdr(); ph->type = PT_LOAD; ph->flags = PF_W+PF_R; ph->off = fo; @@ -774,7 +727,7 @@ asmb(void) ph->align = INITRND; if(!debug['s']) { - ph = newElf64_Phdr(); + ph = newElfPhdr(); ph->type = PT_LOAD; ph->flags = PF_W+PF_R; ph->off = symo; @@ -788,14 +741,14 @@ asmb(void) /* Dynamic linking sections */ if (!debug['d']) { /* -d suppresses dynamic loader format */ /* S headers for dynamic linking */ - sh = newElf64_Shdr(elfstr[ElfStrGot]); + sh = newElfShdr(elfstr[ElfStrGot]); sh->type = SHT_PROGBITS; sh->flags = SHF_ALLOC+SHF_WRITE; sh->entsize = 8; sh->addralign = 8; shsym(sh, lookup(".got", 0)); - sh = newElf64_Shdr(elfstr[ElfStrGotPlt]); + sh = newElfShdr(elfstr[ElfStrGotPlt]); sh->type = SHT_PROGBITS; sh->flags = SHF_ALLOC+SHF_WRITE; sh->entsize = 8; @@ -803,7 +756,7 @@ asmb(void) shsym(sh, lookup(".got.plt", 0)); dynsym = eh->shnum; - sh = newElf64_Shdr(elfstr[ElfStrDynsym]); + sh = newElfShdr(elfstr[ElfStrDynsym]); sh->type = SHT_DYNSYM; sh->flags = SHF_ALLOC; sh->entsize = ELF64SYMSIZE; @@ -812,13 +765,13 @@ asmb(void) // sh->info = index of first non-local symbol (number of local symbols) shsym(sh, lookup(".dynsym", 0)); - sh = newElf64_Shdr(elfstr[ElfStrDynstr]); + sh = newElfShdr(elfstr[ElfStrDynstr]); sh->type = SHT_STRTAB; sh->flags = SHF_ALLOC; sh->addralign = 1; shsym(sh, lookup(".dynstr", 0)); - sh = newElf64_Shdr(elfstr[ElfStrHash]); + sh = newElfShdr(elfstr[ElfStrHash]); sh->type = SHT_HASH; sh->flags = SHF_ALLOC; sh->entsize = 4; @@ -826,7 +779,7 @@ asmb(void) sh->link = dynsym; shsym(sh, lookup(".hash", 0)); - sh = newElf64_Shdr(elfstr[ElfStrRela]); + sh = newElfShdr(elfstr[ElfStrRela]); sh->type = SHT_RELA; sh->flags = SHF_ALLOC; sh->entsize = ELF64RELASIZE; @@ -835,21 +788,21 @@ asmb(void) shsym(sh, lookup(".rela", 0)); /* sh and PT_DYNAMIC for .dynamic section */ - sh = newElf64_Shdr(elfstr[ElfStrDynamic]); + sh = newElfShdr(elfstr[ElfStrDynamic]); sh->type = SHT_DYNAMIC; sh->flags = SHF_ALLOC+SHF_WRITE; sh->entsize = 16; sh->addralign = 8; sh->link = dynsym+1; // dynstr shsym(sh, lookup(".dynamic", 0)); - ph = newElf64_Phdr(); + ph = newElfPhdr(); ph->type = PT_DYNAMIC; ph->flags = PF_R + PF_W; phsh(ph, sh); } - ph = newElf64_Phdr(); - ph->type = 0x6474e551; /* GNU_STACK */ + ph = newElfPhdr(); + ph->type = PT_GNU_STACK; ph->flags = PF_W+PF_R; ph->align = 8; @@ -857,7 +810,7 @@ asmb(void) va = startva + fo; w = textsize; - sh = newElf64_Shdr(elfstr[ElfStrText]); + sh = newElfShdr(elfstr[ElfStrText]); sh->type = SHT_PROGBITS; sh->flags = SHF_ALLOC+SHF_EXECINSTR; sh->addr = va; @@ -869,7 +822,7 @@ asmb(void) va = rnd(va+w, INITRND); w = datsize; - sh = newElf64_Shdr(elfstr[ElfStrData]); + sh = newElfShdr(elfstr[ElfStrData]); sh->type = SHT_PROGBITS; sh->flags = SHF_WRITE+SHF_ALLOC; sh->addr = va; @@ -881,7 +834,7 @@ asmb(void) va += w; w = bsssize; - sh = newElf64_Shdr(elfstr[ElfStrBss]); + sh = newElfShdr(elfstr[ElfStrBss]); sh->type = SHT_NOBITS; sh->flags = SHF_WRITE+SHF_ALLOC; sh->addr = va; @@ -893,7 +846,7 @@ asmb(void) fo = symo+8; w = symsize; - sh = newElf64_Shdr(elfstr[ElfStrGosymtab]); + sh = newElfShdr(elfstr[ElfStrGosymtab]); sh->type = SHT_PROGBITS; sh->off = fo; sh->size = w; @@ -902,14 +855,14 @@ asmb(void) fo += w; w = lcsize; - sh = newElf64_Shdr(elfstr[ElfStrGopclntab]); + sh = newElfShdr(elfstr[ElfStrGopclntab]); sh->type = SHT_PROGBITS; sh->off = fo; sh->size = w; sh->addralign = 1; } - sh = newElf64_Shstrtab(elfstr[ElfStrShstrtab]); + sh = newElfShstrtab(elfstr[ElfStrShstrtab]); sh->type = SHT_STRTAB; sh->addralign = 1; shsym(sh, lookup(".shstrtab", 0)); @@ -924,7 +877,7 @@ asmb(void) eh->ident[EI_VERSION] = EV_CURRENT; eh->type = ET_EXEC; - eh->machine = 62; /* machine = AMD64 */ + eh->machine = EM_X86_64; eh->version = EV_CURRENT; eh->entry = entryvalue(); @@ -933,9 +886,9 @@ asmb(void) seek(cout, 0, 0); a = 0; - a += elf64writehdr(); - a += elf64writephdrs(); - a += elf64writeshdrs(); + a += elfwritehdr(); + a += elfwritephdrs(); + a += elfwriteshdrs(); if (a > ELFRESERVE) { diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE); } diff --git a/src/cmd/8l/8.out.h b/src/cmd/8l/8.out.h index c47439843..e9554fa4f 100644 --- a/src/cmd/8l/8.out.h +++ b/src/cmd/8l/8.out.h @@ -450,6 +450,7 @@ enum D_INDIR, /* additive */ D_CONST2 = D_INDIR+D_INDIR, + D_SIZE, /* 8l internal */ T_TYPE = 1<<0, T_INDEX = 1<<1, diff --git a/src/cmd/8l/Makefile b/src/cmd/8l/Makefile index 27004bb83..21b589b13 100644 --- a/src/cmd/8l/Makefile +++ b/src/cmd/8l/Makefile @@ -10,6 +10,7 @@ TARG=\ OFILES=\ asm.$O\ compat.$O\ + elf.$O\ enam.$O\ list.$O\ obj.$O\ @@ -21,6 +22,7 @@ OFILES=\ HFILES=\ l.h\ ../8l/8.out.h\ + ../ld/elf.h\ $(TARG): $(OFILES) @@ -38,3 +40,4 @@ install: $(TARG) cp $(TARG) $(GOBIN)/$(TARG) go.o: ../ld/go.c +elf.o: ../ld/elf.c diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c index 766349d18..f5a73884d 100644 --- a/src/cmd/8l/asm.c +++ b/src/cmd/8l/asm.c @@ -29,9 +29,12 @@ // THE SOFTWARE. #include "l.h" +#include "../ld/elf.h" #define Dbufslop 100 +char linuxdynld[] = "/lib/ld-linux.so.2"; + uint32 symdatva = 0x99<<24; uint32 stroffset; uint32 strtabsize; @@ -124,15 +127,315 @@ strnput(char *s, int n) } } +vlong +addstring(Sym *s, char *str) +{ + int n, m; + vlong r; + Prog *p; + + if(s->type == 0) + s->type = SDATA; + s->reachable = 1; + r = s->value; + n = strlen(str)+1; + while(n > 0) { + m = n; + if(m > sizeof(p->to.scon)) + m = sizeof(p->to.scon); + p = newdata(s, s->value, m, D_EXTERN); + p->to.type = D_SCONST; + memmove(p->to.scon, str, m); + s->value += m; + str += m; + n -= m; + } + return r; +} + +vlong +adduintxx(Sym *s, uint64 v, int wid) +{ + vlong r; + Prog *p; + + if(s->type == 0) + s->type = SDATA; + s->reachable = 1; + r = s->value; + p = newdata(s, s->value, wid, D_EXTERN); + s->value += wid; + p->to.type = D_CONST; + p->to.offset = v; + return r; +} + +vlong +adduint8(Sym *s, uint8 v) +{ + return adduintxx(s, v, 1); +} + +vlong +adduint16(Sym *s, uint16 v) +{ + return adduintxx(s, v, 2); +} + +vlong +adduint32(Sym *s, uint32 v) +{ + return adduintxx(s, v, 4); +} + +vlong +adduint64(Sym *s, uint64 v) +{ + return adduintxx(s, v, 8); +} + +vlong +addaddr(Sym *s, Sym *t) +{ + vlong r; + Prog *p; + enum { Ptrsize = 4 }; + + if(s->type == 0) + s->type = SDATA; + s->reachable = 1; + r = s->value; + p = newdata(s, s->value, Ptrsize, D_EXTERN); + s->value += Ptrsize; + p->to.type = D_ADDR; + p->to.index = D_EXTERN; + p->to.offset = 0; + p->to.sym = t; + return r; +} + +vlong +addsize(Sym *s, Sym *t) +{ + vlong r; + Prog *p; + enum { Ptrsize = 4 }; + + if(s->type == 0) + s->type = SDATA; + s->reachable = 1; + r = s->value; + p = newdata(s, s->value, Ptrsize, D_EXTERN); + s->value += Ptrsize; + p->to.type = D_SIZE; + p->to.index = D_EXTERN; + p->to.offset = 0; + p->to.sym = t; + return r; +} + +vlong +datoff(vlong addr) +{ + if(addr >= INITDAT) + return addr - INITDAT + rnd(HEADR+textsize, INITRND); + diag("datoff %#llx", addr); + return 0; +} + +enum { + ElfStrEmpty, + ElfStrInterp, + ElfStrHash, + ElfStrGot, + ElfStrGotPlt, + ElfStrDynamic, + ElfStrDynsym, + ElfStrDynstr, + ElfStrRel, + ElfStrText, + ElfStrData, + ElfStrBss, + ElfStrGosymtab, + ElfStrGopclntab, + ElfStrShstrtab, + NElfStr +}; + +vlong elfstr[NElfStr]; + +static int +needlib(char *name) +{ + char *p; + Sym *s; + + /* reuse hash code in symbol table */ + p = smprint(".elfload.%s", name); + s = lookup(p, 0); + if(s->type == 0) { + s->type = 100; // avoid SDATA, etc. + return 1; + } + return 0; +} + +void +doelf(void) +{ + Sym *s, *shstrtab, *dynamic, *dynstr, *d; + int h, nsym, t; + + if(HEADTYPE != 7 && HEADTYPE != 8) + return; + + /* predefine strings we need for section headers */ + shstrtab = lookup(".shstrtab", 0); + shstrtab->reachable = 1; + elfstr[ElfStrEmpty] = addstring(shstrtab, ""); + elfstr[ElfStrText] = addstring(shstrtab, ".text"); + elfstr[ElfStrData] = addstring(shstrtab, ".data"); + elfstr[ElfStrBss] = addstring(shstrtab, ".bss"); + if(!debug['s']) { + elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab"); + elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab"); + } + elfstr[ElfStrShstrtab] = addstring(shstrtab, ".shstrtab"); + + if(!debug['d']) { /* -d suppresses dynamic loader format */ + elfstr[ElfStrInterp] = addstring(shstrtab, ".interp"); + elfstr[ElfStrHash] = addstring(shstrtab, ".hash"); + elfstr[ElfStrGot] = addstring(shstrtab, ".got"); + elfstr[ElfStrGotPlt] = addstring(shstrtab, ".got.plt"); + elfstr[ElfStrDynamic] = addstring(shstrtab, ".dynamic"); + elfstr[ElfStrDynsym] = addstring(shstrtab, ".dynsym"); + elfstr[ElfStrDynstr] = addstring(shstrtab, ".dynstr"); + elfstr[ElfStrRel] = addstring(shstrtab, ".rel"); + + /* interpreter string */ + s = lookup(".interp", 0); + s->reachable = 1; + s->type = SDATA; // TODO: rodata + addstring(lookup(".interp", 0), linuxdynld); + + /* + * hash table - empty for now. + * we should have to fill it out with an entry for every + * symbol in .dynsym, but it seems to work not to, + * which is fine with me. + */ + s = lookup(".hash", 0); + s->type = SDATA; // TODO: rodata + s->reachable = 1; + s->value += 8; // two leading zeros + + /* dynamic symbol table - first entry all zeros */ + s = lookup(".dynsym", 0); + s->type = SDATA; + s->reachable = 1; + s->value += ELF64SYMSIZE; + + /* dynamic string table */ + s = lookup(".dynstr", 0); + addstring(s, ""); + dynstr = s; + + /* relocation table */ + s = lookup(".rel", 0); + s->reachable = 1; + s->type = SDATA; + + /* global offset table */ + s = lookup(".got", 0); + s->reachable = 1; + s->type = SDATA; + + /* got.plt - ??? */ + s = lookup(".got.plt", 0); + s->reachable = 1; + s->type = SDATA; + + /* define dynamic elf table */ + s = lookup(".dynamic", 0); + dynamic = s; + + /* + * relocation entries for dynld symbols + */ + nsym = 1; // sym 0 is reserved + for(h=0; h<NHASH; h++) { + for(s=hash[h]; s!=S; s=s->link) { + if(!s->reachable || (s->type != SDATA && s->type != SBSS) || s->dynldname == nil) + continue; + + d = lookup(".rela", 0); + addaddr(d, s); + adduint64(d, ELF64_R_INFO(nsym, R_X86_64_64)); + adduint64(d, 0); + nsym++; + + d = lookup(".dynsym", 0); + adduint32(d, addstring(lookup(".dynstr", 0), s->dynldname)); + t = STB_GLOBAL << 4; + t |= STT_OBJECT; // works for func too, empirically + adduint8(d, t); + adduint8(d, 0); /* reserved */ + adduint16(d, SHN_UNDEF); /* section where symbol is defined */ + adduint64(d, 0); /* value */ + adduint64(d, 0); /* size of object */ + + if(needlib(s->dynldlib)) + elfwritedynent(dynamic, DT_NEEDED, addstring(dynstr, s->dynldlib)); + } + } + + /* + * .dynamic table + */ + s = dynamic; + elfwritedynentsym(s, DT_HASH, lookup(".hash", 0)); + elfwritedynentsym(s, DT_SYMTAB, lookup(".dynsym", 0)); + elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE); + elfwritedynentsym(s, DT_STRTAB, lookup(".dynstr", 0)); + elfwritedynentsymsize(s, DT_STRSZ, lookup(".dynstr", 0)); + elfwritedynentsym(s, DT_REL, lookup(".rel", 0)); + elfwritedynentsymsize(s, DT_RELSZ, lookup(".rel", 0)); + elfwritedynent(s, DT_RELENT, ELF32RELSIZE); + elfwritedynent(s, DT_NULL, 0); + } +} + +void +shsym(Elf64_Shdr *sh, Sym *s) +{ + sh->addr = symaddr(s); + sh->off = datoff(sh->addr); + sh->size = s->size; +} + +void +phsh(Elf64_Phdr *ph, Elf64_Shdr *sh) +{ + ph->vaddr = sh->addr; + ph->paddr = ph->vaddr; + ph->off = sh->off; + ph->filesz = sh->size; + ph->memsz = sh->size; + ph->align = sh->addralign; +} + void asmb(void) { Prog *p; int32 v, magic; - int a, np, nl, ns; - uint32 va, fo, w, symo; + int a, nl, dynsym; + uint32 va, fo, w, symo, startva; uchar *op1; ulong expectpc; + Elf64_Ehdr *eh; + Elf64_Phdr *ph, *pph; + Elf64_Shdr *sh; if(debug['v']) Bprint(&bso, "%5.2f asmb\n", cputime()); @@ -201,6 +504,7 @@ asmb(void) } } cflush(); + switch(HEADTYPE) { default: diag("unknown header type %d", HEADTYPE); @@ -230,9 +534,6 @@ asmb(void) break; case 7: case 8: - seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0); - strtabsize = elfstrtable(); - cflush(); v = rnd(HEADR+textsize, INITRND); seek(cout, v, 0); break; @@ -517,192 +818,243 @@ asmb(void) case 7: case 8: - np = 3; - ns = 5; - if(!debug['s']) { - if(HEADTYPE != 8) // no loading of debug info under native client - np++; - ns += 2; - } - - /* ELF header */ - strnput("\177ELF", 4); /* e_ident */ - cput(1); /* class = 32 bit */ - cput(1); /* data = LSB */ - cput(1); /* version = CURRENT */ - if(HEADTYPE == 8) { - cput(123); /* os abi - native client */ - cput(5); /* nacl abi version */ - } else { - cput(0); - cput(0); - } - strnput("", 7); - wputl(2); /* type = EXEC */ - wputl(3); /* machine = AMD64 */ - lputl(1L); /* version = CURRENT */ - lputl(entryvalue()); /* entry vaddr */ - lputl(52L); /* offset to first phdr */ - lputl(52L+32L*np); /* offset to first shdr */ + /* elf 386 */ if(HEADTYPE == 8) - lputl(0x200000); /* native client - align mod 32 */ - else - lputl(0L); /* processor specific flags */ - wputl(52L); /* Ehdr size */ - wputl(32L); /* Phdr size */ - wputl(np); /* # of Phdrs */ - wputl(40L); /* Shdr size */ - wputl(ns); /* # of Shdrs */ - wputl(4); /* Shdr with strings */ - - /* prog headers */ + debug['d'] = 1; + + eh = getElfEhdr(); fo = HEADR; - va = INITTEXT; + startva = INITTEXT - HEADR; + va = startva + fo; w = textsize; - elfphdr(1, /* text - type = PT_LOAD */ - 1L+4L, /* text - flags = PF_X+PF_R */ - fo, /* file offset */ - va, /* vaddr */ - va, /* paddr */ - w, /* file size */ - w, /* memory size */ - INITRND); /* alignment */ + /* This null SHdr must appear before all others */ + sh = newElfShdr(elfstr[ElfStrEmpty]); + + /* program header info - but not on native client */ + pph = nil; + if(HEADTYPE != 8) { + pph = newElfPhdr(); + pph->type = PT_PHDR; + pph->flags = PF_R + PF_X; + pph->off = eh->ehsize; + pph->vaddr = INITTEXT - HEADR + pph->off; + pph->paddr = INITTEXT - HEADR + pph->off; + pph->align = INITRND; + } + + if(!debug['d']) { + /* interpreter */ + sh = newElfShdr(elfstr[ElfStrInterp]); + sh->type = SHT_PROGBITS; + sh->flags = SHF_ALLOC; + sh->addralign = 1; + shsym(sh, lookup(".interp", 0)); + + ph = newElfPhdr(); + ph->type = PT_INTERP; + ph->flags = PF_R; + phsh(ph, sh); + } + + ph = newElfPhdr(); + ph->type = PT_LOAD; + ph->flags = PF_X+PF_R; + ph->vaddr = va; + ph->paddr = va; + ph->off = fo; + ph->filesz = w; + ph->memsz = w; + ph->align = INITRND; fo = rnd(fo+w, INITRND); va = rnd(va+w, INITRND); w = datsize; - elfphdr(1, /* data - type = PT_LOAD */ - 2L+4L, /* data - flags = PF_W+PF_R */ - fo, /* file offset */ - va, /* vaddr */ - va, /* paddr */ - w, /* file size */ - w+bsssize, /* memory size */ - INITRND); /* alignment */ + ph = newElfPhdr(); + ph->type = PT_LOAD; + ph->flags = PF_W+PF_R; + ph->off = fo; + ph->vaddr = va; + ph->paddr = va; + ph->filesz = w; + ph->memsz = w+bsssize; + ph->align = INITRND; if(!debug['s'] && HEADTYPE != 8) { - elfphdr(1, /* data - type = PT_LOAD */ - 2L+4L, /* data - flags = PF_W+PF_R */ - symo, /* file offset */ - symdatva, /* vaddr */ - symdatva, /* paddr */ - 8+symsize+lcsize, /* file size */ - 8+symsize+lcsize, /* memory size */ - INITRND); /* alignment */ + ph = newElfPhdr(); + ph->type = PT_LOAD; + ph->flags = PF_W+PF_R; + ph->off = symo; + ph->vaddr = symdatva; + ph->paddr = symdatva; + ph->filesz = 8+symsize+lcsize; + ph->memsz = 8+symsize+lcsize; + ph->align = INITRND; } - elfphdr(0x6474e551, /* gok - type = gok */ - 1L+2L+4L, /* gok - flags = PF_X+PF_W+PF_R */ - 0, /* file offset */ - 0, /* vaddr */ - 0, /* paddr */ - 0, /* file size */ - 0, /* memory size */ - 8); /* alignment */ - - /* segment headers */ - elfshdr(nil, /* name */ - 0, /* type */ - 0, /* flags */ - 0, /* addr */ - 0, /* off */ - 0, /* size */ - 0, /* link */ - 0, /* info */ - 0, /* align */ - 0); /* entsize */ - - stroffset = 1; /* 0 means no name, so start at 1 */ - fo = HEADR; - va = INITTEXT; + /* Dynamic linking sections */ + if (!debug['d']) { /* -d suppresses dynamic loader format */ + /* S headers for dynamic linking */ + sh = newElfShdr(elfstr[ElfStrGot]); + sh->type = SHT_PROGBITS; + sh->flags = SHF_ALLOC+SHF_WRITE; + sh->entsize = 4; + sh->addralign = 4; + shsym(sh, lookup(".got", 0)); + + sh = newElfShdr(elfstr[ElfStrGotPlt]); + sh->type = SHT_PROGBITS; + sh->flags = SHF_ALLOC+SHF_WRITE; + sh->entsize = 4; + sh->addralign = 4; + shsym(sh, lookup(".got.plt", 0)); + + dynsym = eh->shnum; + sh = newElfShdr(elfstr[ElfStrDynsym]); + sh->type = SHT_DYNSYM; + sh->flags = SHF_ALLOC; + sh->entsize = ELF32SYMSIZE; + sh->addralign = 4; + sh->link = dynsym+1; // dynstr + // sh->info = index of first non-local symbol (number of local symbols) + shsym(sh, lookup(".dynsym", 0)); + + sh = newElfShdr(elfstr[ElfStrDynstr]); + sh->type = SHT_STRTAB; + sh->flags = SHF_ALLOC; + sh->addralign = 1; + shsym(sh, lookup(".dynstr", 0)); + + sh = newElfShdr(elfstr[ElfStrHash]); + sh->type = SHT_HASH; + sh->flags = SHF_ALLOC; + sh->entsize = 4; + sh->addralign = 4; + sh->link = dynsym; + shsym(sh, lookup(".hash", 0)); + + sh = newElfShdr(elfstr[ElfStrRel]); + sh->type = SHT_REL; + sh->flags = SHF_ALLOC; + sh->entsize = ELF32RELSIZE; + sh->addralign = 4; + sh->link = dynsym; + shsym(sh, lookup(".rel", 0)); + + /* sh and PT_DYNAMIC for .dynamic section */ + sh = newElfShdr(elfstr[ElfStrDynamic]); + sh->type = SHT_DYNAMIC; + sh->flags = SHF_ALLOC+SHF_WRITE; + sh->entsize = 8; + sh->addralign = 4; + sh->link = dynsym+1; // dynstr + shsym(sh, lookup(".dynamic", 0)); + ph = newElfPhdr(); + ph->type = PT_DYNAMIC; + ph->flags = PF_R + PF_W; + phsh(ph, sh); + } + + ph = newElfPhdr(); + ph->type = PT_GNU_STACK; + ph->flags = PF_W+PF_R; + ph->align = 4; + + fo = ELFRESERVE; + va = startva + fo; w = textsize; - elfshdr(".text", /* name */ - 1, /* type */ - 6, /* flags */ - va, /* addr */ - fo, /* off */ - w, /* size */ - 0, /* link */ - 0, /* info */ - 8, /* align */ - 0); /* entsize */ + sh = newElfShdr(elfstr[ElfStrText]); + sh->type = SHT_PROGBITS; + sh->flags = SHF_ALLOC+SHF_EXECINSTR; + sh->addr = va; + sh->off = fo; + sh->size = w; + sh->addralign = 4; fo = rnd(fo+w, INITRND); va = rnd(va+w, INITRND); w = datsize; - elfshdr(".data", /* name */ - 1, /* type */ - 3, /* flags */ - va, /* addr */ - fo, /* off */ - w, /* size */ - 0, /* link */ - 0, /* info */ - 8, /* align */ - 0); /* entsize */ + sh = newElfShdr(elfstr[ElfStrData]); + sh->type = SHT_PROGBITS; + sh->flags = SHF_WRITE+SHF_ALLOC; + sh->addr = va; + sh->off = fo; + sh->size = w; + sh->addralign = 4; fo += w; va += w; w = bsssize; - elfshdr(".bss", /* name */ - 8, /* type */ - 3, /* flags */ - va, /* addr */ - fo, /* off */ - w, /* size */ - 0, /* link */ - 0, /* info */ - 8, /* align */ - 0); /* entsize */ - - w = strtabsize; - - elfshdr(".shstrtab", /* name */ - 3, /* type */ - 0, /* flags */ - 0, /* addr */ - fo, /* off */ - w, /* size */ - 0, /* link */ - 0, /* info */ - 1, /* align */ - 0); /* entsize */ - - if (debug['s']) - break; + sh = newElfShdr(elfstr[ElfStrBss]); + sh->type = SHT_NOBITS; + sh->flags = SHF_WRITE+SHF_ALLOC; + sh->addr = va; + sh->off = fo; + sh->size = w; + sh->addralign = 4; + + if (!debug['s']) { + fo = symo+8; + w = symsize; + + sh = newElfShdr(elfstr[ElfStrGosymtab]); + sh->type = SHT_PROGBITS; + sh->off = fo; + sh->size = w; + sh->addralign = 1; + + fo += w; + w = lcsize; + + sh = newElfShdr(elfstr[ElfStrGopclntab]); + sh->type = SHT_PROGBITS; + sh->off = fo; + sh->size = w; + sh->addralign = 1; + } - fo = symo+8; - w = symsize; + sh = newElfShstrtab(elfstr[ElfStrShstrtab]); + sh->type = SHT_STRTAB; + sh->addralign = 1; + shsym(sh, lookup(".shstrtab", 0)); + + /* Main header */ + eh->ident[EI_MAG0] = '\177'; + eh->ident[EI_MAG1] = 'E'; + eh->ident[EI_MAG2] = 'L'; + eh->ident[EI_MAG3] = 'F'; + eh->ident[EI_CLASS] = ELFCLASS32; + eh->ident[EI_DATA] = ELFDATA2LSB; + eh->ident[EI_VERSION] = EV_CURRENT; + if(HEADTYPE == 8) { + eh->ident[EI_OSABI] = ELFOSABI_NACL; + eh->ident[EI_ABIVERSION] = 5; + eh->flags = 0x200000; // aligned mod 32 + } - elfshdr(".gosymtab", /* name */ - 1, /* type 1 = SHT_PROGBITS */ - 0, /* flags */ - 0, /* addr */ - fo, /* off */ - w, /* size */ - 0, /* link */ - 0, /* info */ - 1, /* align */ - 24); /* entsize */ + eh->type = ET_EXEC; + eh->machine = EM_386; + eh->version = EV_CURRENT; + eh->entry = entryvalue(); - fo += w; - w = lcsize; - - elfshdr(".gopclntab", /* name */ - 1, /* type 1 = SHT_PROGBITS*/ - 0, /* flags */ - 0, /* addr */ - fo, /* off */ - w, /* size */ - 0, /* link */ - 0, /* info */ - 1, /* align */ - 24); /* entsize */ + if(pph != nil) { + pph->filesz = eh->phnum * eh->phentsize; + pph->memsz = pph->filesz; + } + + seek(cout, 0, 0); + a = 0; + a += elfwritehdr(); + a += elfwritephdrs(); + a += elfwriteshdrs(); + if (a > ELFRESERVE) { + diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE); + } + cflush(); break; } cflush(); @@ -814,6 +1166,8 @@ datblk(int32 s, int32 n) default: fl = p->to.offset; + if(p->to.type == D_SIZE) + fl += p->to.sym->size; if(p->to.type == D_ADDR) { if(p->to.index != D_STATIC && p->to.index != D_EXTERN) diag("DADDR type%P", p); @@ -1015,92 +1369,3 @@ machheadr(void) return a; } - -uint32 -elfheadr(void) -{ - uint32 a; - - a = 52; /* elf header */ - - a += 32; /* page zero seg */ - a += 32; /* text seg */ - a += 32; /* stack seg */ - - a += 40; /* nil sect */ - a += 40; /* .text sect */ - a += 40; /* .data seg */ - a += 40; /* .bss sect */ - a += 40; /* .shstrtab sect - strings for headers */ - if (!debug['s']) { - a += 32; /* symdat seg */ - a += 40; /* .gosymtab sect */ - a += 40; /* .gopclntab sect */ - } - - return a; -} - - -void -elfphdr(int type, int flags, uint32 foff, - uint32 vaddr, uint32 paddr, - uint32 filesize, uint32 memsize, uint32 align) -{ - - lputl(type); /* text - type = PT_LOAD */ - lputl(foff); /* file offset */ - lputl(vaddr); /* vaddr */ - lputl(paddr); /* paddr */ - lputl(filesize); /* file size */ - lputl(memsize); /* memory size */ - lputl(flags); /* text - flags = PF_X+PF_R */ - lputl(align); /* alignment */ -} - -void -elfshdr(char *name, uint32 type, uint32 flags, uint32 addr, uint32 off, - uint32 size, uint32 link, uint32 info, uint32 align, uint32 entsize) -{ - lputl(stroffset); - lputl(type); - lputl(flags); - lputl(addr); - lputl(off); - lputl(size); - lputl(link); - lputl(info); - lputl(align); - lputl(entsize); - - if(name != nil) - stroffset += strlen(name)+1; -} - -int -putstrtab(char* name) -{ - int w; - - w = strlen(name)+1; - strnput(name, w); - return w; -} - -int -elfstrtable(void) -{ - int size; - - size = 0; - size += putstrtab(""); - size += putstrtab(".text"); - size += putstrtab(".data"); - size += putstrtab(".bss"); - size += putstrtab(".shstrtab"); - if (!debug['s']) { - size += putstrtab(".gosymtab"); - size += putstrtab(".gopclntab"); - } - return size; -} diff --git a/src/cmd/8l/l.h b/src/cmd/8l/l.h index b62d9f8fd..ce28b1336 100644 --- a/src/cmd/8l/l.h +++ b/src/cmd/8l/l.h @@ -118,6 +118,7 @@ struct Sym uchar reachable; ushort file; int32 value; + int32 size; int32 sig; Sym* link; Prog* text; @@ -309,6 +310,7 @@ EXTERN int32 thunk; EXTERN int version; EXTERN Prog zprg; EXTERN int dtype; +EXTERN char thechar; EXTERN Adr* reloca; EXTERN int doexp, dlm; @@ -345,6 +347,7 @@ double cputime(void); void datblk(int32, int32); void diag(char*, ...); void dodata(void); +void doelf(void); void doinit(void); void doprof1(void); void doprof2(void); @@ -367,6 +370,7 @@ void listinit(void); Sym* lookup(char*, int); void lput(int32); void lputl(int32); +void vputl(uvlong); void main(int, char*[]); void mkfwd(void); void* mal(uint32); @@ -386,14 +390,23 @@ void span(void); void undef(void); void undefsym(Sym*); int32 vaddr(Adr*); +int32 symaddr(Sym*); void wput(ushort); +void wputl(ushort); void xdefine(char*, int, int32); void xfol(Prog*); void zaddr(Biobuf*, Adr*, Sym*[]); void zerosig(char*); uint32 machheadr(void); -uint32 elfheadr(void); void whatsys(void); +vlong addaddr(Sym *s, Sym *t); +vlong addsize(Sym *s, Sym *t); +vlong addstring(Sym *s, char *str); +vlong adduint16(Sym *s, uint16 v); +vlong adduint32(Sym *s, uint32 v); +vlong adduint64(Sym *s, uint64 v); +vlong adduint8(Sym *s, uint8 v); +vlong adduintxx(Sym *s, uint64 v, int wid); /* * go.c @@ -407,6 +420,11 @@ extern char* goroot; extern char* goarch; extern char* goos; +/* Native is little-endian */ +#define LPUT(a) lputl(a) +#define WPUT(a) wputl(a) +#define VPUT(a) vputl(a) + #pragma varargck type "D" Adr* #pragma varargck type "P" Prog* #pragma varargck type "R" int diff --git a/src/cmd/8l/obj.c b/src/cmd/8l/obj.c index 3eacf1ea8..96099e77f 100644 --- a/src/cmd/8l/obj.c +++ b/src/cmd/8l/obj.c @@ -30,6 +30,7 @@ #define EXTERN #include "l.h" +#include "../ld/elf.h" #include <ar.h> #ifndef DEFAULT @@ -220,7 +221,8 @@ main(int argc, char *argv[]) INITRND = 4096; break; case 7: /* elf32 executable */ - HEADR = elfheadr(); + elfinit(); + HEADR = ELFRESERVE; if(INITTEXT == -1) INITTEXT = 0x08048000+HEADR; if(INITDAT == -1) @@ -229,6 +231,7 @@ main(int argc, char *argv[]) INITRND = 4096; break; case 8: /* native client elf32 executable */ + elfinit(); HEADR = 4096; if(INITTEXT == -1) INITTEXT = 0x20000; @@ -367,6 +370,7 @@ main(int argc, char *argv[]) } patch(); follow(); + doelf(); dodata(); dostkoff(); if(debug['p']) diff --git a/src/cmd/8l/pass.c b/src/cmd/8l/pass.c index 576e51bfd..7ce419e8f 100644 --- a/src/cmd/8l/pass.c +++ b/src/cmd/8l/pass.c @@ -72,11 +72,12 @@ dodata(void) if(s->type != SBSS) continue; t = s->value; - if(t == 0) { + if(t == 0 && s->name[0] != '.') { diag("%s: no size", s->name); t = 1; } - t = rnd(t, 4);; + t = rnd(t, 4); + s->size = t; s->value = t; if(t > MINSIZ) continue; @@ -94,6 +95,7 @@ dodata(void) continue; } t = s->value; + s->size = t; s->value = datsize; datsize += t; } @@ -115,6 +117,7 @@ dodata(void) if(t > u) continue; u -= t; + s->size = t; s->value = datsize; s->type = SDATA; datsize += t; @@ -131,6 +134,7 @@ dodata(void) if(s->type != SBSS) continue; t = s->value; + s->size = t; s->value = bsssize + datsize; bsssize += t; } diff --git a/src/cmd/8l/span.c b/src/cmd/8l/span.c index 7745c361c..71607fcf2 100644 --- a/src/cmd/8l/span.c +++ b/src/cmd/8l/span.c @@ -573,6 +573,18 @@ put4(int32 v) } int32 +symaddr(Sym *s) +{ + Adr a; + + a.type = D_ADDR; + a.index = D_EXTERN; + a.offset = 0; + a.sym = s; + return vaddr(&a); +} + +int32 vaddr(Adr *a) { int t; diff --git a/src/cmd/ld/elf.c b/src/cmd/ld/elf.c index 1784fd50c..9948a8503 100644 --- a/src/cmd/ld/elf.c +++ b/src/cmd/ld/elf.c @@ -12,10 +12,9 @@ #define NSECT 16 static int elf64; -static Elf64_Ehdr hdr; -static Elf64_Phdr *phdr[NSECT]; -static Elf64_Shdr *shdr[NSECT]; -static char *sname[NSECT]; +static ElfEhdr hdr; +static ElfPhdr *phdr[NSECT]; +static ElfShdr *shdr[NSECT]; /* Initialize the global variable that describes the ELF header. It will be updated as @@ -42,12 +41,11 @@ elfinit(void) hdr.ehsize = ELF32HDRSIZE; /* Must be ELF32HDRSIZE */ hdr.phentsize = ELF32PHDRSIZE; /* Must be ELF32PHDRSIZE */ hdr.shentsize = ELF32SHDRSIZE; /* Must be ELF32SHDRSIZE */ - } } void -elf64phdr(Elf64_Phdr *e) +elf64phdr(ElfPhdr *e) { LPUT(e->type); LPUT(e->flags); @@ -60,7 +58,20 @@ elf64phdr(Elf64_Phdr *e) } void -elf64shdr(char *name, Elf64_Shdr *e) +elf32phdr(ElfPhdr *e) +{ + LPUT(e->type); + LPUT(e->off); + LPUT(e->vaddr); + LPUT(e->paddr); + LPUT(e->filesz); + LPUT(e->memsz); + LPUT(e->flags); + LPUT(e->align); +} + +void +elf64shdr(ElfShdr *e) { LPUT(e->name); LPUT(e->type); @@ -74,30 +85,55 @@ elf64shdr(char *name, Elf64_Shdr *e) VPUT(e->entsize); } +void +elf32shdr(ElfShdr *e) +{ + LPUT(e->name); + LPUT(e->type); + LPUT(e->flags); + LPUT(e->addr); + LPUT(e->off); + LPUT(e->size); + LPUT(e->link); + LPUT(e->info); + LPUT(e->addralign); + LPUT(e->entsize); +} + uint32 -elf64writeshdrs(void) +elfwriteshdrs(void) { int i; + if (elf64) { + for (i = 0; i < hdr.shnum; i++) + elf64shdr(shdr[i]); + return hdr.shnum * ELF64SHDRSIZE; + } for (i = 0; i < hdr.shnum; i++) - elf64shdr(sname[i], shdr[i]); - return hdr.shnum * ELF64SHDRSIZE; + elf32shdr(shdr[i]); + return hdr.shnum * ELF32SHDRSIZE; } uint32 -elf64writephdrs(void) +elfwritephdrs(void) { int i; + if (elf64) { + for (i = 0; i < hdr.phnum; i++) + elf64phdr(phdr[i]); + return hdr.phnum * ELF64PHDRSIZE; + } for (i = 0; i < hdr.phnum; i++) - elf64phdr(phdr[i]); - return hdr.phnum * ELF64PHDRSIZE; + elf32phdr(phdr[i]); + return hdr.phnum * ELF32PHDRSIZE; } -Elf64_Phdr* -newElf64_Phdr(void) +ElfPhdr* +newElfPhdr(void) { - Elf64_Phdr *e; + ElfPhdr *e; e = malloc(sizeof *e); memset(e, 0, sizeof *e); @@ -105,21 +141,24 @@ newElf64_Phdr(void) diag("too many phdrs"); else phdr[hdr.phnum++] = e; - hdr.shoff += ELF64PHDRSIZE; + if (elf64) + hdr.shoff += ELF64PHDRSIZE; + else + hdr.shoff += ELF32PHDRSIZE; return e; } -Elf64_Shdr* -newElf64_Shstrtab(vlong name) +ElfShdr* +newElfShstrtab(vlong name) { hdr.shstrndx = hdr.shnum; - return newElf64_Shdr(name); + return newElfShdr(name); } -Elf64_Shdr* -newElf64_Shdr(vlong name) +ElfShdr* +newElfShdr(vlong name) { - Elf64_Shdr *e; + ElfShdr *e; e = malloc(sizeof *e); memset(e, 0, sizeof *e); @@ -132,8 +171,8 @@ newElf64_Shdr(vlong name) return e; } -Elf64_Ehdr* -getElf64_Ehdr(void) +ElfEhdr* +getElfEhdr(void) { return &hdr; } @@ -161,11 +200,42 @@ elf64writehdr(void) return ELF64HDRSIZE; } +uint32 +elf32writehdr(void) +{ + int i; + + for (i = 0; i < EI_NIDENT; i++) + cput(hdr.ident[i]); + WPUT(hdr.type); + WPUT(hdr.machine); + LPUT(hdr.version); + LPUT(hdr.entry); + LPUT(hdr.phoff); + LPUT(hdr.shoff); + LPUT(hdr.flags); + WPUT(hdr.ehsize); + WPUT(hdr.phentsize); + WPUT(hdr.phnum); + WPUT(hdr.shentsize); + WPUT(hdr.shnum); + WPUT(hdr.shstrndx); + return ELF32HDRSIZE; +} + +uint32 +elfwritehdr(void) +{ + if(elf64) + return elf64writehdr(); + return elf32writehdr(); +} + /* Taken directly from the definition document for ELF64 */ uint32 -elf64_hash(uchar *name) +elfhash(uchar *name) { - unsigned long h = 0, g; + uint32 h = 0, g; while (*name) { h = (h << 4) + *name++; if (g = h & 0xf0000000) diff --git a/src/cmd/ld/elf.h b/src/cmd/ld/elf.h index 2a71a174f..0edadc43d 100644 --- a/src/cmd/ld/elf.h +++ b/src/cmd/ld/elf.h @@ -110,6 +110,7 @@ typedef struct { #define ELFOSABI_OPENVMS 13 /* Open VMS */ #define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */ #define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_NACL 123 /* Native Client */ #define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ #define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */ @@ -247,6 +248,7 @@ typedef struct { #define PT_HIOS 0x6fffffff /* Last OS-specific. */ #define PT_LOPROC 0x70000000 /* First processor-specific type. */ #define PT_HIPROC 0x7fffffff /* Last processor-specific type. */ +#define PT_GNU_STACK 0x6474e551 /* Values for p_flags. */ #define PF_X 0x1 /* Executable. */ @@ -931,23 +933,34 @@ typedef struct { #define ELF32HDRSIZE sizeof(Elf32_Ehdr) #define ELF32PHDRSIZE sizeof(Elf32_Phdr) #define ELF32SHDRSIZE sizeof(Elf32_Shdr) +#define ELF32SYMSIZE sizeof(Elf32_Sym) +#define ELF32RELSIZE 8 + +/* + * The interface uses the 64-bit structures always, + * to avoid code duplication. The writers know how to + * marshal a 32-bit representation from the 64-bit structure. + */ +typedef Elf64_Ehdr ElfEhdr; +typedef Elf64_Shdr ElfShdr; +typedef Elf64_Phdr ElfPhdr; void elfinit(void); -Elf64_Ehdr *getElf64_Ehdr(); -Elf64_Shdr *newElf64_Shstrtab(vlong); -Elf64_Shdr *newElf64_Shdr(vlong); -Elf64_Phdr *newElf64_Phdr(); -uint32 elf64writehdr(void); -uint32 elf64writephdrs(void); -uint32 elf64writeshdrs(void); +ElfEhdr *getElfEhdr(); +ElfShdr *newElfShstrtab(vlong); +ElfShdr *newElfShdr(vlong); +ElfPhdr *newElfPhdr(); +uint32 elfwritehdr(void); +uint32 elfwritephdrs(void); +uint32 elfwriteshdrs(void); void elfwritedynent(Sym*, int, uint64); void elfwritedynentsym(Sym*, int, Sym*); void elfwritedynentsymsize(Sym*, int, Sym*); -uint32 elf64_hash(uchar*); +uint32 elfhash(uchar*); uint64 startelf(void); uint64 endelf(void); -extern int nume64phdr; -extern int nume64shdr; +extern int numelfphdr; +extern int numelfshdr; /* * Total amount of ELF space to reserve at the start of the file |