diff options
author | miod <miod@openbsd.org> | 2013-07-05 21:02:07 +0000 |
---|---|---|
committer | miod <miod@openbsd.org> | 2013-07-05 21:02:07 +0000 |
commit | 05230cd51107c8382d98465f8b4e124b5cdc9dd5 (patch) | |
tree | 3a2325859f4a0657b2afa0aaa3d1ea915a8db92e /usr.sbin/mopd | |
parent | Avoid truncation when calculating clock gain/loss (diff) | |
download | wireguard-openbsd-05230cd51107c8382d98465f8b4e124b5cdc9dd5.tar.xz wireguard-openbsd-05230cd51107c8382d98465f8b4e124b5cdc9dd5.zip |
Teach mopd and mopa.out about ELF files, and allow forthcoming VAX ELF boot
blocks to be converted to working mop binaries. From NetBSD.
Diffstat (limited to 'usr.sbin/mopd')
-rw-r--r-- | usr.sbin/mopd/common/common.h | 95 | ||||
-rw-r--r-- | usr.sbin/mopd/common/device.c | 16 | ||||
-rw-r--r-- | usr.sbin/mopd/common/device.h | 10 | ||||
-rw-r--r-- | usr.sbin/mopd/common/file.c | 914 | ||||
-rw-r--r-- | usr.sbin/mopd/common/file.h | 36 | ||||
-rw-r--r-- | usr.sbin/mopd/mopa.out/mopa.out.1 | 24 | ||||
-rw-r--r-- | usr.sbin/mopd/mopa.out/mopa.out.c | 111 | ||||
-rw-r--r-- | usr.sbin/mopd/mopchk/mopchk.c | 32 | ||||
-rw-r--r-- | usr.sbin/mopd/mopd/mopd.c | 3 | ||||
-rw-r--r-- | usr.sbin/mopd/mopd/process.c | 8 | ||||
-rw-r--r-- | usr.sbin/mopd/mopprobe/mopprobe.c | 3 | ||||
-rw-r--r-- | usr.sbin/mopd/moptrace/moptrace.c | 3 |
12 files changed, 831 insertions, 424 deletions
diff --git a/usr.sbin/mopd/common/common.h b/usr.sbin/mopd/common/common.h index ea43ea3aaf4..80bbb496278 100644 --- a/usr.sbin/mopd/common/common.h +++ b/usr.sbin/mopd/common/common.h @@ -1,4 +1,5 @@ -/* $OpenBSD: common.h,v 1.7 2006/05/11 05:18:38 maja Exp $ */ +/* $OpenBSD: common.h,v 1.8 2013/07/05 21:02:07 miod Exp $ */ +/* $NetBSD: common.h,v 1.9 2011/08/30 19:49:10 joerg Exp $ */ /* * Copyright (c) 1993-95 Mats O Jansson. All rights reserved. @@ -23,25 +24,23 @@ * (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: common.h,v 1.7 2006/05/11 05:18:38 maja Exp $ - * */ #ifndef _COMMON_H_ #define _COMMON_H_ -#define MAXDL 16 /* maximum number concurrent load */ -#define IFNAME_SIZE 32 /* maximum size if interface name */ -#define BUFSIZE 1600 /* main receive buffer size */ -#define HDRSIZ 22 /* room for 803.2 header */ +#define MAXDL 16 /* maximum number concurrent load */ +#define IFNAME_SIZE 32 /* maximum size if interface name */ +#define BUFSIZE 1600 /* main receive buffer size */ +#define HDRSIZ 22 /* room for 803.2 header */ #ifndef MOP_FILE_PATH #define MOP_FILE_PATH "/tftpboot/mop" #endif -#define DEBUG_ONELINE 1 -#define DEBUG_HEADER 2 -#define DEBUG_INFO 3 +#define DEBUG_ONELINE 1 +#define DEBUG_HEADER 2 +#define DEBUG_INFO 3 /* * structure per interface @@ -53,37 +52,63 @@ struct if_info { int trans; /* Transport type Ethernet/802.3 */ u_char eaddr[6]; /* Ethernet addr of this interface */ char if_name[IFNAME_SIZE]; /* Interface Name */ - int (*iopen)(); /* Interface Open Routine */ - int (*write)(); /* Interface Write Routine */ - void (*read)(); /* Interface Read Routine */ + int (*iopen)(char *, int, u_short, int); + /* Interface Open Routine */ + int (*write)(int, u_char *, int, int); + /* Interface Write Routine */ + void (*read)(void); /* Interface Read Routine */ struct if_info *next; /* Next Interface */ }; -#define DL_STATUS_FREE 0 -#define DL_STATUS_READ_IMGHDR 1 -#define DL_STATUS_SENT_MLD 2 -#define DL_STATUS_SENT_PLT 3 +#define DL_STATUS_FREE 0 +#define DL_STATUS_READ_IMGHDR 1 +#define DL_STATUS_SENT_MLD 2 +#define DL_STATUS_SENT_PLT 3 + +typedef enum { + IMAGE_TYPE_MOP, /* MOP image */ + IMAGE_TYPE_AOUT, /* a.out image */ + IMAGE_TYPE_ELF32 /* Elf32 image */ +} mopd_imagetype; struct dllist { - u_char status; /* Status byte */ + u_char status; /* Status byte */ struct if_info *ii; /* interface pointer */ - u_char eaddr[6]; /* targets ethernet address */ - int ldfd; /* filedescriptor for loadfile */ - u_long dl_bsz; /* Data Link Buffer Size */ - int timeout; /* Timeout counter */ - u_char count; /* Packet Counter */ - u_long loadaddr; /* Load Address */ - u_long xferaddr; /* Transfer Address */ - u_long nloadaddr; /* Next Load Address */ - off_t lseek; /* Seek before last read */ - int aout; /* Is it an a.out file */ - u_long a_text; /* Size of text segment */ - u_long a_text_fill; /* Size of text segment fill */ - u_long a_data; /* Size of data segment */ - u_long a_data_fill; /* Size of data segment fill */ - u_long a_bss; /* Size of bss segment */ - u_long a_bss_fill; /* Size of bss segment fill */ - off_t a_lseek; /* Keep track of pos in newfile */ + u_char eaddr[6]; /* targets ethernet addres */ + int ldfd; /* filedescriptor for loadfile */ + u_short dl_bsz; /* Data Link Buffer Size */ + int timeout; /* Timeout counter */ + u_char count; /* Packet Counter */ + u_int32_t loadaddr; /* Load Address */ + u_int32_t xferaddr; /* Transfer Address */ + u_int32_t nloadaddr; /* Next Load Address */ + off_t lseek; /* Seek before last read */ + mopd_imagetype image_type; /* what type of image is it? */ + + /* For Elf32 files */ + int e_machine; /* Machine ID */ + int e_nsec; /* number of program sections */ +#define SEC_MAX 4 + struct { + off_t s_foff; /* file offset of section */ + u_int32_t s_vaddr; /* virtual address of section */ + u_int32_t s_fsize; /* file size of section */ + u_int32_t s_msize; /* memory size of section */ + u_int32_t s_pad; /* padding until next section */ + u_int32_t s_loff; /* logical offset into image */ + } e_sections[SEC_MAX]; /* program sections */ + u_int32_t e_curpos; /* current logical position */ + int e_cursec; /* current section */ + + /* For a.out files */ + int a_mid; /* Machine ID */ + u_int32_t a_text; /* Size of text segment */ + u_int32_t a_text_fill; /* Size of text segment fill */ + u_int32_t a_data; /* Size of data segment */ + u_int32_t a_data_fill; /* Size of data segment fill */ + u_int32_t a_bss; /* Size of bss segment */ + u_int32_t a_bss_fill; /* Size of bss segment fill */ + off_t a_lseek; /* Keep track of pos in newfile */ }; #endif /* _COMMON_H_ */ diff --git a/usr.sbin/mopd/common/device.c b/usr.sbin/mopd/common/device.c index 394719a8777..35f0728652d 100644 --- a/usr.sbin/mopd/common/device.c +++ b/usr.sbin/mopd/common/device.c @@ -1,4 +1,4 @@ -/* $OpenBSD: device.c,v 1.14 2009/10/27 23:59:52 deraadt Exp $ */ +/* $OpenBSD: device.c,v 1.15 2013/07/05 21:02:07 miod Exp $ */ /* * Copyright (c) 1993-95 Mats O Jansson. All rights reserved. @@ -25,19 +25,13 @@ */ #include "os.h" -#include "common/common.h" -#include "common/mopdef.h" +#include "common.h" +#include "device.h" +#include "mopdef.h" +#include "pf.h" struct if_info *iflist; /* Interface List */ -void mopReadDL(void); -void mopReadRC(void); -int mopOpenDL(struct if_info *, int); -int mopOpenRC(struct if_info *, int); -int pfTrans(); -int pfInit(); -int pfWrite(); - #ifdef DEV_NEW_CONF /* * Return ethernet address for interface diff --git a/usr.sbin/mopd/common/device.h b/usr.sbin/mopd/common/device.h index 0af7b8abba8..681c5d6cabb 100644 --- a/usr.sbin/mopd/common/device.h +++ b/usr.sbin/mopd/common/device.h @@ -1,4 +1,4 @@ -/* $OpenBSD: device.h,v 1.7 2004/04/14 20:37:28 henning Exp $ */ +/* $OpenBSD: device.h,v 1.8 2013/07/05 21:02:07 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: device.h,v 1.7 2004/04/14 20:37:28 henning Exp $ + * $OpenBSD: device.h,v 1.8 2013/07/05 21:02:07 miod Exp $ * */ @@ -36,4 +36,10 @@ void deviceEthAddr(char *, u_char *); void deviceInitOne(char *); void deviceInitAll(void); +__dead void Loop(void); +int mopOpenDL(struct if_info *, int); +int mopOpenRC(struct if_info *, int); +void mopReadDL(void); +void mopReadRC(void); + #endif /* _DEVICE_H_ */ diff --git a/usr.sbin/mopd/common/file.c b/usr.sbin/mopd/common/file.c index b6838378c8b..55a9566c80c 100644 --- a/usr.sbin/mopd/common/file.c +++ b/usr.sbin/mopd/common/file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: file.c,v 1.13 2009/10/27 23:59:52 deraadt Exp $ */ +/* $OpenBSD: file.c,v 1.14 2013/07/05 21:02:07 miod Exp $ */ /* * Copyright (c) 1995-96 Mats O Jansson. All rights reserved. @@ -25,10 +25,10 @@ */ #include "os.h" -#include "common/common.h" -#include "common/mopdef.h" - -#define INFO_PRINT 1 +#include "common.h" +#include "file.h" +#include "mopdef.h" +#include <stddef.h> #ifndef NOAOUT #if defined(__NetBSD__) || defined(__OpenBSD__) @@ -51,58 +51,94 @@ #endif #endif +#ifndef NOELF +#if defined(__NetBSD__) || defined(__OpenBSD__) +#include <sys/exec_elf.h> +#else +#define NOELF +#endif +#endif + +#ifndef NOAOUT +static int getCLBYTES(int); +static int getMID(int, int); +#endif + +const char * +FileTypeName(mopd_imagetype type) +{ + + switch (type) { + case IMAGE_TYPE_MOP: + return ("MOP"); + + case IMAGE_TYPE_ELF32: + return ("Elf32"); + + case IMAGE_TYPE_AOUT: + return ("a.out"); + } + + abort(); +} + void -mopFilePutLX(u_char *buf, int idx, u_long value, int cnt) +mopFilePutLX(u_char *buf, int idx, u_int32_t value, int cnt) { int i; for (i = 0; i < cnt; i++) { - buf[idx+i] = (u_char)(value % 256); - value = (u_char)(value / 256); + buf[idx+i] = value % 256; + value = value / 256; } } void -mopFilePutBX(u_char *buf, int idx, u_long value, int cnt) +mopFilePutBX(u_char *buf, int idx, u_int32_t value, int cnt) { int i; for (i = 0; i < cnt; i++) { - buf[idx+cnt-1-i] = (u_char)(value % 256); + buf[idx+cnt-1-i] = value % 256; value = value / 256; } } -u_long -mopFileGetLX(void *buffer, int idx, int cnt) +u_int32_t +mopFileGetLX(u_char *buf, int idx, int cnt) { - u_long ret = 0; - int i; - u_char *buf = (u_char *)buffer; + u_int32_t ret = 0; + int i; - for (i = 0; i < cnt; i++) - ret = ret*256 + buf[idx+cnt-1-i]; + for (i = 0; i < cnt; i++) { + int j = idx + cnt - 1 - i; + if (j < 0) + abort(); + ret = ret * 256 + buf[j]; + } - return (ret); + return(ret); } -u_long -mopFileGetBX(void *buffer, int idx, int cnt) +u_int32_t +mopFileGetBX(u_char *buf, int idx, int cnt) { - u_long ret = 0; - int i; - u_char *buf = (u_char *)buffer; + u_int32_t ret = 0; + int i; - for (i = 0; i < cnt; i++) - ret = ret*256 + buf[idx+i]; + for (i = 0; i < cnt; i++) { + int j = idx + i; + if (j < 0) + abort(); + ret = ret * 256 + buf[j]; + } - return (ret); + return(ret); } void -mopFileSwapX(void *buffer, int idx, int cnt) +mopFileSwapX(u_char *buf, int idx, int cnt) { - int i; - u_char c; - u_char *buf = (u_char *)buffer; + int i; + u_char c; for (i = 0; i < (cnt / 2); i++) { c = buf[idx+i]; @@ -119,13 +155,14 @@ CheckMopFile(int fd) short image_type; if (read(fd, header, 512) != 512) - return (-1); + return(-1); - lseek(fd, 0, SEEK_SET); + (void)lseek(fd, (off_t) 0, SEEK_SET); - image_type = (short)mopFileGetLX(header,IHD_W_ALIAS,2); + image_type = (u_short)(header[IHD_W_ALIAS+1]*256 + + header[IHD_W_ALIAS]); - switch (image_type) { + 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 */ @@ -135,117 +172,141 @@ CheckMopFile(int fd) case IHD_C_ALPHA: /* ALPHA system image */ break; default: - return (-1); + return(-1); } - return (0); + return(0); } int -GetMopFileInfo(int fd, u_long *load, u_long *xfr, int info) +GetMopFileInfo(struct dllist *dl, int info) { - u_char header[512]; - short image_type, isd, iha; - u_long load_addr, xfr_addr, isize, hbcnt; + u_char header[512]; + short image_type; + u_int32_t load_addr, xfr_addr, isd, iha, hbcnt, isize; - if (read(fd, header, 512) != 512) - return (-1); + if (read(dl->ldfd, header, 512) != 512) + return(-1); - image_type = (short)mopFileGetLX(header,IHD_W_ALIAS,2); + image_type = (u_short)(header[IHD_W_ALIAS+1]*256 + + header[IHD_W_ALIAS]); - switch (image_type) { + switch(image_type) { case IHD_C_NATIVE: /* Native mode image (VAX) */ - isd = (short)mopFileGetLX(header,IHD_W_SIZE,2); - iha = (short)mopFileGetLX(header,IHD_W_ACTIVOFF,2); - hbcnt = header[IHD_B_HDRBLKCNT]; - isize = mopFileGetLX(header,isd+ISD_W_PAGCNT,2) * 512; - load_addr = (mopFileGetLX(header,isd+ISD_V_VPN,2) & - ISD_M_VPN) * 512; - xfr_addr = mopFileGetLX(header,iha+IHA_L_TFRADR1,4) & - 0x7fffffff; + 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: %lu\n", hbcnt); - printf("Image Size: %08lx\n", isize); - printf("Load Address: %08lx\n", load_addr); - printf("Transfer Address: %08lx\n", xfr_addr); + 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 = mopFileGetLX(header,L_BBLK,2); - isize = mopFileGetLX(header,L_BLDZ,2) * 64; - load_addr = mopFileGetLX(header,L_BSA,2); - xfr_addr = mopFileGetLX(header,L_BXFR,2); + 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: %lu\n",hbcnt); - printf("Image Size: %08lx\n", isize); - printf("Load Address: %08lx\n", load_addr); - printf("Transfer Address: %08lx\n", xfr_addr); + 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); + return(-1); + break; case IHD_C_ALIAS: /* Alias */ if (info == INFO_PRINT) { printf("Alias, not supported\n"); } - return (-1); + return(-1); + break; case IHD_C_CLI: /* Image is CLI */ if (info == INFO_PRINT) { printf("CLI, not supported\n"); } - return (-1); + return(-1); + break; case IHD_C_PMAX: /* PMAX system image */ - isd = (short)mopFileGetLX(header,IHD_W_SIZE,2); - iha = (short)mopFileGetLX(header,IHD_W_ACTIVOFF,2); - hbcnt = header[IHD_B_HDRBLKCNT]; - isize = mopFileGetLX(header,isd+ISD_W_PAGCNT,2) * 512; - load_addr = mopFileGetLX(header,isd+ISD_V_VPN,2) * 512; - xfr_addr = mopFileGetLX(header,iha+IHA_L_TFRADR1,4); + 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: %lu\n", hbcnt); - printf("Image Size: %08lx\n", isize); - printf("Load Address: %08lx\n", load_addr); - printf("Transfer Address: %08lx\n", xfr_addr); + 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 = (short)mopFileGetLX(header,EIHD_L_ISDOFF,4); - hbcnt = mopFileGetLX(header,EIHD_L_HDRBLKCNT,4); - isize = mopFileGetLX(header,isd+EISD_L_SECSIZE,4); + 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: %lu\n", hbcnt); - printf("Image Size: %08lx\n", isize); - printf("Load Address: %08lx\n", load_addr); - printf("Transfer Address: %08lx\n", xfr_addr); + 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); + printf("Unknown Image (%d)\n",image_type); } - return (-1); + return(-1); } - if (load != NULL) - *load = load_addr; - - if (xfr != NULL) - *xfr = xfr_addr; + dl->image_type = IMAGE_TYPE_MOP; + dl->loadaddr = load_addr; + dl->xferaddr = xfr_addr; - return (0); + return(0); } #ifndef NOAOUT -int +static int getMID(int old_mid, int new_mid) { int mid; @@ -303,13 +364,13 @@ getMID(int old_mid, int new_mid) break; } - return (mid); + return(mid); } -u_int +static int getCLBYTES(int mid) { - u_int clbytes; + int clbytes; switch (mid) { #ifdef MID_VAX @@ -317,14 +378,15 @@ getCLBYTES(int mid) clbytes = 1024; break; #endif +#ifdef MID_I386 case MID_I386: +#endif #ifdef MID_M68K4K case MID_M68K4K: #endif #ifdef MID_NS32532 case MID_NS32532: #endif - case MID_SPARC: /* It might be 8192 */ #ifdef MID_PMAX case MID_PMAX: #endif @@ -334,15 +396,21 @@ getCLBYTES(int mid) #ifdef MID_ARM6 case MID_ARM6: #endif +#if defined(MID_I386) || defined(MID_M68K4K) || defined(MID_NS32532) || \ + defined(MID_PMAX) || defined(MID_MIPS) || defined(MID_ARM6) clbytes = 4096; break; +#endif #ifdef MID_M68K case MID_M68K: #endif #ifdef MID_ALPHA case MID_ALPHA: #endif -#if defined(MID_M68K) || defined(MID_ALPHA) +#ifdef MID_SPARC + case MID_SPARC: +#endif +#if defined(MID_M68K) || defined(MID_ALPHA) || defined(MID_SPARC) clbytes = 8192; break; #endif @@ -350,76 +418,297 @@ getCLBYTES(int mid) clbytes = 0; } - return (clbytes); + return(clbytes); } #endif int -CheckAOutFile(int fd) +CheckElfFile(int fd) { -#ifdef NOAOUT - return (-1); +#ifdef NOELF + return(-1); #else - struct exec ex, ex_swap; - int mid = -1; + Elf32_Ehdr ehdr; - if (read(fd, &ex, sizeof(ex)) != (ssize_t)sizeof(ex)) - return (-1); + (void)lseek(fd, (off_t) 0, SEEK_SET); - lseek(fd, 0, SEEK_SET); + if (read(fd, (char *)&ehdr, sizeof(ehdr)) != sizeof(ehdr)) + return(-1); - if (read(fd, &ex_swap, sizeof(ex_swap)) != (ssize_t)sizeof(ex_swap)) - 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); - lseek(fd, 0, SEEK_SET); + /* Must be Elf32... */ + if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) + return(-1); - mid = getMID(mid, (int)N_GETMID(ex)); + return(0); +#endif /* NOELF */ +} - if (mid == -1) - mid = getMID(mid, (int)N_GETMID(ex_swap)); +int +GetElfFileInfo(struct dllist *dl, int info) +{ +#ifdef NOELF + return(-1); +#else + Elf32_Ehdr ehdr; + Elf32_Phdr phdr; + uint32_t e_machine, e_entry; + uint32_t e_phoff, e_phentsize, e_phnum; + 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 Elf32... */ + if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) + return(-1); + + ei_data = ehdr.e_ident[EI_DATA]; + + switch (ei_data) { + case ELFDATA2LSB: + e_machine = mopFileGetLX((u_char *) &ehdr, + offsetof(Elf32_Ehdr, e_machine), + sizeof(ehdr.e_machine)); + e_entry = mopFileGetLX((u_char *) &ehdr, + offsetof(Elf32_Ehdr, e_entry), + sizeof(ehdr.e_entry)); + + e_phoff = mopFileGetLX((u_char *) &ehdr, + offsetof(Elf32_Ehdr, e_phoff), + sizeof(ehdr.e_phoff)); + e_phentsize = mopFileGetLX((u_char *) &ehdr, + offsetof(Elf32_Ehdr, e_phentsize), + sizeof(ehdr.e_phentsize)); + e_phnum = mopFileGetLX((u_char *) &ehdr, + offsetof(Elf32_Ehdr, e_phnum), + sizeof(ehdr.e_phnum)); + break; - if (mid != -1) - return (0); - else - return (-1); + case ELFDATA2MSB: + e_machine = mopFileGetBX((u_char *) &ehdr, + offsetof(Elf32_Ehdr, e_machine), + sizeof(ehdr.e_machine)); + e_entry = mopFileGetBX((u_char *) &ehdr, + offsetof(Elf32_Ehdr, e_entry), + sizeof(ehdr.e_entry)); + + e_phoff = mopFileGetBX((u_char *) &ehdr, + offsetof(Elf32_Ehdr, e_phoff), + sizeof(ehdr.e_phoff)); + e_phentsize = mopFileGetBX((u_char *) &ehdr, + offsetof(Elf32_Ehdr, e_phentsize), + sizeof(ehdr.e_phentsize)); + e_phnum = mopFileGetBX((u_char *) &ehdr, + offsetof(Elf32_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(Elf32_Phdr, p_offset), + sizeof(phdr.p_offset)); + dl->e_sections[i].s_vaddr = + mopFileGetLX((u_char *) &phdr, + offsetof(Elf32_Phdr, p_vaddr), + sizeof(phdr.p_vaddr)); + dl->e_sections[i].s_fsize = + mopFileGetLX((u_char *) &phdr, + offsetof(Elf32_Phdr, p_filesz), + sizeof(phdr.p_filesz)); + dl->e_sections[i].s_msize = + mopFileGetLX((u_char *) &phdr, + offsetof(Elf32_Phdr, p_memsz), + sizeof(phdr.p_memsz)); + break; + + case ELFDATA2MSB: + dl->e_sections[i].s_foff = + mopFileGetBX((u_char *) &phdr, + offsetof(Elf32_Phdr, p_offset), + sizeof(phdr.p_offset)); + dl->e_sections[i].s_vaddr = + mopFileGetBX((u_char *) &phdr, + offsetof(Elf32_Phdr, p_vaddr), + sizeof(phdr.p_vaddr)); + dl->e_sections[i].s_fsize = + mopFileGetBX((u_char *) &phdr, + offsetof(Elf32_Phdr, p_filesz), + sizeof(phdr.p_filesz)); + dl->e_sections[i].s_msize = + mopFileGetBX((u_char *) &phdr, + offsetof(Elf32_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_ELF32; + 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("Elf32 image ("); + switch (e_machine) { +#ifdef EM_VAX + case EM_VAX: + printf("VAX"); + 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 */ +} + +int +CheckAOutFile(int fd) +{ +#ifdef NOAOUT + return(-1); +#else + struct exec ex, ex_swap; + int mid = -1; + + if (read(fd, (char *)&ex, sizeof(ex)) != sizeof(ex)) + return(-1); + + (void)lseek(fd, (off_t) 0, SEEK_SET); + + if (read(fd, (char *)&ex_swap, sizeof(ex_swap)) != sizeof(ex_swap)) + return(-1); + + (void)lseek(fd, (off_t) 0, SEEK_SET); + + mid = getMID(mid, N_GETMID (ex)); + + if (mid == -1) { + mid = getMID(mid, N_GETMID (ex_swap)); + } + + if (mid != -1) { + return(0); + } else { + return(-1); + } #endif /* NOAOUT */ } int -GetAOutFileInfo(int fd, u_long *load, u_long *xfr, u_long *a_text, - u_long *a_text_fill, u_long *a_data, u_long *a_data_fill, u_long *a_bss, - u_long *a_bss_fill, int *aout, int info) +GetAOutFileInfo(struct dllist *dl, int info) { #ifdef NOAOUT - return (-1); + return(-1); #else - struct exec ex, ex_swap; - int mid = -1; - u_long magic, clbytes, clofset; + struct exec ex, ex_swap; + u_int32_t mid = -1; + u_int32_t magic, clbytes, clofset; - if (read(fd, &ex, sizeof(ex)) != (ssize_t)sizeof(ex)) - return (-1); + if (read(dl->ldfd, (char *)&ex, sizeof(ex)) != sizeof(ex)) + return(-1); - lseek(fd, 0, SEEK_SET); + (void)lseek(dl->ldfd, (off_t) 0, SEEK_SET); - if (read(fd, &ex_swap, sizeof(ex_swap)) != (ssize_t)sizeof(ex_swap)) - return (-1); + if (read(dl->ldfd, (char *)&ex_swap, + sizeof(ex_swap)) != sizeof(ex_swap)) + return(-1); - mopFileSwapX(&ex_swap, 0, 4); + mopFileSwapX((u_char *)&ex_swap, 0, 4); - mid = getMID(mid, (int)N_GETMID(ex)); + mid = getMID(mid, N_GETMID (ex)); - if (mid == -1) { - mid = getMID(mid, (int)N_GETMID(ex_swap)); - if (mid != -1) - mopFileSwapX(&ex, 0, 4); + if (mid == (uint32_t)-1) { + mid = getMID(mid, N_GETMID (ex_swap)); + if (mid != (uint32_t)-1) { + mopFileSwapX((u_char *)&ex, 0, 4); + } } - if (mid == -1) - return (-1); + if (mid == (uint32_t)-1) { + return(-1); + } - if (N_BADMAG(ex)) - return (-1); + if (N_BADMAG (ex)) { + return(-1); + } switch (mid) { case MID_I386: @@ -438,13 +727,13 @@ GetAOutFileInfo(int fd, u_long *load, u_long *xfr, u_long *a_text, #ifdef MID_ARM6 case MID_ARM6: #endif - ex.a_text = (u_int)mopFileGetLX(&ex_swap, 4, 4); - ex.a_data = (u_int)mopFileGetLX(&ex_swap, 8, 4); - ex.a_bss = (u_int)mopFileGetLX(&ex_swap, 12, 4); - ex.a_syms = (u_int)mopFileGetLX(&ex_swap, 16, 4); - ex.a_entry = (u_int)mopFileGetLX(&ex_swap, 20, 4); - ex.a_trsize = (u_int)mopFileGetLX(&ex_swap, 24, 4); - ex.a_drsize = (u_int)mopFileGetLX(&ex_swap, 28, 4); + ex.a_text = mopFileGetLX((u_char *)&ex_swap, 4, 4); + ex.a_data = mopFileGetLX((u_char *)&ex_swap, 8, 4); + ex.a_bss = mopFileGetLX((u_char *)&ex_swap, 12, 4); + ex.a_syms = mopFileGetLX((u_char *)&ex_swap, 16, 4); + ex.a_entry = mopFileGetLX((u_char *)&ex_swap, 20, 4); + ex.a_trsize= mopFileGetLX((u_char *)&ex_swap, 24, 4); + ex.a_drsize= mopFileGetLX((u_char *)&ex_swap, 28, 4); break; #ifdef MID_M68K case MID_M68K: @@ -456,13 +745,13 @@ GetAOutFileInfo(int fd, u_long *load, u_long *xfr, u_long *a_text, #ifdef MID_MIPS case MID_MIPS: #endif - ex.a_text = (u_int)mopFileGetBX(&ex_swap, 4, 4); - ex.a_data = (u_int)mopFileGetBX(&ex_swap, 8, 4); - ex.a_bss = (u_int)mopFileGetBX(&ex_swap, 12, 4); - ex.a_syms = (u_int)mopFileGetBX(&ex_swap, 16, 4); - ex.a_entry = (u_int)mopFileGetBX(&ex_swap, 20, 4); - ex.a_trsize = (u_int)mopFileGetBX(&ex_swap, 24, 4); - ex.a_drsize = (u_int)mopFileGetBX(&ex_swap, 28, 4); + ex.a_text = mopFileGetBX((u_char *)&ex_swap, 4, 4); + ex.a_data = mopFileGetBX((u_char *)&ex_swap, 8, 4); + ex.a_bss = mopFileGetBX((u_char *)&ex_swap, 12, 4); + ex.a_syms = mopFileGetBX((u_char *)&ex_swap, 16, 4); + ex.a_entry = mopFileGetBX((u_char *)&ex_swap, 20, 4); + ex.a_trsize= mopFileGetBX((u_char *)&ex_swap, 24, 4); + ex.a_drsize= mopFileGetBX((u_char *)&ex_swap, 28, 4); break; default: break; @@ -470,7 +759,7 @@ GetAOutFileInfo(int fd, u_long *load, u_long *xfr, u_long *a_text, if (info == INFO_PRINT) { printf("a.out image ("); - switch (N_GETMID(ex)) { + switch (N_GETMID (ex)) { case MID_I386: printf("i386"); break; @@ -535,202 +824,259 @@ GetAOutFileInfo(int fd, u_long *load, u_long *xfr, u_long *a_text, printf("QMAGIC"); break; default: - printf("Unknown %d",N_GETMAGIC (ex)); + printf("Unknown %ld", (long) N_GETMAGIC (ex)); } printf("\n"); - printf("Size of text: %08x\n", ex.a_text); - printf("Size of data: %08x\n", ex.a_data); - printf("Size of bss: %08x\n", ex.a_bss); - printf("Size of symbol tab: %08x\n", ex.a_syms); - printf("Transfer Address: %08x\n", ex.a_entry); - printf("Size of reloc text: %08x\n", ex.a_trsize); - printf("Size of reloc data: %08x\n", ex.a_drsize); + printf("Size of text: %08lx\n", (long)ex.a_text); + printf("Size of data: %08lx\n", (long)ex.a_data); + printf("Size of bss: %08lx\n", (long)ex.a_bss); + printf("Size of symbol tab: %08lx\n", (long)ex.a_syms); + printf("Transfer Address: %08lx\n", (long)ex.a_entry); + printf("Size of reloc text: %08lx\n", (long)ex.a_trsize); + printf("Size of reloc data: %08lx\n", (long)ex.a_drsize); } - magic = N_GETMAGIC(ex); + + magic = N_GETMAGIC (ex); clbytes = getCLBYTES(mid); clofset = clbytes - 1; - if (load != NULL) - *load = 0; - - if (xfr != NULL) - *xfr = ex.a_entry; - - if (a_text != NULL) - *a_text = ex.a_text; - - if (a_text_fill != NULL) { - if (magic == ZMAGIC || magic == NMAGIC) { - *a_text_fill = clbytes - (ex.a_text & clofset); - if (*a_text_fill == clbytes) - *a_text_fill = 0; - } else - *a_text_fill = 0; - } - - if (a_data != NULL) - *a_data = ex.a_data; - - if (a_data_fill != NULL) { - if (magic == ZMAGIC || magic == NMAGIC) { - *a_data_fill = clbytes - (ex.a_data & clofset); - if (*a_data_fill == clbytes) - *a_data_fill = 0; - } else - *a_data_fill = 0; - } - - if (a_bss != NULL) - *a_bss = ex.a_bss; - - if (a_bss_fill != NULL) { - if (magic == ZMAGIC || magic == NMAGIC) { - *a_bss_fill = clbytes - (ex.a_bss & clofset); - if (*a_bss_fill == clbytes) - *a_bss_fill = 0; - } else { - *a_bss_fill = clbytes - - ((ex.a_text + ex.a_data + ex.a_bss) & clofset); - if (*a_text_fill == clbytes) - *a_text_fill = 0; - } + dl->image_type = IMAGE_TYPE_AOUT; + dl->loadaddr = 0; + dl->xferaddr = ex.a_entry; + + dl->a_text = ex.a_text; + if (magic == ZMAGIC || magic == NMAGIC) { + dl->a_text_fill = clbytes - (ex.a_text & clofset); + if (dl->a_text_fill == clbytes) + dl->a_text_fill = 0; + } else + dl->a_text_fill = 0; + dl->a_data = ex.a_data; + if (magic == ZMAGIC || magic == NMAGIC) { + dl->a_data_fill = clbytes - (ex.a_data & clofset); + if (dl->a_data_fill == clbytes) + dl->a_data_fill = 0; + } else + dl->a_data_fill = 0; + dl->a_bss = ex.a_bss; + if (magic == ZMAGIC || magic == NMAGIC) { + dl->a_bss_fill = clbytes - (ex.a_bss & clofset); + if (dl->a_bss_fill == clbytes) + dl->a_bss_fill = 0; + } else { + dl->a_bss_fill = clbytes - + ((ex.a_text+ex.a_data+ex.a_bss) & clofset); + if (dl->a_bss_fill == clbytes) + dl->a_bss_fill = 0; } + dl->a_mid = mid; - if (aout != NULL) - *aout = mid; - - return (0); + return(0); #endif /* NOAOUT */ } int -GetFileInfo(int fd, u_long *load, u_long *xfr, int *aout, u_long *a_text, - u_long *a_text_fill, u_long *a_data, u_long *a_data_fill, u_long *a_bss, - u_long *a_bss_fill, int info) +GetFileInfo(struct dllist *dl, int info) { - int err; + int error; - err = CheckAOutFile(fd); + error = CheckElfFile(dl->ldfd); + if (error == 0) { + error = GetElfFileInfo(dl, info); + if (error != 0) { + return(-1); + } + return (0); + } - if (err == 0) { - err = GetAOutFileInfo(fd, load, xfr, a_text, a_text_fill, - a_data, a_data_fill, a_bss, a_bss_fill, aout, info); - if (err != 0) - return (-1); - } else { - err = CheckMopFile(fd); + error = CheckAOutFile(dl->ldfd); + if (error == 0) { + error = GetAOutFileInfo(dl, info); + if (error != 0) { + return(-1); + } + return (0); + } - if (err == 0) { - err = GetMopFileInfo(fd, load, xfr, info); - if (err != 0) - return (-1); - *aout = -1; - } else - return (-1); + error = CheckMopFile(dl->ldfd); + if (error == 0) { + error = GetMopFileInfo(dl, info); + if (error != 0) { + return(-1); + } + return (0); } - return (0); + /* Unknown file format. */ + return(-1); } ssize_t mopFileRead(struct dllist *dlslot, u_char *buf) { ssize_t len, outlen; - u_long bsz, total, notdone; - off_t pos; - - if (dlslot->aout == -1) + int bsz, sec; + int32_t pos, notdone, total; + uint32_t secoff; + + switch (dlslot->image_type) { + case IMAGE_TYPE_MOP: len = read(dlslot->ldfd,buf,dlslot->dl_bsz); - else { + break; + + case IMAGE_TYPE_ELF32: + sec = dlslot->e_cursec; + + /* + * We're pretty simplistic here. We do only file-backed + * or only zero-fill. + */ + + /* Determine offset into section. */ + secoff = dlslot->e_curpos - dlslot->e_sections[sec].s_loff; + + /* + * If we're in the file-backed part of the section, + * transmit some of the file. + */ + if (secoff < dlslot->e_sections[sec].s_fsize) { + bsz = dlslot->e_sections[sec].s_fsize - secoff; + if (bsz > dlslot->dl_bsz) + bsz = dlslot->dl_bsz; + if (lseek(dlslot->ldfd, + dlslot->e_sections[sec].s_foff + secoff, + SEEK_SET) == (off_t) -1) + return (-1); + len = read(dlslot->ldfd, buf, bsz); + } + /* + * Otherwise, if we're in the zero-fill part of the + * section, transmit some zeros. + */ + else if (secoff < (dlslot->e_sections[sec].s_fsize + + dlslot->e_sections[sec].s_pad)) { + bsz = dlslot->e_sections[sec].s_pad - + (secoff - dlslot->e_sections[sec].s_fsize); + if (bsz > dlslot->dl_bsz) + bsz = dlslot->dl_bsz; + memset(buf, 0, (len = bsz)); + } + /* + * ...and if we haven't hit either of those cases, + * that's the end of the image. + */ + else { + return (0); + } + /* + * Advance the logical image pointer. + */ + dlslot->e_curpos += bsz; + if (dlslot->e_curpos >= (dlslot->e_sections[sec].s_loff + + dlslot->e_sections[sec].s_fsize + + dlslot->e_sections[sec].s_pad)) + dlslot->e_cursec++; + break; + + case IMAGE_TYPE_AOUT: bsz = dlslot->dl_bsz; pos = dlslot->a_lseek; len = 0; total = dlslot->a_text; - - if (pos < (off_t)total) { - notdone = total - (u_long)pos; - if (notdone <= bsz) + + if (pos < total) { + notdone = total - pos; + if (notdone <= bsz) { outlen = read(dlslot->ldfd,&buf[len],notdone); - else + } else { outlen = read(dlslot->ldfd,&buf[len],bsz); + } len = len + outlen; pos = pos + outlen; - bsz = bsz - (u_long)outlen; + bsz = bsz - outlen; } total = total + dlslot->a_text_fill; - if ((bsz > 0) && (pos < (off_t)total)) { - notdone = total - (u_long)pos; - if (notdone <= bsz) - outlen = (ssize_t)notdone; - else - outlen = (ssize_t)bsz; - bzero(&buf[len],(u_long)outlen); + if ((bsz > 0) && (pos < total)) { + notdone = total - pos; + if (notdone <= bsz) { + outlen = notdone; + } else { + outlen = bsz; + } + memset(&buf[len], 0, outlen); len = len + outlen; pos = pos + outlen; - bsz = bsz - (u_long)outlen; + bsz = bsz - outlen; } total = total + dlslot->a_data; - - if ((bsz > 0) && (pos < (off_t)total)) { - notdone = total - (u_long)pos; - if (notdone <= bsz) + + if ((bsz > 0) && (pos < total)) { + notdone = total - pos; + if (notdone <= bsz) { outlen = read(dlslot->ldfd,&buf[len],notdone); - else + } else { outlen = read(dlslot->ldfd,&buf[len],bsz); + } len = len + outlen; pos = pos + outlen; - bsz = bsz - (u_long)outlen; + bsz = bsz - outlen; } total = total + dlslot->a_data_fill; - if ((bsz > 0) && (pos < (off_t)total)) { - notdone = total - (u_long)pos; - if (notdone <= bsz) - outlen = (ssize_t)notdone; - else - outlen = (ssize_t)bsz; - bzero(&buf[len],(u_long)outlen); + if ((bsz > 0) && (pos < total)) { + notdone = total - pos; + if (notdone <= bsz) { + outlen = notdone; + } else { + outlen = bsz; + } + memset(&buf[len], 0, outlen); len = len + outlen; pos = pos + outlen; - bsz = bsz - (u_long)outlen; + bsz = bsz - outlen; } - + total = total + dlslot->a_bss; - if ((bsz > 0) && (pos < (off_t)total)) { - notdone = total - (u_long)pos; - if (notdone <= bsz) - outlen = (ssize_t)notdone; - else - outlen = (ssize_t)bsz; - bzero(&buf[len],(u_long)outlen); + if ((bsz > 0) && (pos < total)) { + notdone = total - pos; + if (notdone <= bsz) { + outlen = notdone; + } else { + outlen = bsz; + } + memset(&buf[len], 0, outlen); len = len + outlen; pos = pos + outlen; - bsz = bsz - (u_long)outlen; + bsz = bsz - outlen; } - + total = total + dlslot->a_bss_fill; - if ((bsz > 0) && (pos < (off_t)total)) { - notdone = total - (u_long)pos; - if (notdone <= bsz) - outlen = (ssize_t)notdone; - else - outlen = (ssize_t)bsz; - bzero(&buf[len],(u_long)outlen); + if ((bsz > 0) && (pos < total)) { + notdone = total - pos; + if (notdone <= bsz) { + outlen = notdone; + } else { + outlen = bsz; + } + memset(&buf[len], 0, outlen); len = len + outlen; pos = pos + outlen; - bsz = bsz - (u_long)outlen; + bsz = bsz - outlen; } - + dlslot->a_lseek = pos; + break; + default: + abort(); } - return (len); + return(len); } diff --git a/usr.sbin/mopd/common/file.h b/usr.sbin/mopd/common/file.h index 5f719b0be03..a4991076e99 100644 --- a/usr.sbin/mopd/common/file.h +++ b/usr.sbin/mopd/common/file.h @@ -1,4 +1,4 @@ -/* $OpenBSD: file.h,v 1.10 2006/04/29 16:26:56 maja Exp $ */ +/* $OpenBSD: file.h,v 1.11 2013/07/05 21:02:07 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.10 2006/04/29 16:26:56 maja Exp $ + * $OpenBSD: file.h,v 1.11 2013/07/05 21:02:07 miod Exp $ * */ @@ -32,18 +32,24 @@ #define INFO_PRINT 1 -void mopFilePutLX(u_char *, int, u_long, int); -void mopFilePutBX(u_char *, int, u_long, int); -u_long mopFileGetLX(void *, int, int); -u_long mopFileGetBX(void *, int, int); -void mopFileSwapX(void *, int, int); -int CheckMopFile(int); -int GetMopFileInfo(int, u_long *, u_long *, int); -int CheckAOutFile(int); -int GetAOutFileInfo(int, u_long *, u_long *, u_long *, u_long *, - u_long *, u_long *, u_long *, u_long *, int *, int); -int GetFileInfo(int, u_long *, u_long *, int *, u_long *, u_long *, - u_long *, u_long *, u_long *, u_long *, int); -ssize_t mopFileRead(struct dllist *, u_char *); +const char *FileTypeName(mopd_imagetype); + +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); +ssize_t mopFileRead(struct dllist *, u_char *); +void mopFileSwapX(u_char *, int, int); + +int CheckMopFile(int); +int GetMopFileInfo(struct dllist *, int); + +int CheckElfFile(int); +int GetElfFileInfo(struct dllist *, int); + +int CheckAOutFile(int); +int GetAOutFileInfo(struct dllist *, int); + +int GetFileInfo(struct dllist *, int); #endif /* _FILE_H_ */ diff --git a/usr.sbin/mopd/mopa.out/mopa.out.1 b/usr.sbin/mopd/mopa.out/mopa.out.1 index bbf37cfc603..60fb1727f77 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.12 2007/05/31 19:20:25 jmc Exp $ +.\" $OpenBSD: mopa.out.1,v 1.13 2013/07/05 21:02:07 miod Exp $ .\" .\" Copyright (c) 1996 Mats O Jansson. All rights reserved. .\" @@ -22,35 +22,31 @@ .\" (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.12 2007/05/31 19:20:25 jmc Exp $ +.\" @(#) $OpenBSD: mopa.out.1,v 1.13 2013/07/05 21:02:07 miod Exp $ .\" -.Dd $Mdocdate: May 31 2007 $ +.Dd $Mdocdate: July 5 2013 $ .Dt MOPA.OUT 1 .Os .Sh NAME .Nm mopa.out -.Nd create MOP image from an a.out file +.Nd create MOP image from another executable format .Sh SYNOPSIS .Nm mopa.out .Ar infile .Ar outfile .Sh DESCRIPTION .Nm -is used to convert an a.out file to a MOP-image. +is used to convert a file from another executable format to a MOP-image. .Pp -This program will check if -.Xr a.out 5 -machine ID is recognized. -If not it will try to swap the -.Xr a.out 5 -header, and try again. +Elf32 and a.out VAX images are the only currently supported input +formats. .Sh SEE ALSO .Xr mopchk 1 , .Xr mopprobe 1 , .Xr moptrace 1 , .Xr a.out 5 , +.Xr elf 5 , .Xr mopd 8 .Sh AUTHORS -Lloyd Parkes -.Sh BUGS -This program just supports the VAX machine ID for now. +.An Lloyd Parkes +.An Jason R. Thorpe diff --git a/usr.sbin/mopd/mopa.out/mopa.out.c b/usr.sbin/mopd/mopa.out/mopa.out.c index 52632de7f8b..c0610eeeb17 100644 --- a/usr.sbin/mopd/mopa.out/mopa.out.c +++ b/usr.sbin/mopd/mopa.out/mopa.out.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mopa.out.c,v 1.11 2010/11/19 21:09:20 miod Exp $ */ +/* $OpenBSD: mopa.out.c,v 1.12 2013/07/05 21:02:07 miod Exp $ */ /* mopa.out - Convert a Unix format kernel into something that * can be transferred via MOP. @@ -65,14 +65,27 @@ #define MID_VAX 140 #endif +#ifndef NOELF +#if defined(__NetBSD__) || defined(__OpenBSD__) +#include <sys/exec_elf.h> +#else +#define NOELF +#endif +#if !defined(EM_VAX) +#define EM_VAX 75 +#endif +#endif + u_char header[512]; /* The VAX header we generate is 1 block. */ +#if !defined(NOAOUT) struct exec ex, ex_swap; +#endif int main (int argc, char **argv) { FILE *out; /* A FILE because that is easier. */ - int i; + int i, j; struct dllist dl; #ifdef NOAOUT @@ -86,32 +99,42 @@ main (int argc, char **argv) } dl.ldfd = open (argv[1], O_RDONLY); - if (dl.ldfd == -1) { - perror (argv[1]); - return (2); - } + if (dl.ldfd == -1) + err(2, "open `%s'", argv[1]); - GetFileInfo(dl.ldfd, - &dl.loadaddr, - &dl.xferaddr, - &dl.aout, - &dl.a_text,&dl.a_text_fill, - &dl.a_data,&dl.a_data_fill, - &dl.a_bss ,&dl.a_bss_fill, 0); - - if (dl.aout == -1) { - fprintf(stderr,"%s: not an a.out file\n",argv[1]); - return (3); - } - - if (dl.aout != MID_VAX) { - fprintf(stderr,"%s: file is not a VAX image (mid=%d)\n", - argv[1],dl.aout); - return (4); + if (GetFileInfo(&dl, 0) == -1) + errx(3, "`%s' is an unknown file type", argv[1]); + + switch (dl.image_type) { + case IMAGE_TYPE_MOP: + errx(3, "`%s' is already a MOP image", argv[1]); + break; + +#ifndef NOELF + case IMAGE_TYPE_ELF32: + if (dl.e_machine != EM_VAX) + printf("WARNING: `%s' is not a VAX 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; + break; +#endif + +#ifndef NOAOUT + case IMAGE_TYPE_AOUT: + if (dl.a_mid != MID_VAX) + printf("WARNING: `%s' is not a VAX image (mid=%d)\n", + 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; + break; +#endif + + default: + errx(3, "Image type `%s' not supported", + FileTypeName(dl.image_type)); } - i = dl.a_text + dl.a_text_fill + dl.a_data + dl.a_data_fill + - dl.a_bss + dl.a_bss_fill; i = (i+1) / 512; dl.nloadaddr = dl.loadaddr; @@ -124,24 +147,44 @@ main (int argc, char **argv) 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.*/ out = fopen (argv[2], "w"); - if (!out) { - perror (argv[2]); - return (2); - } + if (!out) + err(2, "writing `%s'", argv[2]); /* Now we do the actual work. Write VAX MOP-image header */ fwrite (header, sizeof (header), 1, out); - fprintf (stderr, "copying %lu", dl.a_text); - fprintf (stderr, "+%lu", dl.a_data); - fprintf (stderr, "+%lu", dl.a_bss); - fprintf (stderr, "->%lu", dl.xferaddr); - fprintf (stderr, "\n"); + switch (dl.image_type) { + case IMAGE_TYPE_MOP: + abort(); + + case IMAGE_TYPE_ELF32: +#ifdef NOELF + abort(); +#else + fprintf(stderr, "copying "); + for (j = 0; j < dl.e_nsec; j++) + fprintf(stderr, "%s%u+%u", j == 0 ? "" : "+", + dl.e_sections[j].s_fsize, + dl.e_sections[j].s_pad); + fprintf(stderr, "->0x%x\n", dl.xferaddr); +#endif + break; + + case IMAGE_TYPE_AOUT: +#ifdef NOAOUT + abort(); +#else + fprintf(stderr, "copying %u+%u+%u->0x%x\n", dl.a_text, + dl.a_data, dl.a_bss, dl.xferaddr); +#endif + break; + } while ((i = mopFileRead(&dl,header)) > 0) { (void)fwrite(header, i, 1, out); diff --git a/usr.sbin/mopd/mopchk/mopchk.c b/usr.sbin/mopd/mopchk/mopchk.c index f8b8bcb97c7..83607e5e242 100644 --- a/usr.sbin/mopd/mopchk/mopchk.c +++ b/usr.sbin/mopd/mopchk/mopchk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mopchk.c,v 1.15 2010/05/01 08:14:26 mk Exp $ */ +/* $OpenBSD: mopchk.c,v 1.16 2013/07/05 21:02:07 miod Exp $ */ /* * Copyright (c) 1995-96 Mats O Jansson. All rights reserved. @@ -56,10 +56,11 @@ main(argc, argv) int argc; char **argv; { - int op, i, fd; + struct dllist dl; + int op, i; char *filename, *p; struct if_info *ii; - int err, aout; + int error; /* All error reporting is done through syslogs. */ openlog(__progname, LOG_PID | LOG_CONS, LOG_DAEMON); @@ -116,28 +117,25 @@ main(argc, argv) i++; filename = argv[optind++]; printf("Checking: %s\n",filename); - fd = open(filename, O_RDONLY, 0); - if (fd == -1) { + dl.ldfd = open(filename, O_RDONLY, 0); + if (dl.ldfd == -1) { printf("Unknown file.\n"); } else { - err = CheckAOutFile(fd); - if (err == 0) { - if (GetAOutFileInfo(fd, 0, 0, 0, 0, 0, 0, 0, 0, - &aout, INFO_PRINT) < 0) { + if ((error = CheckElfFile(dl.ldfd)) == 0) { + if (GetElfFileInfo(&dl, INFO_PRINT) < 0) { + printf("Some failure in GetElfFileInfo\n"); + } + } else if ((error = CheckAOutFile(dl.ldfd)) == 0) { + if (GetAOutFileInfo(&dl, INFO_PRINT) < 0) { printf("Some failure in GetAOutFileInfo\n"); - aout = -1; } - } else { - aout = -1; - } - if (aout == -1) - err = CheckMopFile(fd); - if (aout == -1 && err == 0) { - if (GetMopFileInfo(fd, 0, 0, INFO_PRINT) < 0) { + } else if ((error = CheckMopFile(dl.ldfd)) == 0) { + if (GetMopFileInfo(&dl, INFO_PRINT) < 0) { printf("Some failure in GetMopFileInfo\n"); } }; } + (void)close(dl.ldfd); } return 0; } diff --git a/usr.sbin/mopd/mopd/mopd.c b/usr.sbin/mopd/mopd/mopd.c index a093c4610ce..16c96b860ef 100644 --- a/usr.sbin/mopd/mopd/mopd.c +++ b/usr.sbin/mopd/mopd/mopd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mopd.c,v 1.17 2009/10/27 23:59:52 deraadt Exp $ */ +/* $OpenBSD: mopd.c,v 1.18 2013/07/05 21:02:07 miod Exp $ */ /* * Copyright (c) 1993-96 Mats O Jansson. All rights reserved. @@ -50,7 +50,6 @@ */ struct if_info *iflist; -__dead void Loop(void); void Usage(void); void mopProcess(struct if_info *, u_char *); diff --git a/usr.sbin/mopd/mopd/process.c b/usr.sbin/mopd/mopd/process.c index 2cfc60a3946..788c24bc6c9 100644 --- a/usr.sbin/mopd/mopd/process.c +++ b/usr.sbin/mopd/mopd/process.c @@ -1,4 +1,4 @@ -/* $OpenBSD: process.c,v 1.19 2009/11/12 16:52:22 maja Exp $ */ +/* $OpenBSD: process.c,v 1.20 2013/07/05 21:02:07 miod Exp $ */ /* * Copyright (c) 1993-95 Mats O Jansson. All rights reserved. @@ -185,11 +185,7 @@ mopStartLoad(u_char *dst, u_char *src, struct dllist *dl_rpr, int trans) dllist[slot].status = DL_STATUS_READ_IMGHDR; /* Get Load and Transfer Address. */ - GetFileInfo(dllist[slot].ldfd, &dllist[slot].loadaddr, - &dllist[slot].xferaddr, &dllist[slot].aout, - &dllist[slot].a_text, &dllist[slot].a_text_fill, - &dllist[slot].a_data, &dllist[slot].a_data_fill, - &dllist[slot].a_bss, &dllist[slot].a_bss_fill, 0); + GetFileInfo(&dllist[slot], 0); dllist[slot].nloadaddr = dllist[slot].loadaddr; dllist[slot].lseek = lseek(dllist[slot].ldfd, 0L, SEEK_CUR); diff --git a/usr.sbin/mopd/mopprobe/mopprobe.c b/usr.sbin/mopd/mopprobe/mopprobe.c index 61e0cb26d90..a023e82eced 100644 --- a/usr.sbin/mopd/mopprobe/mopprobe.c +++ b/usr.sbin/mopd/mopprobe/mopprobe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mopprobe.c,v 1.13 2010/05/01 08:14:26 mk Exp $ */ +/* $OpenBSD: mopprobe.c,v 1.14 2013/07/05 21:02:07 miod Exp $ */ /* * Copyright (c) 1993-96 Mats O Jansson. All rights reserved. @@ -45,7 +45,6 @@ */ struct if_info *iflist; -__dead void Loop(void); void Usage(void); void mopProcess(struct if_info *, u_char *); diff --git a/usr.sbin/mopd/moptrace/moptrace.c b/usr.sbin/mopd/moptrace/moptrace.c index 8083fc5959b..0c69eec6055 100644 --- a/usr.sbin/mopd/moptrace/moptrace.c +++ b/usr.sbin/mopd/moptrace/moptrace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: moptrace.c,v 1.11 2009/10/27 23:59:52 deraadt Exp $ */ +/* $OpenBSD: moptrace.c,v 1.12 2013/07/05 21:02:07 miod Exp $ */ /* * Copyright (c) 1993-95 Mats O Jansson. All rights reserved. @@ -46,7 +46,6 @@ */ struct if_info *iflist; -void Loop(void) __dead; void Usage(void); void mopProcess(struct if_info *, u_char *); |