File:  [MW Coherent from dump] / coherent / d / bin / cc / c / coh / siz286.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:39 2019 UTC (7 years, 2 months ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/*
 * siz286.c
 * 1/31/84
 * Usage:  siz286 [ file ... ]
 *
 * Reads Intel 80286 OMF from standard input or given files,
 * writes segment sizes on standard output.
 * Currently understands only about linkable modules.
 * Prints all numbers in hex.
 *
 * Reference:  "The Concrete Representation of 80286
 * Object Module Formats", Rev. 1.91 (c) Intel 1983.
 */

#include <stdio.h>

#define	VERSION	"1.2"		/* version number */
#ifdef	UDI
#define	VFLAG	"-v"		/* version flag must be l.c. for UDI */
#else
#define	VFLAG	"-V"
#endif
#ifdef vax
#include	<ssdef.h>
#include	<stsdef.h>
#define	SRMODE	"r"
#define	OK	(STS$M_INHIB_MSG|SS$_NORMAL)
#define	BAD	(STS$M_INHIB_MSG|SS$_ABORT)
#else
#define	SRMODE	"rb"
#define	OK	0
#define	BAD	1
#endif

#define	LNKMOD	0xA0		/* linkable module */
#define	MHDLEN	111		/* module header length */
#define	EXTMSK	0x40		/* SEGDEF external attribute mask */

extern unsigned int geti();
extern unsigned long getl();
long len;

main (argc, argv)
int argc;
register char **argv;
{
	if (strcmp(*++argv, VFLAG) == 0) {
		++argv;
		fprintf (stderr, "siz286:  V%s\n", VERSION);
	}
	if (*argv == NULL)
		printsize();
	else {
		while (*argv != NULL) {
			printf("%s:\n", *argv);
			if (freopen(*argv, SRMODE, stdin) == NULL)
				fatal ("open for input failed");
			printsize();
			argv++;
		}
	}
	exit (OK);
}

/*
 * Read an OMF286 object file from stdin and print its size.
 */
printsize()
{
	register unsigned int n;
	int nsegs = 0;			/* number of segments */
	long size;			/* segment size */
	long segloc;			/* location of SEGDEF section */
	long seglen;			/* length of SEGDEF section */
	long total = 0L;		/* sum of segment lengths */
	if (getb() != LNKMOD)		/* Read file type. */
		fatal ("object is not a linkable file");
	ignore(MHDLEN);			/* Ignore module header. */
	segloc = getl();		/* Get SEGDEF location. */
	seglen = getl();		/* Get SEGDEF length. */
	ignore(segloc - (long)(MHDLEN+8));	/* Seek to start of SEGDEF section. */
	len = seglen;
	while (len) {			/* Process segment definitions. */
		++nsegs;
		n = geti()&EXTMSK;	/* Get attributes, mask to external. */
		size = geti();		/* Get slimit. */
		if (n == 0)
			size++;		/* slimit=length-1 for nonexternals. */
		total += size;		/* Bump the sum. */
		printf("\t0x%04lx\t", size);	/* Print the size. */
		ignore(4);		/* Ignore dlength and LDT position. */
		n = getb();		/* Get name length. */
		while (n--)
			putchar (getb());	/* Print the name. */
		putchar('\n');
	}
	if (nsegs > 1) {			/* Print the sum. */
		printf("\t0x%04lx\tTotal (hex)\n", total);
		printf("\t%6ld\tTotal (decimal)\n", total);
	}
}

/*
 * Read a byte from standard input, update len.
 */
getb()
{
	register int i;
	if ((i = getchar()) == EOF)
		fatal ("premature EOF");
	--len;
	return (i);
}

/*
 * Read a word and return it.
 */
unsigned int
geti()
{
	register int i = getb();
	return (i | (getb() << 8));
}

/*
 * Read a long and return it.
 */
unsigned long
getl()
{
	register long l = geti();
	return (l | (((long) geti()) << 16));
}

/*
 * Read and ignore n characters.
 */
ignore(n)
register int n;
{
	while (n--)
		getb();
}

/*
 * Print error message and exit.
 */
fatal (s)
register char *s;
{
	fprintf (stderr, "siz286:  %s\n", s);
	exit(BAD);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.