Commit 0c71ead9 authored by Russ Cox's avatar Russ Cox

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
parent 5de60964
......@@ -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);
}
......
......@@ -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,
......
......@@ -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
This diff is collapsed.
......@@ -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
......
......@@ -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'])
......
......@@ -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;
}
......
......@@ -572,6 +572,18 @@ put4(int32 v)
andptr += 4;
}
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)
{
......
......@@ -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)
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment