uvlong hdr[1];
};
Ehdr; /* elf.h */
+ E64hdr;
struct mipsexec; /* bootexec.h */
struct mips4kexec; /* bootexec.h */
struct sparcexec; /* bootexec.h */
uchar _magic; /* _MAGIC() magic */
Mach *mach; /* Per-machine data */
long hsize; /* header size */
- ulong (*swal)(ulong); /* header swap, beswal or leswal */
+ ulong (*swal)(ulong); /* beswal or leswal */
int (*hparse)(int, Fhdr*, ExecHdr*);
} ExecTable;
extern Mach mi386;
extern Mach mamd64;
extern Mach marm;
+extern Mach marm64;
extern Mach mpower;
extern Mach mpower64;
-extern Mach malpha;
ExecTable exectab[] =
{
1,
&mamd64,
sizeof(Exec)+8,
- beswal,
+ nil,
commonllp64 },
{ Q_MAGIC, /* PowerPC q.out & boot image */
"power plan 9 executable",
1,
&mpower64,
sizeof(Exec)+8,
- beswal,
+ nil,
commonllp64 },
- { ELF_MAG, /* any elf32 */
+ { ELF_MAG, /* any ELF */
"elf executable",
nil,
FNONE,
sizeof(Exec),
leswal,
armdotout },
- { L_MAGIC, /* alpha 7.out */
- "alpha plan 9 executable",
- "alpha plan 9 dlm",
- FALPHA,
+ { R_MAGIC, /* Arm64 7.out and boot image */
+ "arm64 plan 9 executable",
+ "arm64 plan 9 dlm",
+ FARM64,
1,
- &malpha,
- sizeof(Exec),
- beswal,
- common },
- { 0x0700e0c3, /* alpha boot image */
- "alpha plan 9 boot image",
+ &marm64,
+ sizeof(Exec)+8,
nil,
- FALPHA,
- 0,
- &malpha,
- sizeof(Exec),
- beswal,
- common },
+ commonllp64 },
{ 0 },
};
fp->name = "ARM plan 9 boot image";
fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
return;
- case FALPHA:
- fp->type = FALPHAB;
- fp->txtaddr = (u32int)fp->entry;
- fp->name = "alpha plan 9 boot image";
- fp->dataddr = fp->txtaddr+fp->txtsz;
- break;
+ case FARM64:
+ fp->type = FARM64B;
+ fp->txtaddr = fp->entry;
+ fp->name = "arm64 plan 9 boot image";
+ fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
+ return;
case FPOWER:
fp->type = FPOWERB;
fp->txtaddr = (u32int)fp->entry;
fp->type = FAMD64B;
fp->txtaddr = fp->entry;
fp->name = "amd64 plan 9 boot image";
- fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
+ fp->dataddr = _round(fp->txtaddr+fp->txtsz, 4096);
+ break;
+ case FPOWER64:
+ fp->type = FPOWER64B;
+ fp->txtaddr = fp->entry;
+ fp->name = "power64 plan 9 boot image";
+ fp->dataddr = fp->txtaddr+fp->txtsz;
break;
default:
return;
long pgsize;
uvlong entry;
+ hswal(&hp->e, sizeof(Exec)/sizeof(long), beswal);
if(!(hp->e.magic & HDR_MAGIC))
return 0;
}
/*
- * Elf32 binaries.
+ * ELF64 binaries.
*/
static int
-elfdotout(int fd, Fhdr *fp, ExecHdr *hp)
+elf64dotout(int fd, Fhdr *fp, ExecHdr *hp)
{
+ E64hdr *ep;
+ P64hdr *ph;
+ ushort (*swab)(ushort);
+ ulong (*swal)(ulong);
+ uvlong (*swav)(uvlong);
+ int i, it, id, is, phsz;
+ uvlong uvl;
+
+ ep = &hp->e;
+ if(ep->ident[DATA] == ELFDATA2LSB) {
+ swab = leswab;
+ swal = leswal;
+ swav = leswav;
+ } else if(ep->ident[DATA] == ELFDATA2MSB) {
+ swab = beswab;
+ swal = beswal;
+ swav = beswav;
+ } else {
+ werrstr("bad ELF64 encoding - not big or little endian");
+ return 0;
+ }
+
+ ep->type = swab(ep->type);
+ ep->machine = swab(ep->machine);
+ ep->version = swal(ep->version);
+ if(ep->type != EXEC || ep->version != CURRENT)
+ return 0;
+ ep->elfentry = swav(ep->elfentry);
+ ep->phoff = swav(ep->phoff);
+ ep->shoff = swav(ep->shoff);
+ ep->flags = swal(ep->flags);
+ ep->ehsize = swab(ep->ehsize);
+ ep->phentsize = swab(ep->phentsize);
+ ep->phnum = swab(ep->phnum);
+ ep->shentsize = swab(ep->shentsize);
+ ep->shnum = swab(ep->shnum);
+ ep->shstrndx = swab(ep->shstrndx);
+
+ fp->magic = ELF_MAG;
+ fp->hdrsz = (ep->ehsize+ep->phnum*ep->phentsize+16)&~15;
+ switch(ep->machine) {
+ default:
+ return 0;
+ case AMD64:
+ mach = &mamd64;
+ fp->type = FAMD64;
+ fp->name = "amd64 ELF64 executable";
+ break;
+ case POWER64:
+ mach = &mpower64;
+ fp->type = FPOWER64;
+ fp->name = "power64 ELF64 executable";
+ break;
+ }
+
+ if(ep->phentsize != sizeof(P64hdr)) {
+ werrstr("bad ELF64 header size");
+ return 0;
+ }
+ phsz = sizeof(P64hdr)*ep->phnum;
+ ph = malloc(phsz);
+ if(!ph)
+ return 0;
+ seek(fd, ep->phoff, 0);
+ if(read(fd, ph, phsz) < 0) {
+ free(ph);
+ return 0;
+ }
+ for(i = 0; i < ep->phnum; i++) {
+ ph[i].type = swal(ph[i].type);
+ ph[i].flags = swal(ph[i].flags);
+ ph[i].offset = swav(ph[i].offset);
+ ph[i].vaddr = swav(ph[i].vaddr);
+ ph[i].paddr = swav(ph[i].paddr);
+ ph[i].filesz = swav(ph[i].filesz);
+ ph[i].memsz = swav(ph[i].memsz);
+ ph[i].align = swav(ph[i].align);
+ }
+
+ /* find text, data and symbols and install them */
+ it = id = is = -1;
+ for(i = 0; i < ep->phnum; i++) {
+ if(ph[i].type == LOAD
+ && (ph[i].flags & (R|X)) == (R|X) && it == -1)
+ it = i;
+ else if(ph[i].type == LOAD
+ && (ph[i].flags & (R|W)) == (R|W) && id == -1)
+ id = i;
+ else if(ph[i].type == NOPTYPE && is == -1)
+ is = i;
+ }
+ if(it == -1 || id == -1) {
+ werrstr("No ELF64 TEXT or DATA sections");
+ free(ph);
+ return 0;
+ }
+ settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset);
+ /* 8c: out of fixed registers */
+ uvl = ph[id].memsz - ph[id].filesz;
+ setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, uvl);
+ if(is != -1)
+ setsym(fp, ph[is].filesz, 0, ph[is].memsz, ph[is].offset);
+ free(ph);
+ return 1;
+}
+
+/*
+ * ELF32 binaries.
+ */
+static int
+elf32dotout(int fd, Fhdr *fp, ExecHdr *hp)
+{
ulong (*swal)(ulong);
ushort (*swab)(ushort);
Ehdr *ep;
/* bitswap the header according to the DATA format */
ep = &hp->e;
- if(ep->ident[CLASS] != ELFCLASS32) {
- werrstr("bad ELF class - not 32 bit");
- return 0;
- }
if(ep->ident[DATA] == ELFDATA2LSB) {
swab = leswab;
swal = leswal;
swab = beswab;
swal = beswal;
} else {
- werrstr("bad ELF encoding - not big or little endian");
+ werrstr("bad ELF32 encoding - not big or little endian");
return 0;
}
case I386:
mach = &mi386;
fp->type = FI386;
+ fp->name = "386 ELF32 executable";
break;
case MIPS:
mach = &mmips;
- fp->type = FMIPS;
+ if(ep->ident[DATA] == ELFDATA2LSB){
+ fp->type = FMIPSLE;
+ fp->name = "mips le ELF32 executable";
+ } else {
+ fp->type = FMIPS;
+ fp->name = "mips be ELF32 executable";
+ }
break;
case SPARC64:
mach = &msparc64;
fp->type = FSPARC64;
+ fp->name = "sparc64 ELF32 executable";
break;
case POWER:
mach = &mpower;
fp->type = FPOWER;
+ fp->name = "power ELF32 executable";
+ break;
+ case POWER64:
+ mach = &mpower64;
+ fp->type = FPOWER64;
+ fp->name = "power64 ELF32 executable";
break;
case AMD64:
mach = &mamd64;
fp->type = FAMD64;
+ fp->name = "amd64 ELF32 executable";
break;
case ARM:
mach = &marm;
fp->type = FARM;
+ fp->name = "arm ELF32 executable";
break;
default:
return 0;
}
if(ep->phentsize != sizeof(Phdr)) {
- werrstr("bad ELF header size");
+ werrstr("bad ELF32 header size");
return 0;
}
phsz = sizeof(Phdr)*ep->phnum;
return 1;
}
- werrstr("No TEXT or DATA sections");
+ werrstr("No ELF32 TEXT or DATA sections");
free(ph);
return 0;
}
return 1;
}
+/*
+ * Elf binaries.
+ */
+static int
+elfdotout(int fd, Fhdr *fp, ExecHdr *hp)
+{
+ Ehdr *ep;
+
+ /* bitswap the header according to the DATA format */
+ ep = &hp->e;
+ if(ep->ident[CLASS] == ELFCLASS32)
+ return elf32dotout(fd, fp, hp);
+ else if(ep->ident[CLASS] == ELFCLASS64)
+ return elf64dotout(fd, fp, hp);
+
+ werrstr("bad ELF class - not 32 bit");
+ return 0;
+}
+
/*
* (Free|Net)BSD ARM header.
*/