home *** CD-ROM | disk | FTP | other *** search
- #include <fcntl.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <filehdr.h>
- #include <scnhdr.h>
- #include <syms.h>
- #include <ldfcn.h>
- #include <aouthdr.h>
- #include <errno.h>
- #include "register.h"
- #include "symtab.h"
- #include "diblock.h"
- #include "instrn.h"
- #include "process.h"
- #include "wcache.h"
- #include "nels.h"
-
- #if 0
- #endif /* 0 */
- #define SPECIAL_MEMCPY
-
- #if defined(SPECIAL_MEMCPY)
- #define Wmemcpy(to,from,n) \
- { \
- if \
- ( \
- (n) == sizeof(unsigned long) \
- && \
- (((unsigned long)(from)) & 0x3) == 0x0 \
- && \
- (((unsigned long)(to)) & 0x3) == 0x0 \
- ) \
- *(unsigned long *)(to) = *(unsigned long *)(from); \
- else \
- (void)memcpy((to), (from), (n)); \
- }
- #else /* defined(SPECIAL_MEMCPY) */
- #define Wmemcpy(to,from,n) (void)memcpy((to), (from), (n))
- #endif /* defined(SPECIAL_MEMCPY) */
-
- extern void couldnot();
- extern void warning();
- extern char *strdup();
- extern char *say_register();
- extern int symtab_open();
- extern int symtab_close();
- extern char *symtab_text_address();
- extern LDFILE *my_ldopen();
- extern int histo_init();
- extern char *proc_text_address();
- extern int clear_decoded_page();
-
- extern int errno;
-
- extern FILE *outfp;
-
- extern int Cflag;
- extern int Hflag;
- extern int Vflag;
-
- process P;
- int give_warnings = 1;
-
- static int ld_section_read();
- static int procimput();
-
- int
- procopen(adotout)
- char *adotout;
- {
- FILE *fp;
- LDFILE *ldptr;
- struct filehdr *fhp;
- unsigned short sectindx;
- SCNHDR secthead;
- AOUTHDR adotout_header;
- int i;
- int length;
-
- if ((P.p_adotout = strdup(adotout)) == (char *)0)
- return -1;
-
- P.p_pid = getpid();
-
- /*
- * Read the executable and initialise
- * our memory image of it.
- */
-
- if ((ldptr = my_ldopen(adotout, (LDFILE *)0)) == (LDFILE *)0)
- return -1;
-
- if (ISARCHIVE(TYPE(ldptr)))
- {
- vcouldnot("interpret contents of archive \"%s\"", adotout);
- (void)ldclose(ldptr);
- return -1;
- }
-
- fhp = &HEADER(ldptr);
-
- if (!ISCOFF(fhp->f_magic))
- {
- vcouldnot("interpret contents of non-COFF executable \"%s\"", adotout);
- (void)ldclose(ldptr);
- return -1;
- }
-
- /*
- * Determine the entry point of the process.
- */
- if (ldohseek(ldptr) != SUCCESS)
- {
- vcouldnot("seek to start of optional header structure in executable \"%s\"", adotout);
- (void)ldclose(ldptr);
- return -1;
- }
-
- if (FREAD(&adotout_header, sizeof(adotout_header), 1, ldptr) != 1)
- {
- vcouldnot("read optional header structure from executable \"%s\"", adotout);
- (void)ldclose(ldptr);
- return -1;
- }
-
- if (Vflag)
- {
- fprintf(outfp, "magic == 0%o\n", adotout_header.magic);
- fprintf(outfp, "vstamp == 0x%x(%d)\n", adotout_header.vstamp, adotout_header.vstamp);
- fprintf(outfp, "tsize == 0x%x(%d)\n", adotout_header.tsize, adotout_header.tsize);
- fprintf(outfp, "dsize == 0x%x(%d)\n", adotout_header.dsize, adotout_header.dsize);
- fprintf(outfp, "bsize == 0x%x(%d)\n", adotout_header.bsize, adotout_header.bsize);
- fprintf(outfp, "entry == 0x%x(%d)\n", adotout_header.entry, adotout_header.entry);
- fprintf(outfp, "text_start == 0x%x(%d)\n", adotout_header.text_start, adotout_header.text_start);
- fprintf(outfp, "data_start == 0x%x(%d)\n", adotout_header.data_start, adotout_header.data_start);
- fprintf(outfp, "bss_start == 0x%x(%d)\n", adotout_header.bss_start, adotout_header.bss_start);
- fprintf(outfp, "gprmask == 0x%x(%d)\n", adotout_header.gprmask, adotout_header.gprmask);
- fprintf(outfp, "gp_value == 0x%x(%d)\n", adotout_header.gp_value, adotout_header.gp_value);
- }
-
- if (adotout_header.magic == OMAGIC)
- P.p_text_region_is_readonly = 0;
- else
- P.p_text_region_is_readonly = 1;
-
- /*
- * Initialise the PC as the process's entry point.
- */
- P.p_entry_point = adotout_header.entry;
-
- P.p_text_region_min = adotout_header.text_start;
- P.p_text_region_limit = P.p_text_region_min + adotout_header.tsize - 1;
- P.p_text_region_wlimit = P.p_text_region_limit + 1 - sizeof(unsigned long);
- P.p_text_region = calloc(adotout_header.tsize / sizeof(unsigned long), sizeof(unsigned long));
- if (P.p_text_region == (unsigned char *)0)
- {
- vcouldnot("grow text space to size %d bytes", adotout_header.tsize);
- (void)ldclose(ldptr);
- return -1;
- }
-
- P.p_data_region_min = adotout_header.data_start;
-
- /*
- * Initialise GP to the process's gp value.
- */
- if (quiet_procsput(R_GP, adotout_header.gp_value) == -1)
- {
- (void)ldclose(ldptr);
- return -1;
- }
-
- /*
- * Read each COFF section in turn, copying the data of those
- * that are required to memory.
- */
- sectindx = 1;
- while (ldshread(ldptr, sectindx, §head) == SUCCESS)
- {
- if (Vflag)
- {
- fprintf
- (
- outfp,
- "read section %d: name=\"%s\",paddr=0x%x,vaddr=0x%x,size=%d,scnptr=%d,relptr=%d,lnnoptr=%d,nreloc=%d,nlnno=%d,flags=0x%x\n",
- sectindx,
- §head.s_name[0],
- secthead.s_paddr,
- secthead.s_vaddr,
- secthead.s_size,
- secthead.s_scnptr,
- secthead.s_relptr,
- secthead.s_lnnoptr,
- secthead.s_nreloc,
- secthead.s_nlnno,
- secthead.s_flags
- );
- }
-
- switch (secthead.s_flags & 0xF)
- {
- case STYP_REG:
- if (Vflag)
- fprintf(outfp, "STYP_REG: allocated, relocated, loaded\n");
- break;
-
- case STYP_DSECT:
- if (Vflag)
- fprintf(outfp, "STYP_DSECT: not allocated, relocated, not loaded\n");
- break;
-
- case STYP_NOLOAD:
- if (Vflag)
- fprintf(outfp, "STYP_NOLOAD: allocated, relocated, not loaded\n");
- break;
-
- case STYP_GROUP:
- if (Vflag)
- fprintf(outfp, "STYP_GROUP: grouped\n");
- break;
-
- case STYP_PAD:
- if (Vflag)
- fprintf(outfp, "STYP_PAD: not allocated, not relocated, loaded\n");
- break;
-
- default:
- vcouldnot("recognise section type 0x%x", secthead.s_flags & 0xF);
- (void)ldclose(ldptr);
- return -1;
- }
-
- switch (secthead.s_flags & ~0xF)
- {
- case STYP_COPY:
- if (Vflag)
- fprintf(outfp, "STYP_COPY: not allocated, not relocated, loaded\n");
- break;
-
- case STYP_TEXT:
- if (Vflag)
- fprintf(outfp, "STYP_TEXT: text only\n");
- break;
-
- case STYP_DATA:
- if (Vflag)
- fprintf(outfp, "STYP_DATA: data only\n");
- break;
-
- case STYP_BSS:
- if (Vflag)
- fprintf(outfp, "STYP_BSS: bss only\n");
- break;
-
- case STYP_RDATA:
- if (Vflag)
- fprintf(outfp, "STYP_RDATA: read only data only\n");
- break;
-
- case STYP_SDATA:
- if (Vflag)
- fprintf(outfp, "STYP_SDATA: small data only\n");
- break;
-
- case STYP_SBSS:
- if (Vflag)
- fprintf(outfp, "STYP_SBSS: small bss only\n");
- break;
-
- case STYP_UCODE:
- if (Vflag)
- fprintf(outfp, "STYP_UCODE: ucode only\n");
- break;
-
- case STYP_LIT8:
- if (Vflag)
- fprintf(outfp, "STYP_LIT8: literal pool for 8-byte literals\n");
- break;
-
- case STYP_LIT4:
- if (Vflag)
- fprintf(outfp, "STYP_LIT4: literal pool for 4-byte literals\n");
- break;
-
- case S_NRELOC_OVFL:
- if (Vflag)
- fprintf(outfp, "S_NRELOC_OVFL: s_nreloc overflowed, the value is in v_addr of the first entry\n");
- break;
-
- case STYP_LIB:
- if (Vflag)
- fprintf(outfp, "STYP_LIB: section is a .lib section\n");
- break;
-
- case STYP_INIT:
- if (Vflag)
- fprintf(outfp, "STYP_INIT: section only contains the text instructions for the .init sec.\n");
- break;
-
- default:
- vcouldnot("recognise section type 0x%x", secthead.s_flags & ~0xF);
- (void)ldclose(ldptr);
- return -1;
- }
-
- if (strcmp(§head.s_name[0], ".lib") == 0)
- {
- vcouldnot("handle executable containing a .lib (call to shared library) section");
- return -1;
- }
- else if (strcmp(§head.s_name[0], ".data") == 0)
- {
- /*
- * Initialise the start of the writable data.
- */
- if (quiet_procwrdataput(secthead.s_vaddr) == -1)
- {
- (void)ldclose(ldptr);
- return -1;
- }
- }
- else if (strcmp(§head.s_name[0], ".bss") == 0)
- {
- /*
- * Initialise The Break.
- */
- if (procbreakput(secthead.s_vaddr + secthead.s_size) == -1)
- {
- vcouldnot("set break to 0x%x", secthead.s_vaddr + secthead.s_size);
- (void)ldclose(ldptr);
- return -1;
- }
- }
-
- if (ld_section_read(ldptr, secthead.s_scnptr, secthead.s_vaddr, secthead.s_size) == -1)
- {
- (void)ldclose(ldptr);
- return -1;
- }
-
- sectindx++;
- }
-
- if (symtab_open(ldptr, adotout, &P.p_symtab) == -1)
- {
- (void)ldclose(ldptr);
- return -1;
- }
-
- /*
- * Close the executable file.
- */
- if (ldclose(ldptr) != SUCCESS)
- {
- vcouldnot("close executable \"%s\"", adotout);
- return -1;
- }
-
- if (Hflag)
- {
- if (histo_init(P.p_text_region_min, P.p_text_region_limit + 1 - P.p_text_region_min) == -1)
- return -1;
- }
-
- P.p_stack_region_min = STACK_MAX + 1;
-
- return 0;
- }
-
- static
- int
- ld_section_read(srce_ldptr, srce_offset, dest_offset, count)
- LDFILE *srce_ldptr;
- long srce_offset;
- long dest_offset;
- long count;
- {
- unsigned char buf[64 * 1024];
-
- if (srce_offset == (long)0)
- (void)memset(&buf[0], 0x00, sizeof(buf));
- else
- {
- if (FSEEK(srce_ldptr, srce_offset, SEEK_SET) != 0)
- {
- vcouldnot("FSEEK to offset %d in source file in ld_section_read()", srce_offset);
- return -1;
- }
- }
-
- while (count > 0)
- {
- int chunk;
-
- chunk = (count >= sizeof(buf)) ? sizeof(buf) : count;
-
- if (srce_offset != (long)0)
- {
- if (FREAD(&buf[0], chunk, 1, srce_ldptr) != 1)
- {
- vcouldnot("FREAD from source file in ld_section_read()");
- return -1;
- }
- }
-
- if (procimput(dest_offset, &buf[0], chunk) == -1)
- return -1;
-
- count -= chunk;
- dest_offset += chunk;
- }
-
- return 0;
- }
-
- int
- procclose()
- {
- FILE *fp;
- int mi;
- int i;
-
- if (P.p_stack_region != (unsigned char *)0)
- (void)free(P.p_stack_region);
-
- if (P.p_data_region != (unsigned char *)0)
- (void)free(P.p_data_region);
-
- if (P.p_text_region != (unsigned char *)0)
- (void)free(P.p_text_region);
-
- if (symtab_close(&P.p_symtab) == -1)
- return -1;
-
- if (P.p_adotout != (char *)0)
- {
- (void)free(P.p_adotout);
- P.p_adotout = (char *)0;
- }
-
- (void)fflush(outfp);
-
- return 0;
- }
-
- void
- procsput_trace(regi, v)
- int regi;
- unsigned long v;
- {
- if (Cflag)
- {
- switch (regi)
- {
- case R_0:
- break;
-
- case R_GP:
- case R_RA:
- case R_SP:
- fprintf(outfp, "%6d:\t%s = %s;\n", P.p_pid, say_register(regi), proc_text_address(v));
- break;
-
- default:
- fprintf(outfp, "%6d:\t%s = 0x%08x;\n", P.p_pid, say_register(regi), v);
- break;
- }
- }
- else
- fprintf(outfp, "\t\tprocsput(%d, %s, %d)\n", P.p_pid, say_register(regi), v);
- }
-
- void
- procsget_trace(regi, r)
- int regi;
- unsigned long r;
- {
- if (Cflag)
- {
- #if 0
- switch (regi)
- {
- case R_RA:
- fprintf(outfp, "%6d:\t? = %s /* %s */;\n", P.p_pid, say_register(regi), proc_text_address(r));
- break;
-
- default:
- fprintf(outfp, "%6d:\t? = %s /* 0x%08x */;\n", P.p_pid, say_register(regi), r);
- break;
- }
- #endif /* 0 */
- }
- else
- fprintf(outfp, "\t\tprocsget(%d, %s, %d)\n", P.p_pid, say_register(regi), r);
- }
-
- void
- procmput_trace(offset, cp, length)
- unsigned long offset;
- char *cp;
- int length;
- {
- if (Cflag)
- {
- while (length >= sizeof(int))
- {
- fprintf(outfp, "%6d:\t*(int *)%s = 0x%08x;\n", P.p_pid, proc_text_address(offset), *(int *)cp);
- length -= sizeof(int);
- cp += sizeof(int);
- offset += sizeof(int);
- }
-
- while (length >= sizeof(short))
- {
- fprintf(outfp, "%6d:\t*(short *)%s = 0x%04x;\n", P.p_pid, proc_text_address(offset), *(short *)cp);
- length -= sizeof(short);
- cp += sizeof(short);
- offset += sizeof(short);
- }
-
- while (length >= sizeof(char))
- {
- fprintf(outfp, "%6d:\t*(char *)%s = 0x%02x;\n", P.p_pid, proc_text_address(offset), *(unsigned char *)cp);
- length -= sizeof(char);
- cp += sizeof(char);
- offset += sizeof(char);
- }
- }
- else
- fprintf(outfp, "\t\t\tprocmput(pid=%d,offset=%d,length=%d)\n", P.p_pid, offset, length);
- }
-
- void
- procmget_trace(offset, cp, length)
- unsigned long offset;
- char *cp;
- int length;
- {
- if (Cflag)
- {
- #if 0
- while (length >= sizeof(int))
- {
- fprintf(outfp, "%6d:\t? = *(int *)%s /* 0x%08x */;\n", P.p_pid, proc_text_address(offset), *(int *)cp);
- length -= sizeof(int);
- cp += sizeof(int);
- offset += sizeof(int);
- }
-
- while (length >= sizeof(short))
- {
- fprintf(outfp, "%6d:\t? = *(short *)%s /* 0x%04x */;\n", P.p_pid, proc_text_address(offset), *(short *)cp);
- length -= sizeof(short);
- cp += sizeof(short);
- offset += sizeof(short);
- }
-
- while (length >= sizeof(char))
- {
- fprintf(outfp, "%6d:\t? = *(char *)%s /* 0x%02x */;\n", P.p_pid, proc_text_address(offset), *(unsigned char *)cp);
- length -= sizeof(char);
- cp += sizeof(char);
- offset += sizeof(char);
- }
- #endif /* 0 */
- }
- else
- fprintf(outfp, "\t\t\tprocmget(pid=%d,offset=%d,length=%d)\n", P.p_pid, offset, length);
- }
-
- void
- procsget_warning(regi)
- int regi;
- {
- warning("read from kernel-reserved register %s", say_register(regi));
- }
-
- int
- procbreakput(newbrk)
- unsigned long newbrk;
- {
- unsigned long new_region_size;
- unsigned char *new_region;
-
- wcache_clear();
-
- new_region_size = newbrk - P.p_data_region_min;
-
- if ((new_region = calloc(new_region_size, 1)) == (unsigned char *)0)
- return -1;
-
- if (P.p_data_region != (unsigned char *)0)
- {
- unsigned long p_data_region_size;
-
- p_data_region_size = P.p_data_region_limit + 1 - P.p_data_region_min;
-
- (void)memcpy(new_region, P.p_data_region, (new_region_size < p_data_region_size) ? new_region_size : p_data_region_size);
- (void)free(P.p_data_region);
- }
-
- P.p_data_region = new_region;
- P.p_data_region_limit = newbrk - 1;
- P.p_data_region_wlimit = P.p_data_region_limit + 1 - sizeof(unsigned long);
-
- return 0;
- }
-
- int
- procbreakget(oldbrkp)
- unsigned long *oldbrkp;
- {
- *oldbrkp = P.p_data_region_limit + 1;
-
- return 0;
- }
-
- int
- procwrdataput(newwrdata)
- unsigned long newwrdata;
- {
- P.p_writable_data = newwrdata;
-
- return 0;
- }
-
- int
- procwrdataget(oldwrdatap)
- unsigned long *oldwrdatap;
- {
- *oldwrdatap = P.p_writable_data;
-
- return 0;
- }
-
- static
- int
- procimput(offset, cp, length)
- unsigned long offset;
- unsigned char *cp;
- int length;
- {
- unsigned long limit;
- int i;
-
- limit = offset + length - 1;
-
- if (limit <= P.p_text_region_limit)
- {
- if ((i = offset - P.p_text_region_min) < 0)
- {
- vcouldnot("write %d byte%s at text address 0x%x: illegal (too small) address", length, (length == 1) ? "" : "s", offset);
- return -1;
- }
-
- Wmemcpy(&P.p_text_region[i], cp, length);
- }
- else if (limit <= DATA_MAX)
- {
- if ((i = offset - P.p_data_region_min) < 0)
- {
- vcouldnot("write %d byte%s at data address 0x%x: illegal (too small) address", length, (length == 1) ? "" : "s", offset);
- return -1;
- }
-
- if (limit > P.p_data_region_limit)
- {
- if (procbreakput(limit + 1) == -1)
- {
- vcouldnot("set break to 0x%x", limit + 1);
- return -1;
- }
- }
-
- Wmemcpy(&P.p_data_region[i], cp, length);
- }
- else
- {
- /*
- * Stack space or above.
- */
- vcouldnot("write %d byte%s at non-text, non-data address 0x%x: illegal (too big) address", length, (length == 1) ? "" : "s", offset);
- return -1;
- }
-
- return 0;
- }
-
- /*
- * Grow the stack down to include 'offset'.
- */
- int
- proc_grow_stack(dipc, offset)
- dinstrn *dipc;
- unsigned long offset;
- {
- unsigned long new_stack_region_size;
- unsigned char *new_stack_region;
-
- wcache_clear();
-
- if (offset < STACK_MIN)
- {
- GLOBALdipc = dipc;
- vcouldnot("grow stack to address 0x%x: below 0x%x", offset, STACK_MIN);
- return -1;
- }
-
- new_stack_region_size = STACK_MAX + 1 - offset;
- new_stack_region_size += 4096; /* slop */
- new_stack_region_size &= ~0xF; /* Quadword aligned */
-
- if ((new_stack_region = calloc(new_stack_region_size / 16, sizeof(unsigned char) * 16)) == (unsigned char *)0)
- {
- GLOBALdipc = dipc;
- vcouldnot("grow stack to %d bytes", new_stack_region_size);
- return -1;
- }
-
- if (P.p_stack_region != (unsigned char *)0)
- {
- unsigned long p_stack_region_size;
-
- p_stack_region_size = STACK_MAX + 1 - P.p_stack_region_min;
-
- (void)memcpy(&new_stack_region[new_stack_region_size - p_stack_region_size], P.p_stack_region, p_stack_region_size);
- (void)free(P.p_stack_region);
- }
-
- P.p_stack_region = new_stack_region;
- P.p_stack_region_min = STACK_MAX + 1 - new_stack_region_size;
-
- return 0;
- }
-
- int
- quiet_procmget(dipc, offset, cp, length)
- dinstrn *dipc;
- unsigned long offset;
- unsigned char *cp;
- int length;
- {
- unsigned long limit;
- int i;
-
- if (length == 0)
- return 0;
-
- limit = offset + length - 1;
-
- if (limit <= P.p_text_region_limit)
- {
- if ((i = offset - P.p_text_region_min) < 0)
- {
- GLOBALdipc = dipc;
- vcouldnot("read %d byte%s at text address 0x%x: illegal (too small) address", length, (length == 1) ? "" : "s", offset);
- return -1;
- }
-
- Wmemcpy(cp, &P.p_text_region[i], length);
- }
- else if (limit <= P.p_data_region_limit)
- {
- if ((i = offset - P.p_data_region_min) < 0)
- {
- GLOBALdipc = dipc;
- vcouldnot("read %d byte%s at data address 0x%x: illegal (too small) address", length, (length == 1) ? "" : "s", offset);
- return -1;
- }
-
- Wmemcpy(cp, &P.p_data_region[i], length);
- }
- else if (limit <= STACK_MAX)
- {
- if ((i = offset - P.p_stack_region_min) < 0)
- {
- if (proc_grow_stack(dipc, offset) == -1)
- return -1;
-
- i = offset - P.p_stack_region_min;
- }
-
- Wmemcpy(cp, &P.p_stack_region[i], length);
- }
- else
- {
- /*
- * Hole above Stack space.
- */
- GLOBALdipc = dipc;
- vcouldnot("read %d byte%s at data address 0x%x: illegal (i.e. too big) address", length, (length == 1) ? "" : "s", offset);
- return -1;
- }
-
- return 0;
- }
-
- int
- procmget(dipc, offset, cp, length)
- dinstrn *dipc;
- unsigned long offset;
- unsigned char *cp;
- int length;
- {
- int result;
-
- result = quiet_procmget(dipc, offset, cp, length);
-
- if (Mflag)
- procmget_trace(offset, cp, length);
-
- return result;
- }
-
- int
- proc_mem_contiguous(offset, length, p)
- unsigned long offset;
- int length;
- char **p;
- {
- unsigned long limit;
-
- limit = offset + length - 1;
-
- if
- (
- offset >= P.p_text_region_min
- &&
- limit <= P.p_text_region_limit
- )
- {
- if (p != (char **)0)
- *p = &P.p_text_region[offset - P.p_text_region_min];
- return 1;
- }
-
- if
- (
- offset >= P.p_data_region_min
- &&
- limit <= P.p_data_region_limit
- )
- {
- if (p != (char **)0)
- *p = &P.p_data_region[offset - P.p_data_region_min];
- return 1;
- }
-
- if
- (
- offset >= P.p_stack_region_min
- &&
- limit <= STACK_MAX
- )
- {
- if (p != (char **)0)
- *p = &P.p_stack_region[offset - P.p_stack_region_min];
- return 1;
- }
-
- return 0;
- }
-
- int
- quiet_procmput(dipc, offset, cp, length)
- dinstrn *dipc;
- unsigned long offset;
- unsigned char *cp;
- int length;
- {
- unsigned long limit;
- int i;
-
- if (length == 0)
- return 0;
-
- limit = offset + length - 1;
-
- if (offset < P.p_text_region_min)
- {
- /*
- * Hole before text.
- */
- GLOBALdipc = dipc;
- vcouldnot("write %d byte%s at address 0x%x: illegal (i.e. too small) address", length, (length == 1) ? "" : "s", offset);
- return -1;
- }
-
- if (offset <= P.p_text_region_limit)
- {
- int tlength;
-
- /*
- * Text (or Readonly Data?) space.
- */
- if (P.p_text_region_is_readonly)
- {
- GLOBALdipc = dipc;
- vcouldnot("write %d byte%s at address 0x%x: readonly (text or data) address", length, (length == 1) ? "" : "s", offset);
- return -1;
- }
-
- if (limit > P.p_text_region_limit)
- tlength = P.p_text_region_limit + 1 - offset;
- else
- tlength = length;
-
- Wmemcpy(&P.p_text_region[offset - P.p_text_region_min], cp, tlength);
-
- /*
- * Disable decoded instructions for this range.
- */
- {
- int t;
- unsigned long o;
-
- t = tlength;
- o = offset;
-
- while (t > 0)
- {
- int remainder;
-
- if (clear_decoded_page(dipc, o, &remainder) == -1)
- return -1;
-
- o += remainder;
- t -= remainder;
- }
- }
-
- offset += tlength;
- cp += tlength;
- length -= tlength;
-
- if (length == 0)
- return 0;
- }
-
- if ((i = offset - P.p_data_region_min) < 0)
- {
- /*
- * Hole between text and data.
- */
- GLOBALdipc = dipc;
- vcouldnot("write %d byte%s at address 0x%x: illegal (i.e. unmapped) address between text and data regions", length, (length == 1) ? "" : "s", offset);
- return -1;
- }
-
- if (limit <= P.p_data_region_limit)
- {
- /*
- * Data space.
- */
- Wmemcpy(&P.p_data_region[i], cp, length);
- return 0;
- }
-
- if (limit <= STACK_MAX)
- {
- /*
- * Stack space.
- */
- if ((i = offset - P.p_stack_region_min) < 0)
- {
- if (proc_grow_stack(dipc, offset) == -1)
- return -1;
-
- i = offset - P.p_stack_region_min;
- }
-
- Wmemcpy(&P.p_stack_region[i], cp, length);
- return 0;
- }
-
- /*
- * Hole above Stack space.
- */
- GLOBALdipc = dipc;
- vcouldnot("write %d byte%s starting at address 0x%x: illegal (i.e. too big) address", length, (length == 1) ? "" : "s", offset);
- return -1;
- }
-
- int
- procmput(dipc, offset, cp, length)
- dinstrn *dipc;
- unsigned long offset;
- unsigned char *cp;
- int length;
- {
- if (Mflag)
- procmput_trace(offset, cp, length);
-
- return quiet_procmput(dipc, offset, cp, length);
- }
-
- char *
- proc_text_address(text_address)
- unsigned long text_address;
- {
- return symtab_text_address((P.p_adotout == (char *)0) ? (symtab *)0 : &P.p_symtab, text_address);
- }
-
- int
- quiet_procsget(r, v)
- int r;
- unsigned long *v;
- {
- int saved_Rflag;
-
- saved_Rflag = Rflag;
- Rflag = 0;
- procsget(r, *v);
- Rflag = saved_Rflag;
-
- return 0;
- }
-
- int
- quiet_procsput(r, v)
- int r;
- unsigned long v;
- {
- int saved_Rflag;
-
- saved_Rflag = Rflag;
- Rflag = 0;
- procsput(r, v);
- Rflag = saved_Rflag;
-
- return 0;
- }
-
- int
- quiet_procbreakget(v)
- unsigned long *v;
- {
- int result;
- int saved_Rflag;
-
- saved_Rflag = Rflag;
- Rflag = 0;
- result = procbreakget(v);
- Rflag = saved_Rflag;
-
- return result;
- }
-
- int
- quiet_procbreakput(v)
- unsigned long v;
- {
- int result;
- int saved_Rflag;
-
- saved_Rflag = Rflag;
- Rflag = 0;
- result = procbreakput(v);
- Rflag = saved_Rflag;
-
- return result;
- }
-
- int
- quiet_procwrdataput(v)
- unsigned long v;
- {
- int result;
- int saved_Rflag;
-
- saved_Rflag = Rflag;
- Rflag = 0;
- result = procwrdataput(v);
- Rflag = saved_Rflag;
-
- return result;
- }
-
- int
- magic_ok(filename)
- char *filename;
- {
- int fd;
- int saved_errno;
- unsigned short smagic;
-
- saved_errno = errno;
-
- if ((fd = open(filename, O_RDONLY)) == -1)
- return 0;
-
- if (read(fd, (unsigned char *)&smagic, sizeof(smagic)) != sizeof(smagic))
- {
- saved_errno = errno;
- (void)close(fd);
- errno = saved_errno;
- return 0;
- }
-
- (void)close(fd);
-
- if
- (
- smagic == MIPSEBMAGIC
- ||
- smagic == MIPSELMAGIC
- ||
- smagic == SMIPSEBMAGIC
- ||
- smagic == SMIPSELMAGIC
- ||
- smagic == MIPSEBUMAGIC
- ||
- smagic == MIPSELUMAGIC
- ||
- smagic == MIPSEBMAGIC_2
- ||
- smagic == MIPSELMAGIC_2
- ||
- smagic == SMIPSEBMAGIC_2
- ||
- smagic == SMIPSELMAGIC_2
- ||
- smagic == MIPSEBMAGIC_3
- ||
- smagic == MIPSELMAGIC_3
- ||
- smagic == SMIPSEBMAGIC_3
- ||
- smagic == SMIPSELMAGIC_3
- )
- {
- errno = saved_errno;
- return 1;
- }
-
- if
- (
- ((unsigned char *)&smagic)[0] == '#'
- &&
- ((unsigned char *)&smagic)[1] == '!'
- )
- {
- errno = saved_errno;
- return 2;
- }
-
- errno = ENOEXEC;
-
- return 0;
- }
-
- int
- interpreter_ok(filename)
- char *filename;
- {
- int fd;
- int saved_errno;
- char interpreter_data[64 + 1];
- char *new_filename;
- char *cp;
-
- saved_errno = errno;
-
- if ((fd = open(filename, O_RDONLY)) == -1)
- return 0;
-
- /*
- * Skip the magic number -- we know
- * it looks ok.
- */
- if (lseek(fd, 2, 0) == -1)
- {
- saved_errno = errno;
- (void)close(fd);
- errno = saved_errno;
- return 0;
- }
-
- bzero(&interpreter_data[0], sizeof(interpreter_data));
-
- if (read(fd, &interpreter_data[0], sizeof(interpreter_data) - 1) <= 0)
- {
- saved_errno = errno;
- (void)close(fd);
- errno = saved_errno;
- return 0;
- }
-
- (void)close(fd);
-
- /*
- * Skip leading white space.
- */
- for (new_filename = &interpreter_data[0]; *new_filename == ' ' || *new_filename == '\t'; new_filename++)
- ;
-
- /*
- * Terminate the filename with a '\0'.
- */
- for (cp = new_filename; *cp != ' ' && *cp != '\t' && *cp != '\n' && *cp != '\0'; cp++)
- ;
-
- *cp = '\0';
-
- if (magic_ok(new_filename) == 1)
- {
- errno = saved_errno;
- return 1;
- }
-
- errno = ENOEXEC;
-
- return 0;
- }
-
- int
- get_interpreter_data(filename, interpreter_namep, interpreter_argp)
- char *filename;
- char **interpreter_namep;
- char **interpreter_argp;
- {
- int saved_errno;
- int fd;
- static char interpreter_data[64 + 1];
- char *new_filename;
- char *cp;
- int savedc;
-
- saved_errno = errno;
-
- if ((fd = open(filename, O_RDONLY)) == -1)
- {
- (void)close(fd);
- errno = saved_errno;
- return -1;
- }
-
- bzero(&interpreter_data[0], sizeof(interpreter_data));
-
- if (read(fd, &interpreter_data[0], sizeof(interpreter_data) - 1) < 3)
- {
- (void)close(fd);
- errno = saved_errno;
- return -1;
- }
-
- (void)close(fd);
-
- errno = saved_errno;
-
- if
- (
- interpreter_data[0] != '#'
- ||
- interpreter_data[1] != '!'
- )
- return -1;
-
- /*
- * Skip leading white space.
- */
- for (new_filename = &interpreter_data[2]; *new_filename == ' ' || *new_filename == '\t'; new_filename++)
- ;
-
- *interpreter_namep = new_filename;
-
- /*
- * Terminate the filename with a '\0'.
- */
- for (cp = new_filename; *cp != ' ' && *cp != '\t' && *cp != '\n' && *cp != '\0'; cp++)
- ;
-
- savedc = *cp;
- *cp++ = '\0';
-
- if (savedc == '\n' || savedc == '\0')
- return 0;
-
- /*
- * Skip any further white space.
- */
- while (*cp == ' ' || *cp == '\t')
- cp++;
-
- if (*cp == '\n' || *cp == '\0')
- return 0;
-
- *interpreter_argp = cp;
-
- /*
- * Terminate the argument with a '\0'.
- */
- while (*cp != '\n' && *cp != '\0')
- cp++;
-
- *cp = '\0';
-
- return 0;
- }
-
- int
- is_a_shared_library(filename)
- char *filename;
- {
- /*
- * TODO: check for shared libraries.
- */
- return 0;
- }
-