+ 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;
+ }