Esempio n. 1
0
int
excluded(struct nlist *p)
{
	char *nam;
	int x;

	if (p->n_type & N_STAB || p->n_un.n_strx == 0)
		return (0);
	if (p->n_un.n_strx < sizeof(int) || p->n_un.n_strx >= strtabsize)
		badfmt("corrupted symbol table");
	nam = &strings[p->n_un.n_strx - sizeof(int)];
	for (x = nexclude; --x >= 0; )
		if (strcmp(nam, exclude[x]) == 0)
			return (1);
	return (0);
}
Esempio n. 2
0
int
inlist(struct nlist *p)
{
	char *nam;
	struct nlist *op;

	if (p->n_type & N_STAB || p->n_un.n_strx == 0)
		return (-1);
	if (p->n_un.n_strx < sizeof(int) || p->n_un.n_strx >= strtabsize)
		badfmt("corrupted symbol table");
	nam = &strings[p->n_un.n_strx - sizeof(int)];
	for (op = &order[nsym]; --op >= order; ) {
		if (strcmp(op->n_un.n_name, nam) != 0)
			continue;
		op->n_value = 1;
		return (op - order);
	}
	return (-1);
}
Esempio n. 3
0
/*
 * Compare the types in the NULL-terminated array ap with the format
 * string fmt.
 */
static void
scanflike(hte_t *hte, fcall_t *call, int n, const char *fmt, type_t **ap)
{
    const	char *fp;
    int	fc;
    int	noasgn, fwidth;
    tspec_t	sz, t1 = NOTSPEC, t2 = NOTSPEC;
    type_t	*tp = NULL;

    fp = fmt;
    fc = *fp++;

    for ( ; ; ) {
        if (fc == '\0') {
            if (*ap != NULL)
                tomanyarg(hte, call);
            break;
        }
        if (fc != '%') {
            badfmt(hte, call);
            break;
        }
        fc = *fp++;

        noasgn = fwidth = 0;
        sz = NOTSPEC;

        if (fc == '*') {
            noasgn = 1;
            fc = *fp++;
        }

        if (isdigit(fc)) {
            fwidth = 1;
            do {
                fc = *fp++;
            }
            while (isdigit(fc));
        }

        if (fc == 'h') {
            sz = SHORT;
        } else if (fc == 'l') {
            sz = LONG;
        } else if (fc == 'q') {
            sz = QUAD;
        } else if (fc == 'L') {
            sz = LDOUBLE;
        }
        if (sz != NOTSPEC)
            fc = *fp++;

        if (fc == '%') {
            if (sz != NOTSPEC || noasgn || fwidth)
                badfmt(hte, call);
            fc = *fp++;
            continue;
        }

        if (!noasgn) {
            if ((tp = *ap++) == NULL) {
                tofewarg(hte, call);
                break;
            }
            n++;
            if ((t1 = tp->t_tspec) == PTR)
                t2 = tp->t_subt->t_tspec;
        }

        if (fc == 'd' || fc == 'i' || fc == 'n') {
            if (sz == LDOUBLE)
                badfmt(hte, call);
            if (sz != SHORT && sz != LONG && sz != QUAD)
                sz = INT;
conv:
            if (!noasgn) {
                if (t1 != PTR) {
                    inconarg(hte, call, n);
                } else if (t2 != styp(sz)) {
                    inconarg(hte, call, n);
                } else if (hflag && t2 != sz) {
                    inconarg(hte, call, n);
                } else if (tp->t_subt->t_const) {
                    inconarg(hte, call, n);
                }
            }
        } else if (fc == 'o' || fc == 'u' || fc == 'x') {
            if (sz == LDOUBLE)
                badfmt(hte, call);
            if (sz == SHORT) {
                sz = USHORT;
            } else if (sz == LONG) {
                sz = ULONG;
            } else if (sz == QUAD) {
                sz = UQUAD;
            } else {
                sz = UINT;
            }
            goto conv;
        } else if (fc == 'D') {
            if (sz != NOTSPEC || !tflag)
                badfmt(hte, call);
            sz = LONG;
            goto conv;
        } else if (fc == 'O') {
            if (sz != NOTSPEC || !tflag)
                badfmt(hte, call);
            sz = ULONG;
            goto conv;
        } else if (fc == 'X') {
            /*
             * XXX valid in ANSI C, but in NetBSD's libc imple-
             * mented as "lx". Thats why it should be avoided.
             */
            if (sz != NOTSPEC || !tflag)
                badfmt(hte, call);
            sz = ULONG;
            goto conv;
        } else if (fc == 'E') {
            /*
             * XXX valid in ANSI C, but in NetBSD's libc imple-
             * mented as "lf". Thats why it should be avoided.
             */
            if (sz != NOTSPEC || !tflag)
                badfmt(hte, call);
            sz = DOUBLE;
            goto conv;
        } else if (fc == 'F') {
            /* XXX only for backward compatibility */
            if (sz != NOTSPEC || !tflag)
                badfmt(hte, call);
            sz = DOUBLE;
            goto conv;
        } else if (fc == 'G') {
            /*
             * XXX valid in ANSI C, but in NetBSD's libc not
             * implemented
             */
            if (sz != NOTSPEC && sz != LONG && sz != LDOUBLE)
                badfmt(hte, call);
            goto fconv;
        } else if (fc == 'e' || fc == 'f' || fc == 'g') {
fconv:
            if (sz == NOTSPEC) {
                sz = FLOAT;
            } else if (sz == LONG) {
                sz = DOUBLE;
            } else if (sz != LDOUBLE) {
                badfmt(hte, call);
                sz = FLOAT;
            }
            goto conv;
        } else if (fc == 's' || fc == '[' || fc == 'c') {
            if (sz != NOTSPEC)
                badfmt(hte, call);
            if (fc == '[') {
                if ((fc = *fp++) == '-') {
                    badfmt(hte, call);
                    fc = *fp++;
                }
                if (fc != ']') {
                    badfmt(hte, call);
                    if (fc == '\0')
                        break;
                }
            }
            if (!noasgn) {
                if (t1 != PTR) {
                    inconarg(hte, call, n);
                } else if (t2 != CHAR && t2 != UCHAR &&
                           t2 != SCHAR) {
                    inconarg(hte, call, n);
                }
            }
        } else if (fc == 'p') {
            if (sz != NOTSPEC)
                badfmt(hte, call);
            if (!noasgn) {
                if (t1 != PTR || t2 != PTR) {
                    inconarg(hte, call, n);
                } else if (tp->t_subt->t_subt->t_tspec!=VOID) {
                    if (hflag)
                        inconarg(hte, call, n);
                }
            }
        } else {
            badfmt(hte, call);
            break;
        }

        fc = *fp++;
    }
}
Esempio n. 4
0
/*
 * Compare the types in the NULL-terminated array ap with the format
 * string fmt.
 */
static void
printflike(hte_t *hte, fcall_t *call, int n, const char *fmt, type_t **ap)
{
    const	char *fp;
    int	fc;
    int	fwidth, prec, left, sign, space, alt, zero;
    tspec_t	sz, t1, t2 = NOTSPEC;
    type_t	*tp;

    fp = fmt;
    fc = *fp++;

    for ( ; ; ) {
        if (fc == '\0') {
            if (*ap != NULL)
                tomanyarg(hte, call);
            break;
        }
        if (fc != '%') {
            badfmt(hte, call);
            break;
        }
        fc = *fp++;
        fwidth = prec = left = sign = space = alt = zero = 0;
        sz = NOTSPEC;

        /* Flags */
        for ( ; ; ) {
            if (fc == '-') {
                if (left)
                    break;
                left = 1;
            } else if (fc == '+') {
                if (sign)
                    break;
                sign = 1;
            } else if (fc == ' ') {
                if (space)
                    break;
                space = 1;
            } else if (fc == '#') {
                if (alt)
                    break;
                alt = 1;
            } else if (fc == '0') {
                if (zero)
                    break;
                zero = 1;
            } else {
                break;
            }
            fc = *fp++;
        }

        /* field width */
        if (isdigit(fc)) {
            fwidth = 1;
            do {
                fc = *fp++;
            }
            while (isdigit(fc)) ;
        } else if (fc == '*') {
            fwidth = 1;
            fc = *fp++;
            if ((tp = *ap++) == NULL) {
                tofewarg(hte, call);
                break;
            }
            n++;
            if ((t1 = tp->t_tspec) != INT && (hflag || t1 != UINT))
                inconarg(hte, call, n);
        }

        /* precision */
        if (fc == '.') {
            fc = *fp++;
            prec = 1;
            if (isdigit(fc)) {
                do {
                    fc = *fp++;
                }
                while (isdigit(fc));
            } else if (fc == '*') {
                fc = *fp++;
                if ((tp = *ap++) == NULL) {
                    tofewarg(hte, call);
                    break;
                }
                n++;
                if (tp->t_tspec != INT)
                    inconarg(hte, call, n);
            } else {
                badfmt(hte, call);
                break;
            }
        }

        if (fc == 'h') {
            sz = SHORT;
        } else if (fc == 'l') {
            sz = LONG;
        } else if (fc == 'q') {
            sz = QUAD;
        } else if (fc == 'L') {
            sz = LDOUBLE;
        }
        if (sz != NOTSPEC)
            fc = *fp++;

        if (fc == '%') {
            if (sz != NOTSPEC || left || sign || space ||
                    alt || zero || prec || fwidth) {
                badfmt(hte, call);
            }
            fc = *fp++;
            continue;
        }

        if (fc == '\0') {
            badfmt(hte, call);
            break;
        }

        if ((tp = *ap++) == NULL) {
            tofewarg(hte, call);
            break;
        }
        n++;
        if ((t1 = tp->t_tspec) == PTR)
            t2 = tp->t_subt->t_tspec;

        if (fc == 'd' || fc == 'i') {
            if (alt || sz == LDOUBLE) {
                badfmt(hte, call);
                break;
            }
int_conv:
            if (sz == LONG) {
                if (t1 != LONG && (hflag || t1 != ULONG))
                    inconarg(hte, call, n);
            } else if (sz == QUAD) {
                if (t1 != QUAD && (hflag || t1 != UQUAD))
                    inconarg(hte, call, n);
            } else {
                /*
                 * SHORT is always promoted to INT, USHORT
                 * to INT or UINT.
                 */
                if (t1 != INT && (hflag || t1 != UINT))
                    inconarg(hte, call, n);
            }
        } else if (fc == 'o' || fc == 'u' || fc == 'x' || fc == 'X') {
            if ((alt && fc == 'u') || sz == LDOUBLE)
                badfmt(hte, call);
uint_conv:
            if (sz == LONG) {
                if (t1 != ULONG && (hflag || t1 != LONG))
                    inconarg(hte, call, n);
            } else if (sz == QUAD) {
                if (t1 != UQUAD && (hflag || t1 != QUAD))
                    inconarg(hte, call, n);
            } else if (sz == SHORT) {
                /* USHORT was promoted to INT or UINT */
                if (t1 != UINT && t1 != INT)
                    inconarg(hte, call, n);
            } else {
                if (t1 != UINT && (hflag || t1 != INT))
                    inconarg(hte, call, n);
            }
        } else if (fc == 'D' || fc == 'O' || fc == 'U') {
            if ((alt && fc != 'O') || sz != NOTSPEC || !tflag)
                badfmt(hte, call);
            sz = LONG;
            if (fc == 'D') {
                goto int_conv;
            } else {
                goto uint_conv;
            }
        } else if (fc == 'f' || fc == 'e' || fc == 'E' ||
                   fc == 'g' || fc == 'G') {
            if (sz == NOTSPEC)
                sz = DOUBLE;
            if (sz != DOUBLE && sz != LDOUBLE)
                badfmt(hte, call);
            if (t1 != sz)
                inconarg(hte, call, n);
        } else if (fc == 'c') {
            if (sz != NOTSPEC || alt || zero)
                badfmt(hte, call);
            if (t1 != INT)
                inconarg(hte, call, n);
        } else if (fc == 's') {
            if (sz != NOTSPEC || alt || zero)
                badfmt(hte, call);
            if (t1 != PTR ||
                    (t2 != CHAR && t2 != UCHAR && t2 != SCHAR)) {
                inconarg(hte, call, n);
            }
        } else if (fc == 'p') {
            if (fwidth || prec || sz != NOTSPEC || alt || zero)
                badfmt(hte, call);
            if (t1 != PTR || (hflag && t2 != VOID))
                inconarg(hte, call, n);
        } else if (fc == 'n') {
            if (fwidth || prec || alt || zero || sz == LDOUBLE)
                badfmt(hte, call);
            if (t1 != PTR) {
                inconarg(hte, call, n);
            } else if (sz == LONG) {
                if (t2 != LONG && t2 != ULONG)
                    inconarg(hte, call, n);
            } else if (sz == SHORT) {
                if (t2 != SHORT && t2 != USHORT)
                    inconarg(hte, call, n);
            } else {
                if (t2 != INT && t2 != UINT)
                    inconarg(hte, call, n);
            }
        } else {
            badfmt(hte, call);
            break;
        }

        fc = *fp++;
    }
}
Esempio n. 5
0
void
add(const char *fmt)
{
	const char *p;
	static FS **nextfs;
	FS *tfs;
	FU *tfu, **nextfu;
	const char *savep;

	/* start new linked list of format units */
	tfs = ecalloc(1, sizeof(FS));
	if (!fshead)
		fshead = tfs;
	else
		*nextfs = tfs;
	nextfs = &tfs->nextfs;
	nextfu = &tfs->nextfu;

	/* take the format string and break it up into format units */
	for (p = fmt;;) {
		/* skip leading white space */
		for (; isspace((unsigned char)*p); ++p);
		if (!*p)
			break;

		/* allocate a new format unit and link it in */
		tfu = ecalloc(1, sizeof(FU));
		*nextfu = tfu;
		nextfu = &tfu->nextfu;
		tfu->reps = 1;

		/* if leading digit, repetition count */
		if (isdigit((unsigned char)*p)) {
			for (savep = p; isdigit((unsigned char)*p); ++p);
			if (!isspace((unsigned char)*p) && *p != '/')
				badfmt(fmt);
			/* may overwrite either white space or slash */
			tfu->reps = atoi(savep);
			tfu->flags = F_SETREP;
			/* skip trailing white space */
			for (++p; isspace((unsigned char)*p); ++p);
		}

		/* skip slash and trailing white space */
		if (*p == '/')
			while (isspace((unsigned char)*++p));

		/* byte count */
		if (isdigit((unsigned char)*p)) {
			for (savep = p; isdigit((unsigned char)*p); ++p);
			if (!isspace((unsigned char)*p))
				badfmt(fmt);
			tfu->bcnt = atoi(savep);
			/* skip trailing white space */
			for (++p; isspace((unsigned char)*p); ++p);
		}

		/* format */
		if (*p != '"')
			badfmt(fmt);
		for (savep = ++p; *p != '"';)
			if (*p++ == 0)
				badfmt(fmt);
		tfu->fmt = emalloc(p - savep + 1);
		(void) strncpy(tfu->fmt, savep, p - savep);
		tfu->fmt[p - savep] = '\0';
		escape(tfu->fmt);
		p++;
	}
}
Esempio n. 6
0
/*
 * read_exec
 *	Read the exec structure; ignore any files that don't look
 *	exactly right. Return MID.
 *	return -1 for files that don't look right.
 *	XXX it's hard to be sure when to ignore files, and when to error
 *	out.
 */
int
read_exec(FILE *rfp, FILE *wfp, long *symcnt, long *tsymlen)
{
	union {
		struct exec exec;
		Elf32_Ehdr elf32;
		Elf64_Ehdr elf64;
	} eh;
	struct nlist nl;
	off_t r_off, w_off;
	char *strtab = NULL;
	long strsize, nsyms;
	int i;

	/* Get current offsets for original and tmp files. */
	r_off = ftello(rfp);
	w_off = ftello(wfp);

	/* Read in exec structure. */
	if (fread(&eh, sizeof(eh), 1, rfp) != 1)
		err(1, "fread: %s", archive);

	if (!elf32_chk_header(&eh.elf32)) {
		Elf32_Sym sbuf;
		char *shstr;
		Elf32_Shdr *shdr;
		size_t stabsize;

		elf32_fix_header(&eh.elf32);
		if (eh.elf32.e_ehsize < sizeof eh.elf32) {
			warnx("%s: ELF header is too short", archive);
			goto bad;
		}

		if (!(shdr = elf32_load_shdrs(archive, rfp, r_off, &eh.elf32)))
			goto bad;
		elf32_fix_shdrs(&eh.elf32, shdr);

		if (!(shstr = elf32_shstrload(archive, rfp, r_off, &eh.elf32,
		    shdr))) {
			free(shdr);
			goto bad;
		}

		if (!(strtab = elf32_strload(archive, rfp, r_off, &eh.elf32,
		    shdr, shstr, ELF_STRTAB, &stabsize))) {
			free(shstr);
			free(shdr);
			goto bad;
		}

		/* find the symtab section */
		for (i = 0; i < eh.elf32.e_shnum; i++)
			if (!strcmp(shstr + shdr[i].sh_name, ELF_SYMTAB)) {
				nsyms = shdr[i].sh_size / sizeof(Elf32_Sym);
				break;
			}

		if (i == eh.elf32.e_shnum) {
			free(shstr);
			free(shdr);
			goto bad;
		}

		if (fseeko(rfp, r_off + shdr[i].sh_offset, SEEK_SET))
			err(1, "fseeko: %s", archive);

		for (i = 0; i < nsyms; i++) {
			if (fread(&sbuf, sizeof(sbuf), 1, rfp) != 1)
				err(1, "fread: %s", archive);

			elf32_fix_sym(&eh.elf32, &sbuf);
			if (!sbuf.st_name || sbuf.st_name > stabsize)
				continue;

			if (elf32_2nlist(&sbuf, &eh.elf32, shdr, shstr, &nl))
				continue;

			addsym(&nl, strtab, r_off - r_fuzz -
			    sizeof(struct ar_hdr), symcnt, tsymlen, archive);
		}

		free(strtab);
		free(shstr);
		free(shdr);
		(void)fseeko(rfp, r_off, SEEK_SET);
		return MID_ELFFL | eh.elf32.e_machine;

	} else if (!elf64_chk_header(&eh.elf64)) {
		Elf64_Sym sbuf;
		char *shstr;
		Elf64_Shdr *shdr;
		size_t stabsize;

		elf64_fix_header(&eh.elf64);
		if (eh.elf64.e_ehsize < sizeof eh.elf64) {
			warnx("%s: ELF header is too short", archive);
			goto bad;
		}

		if (!(shdr = elf64_load_shdrs(archive, rfp, r_off, &eh.elf64)))
			goto bad;
		elf64_fix_shdrs(&eh.elf64, shdr);

		if (!(shstr = elf64_shstrload(archive, rfp, r_off, &eh.elf64,
		    shdr))) {
			free(shdr);
			goto bad;
		}

		if (!(strtab = elf64_strload(archive, rfp, r_off, &eh.elf64,
		    shdr, shstr, ELF_STRTAB, &stabsize))) {
			free(shstr);
			free(shdr);
			goto bad;
		}

		/* find the symtab section */
		for (i = 0; i < eh.elf64.e_shnum; i++)
			if (!strcmp(shstr + shdr[i].sh_name, ELF_SYMTAB)) {
				nsyms = shdr[i].sh_size / sizeof(Elf64_Sym);
				break;
			}

		if (i == eh.elf64.e_shnum) {
			free(shstr);
			free(shdr);
			goto bad;
		}

		if (fseeko(rfp, r_off + shdr[i].sh_offset, SEEK_SET))
			err(1, "fseeko: %s", archive);

		for (i = 0; i < nsyms; i++) {
			if (fread(&sbuf, sizeof(sbuf), 1, rfp) != 1)
				err(1, "fread: %s", archive);

			elf64_fix_sym(&eh.elf64, &sbuf);
			if (!sbuf.st_name || sbuf.st_name > stabsize)
				continue;

			if (elf64_2nlist(&sbuf, &eh.elf64, shdr, shstr, &nl))
				continue;

			addsym(&nl, strtab, r_off - r_fuzz -
			    sizeof(struct ar_hdr), symcnt, tsymlen, archive);
		}

		free(strtab);
		free(shstr);
		free(shdr);
		(void)fseeko(rfp, r_off, SEEK_SET);
		return MID_ELFFL | eh.elf64.e_machine;

	} else if (BAD_OBJECT(eh.exec) || eh.exec.a_syms == 0)
		goto bad;

	fix_header_order(&eh.exec);

	/* Seek to string table. */
	if (fseeko(rfp, N_STROFF(eh.exec) + r_off, SEEK_SET) == -1) {
		if (errno == EINVAL)
			goto bad;
		else
			err(1, "lseek: %s", archive);
	}

	/* Read in size of the string table. */
	if (fread((char *)&strsize, sizeof(strsize), 1, rfp) != 1)
		err(1, "fread: %s", archive);

	strsize = fix_32_order(strsize, N_GETMID(eh.exec));

	/* Read in the string table. */
	strsize -= sizeof(strsize);
	strtab = malloc(strsize);
	if (!strtab)
		err(1, "malloc: %s", archive);
	if (fread(strtab, strsize, 1, rfp) != 1)
		err(1, "fread: %s", archive);

	/* Seek to symbol table. */
	if (fseek(rfp, N_SYMOFF(eh.exec) + r_off, SEEK_SET) == (off_t)-1)
		err(1, "fseeko: %s", archive);

	/* For each symbol read the nlist entry and save it as necessary. */
	nsyms = eh.exec.a_syms / sizeof(struct nlist);
	while (nsyms--) {
		if (!fread((char *)&nl, sizeof(struct nlist), 1, rfp)) {
			if (feof(rfp))
				badfmt();
			err(1, "fread: %s", archive);
		}
		fix_nlist_order(&nl, N_GETMID(eh.exec));

		addsym(&nl, strtab - sizeof(long), r_off - r_fuzz -
		    sizeof(struct ar_hdr), symcnt, tsymlen, archive);
	}

bad:
	free(strtab);
	(void)fseeko(rfp, r_off, SEEK_SET);
	return N_GETMID(eh.exec);
}
Esempio n. 7
0
jac0dim_ASL(ASL *asl, char *stub, ftnlen stub_len)
#endif
{
	FILE *nl;
	int i, k, nlv;
	char *s, *se;
	const char *opfmt;
	EdRead ER, *R;

	if (!asl)
		badasl_ASL(asl,0,"jac0dim");
	fpinit_ASL();	/* get IEEE arithmetic, if possible */

	if (stub_len <= 0)
		for(i = 0; stub[i]; i++);
	else
		for(i = stub_len; stub[i-1] == ' ' && i > 0; --i);
	filename = (char *)M1alloc(i + 5);
	s = stub_end = filename + i;
	strncpy(filename, stub, i);
	strcpy(s, ".nl");
	nl = fopen(filename, "rb");
	if (!nl && i > 3 && !strncmp(s-3, ".nl", 3)) {
		*s = 0;
		stub_end = s - 3;
		nl = fopen(filename, "rb");
		}
	if (!nl) {
		if (return_nofile)
			return 0;
		fflush(stdout);
		what_prog();
		fprintf(Stderr, "can't open %s\n", filename);
		exit(1);
		}
	R = EdReadInit_ASL(&ER, asl, nl, 0);
	R->Line = 0;
	s = read_line(R);
	binary_nl = 0;
	opfmt = "%d";
	switch(*s) {
#ifdef DEPRECATED
		case 'E':	/* deprecated "-oe" format */
			{int ncsi = 0;
			k = Sscanf(s, "E%d %d %d %d %d %d", &n_var, &n_con,
				&n_obj, &maxrownamelen, &maxcolnamelen, &ncsi);
			if (k < 5)
				badints(R, k, 5);
			if (ncsi) {
				if (ncsi != 6) {
					badread(R);
					fprintf(Stderr,
					 "expected 6th integer to be 0 or 6, not %d\n",
						ncsi);
					exit(1);
					}
				s = read_line(R);
				k = Sscanf(s, " %d %d %d %d %d %d",
					&comb, &comc, &como, &comc1, &como1, &nfunc);
				if (k != 6)
					badints(R, k, 6);
				}
			}
			break;
#endif
		case 'z':
		case 'Z':
			opfmt = "%hd";
		case 'B':
		case 'b':
			binary_nl = 1;
			xscanf = bscanf;
			goto have_xscanf;
		case 'h':
		case 'H':
			opfmt = "%hd";
			binary_nl = 1;
			xscanf = hscanf;
			goto have_xscanf;
		case 'G':
		case 'g':
			xscanf = ascanf;
 have_xscanf:
			if ((k = ampl_options[0] = strtol(++s, &se, 10))) {
				if (k > 9) {
					fprintf(Stderr,
					"ampl_options = %d is too large\n", k);
					exit(1);
					}
				for(i = 1; i <= k && se > s; i++)
					ampl_options[i] = strtol(s = se,&se,10);
				if (ampl_options[2] == 3)
					ampl_vbtol = strtod(s = se, &se);
				}
			s = read_line(R);
			n_eqn = -1;
			k = Sscanf(s, " %d %d %d %d %d %d", &n_var, &n_con,
				&n_obj, &nranges, &n_eqn, &n_lcon);
			if (k < 3)
				badints(R,k,3);
			nclcon = n_con + n_lcon;

			/* formerly read2(R, &nlc, &nlo); */
			s = read_line(R);
			n_cc = nlcc = ndcc = nzlb = 0;
			k = Sscanf(s, " %d %d %d %d %d %d", &nlc, &nlo, &n_cc, &nlcc,
					&ndcc, &nzlb);
			if (k < 2)
				badints(R,k,2);
			if ((n_cc += nlcc) > 0 && k < 6)
				ndcc = -1; /* indicate unknown */

			read2(R, &nlnc, &lnc);
			nlvb = -1;
			s = read_line(R);
			k = Sscanf(s, " %d %d %d", &nlvc, &nlvo, &nlvb);
			if (k < 2)
				badints(R,k,2);

			/* read2(R, &nwv, &nfunc); */
			s = read_line(R);
			asl->i.flags = 0;
			k = Sscanf(s, " %d %d %d %d", &nwv, &nfunc, &i,
				&asl->i.flags);
			if (k < 2)
				badints(R,k,2);
			else if (k >= 3 && i != Arith_Kind_ASL && i) {
#ifdef Want_bswap
				if (i > 0 && i + Arith_Kind_ASL == 3) {
					asl->i.iadjfcn = asl->i.dadjfcn = bswap_ASL;
					binary_nl = i << 1;
					}
				else
#endif
					badfmt(R);
				}

			if (nlvb < 0)	/* ampl versions < 19930630 */
				read2(R, &nbv, &niv);
			else {
				s = read_line(R);
				k = Sscanf(s, " %d %d %d %d %d", &nbv, &niv,
					&nlvbi, &nlvci, &nlvoi);
				if (k != 5)
					badints(R,k,5);
				}
			/* formerly read2(R, &nzc, &nzo); */
			s = read_line(R);
			k = Sscanf(s, " %D %D", &nZc, &nZo);
			if (k != 2)
				badints(R, k, 2);
			nzc = nZc;
			nzo = nZo;
			read2(R, &maxrownamelen, &maxcolnamelen);
			s = read_line(R);
			k = Sscanf(s, " %d %d %d %d %d", &comb, &comc, &como,
					&comc1, &como1);
			if (k != 5)
				badints(R,k,5);
		}
	student_check_ASL(asl);
	if (n_con < 0 || n_var <= 0 || n_obj < 0) {
		what_prog();
		fprintf(Stderr,
		"jacdim: got M = %d, N = %d, NO = %d\n", n_con, n_var, n_obj);
		exit(1);
		}
	asl->i.opfmt = opfmt;
	asl->i.n_var0 = asl->i.n_var1 = n_var;
	asl->i.n_con0 = asl->i.n_con1 = n_con;
	if ((nlv = nlvc) < nlvo)
		nlv = nlvo;
	if (nlv <= 0)
		nlv = 1;
	x0len = nlv * sizeof(real);
	x0kind = ASL_first_x;
	n_conjac[0] = 0;
	n_conjac[1] = n_con;
	c_vars = o_vars = n_var;	/* confusion arises otherwise */
	return nl;
	}
Esempio n. 8
0
/*
 * rexec
 *	Read the exec structure; ignore any files that don't look
 *	exactly right. Return MID.
 * 	return -1 for files that don't look right.
 *	XXX it's hard to be sure when to ignore files, and when to error
 *	out.
 */
static int
rexec(int rfd, int wfd)
{
	RLIB *rp;
	long nsyms;
	int nr, symlen;
	char *strtab = 0;
	char *sym;
	struct exec ebuf;
	struct nlist nl;
	off_t r_off, w_off;
	long strsize;
	int result = -1;

	/* Get current offsets for original and tmp files. */
	r_off = lseek(rfd, (off_t)0, SEEK_CUR);
	w_off = lseek(wfd, (off_t)0, SEEK_CUR);

	/* Read in exec structure. */
	nr = read(rfd, (char *)&ebuf, sizeof(struct exec));
	if (nr != sizeof(struct exec))
		goto bad;

	/* Check magic number and symbol count. */
	if (BAD_OBJECT(ebuf) || ebuf.a_syms == 0)
		goto bad;
	fix_header_order(&ebuf);

	/* Seek to string table. */
	if (lseek(rfd, N_STROFF(ebuf) + r_off, SEEK_SET) == (off_t)-1) {
		if (errno == EINVAL)
			goto bad;
		else
			error(archive);
	}

	/* Read in size of the string table. */
	nr = read(rfd, (char *)&strsize, sizeof(strsize));
	if (nr != sizeof(strsize))
		goto bad;

	strsize = fix_32_order(strsize, N_GETMID(ebuf));

	/* Read in the string table. */
	strsize -= sizeof(strsize);
	strtab = (char *)emalloc(strsize);
	nr = read(rfd, strtab, strsize);
	if (nr != strsize) 
		goto bad;

	/* Seek to symbol table. */
	if (fseek(fp, N_SYMOFF(ebuf) + r_off, SEEK_SET) == (off_t)-1)
		goto bad;

	result = N_GETMID(ebuf);
	/* For each symbol read the nlist entry and save it as necessary. */
	nsyms = ebuf.a_syms / sizeof(struct nlist);
	while (nsyms--) {
		if (!fread((char *)&nl, sizeof(struct nlist), 1, fp)) {
			if (feof(fp))
				badfmt();
			error(archive);
		}
		fix_nlist_order(&nl, N_GETMID(ebuf));

		/* Ignore if no name or local. */
		if (!nl.n_un.n_strx || !(nl.n_type & N_EXT))
			continue;

		/*
		 * If the symbol is an undefined external and the n_value
		 * field is non-zero, keep it.
		 */
		if ((nl.n_type & N_TYPE) == N_UNDF && !nl.n_value)
			continue;

		/* First four bytes are the table size. */
		sym = strtab + nl.n_un.n_strx - sizeof(long);
		symlen = strlen(sym) + 1;

		rp = (RLIB *)emalloc(sizeof(RLIB));
		rp->sym = (char *)emalloc(symlen);
		bcopy(sym, rp->sym, symlen);
		rp->symlen = symlen;
		rp->pos = w_off;

		/* Build in forward order for "ar -m" command. */
		*pnext = rp;
		pnext = &rp->next;

		++symcnt;
		tsymlen += symlen;
	}

bad: 	if (nr < 0)
		error(archive);
	free(strtab);
	(void)lseek(rfd, (off_t)r_off, SEEK_SET);
	return result;
}
Esempio n. 9
0
int
main(int argc, char **argv)
{
	struct nlist *p, *symp;
	FILE *f, *xfile;
	int i;
	char *start, *t, *xfilename;
	int ch, n, o;

	xfilename = NULL;
	while ((ch = getopt(argc, argv, "cmtx:")) != -1)
		switch(ch) {
		case 'c':
			clean = 1;
			break;
		case 'm':
			missing = 1;
			break;
		case 't':
			small = 1;
			break;
		case 'x':
			if (xfilename != NULL)
				usage();
			xfilename = optarg;
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (argc != 2)
		usage();

	if ((f = fopen(argv[0], "r")) == NULL)
		err(ERREXIT, "%s", argv[0]);

	for (p = order; fgets(asym, sizeof(asym), f) != NULL;) {
		for (t = asym; isspace(*t); ++t);
		if (!*(start = t))
			continue;
		while (*++t);
		if (*--t == '\n')
			*t = '\0';
		p->n_un.n_name = strdup(start);
		++p;
		if (++nsym >= sizeof order / sizeof order[0])
			break;
	}
	(void)fclose(f);

	if (xfilename != NULL) {
		if ((xfile = fopen(xfilename, "r")) == NULL)
			err(ERREXIT, "%s", xfilename);
		for (; fgets(asym, sizeof(asym), xfile) != NULL;) {
			for (t = asym; isspace(*t); ++t);
			if (!*(start = t))
				continue;
			while (*++t);
			if (*--t == '\n')
				*t = '\0';
			exclude[nexclude] = strdup(start);
			if (++nexclude >= sizeof exclude / sizeof exclude[0])
				break;
		}
		(void)fclose(xfile);
	}

	kfile = argv[1];
	if ((f = fopen(kfile, "r")) == NULL)
		err(ERREXIT, "%s", kfile);
	if ((o = open(kfile, O_WRONLY)) < 0)
		err(ERREXIT, "%s", kfile);

	/* read exec header */
	if ((fread(&exec, sizeof(exec), 1, f)) != 1)
		badfmt("no exec header");
	if (N_BADMAG(exec))
		badfmt("bad magic number");
	if (exec.a_syms == 0)
		badfmt("stripped");
	(void)fstat(fileno(f), &stb);
	if (stb.st_size < N_STROFF(exec) + sizeof(off_t))
		badfmt("no string table");

	/* seek to and read the symbol table */
	sa = N_SYMOFF(exec);
	(void)fseek(f, sa, SEEK_SET);
	n = exec.a_syms;
	if (!(symtab = (struct nlist *)malloc(n)))
		err(ERREXIT, NULL);
	if (fread((void *)symtab, 1, n, f) != n)
		badfmt("corrupted symbol table");

	/* read string table size and string table */
	if (fread((void *)&strtabsize, sizeof(int), 1, f) != 1 ||
	    strtabsize <= 0)
		badfmt("corrupted string table");
	strings = malloc(strtabsize);
	if (strings == NULL)
		err(ERREXIT, NULL);
	/*
	 * Subtract four from strtabsize since strtabsize includes itself,
	 * and we've already read it.
	 */
	if (fread(strings, 1, strtabsize - sizeof(int), f) !=
	    strtabsize - sizeof(int))
		badfmt("corrupted string table");

	i = n / sizeof(struct nlist);
	if (!clean) {
		newtab = (struct nlist *)malloc(n);
		if (newtab == NULL)
			err(ERREXIT, NULL);
		memset(newtab, 0, n);

		reorder(symtab, newtab, i);
		free((void *)symtab);
		symtab = newtab;
	} else {
		symkept = i;
	}

	newstrings = malloc(strtabsize);
	if (newstrings == NULL)
		err(ERREXIT, NULL);
	t = newstrings;
	for (symp = symtab; --i >= 0; symp++) {
		if (symp->n_un.n_strx == 0)
			continue;
		if (inlist(symp) < 0) {
			if (small)
				continue;
			if (clean && !savesymb(symp))
				symp->n_type &= ~N_EXT;
		} else if (clean)
			symfound++;
		symp->n_un.n_strx -= sizeof(int);
		(void)strcpy(t, &strings[symp->n_un.n_strx]);
		symp->n_un.n_strx = (t - newstrings) + sizeof(int);
		t += strlen(t) + 1;
	}

	/* update shrunk sizes */
	strtabsize = t - newstrings + sizeof(int);
	n = symkept * sizeof(struct nlist);

	/* fix exec sym size */
	(void)lseek(o, (off_t)0, SEEK_SET);
	exec.a_syms = n;
	if (write(o, (void *)&exec, sizeof(exec)) != sizeof(exec))
		err(ERREXIT, "%s", kfile);

	(void)lseek(o, sa, SEEK_SET);
	if (write(o, (void *)symtab, n) != n)
		err(ERREXIT, "%s", kfile);
	if (write(o, (void *)&strtabsize, sizeof(int)) != sizeof(int))
		err(ERREXIT, "%s", kfile);
	if (write(o, newstrings, strtabsize - sizeof(int)) !=
	    strtabsize - sizeof(int))
		err(ERREXIT, "%s", kfile);

	ftruncate(o, lseek(o, (off_t)0, SEEK_CUR));

	if ((i = nsym - symfound) > 0) {
		(void)printf("symorder: %d symbol%s not found:\n",
		    i, i == 1 ? "" : "s");
		for (i = 0; i < nsym; i++)
			if (order[i].n_value == 0)
				printf("%s\n", order[i].n_un.n_name);
		if (!missing)
			exit(NOTFOUNDEXIT);
	}
	exit(OKEXIT);
}