From: miod Date: Sat, 13 Dec 2014 14:44:59 +0000 (+0000) Subject: Give the mop suite the ability to process alpha Elf64 files and create mop X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=8f9114865737fffc70ea5264209b99e98032bd32;p=openbsd Give the mop suite the ability to process alpha Elf64 files and create mop alpha images of them. --- diff --git a/usr.sbin/mopd/common/common.h b/usr.sbin/mopd/common/common.h index 80bbb496278..4f2cf122c43 100644 --- a/usr.sbin/mopd/common/common.h +++ b/usr.sbin/mopd/common/common.h @@ -1,4 +1,4 @@ -/* $OpenBSD: common.h,v 1.8 2013/07/05 21:02:07 miod Exp $ */ +/* $OpenBSD: common.h,v 1.9 2014/12/13 14:44:59 miod Exp $ */ /* $NetBSD: common.h,v 1.9 2011/08/30 19:49:10 joerg Exp $ */ /* @@ -68,7 +68,8 @@ struct if_info { typedef enum { IMAGE_TYPE_MOP, /* MOP image */ IMAGE_TYPE_AOUT, /* a.out image */ - IMAGE_TYPE_ELF32 /* Elf32 image */ + IMAGE_TYPE_ELF32, /* Elf32 image */ + IMAGE_TYPE_ELF64 /* Elf64 image */ } mopd_imagetype; struct dllist { @@ -85,7 +86,7 @@ struct dllist { off_t lseek; /* Seek before last read */ mopd_imagetype image_type; /* what type of image is it? */ - /* For Elf32 files */ + /* For ELF files */ int e_machine; /* Machine ID */ int e_nsec; /* number of program sections */ #define SEC_MAX 4 diff --git a/usr.sbin/mopd/common/file.c b/usr.sbin/mopd/common/file.c index 5382d35ab1c..170dded7d5f 100644 --- a/usr.sbin/mopd/common/file.c +++ b/usr.sbin/mopd/common/file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: file.c,v 1.16 2014/11/30 13:47:42 miod Exp $ */ +/* $OpenBSD: file.c,v 1.17 2014/12/13 14:44:59 miod Exp $ */ /* * Copyright (c) 1995-96 Mats O Jansson. All rights reserved. @@ -59,6 +59,12 @@ #endif #endif +#ifndef NOELF +#if !defined(_LP64) +#define NOELF64 +#endif +#endif + #ifndef NOAOUT static int getCLBYTES(int); static int getMID(int, int); @@ -75,6 +81,9 @@ FileTypeName(mopd_imagetype type) case IMAGE_TYPE_ELF32: return ("Elf32"); + case IMAGE_TYPE_ELF64: + return ("Elf64"); + case IMAGE_TYPE_AOUT: return ("a.out"); } @@ -134,6 +143,40 @@ mopFileGetBX(u_char *buf, int idx, int cnt) return(ret); } +#if !defined(NOELF) && !defined(NOELF64) +u_int64_t +mopFileGetLXX(u_char *buf, int idx, int cnt) +{ + u_int64_t ret = 0; + int i; + + for (i = 0; i < cnt; i++) { + int j = idx + cnt - 1 - i; + if (j < 0) + abort(); + ret = ret * 256 + buf[j]; + } + + return(ret); +} + +u_int64_t +mopFileGetBXX(u_char *buf, int idx, int cnt) +{ + u_int64_t ret = 0; + int i; + + for (i = 0; i < cnt; i++) { + int j = idx + i; + if (j < 0) + abort(); + ret = ret * 256 + buf[j]; + } + + return(ret); +} +#endif + void mopFileSwapX(u_char *buf, int idx, int cnt) { @@ -159,20 +202,19 @@ CheckMopFile(int fd) (void)lseek(fd, (off_t) 0, SEEK_SET); - image_type = (u_short)(header[IHD_W_ALIAS+1]*256 + - header[IHD_W_ALIAS]); + image_type = (u_short)(header[IHD_W_ALIAS+1]*256 + header[IHD_W_ALIAS]); switch(image_type) { - case IHD_C_NATIVE: /* Native mode image (VAX) */ - case IHD_C_RSX: /* RSX image produced by TKB */ - case IHD_C_BPA: /* BASIC plus analog */ - case IHD_C_ALIAS: /* Alias */ - case IHD_C_CLI: /* Image is CLI */ - case IHD_C_PMAX: /* PMAX system image */ - case IHD_C_ALPHA: /* ALPHA system image */ - break; - default: - return(-1); + case IHD_C_NATIVE: /* Native mode image (VAX) */ + case IHD_C_RSX: /* RSX image produced by TKB */ + case IHD_C_BPA: /* BASIC plus analog */ + case IHD_C_ALIAS: /* Alias */ + case IHD_C_CLI: /* Image is CLI */ + case IHD_C_PMAX: /* PMAX system image */ + case IHD_C_ALPHA: /* ALPHA system image */ + break; + default: + return(-1); } return(0); @@ -191,111 +233,111 @@ GetMopFileInfo(struct dllist *dl, int info) image_type = (u_short)(header[IHD_W_ALIAS+1]*256 + header[IHD_W_ALIAS]); - switch(image_type) { - case IHD_C_NATIVE: /* Native mode image (VAX) */ - isd = (header[IHD_W_SIZE+1]*256 + - header[IHD_W_SIZE]); - iha = (header[IHD_W_ACTIVOFF+1]*256 + - header[IHD_W_ACTIVOFF]); - hbcnt = (header[IHD_B_HDRBLKCNT]); - isize = (header[isd+ISD_W_PAGCNT+1]*256 + - header[isd+ISD_W_PAGCNT]) * 512; - load_addr = ((header[isd+ISD_V_VPN+1]*256 + - header[isd+ISD_V_VPN]) & ISD_M_VPN) - * 512; - xfr_addr = (header[iha+IHA_L_TFRADR1+3]*0x1000000 + - header[iha+IHA_L_TFRADR1+2]*0x10000 + - header[iha+IHA_L_TFRADR1+1]*0x100 + - header[iha+IHA_L_TFRADR1]) & 0x7fffffff; - if (info == INFO_PRINT) { - printf("Native Image (VAX)\n"); - printf("Header Block Count: %d\n",hbcnt); - printf("Image Size: %08x\n",isize); - printf("Load Address: %08x\n",load_addr); - printf("Transfer Address: %08x\n",xfr_addr); - } - break; - case IHD_C_RSX: /* RSX image produced by TKB */ - hbcnt = header[L_BBLK+1]*256 + header[L_BBLK]; - isize = (header[L_BLDZ+1]*256 + header[L_BLDZ]) * 64; - load_addr = header[L_BSA+1]*256 + header[L_BSA]; - xfr_addr = header[L_BXFR+1]*256 + header[L_BXFR]; - if (info == INFO_PRINT) { - printf("RSX Image\n"); - printf("Header Block Count: %d\n",hbcnt); - printf("Image Size: %08x\n",isize); - printf("Load Address: %08x\n",load_addr); - printf("Transfer Address: %08x\n",xfr_addr); - } - break; - case IHD_C_BPA: /* BASIC plus analog */ - if (info == INFO_PRINT) { - printf("BASIC-Plus Image, not supported\n"); - } - return(-1); - break; - case IHD_C_ALIAS: /* Alias */ - if (info == INFO_PRINT) { - printf("Alias, not supported\n"); - } - return(-1); - break; - case IHD_C_CLI: /* Image is CLI */ - if (info == INFO_PRINT) { - printf("CLI, not supported\n"); - } - return(-1); - break; - case IHD_C_PMAX: /* PMAX system image */ - isd = (header[IHD_W_SIZE+1]*256 + - header[IHD_W_SIZE]); - iha = (header[IHD_W_ACTIVOFF+1]*256 + - header[IHD_W_ACTIVOFF]); - hbcnt = (header[IHD_B_HDRBLKCNT]); - isize = (header[isd+ISD_W_PAGCNT+1]*256 + - header[isd+ISD_W_PAGCNT]) * 512; - load_addr = (header[isd+ISD_V_VPN+1]*256 + - header[isd+ISD_V_VPN]) * 512; - xfr_addr = (header[iha+IHA_L_TFRADR1+3]*0x1000000 + - header[iha+IHA_L_TFRADR1+2]*0x10000 + - header[iha+IHA_L_TFRADR1+1]*0x100 + - header[iha+IHA_L_TFRADR1]); - if (info == INFO_PRINT) { - printf("PMAX Image \n"); - printf("Header Block Count: %d\n",hbcnt); - printf("Image Size: %08x\n",isize); - printf("Load Address: %08x\n",load_addr); - printf("Transfer Address: %08x\n",xfr_addr); - } - break; - case IHD_C_ALPHA: /* ALPHA system image */ - isd = (header[EIHD_L_ISDOFF+3]*0x1000000 + - header[EIHD_L_ISDOFF+2]*0x10000 + - header[EIHD_L_ISDOFF+1]*0x100 + - header[EIHD_L_ISDOFF]); - hbcnt = (header[EIHD_L_HDRBLKCNT+3]*0x1000000 + - header[EIHD_L_HDRBLKCNT+2]*0x10000 + - header[EIHD_L_HDRBLKCNT+1]*0x100 + - header[EIHD_L_HDRBLKCNT]); - isize = (header[isd+EISD_L_SECSIZE+3]*0x1000000 + - header[isd+EISD_L_SECSIZE+2]*0x10000 + - header[isd+EISD_L_SECSIZE+1]*0x100 + - header[isd+EISD_L_SECSIZE]); - load_addr = 0; - xfr_addr = 0; - if (info == INFO_PRINT) { - printf("Alpha Image \n"); - printf("Header Block Count: %d\n",hbcnt); - printf("Image Size: %08x\n",isize); - printf("Load Address: %08x\n",load_addr); - printf("Transfer Address: %08x\n",xfr_addr); - } - break; - default: - if (info == INFO_PRINT) { - printf("Unknown Image (%d)\n",image_type); - } - return(-1); + switch (image_type) { + case IHD_C_NATIVE: /* Native mode image (VAX) */ + isd = (header[IHD_W_SIZE+1]*256 + + header[IHD_W_SIZE]); + iha = (header[IHD_W_ACTIVOFF+1]*256 + + header[IHD_W_ACTIVOFF]); + hbcnt = (header[IHD_B_HDRBLKCNT]); + isize = (header[isd+ISD_W_PAGCNT+1]*256 + + header[isd+ISD_W_PAGCNT]) * 512; + load_addr = ((header[isd+ISD_V_VPN+1]*256 + + header[isd+ISD_V_VPN]) & ISD_M_VPN) + * 512; + xfr_addr = (header[iha+IHA_L_TFRADR1+3]*0x1000000 + + header[iha+IHA_L_TFRADR1+2]*0x10000 + + header[iha+IHA_L_TFRADR1+1]*0x100 + + header[iha+IHA_L_TFRADR1]) & 0x7fffffff; + if (info == INFO_PRINT) { + printf("Native Image (VAX)\n"); + printf("Header Block Count: %d\n",hbcnt); + printf("Image Size: %08x\n",isize); + printf("Load Address: %08x\n",load_addr); + printf("Transfer Address: %08x\n",xfr_addr); + } + break; + case IHD_C_RSX: /* RSX image produced by TKB */ + hbcnt = header[L_BBLK+1]*256 + header[L_BBLK]; + isize = (header[L_BLDZ+1]*256 + header[L_BLDZ]) * 64; + load_addr = header[L_BSA+1]*256 + header[L_BSA]; + xfr_addr = header[L_BXFR+1]*256 + header[L_BXFR]; + if (info == INFO_PRINT) { + printf("RSX Image\n"); + printf("Header Block Count: %d\n",hbcnt); + printf("Image Size: %08x\n",isize); + printf("Load Address: %08x\n",load_addr); + printf("Transfer Address: %08x\n",xfr_addr); + } + break; + case IHD_C_BPA: /* BASIC plus analog */ + if (info == INFO_PRINT) { + printf("BASIC-Plus Image, not supported\n"); + } + return(-1); + break; + case IHD_C_ALIAS: /* Alias */ + if (info == INFO_PRINT) { + printf("Alias, not supported\n"); + } + return(-1); + break; + case IHD_C_CLI: /* Image is CLI */ + if (info == INFO_PRINT) { + printf("CLI, not supported\n"); + } + return(-1); + break; + case IHD_C_PMAX: /* PMAX system image */ + isd = (header[IHD_W_SIZE+1]*256 + + header[IHD_W_SIZE]); + iha = (header[IHD_W_ACTIVOFF+1]*256 + + header[IHD_W_ACTIVOFF]); + hbcnt = (header[IHD_B_HDRBLKCNT]); + isize = (header[isd+ISD_W_PAGCNT+1]*256 + + header[isd+ISD_W_PAGCNT]) * 512; + load_addr = (header[isd+ISD_V_VPN+1]*256 + + header[isd+ISD_V_VPN]) * 512; + xfr_addr = (header[iha+IHA_L_TFRADR1+3]*0x1000000 + + header[iha+IHA_L_TFRADR1+2]*0x10000 + + header[iha+IHA_L_TFRADR1+1]*0x100 + + header[iha+IHA_L_TFRADR1]); + if (info == INFO_PRINT) { + printf("PMAX Image \n"); + printf("Header Block Count: %d\n",hbcnt); + printf("Image Size: %08x\n",isize); + printf("Load Address: %08x\n",load_addr); + printf("Transfer Address: %08x\n",xfr_addr); + } + break; + case IHD_C_ALPHA: /* ALPHA system image */ + isd = (header[EIHD_L_ISDOFF+3]*0x1000000 + + header[EIHD_L_ISDOFF+2]*0x10000 + + header[EIHD_L_ISDOFF+1]*0x100 + + header[EIHD_L_ISDOFF]); + hbcnt = (header[EIHD_L_HDRBLKCNT+3]*0x1000000 + + header[EIHD_L_HDRBLKCNT+2]*0x10000 + + header[EIHD_L_HDRBLKCNT+1]*0x100 + + header[EIHD_L_HDRBLKCNT]); + isize = (header[isd+EISD_L_SECSIZE+3]*0x1000000 + + header[isd+EISD_L_SECSIZE+2]*0x10000 + + header[isd+EISD_L_SECSIZE+1]*0x100 + + header[isd+EISD_L_SECSIZE]); + load_addr = 0; + xfr_addr = 0; + if (info == INFO_PRINT) { + printf("Alpha Image \n"); + printf("Header Block Count: %d\n",hbcnt); + printf("Image Size: %08x\n",isize); + printf("Load Address: %08x\n",load_addr); + printf("Transfer Address: %08x\n",xfr_addr); + } + break; + default: + if (info == INFO_PRINT) { + printf("Unknown Image (%d)\n",image_type); + } + return(-1); } dl->image_type = IMAGE_TYPE_MOP; @@ -441,8 +483,9 @@ CheckElfFile(int fd) ehdr.e_ident[3] != ELFMAG3) return(-1); - /* Must be Elf32... */ - if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) + /* Must be Elf32 or Elf64... */ + if (ehdr.e_ident[EI_CLASS] != ELFCLASS32 && + ehdr.e_ident[EI_CLASS] != ELFCLASS64) return(-1); return(0); @@ -450,7 +493,7 @@ CheckElfFile(int fd) } int -GetElfFileInfo(struct dllist *dl, int info) +GetElf32FileInfo(struct dllist *dl, int info) { #ifdef NOELF return(-1); @@ -639,6 +682,202 @@ GetElfFileInfo(struct dllist *dl, int info) #endif /* NOELF */ } +int +GetElf64FileInfo(struct dllist *dl, int info) +{ +#if defined(NOELF) || defined(NOELF64) + return(-1); +#else + Elf64_Ehdr ehdr; + Elf64_Phdr phdr; + uint32_t e_machine; + uint32_t e_phentsize, e_phnum; + uint64_t e_entry, e_phoff; + int ei_data, i; + + (void)lseek(dl->ldfd, (off_t) 0, SEEK_SET); + + if (read(dl->ldfd, (char *)&ehdr, sizeof(ehdr)) != sizeof(ehdr)) + return(-1); + + if (ehdr.e_ident[0] != ELFMAG0 || + ehdr.e_ident[1] != ELFMAG1 || + ehdr.e_ident[2] != ELFMAG2 || + ehdr.e_ident[3] != ELFMAG3) + return(-1); + + /* Must be Elf64... */ + if (ehdr.e_ident[EI_CLASS] != ELFCLASS64) + return(-1); + + ei_data = ehdr.e_ident[EI_DATA]; + + switch (ei_data) { + case ELFDATA2LSB: + e_machine = mopFileGetLX((u_char *) &ehdr, + offsetof(Elf64_Ehdr, e_machine), + sizeof(ehdr.e_machine)); + e_entry = mopFileGetLXX((u_char *) &ehdr, + offsetof(Elf64_Ehdr, e_entry), + sizeof(ehdr.e_entry)); + + e_phoff = mopFileGetLXX((u_char *) &ehdr, + offsetof(Elf64_Ehdr, e_phoff), + sizeof(ehdr.e_phoff)); + e_phentsize = mopFileGetLX((u_char *) &ehdr, + offsetof(Elf64_Ehdr, e_phentsize), + sizeof(ehdr.e_phentsize)); + e_phnum = mopFileGetLX((u_char *) &ehdr, + offsetof(Elf64_Ehdr, e_phnum), + sizeof(ehdr.e_phnum)); + break; + + case ELFDATA2MSB: + e_machine = mopFileGetBX((u_char *) &ehdr, + offsetof(Elf64_Ehdr, e_machine), + sizeof(ehdr.e_machine)); + e_entry = mopFileGetBXX((u_char *) &ehdr, + offsetof(Elf64_Ehdr, e_entry), + sizeof(ehdr.e_entry)); + + e_phoff = mopFileGetBXX((u_char *) &ehdr, + offsetof(Elf64_Ehdr, e_phoff), + sizeof(ehdr.e_phoff)); + e_phentsize = mopFileGetBX((u_char *) &ehdr, + offsetof(Elf64_Ehdr, e_phentsize), + sizeof(ehdr.e_phentsize)); + e_phnum = mopFileGetBX((u_char *) &ehdr, + offsetof(Elf64_Ehdr, e_phnum), + sizeof(ehdr.e_phnum)); + break; + + default: + return(-1); + } + + if (e_phnum > SEC_MAX) + return(-1); + dl->e_nsec = e_phnum; + for (i = 0; i < dl->e_nsec; i++) { + if (lseek(dl->ldfd, (off_t) e_phoff + (i * e_phentsize), + SEEK_SET) == (off_t) -1) + return(-1); + if (read(dl->ldfd, (char *) &phdr, sizeof(phdr)) != + sizeof(phdr)) + return(-1); + + switch (ei_data) { + case ELFDATA2LSB: + dl->e_sections[i].s_foff = + mopFileGetLX((u_char *) &phdr, + offsetof(Elf64_Phdr, p_offset), + sizeof(phdr.p_offset)); + dl->e_sections[i].s_vaddr = + mopFileGetLX((u_char *) &phdr, + offsetof(Elf64_Phdr, p_vaddr), + sizeof(phdr.p_vaddr)); + dl->e_sections[i].s_fsize = + mopFileGetLX((u_char *) &phdr, + offsetof(Elf64_Phdr, p_filesz), + sizeof(phdr.p_filesz)); + dl->e_sections[i].s_msize = + mopFileGetLX((u_char *) &phdr, + offsetof(Elf64_Phdr, p_memsz), + sizeof(phdr.p_memsz)); + break; + + case ELFDATA2MSB: + dl->e_sections[i].s_foff = + mopFileGetBX((u_char *) &phdr, + offsetof(Elf64_Phdr, p_offset), + sizeof(phdr.p_offset)); + dl->e_sections[i].s_vaddr = + mopFileGetBX((u_char *) &phdr, + offsetof(Elf64_Phdr, p_vaddr), + sizeof(phdr.p_vaddr)); + dl->e_sections[i].s_fsize = + mopFileGetBX((u_char *) &phdr, + offsetof(Elf64_Phdr, p_filesz), + sizeof(phdr.p_filesz)); + dl->e_sections[i].s_msize = + mopFileGetBX((u_char *) &phdr, + offsetof(Elf64_Phdr, p_memsz), + sizeof(phdr.p_memsz)); + break; + + default: + return(-1); + } + } + /* + * In addition to padding between segments, this also + * takes care of memsz > filesz. + */ + for (i = 0; i < dl->e_nsec - 1; i++) { + dl->e_sections[i].s_pad = + dl->e_sections[i + 1].s_vaddr - + (dl->e_sections[i].s_vaddr + dl->e_sections[i].s_fsize); + } + dl->e_sections[dl->e_nsec - 1].s_pad = + dl->e_sections[dl->e_nsec - 1].s_msize - + dl->e_sections[dl->e_nsec - 1].s_fsize; + /* + * Now compute the logical offsets for each section. + */ + dl->e_sections[0].s_loff = 0; + for (i = 1; i < dl->e_nsec; i++) { + dl->e_sections[i].s_loff = + dl->e_sections[i - 1].s_loff + + dl->e_sections[i - 1].s_fsize + + dl->e_sections[i - 1].s_pad; + } + + dl->image_type = IMAGE_TYPE_ELF64; + dl->loadaddr = 0; +#if 0 + dl->xferaddr = e_entry; /* will relocate itself if necessary */ +#else + dl->xferaddr = e_entry - dl->e_sections[0].s_vaddr; +#endif + + /* Print info about the image. */ + if (info == INFO_PRINT) { + printf("Elf64 image ("); + switch (e_machine) { +#ifdef EM_ALPHA + case EM_ALPHA: +#endif +#ifdef EM_ALPHA_EXP + case EM_ALPHA_EXP: +#endif +#if defined(EM_ALPHA) || defined(EM_ALPHA_EXP) + printf("ALPHA"); + break; +#endif + default: + printf("machine %d", e_machine); + break; + } + printf(")\n"); + printf("Transfer Address: %08x\n", dl->xferaddr); + printf("Program Sections: %d\n", dl->e_nsec); + for (i = 0; i < dl->e_nsec; i++) { + printf(" S%d File Size: %08x\n", i, + dl->e_sections[i].s_fsize); + printf(" S%d Pad Size: %08x\n", i, + dl->e_sections[i].s_pad); + } + } + + dl->e_machine = e_machine; + + dl->e_curpos = 0; + dl->e_cursec = 0; + + return(0); +#endif /* NOELF || NOELF64 */ +} + int CheckAOutFile(int fd) { @@ -878,11 +1117,13 @@ GetAOutFileInfo(struct dllist *dl, int info) int GetFileInfo(struct dllist *dl, int info) { - int error; + int error; error = CheckElfFile(dl->ldfd); if (error == 0) { - error = GetElfFileInfo(dl, info); + error = GetElf32FileInfo(dl, info); + if (error != 0) + error = GetElf64FileInfo(dl, info); if (error != 0) { return(-1); } @@ -925,6 +1166,7 @@ mopFileRead(struct dllist *dlslot, u_char *buf) break; case IMAGE_TYPE_ELF32: + case IMAGE_TYPE_ELF64: sec = dlslot->e_cursec; /* diff --git a/usr.sbin/mopd/common/file.h b/usr.sbin/mopd/common/file.h index a4991076e99..ddfbf7913f9 100644 --- a/usr.sbin/mopd/common/file.h +++ b/usr.sbin/mopd/common/file.h @@ -1,4 +1,4 @@ -/* $OpenBSD: file.h,v 1.11 2013/07/05 21:02:07 miod Exp $ */ +/* $OpenBSD: file.h,v 1.12 2014/12/13 14:44:59 miod Exp $ */ /* * Copyright (c) 1993-95 Mats O Jansson. All rights reserved. @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $OpenBSD: file.h,v 1.11 2013/07/05 21:02:07 miod Exp $ + * $OpenBSD: file.h,v 1.12 2014/12/13 14:44:59 miod Exp $ * */ @@ -38,6 +38,8 @@ void mopFilePutLX(u_char *, int, u_int32_t, int); void mopFilePutBX(u_char *, int, u_int32_t, int); u_int32_t mopFileGetLX(u_char *, int, int); u_int32_t mopFileGetBX(u_char *, int, int); +u_int64_t mopFileGetLXX(u_char *, int, int); +u_int64_t mopFileGetBXX(u_char *, int, int); ssize_t mopFileRead(struct dllist *, u_char *); void mopFileSwapX(u_char *, int, int); @@ -45,7 +47,8 @@ int CheckMopFile(int); int GetMopFileInfo(struct dllist *, int); int CheckElfFile(int); -int GetElfFileInfo(struct dllist *, int); +int GetElf32FileInfo(struct dllist *, int); +int GetElf64FileInfo(struct dllist *, int); int CheckAOutFile(int); int GetAOutFileInfo(struct dllist *, int); diff --git a/usr.sbin/mopd/mopa.out/mopa.out.1 b/usr.sbin/mopd/mopa.out/mopa.out.1 index 01af191a1db..5c05200cc47 100644 --- a/usr.sbin/mopd/mopa.out/mopa.out.1 +++ b/usr.sbin/mopd/mopa.out/mopa.out.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: mopa.out.1,v 1.14 2013/10/20 07:40:43 jmc Exp $ +.\" $OpenBSD: mopa.out.1,v 1.15 2014/12/13 14:44:59 miod Exp $ .\" .\" Copyright (c) 1996 Mats O Jansson. All rights reserved. .\" @@ -22,9 +22,9 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" @(#) $OpenBSD: mopa.out.1,v 1.14 2013/10/20 07:40:43 jmc Exp $ +.\" @(#) $OpenBSD: mopa.out.1,v 1.15 2014/12/13 14:44:59 miod Exp $ .\" -.Dd $Mdocdate: October 20 2013 $ +.Dd $Mdocdate: December 13 2014 $ .Dt MOPA.OUT 1 .Os .Sh NAME @@ -38,8 +38,8 @@ .Nm is used to convert a file from another executable format to a MOP-image. .Pp -Elf32 and a.out VAX images are the only currently supported input -formats. +Elf64 alpha images, as well as Elf32 and a.out VAX images, +are the only currently supported input formats. .Sh SEE ALSO .Xr mopchk 1 , .Xr mopprobe 1 , diff --git a/usr.sbin/mopd/mopa.out/mopa.out.c b/usr.sbin/mopd/mopa.out/mopa.out.c index 964220e7cd2..09106e26a8c 100644 --- a/usr.sbin/mopd/mopa.out/mopa.out.c +++ b/usr.sbin/mopd/mopa.out/mopa.out.c @@ -1,6 +1,7 @@ -/* $OpenBSD: mopa.out.c,v 1.13 2013/10/17 08:02:21 deraadt Exp $ */ +/* $OpenBSD: mopa.out.c,v 1.14 2014/12/13 14:44:59 miod Exp $ */ -/* mopa.out - Convert a Unix format kernel into something that +/* + * mopa.out - Convert a Unix format kernel into something that * can be transferred via MOP. * * This code was written while referring to the NetBSD/vax boot @@ -71,12 +72,15 @@ #else #define NOELF #endif -#if !defined(EM_VAX) -#define EM_VAX 75 +#endif + +#ifndef NOELF +#if !defined(_LP64) +#define NOELF64 #endif #endif -u_char header[512]; /* The VAX header we generate is 1 block. */ +u_char header[512]; /* The MOP header we generate is 1 block. */ #if !defined(NOAOUT) struct exec ex, ex_swap; #endif @@ -87,6 +91,7 @@ main (int argc, char **argv) FILE *out; /* A FILE because that is easier. */ int i, j; struct dllist dl; + short image_type; #ifdef NOAOUT fprintf(stderr, "%s: has no function in OS/BSD\n", argv[0]); @@ -117,6 +122,18 @@ main (int argc, char **argv) "(machine=%d)\n", argv[1], dl.e_machine); for (i = 0, j = 0; j < dl.e_nsec; j++) i += dl.e_sections[j].s_fsize + dl.e_sections[j].s_pad; + image_type = IHD_C_NATIVE; + break; +#endif + +#if !defined(NOELF) && !defined(NOELF64) + case IMAGE_TYPE_ELF64: + if (dl.e_machine != EM_ALPHA && dl.e_machine != EM_ALPHA_EXP) + printf("WARNING: `%s' is not an ALPHA image " + "(machine=%d)\n", argv[1], dl.e_machine); + for (i = 0, j = 0; j < dl.e_nsec; j++) + i += dl.e_sections[j].s_fsize + dl.e_sections[j].s_pad; + image_type = IHD_C_ALPHA; break; #endif @@ -127,6 +144,7 @@ main (int argc, char **argv) argv[1], dl.a_mid); i = dl.a_text + dl.a_text_fill + dl.a_data + dl.a_data_fill + dl.a_bss + dl.a_bss_fill; + image_type = IHD_C_NATIVE; break; #endif @@ -135,27 +153,51 @@ main (int argc, char **argv) FileTypeName(dl.image_type)); } - i = (i+1) / 512; - dl.nloadaddr = dl.loadaddr; dl.lseek = lseek(dl.ldfd,0L,SEEK_CUR); dl.a_lseek = 0; dl.count = 0; dl.dl_bsz = 512; - mopFilePutLX(header,IHD_W_SIZE,0xd4,2); /* Offset to ISD section. */ - mopFilePutLX(header,IHD_W_ACTIVOFF,0x30,2);/* Offset to 1st section.*/ - mopFilePutLX(header,IHD_W_ALIAS,IHD_C_NATIVE,2);/* It's a VAX image.*/ - mopFilePutLX(header,IHD_B_HDRBLKCNT,1,1); /* Only one header block. */ - mopFilePutLX(header,0xd4+ISD_V_VPN,dl.loadaddr/512,2);/* load Addr */ - mopFilePutLX(header,0x30+IHA_L_TFRADR1,dl.xferaddr,4); /* Xfer Addr */ - mopFilePutLX(header,0xd4+ISD_W_PAGCNT,i,2);/* Imagesize in blks.*/ + switch (image_type) { + default: + case IHD_C_NATIVE: + /* Offset to ISD section. */ + mopFilePutLX(header, IHD_W_SIZE, 0xd4, 2); + /* Offset to 1st section.*/ + mopFilePutLX(header, IHD_W_ACTIVOFF, 0x30, 2); + /* It's a VAX image.*/ + mopFilePutLX(header, IHD_W_ALIAS, IHD_C_NATIVE, 2); + /* Only one header block. */ + mopFilePutLX(header, IHD_B_HDRBLKCNT, 1, 1); + + /* Xfer Addr */ + mopFilePutLX(header, 0x30 + IHA_L_TFRADR1, dl.xferaddr, 4); + + /* load Addr */ + mopFilePutLX(header, 0xd4 + ISD_V_VPN, dl.loadaddr / 512, 2); + /* Imagesize in blks.*/ + i = (i + 1) / 512; + mopFilePutLX(header, 0xd4 + ISD_W_PAGCNT, i, 2); + break; + case IHD_C_ALPHA: + /* Offset to ISD section. */ + mopFilePutLX(header, EIHD_L_ISDOFF, 0xd4, 4); + /* It's an alpha image.*/ + mopFilePutLX(header, IHD_W_ALIAS, IHD_C_ALPHA, 2); + /* Only one header block. */ + mopFilePutLX(header, EIHD_L_HDRBLKCNT, 1, 4); + + /* Imagesize in bytes.*/ + mopFilePutLX(header, 0xd4 + EISD_L_SECSIZE, i, 4); + break; + } out = fopen (argv[2], "w"); if (!out) err(2, "writing `%s'", argv[2]); - /* Now we do the actual work. Write VAX MOP-image header */ + /* Now we do the actual work. Write MOP-image header */ fwrite (header, sizeof (header), 1, out); diff --git a/usr.sbin/mopd/mopchk/mopchk.c b/usr.sbin/mopd/mopchk/mopchk.c index 83607e5e242..4596161946f 100644 --- a/usr.sbin/mopd/mopchk/mopchk.c +++ b/usr.sbin/mopd/mopchk/mopchk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mopchk.c,v 1.16 2013/07/05 21:02:07 miod Exp $ */ +/* $OpenBSD: mopchk.c,v 1.17 2014/12/13 14:44:59 miod Exp $ */ /* * Copyright (c) 1995-96 Mats O Jansson. All rights reserved. @@ -122,8 +122,9 @@ main(argc, argv) printf("Unknown file.\n"); } else { if ((error = CheckElfFile(dl.ldfd)) == 0) { - if (GetElfFileInfo(&dl, INFO_PRINT) < 0) { - printf("Some failure in GetElfFileInfo\n"); + if (GetElf32FileInfo(&dl, INFO_PRINT) < 0 && + GetElf64FileInfo(&dl, INFO_PRINT) < 0) { + printf("Some failure in GetElfXXFileInfo\n"); } } else if ((error = CheckAOutFile(dl.ldfd)) == 0) { if (GetAOutFileInfo(&dl, INFO_PRINT) < 0) {