Hah!

Dennis Flaherty dflahert at tagore.helios.nd.edu
Thu Oct 25 11:09:22 AEST 1990


In article <59463 at wlbr.IMSD.CONTEL.COM> sms at WLV.IMSD.CONTEL.COM.UUCP (Steven M. Schultz) writes:
> In article <69909 at lll-winken.LLNL.GOV> casey at gauss.llnl.gov (Casey Leedom) writes:
> >/ From:  dflahert at tagore.helios.nd.edu (Dennis Flaherty)
> >| 
> >| Hah!  This topic has generated more traffic than comp.bugs.2bsd has seen
> >\ in a long time!  At least comp.sys.cbm keeps busy with for-sale articles.
> >
> >  That's because there are so few bugs in 2BSD ... :-) Besides, who in
> 
> 	It is a rather stable system by now, isn't it? ;-)
> 
> >their right mind would buy a used PDP-11?? :-) :-)
> 
> 	ME!  Right now i've got a loaner 11/73 but with only a single RD53.
> 	And, since it has been a while, here's a fix.  

Ok, ok, I can't let Steven go out on a limb as the only one to
attempt to put some life back in this dying group.  Below is a
program I wrote a few months ago, with a README and a man page.
I'd appreciate it if people would beta-test it for me, if that
still means anything anymore.

It's mkovmake, an overlay-makefile maker.  You give it a list of
object modules and it figures out how to put them on overlays.
It gave me quite an appreciation of the work Casey and Keith put
in the original release that made this possible.  Mkovmake is
capable of some static optimization; although it's not as good as
it could be if it did some profiling, at least it should get the
program running.  And if you were worried about speed, would you
have a PDP-11?

Dennis
--
Dennis Flaherty              dennisf at ndcvx.cc.nd.edu
U of Notre Dame      Dept. of Electrical Engineering
  Notre Dame *tells* me what opinions to have.


------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README mkovmake.c mkovmake.man
# Wrapped by dflahert at tagore on Fri Oct 19 22:33:11 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(761 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X 
X Mkovmake is an optimizing overlay makefile generator--
X in other words, you use it in the Makefile of a large
X program that you are trying to make, and it generates
X base and overlay definitions and an ld command that
X would correctly load the object modules.  This avoids
X incessant calculations of module sizes each time sources
X are changed, and allows large programs to be easily put
X together on a PDP-11.  It is designed to allow varying
X levels of user participation in case the user can 
X optimize better than mkovmake's static algorithm.
X 
X Try it out; the man page even has examples.
X 
X 
X --
X Dennis Flaherty              dennisf at ndcvx.cc.nd.edu
X U of Notre Dame      Dept. of Electrical Engineering
X   Notre Dame *tells* me what opinions to have.
END_OF_FILE
if test 761 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'mkovmake.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mkovmake.c'\"
else
echo shar: Extracting \"'mkovmake.c'\" \(13602 characters\)
sed "s/^X//" >'mkovmake.c' <<'END_OF_FILE'
X/*
X * mkovmake.c	by dennisf at ndcvx.cc.nd.edu  March 1990
X *	makes an overlay makefile for specified object modules.
X */
X
X#include <stdio.h>
X#include <strings.h>
X#include <ctype.h>
X#include <sys/param.h>
X#include <a.out.h>
X
X#ifndef NOVL
X#define NOVL	15
X#endif	NOVL
X#define N_NAMELENGTH	8
X#define IN_BASE	0
X#define UNCOMMITTED	-1
X#define strequ	!strcmp
X#define strnequ	!strncmp
X#define isobj(name)	name[0] && name[0] != '-' && rindex(name,'.') \
X	&& strequ(rindex(name,'.'), ".o")
X#define isarc(name)	name[0] && name[0] != '-' && rindex(name,'.') \
X	&& strequ(rindex(name,'.'), ".a")
X
Xstruct modstruct
X{
X	char *name;
X	unsigned text;
X	short overlay;
X	char **textnames;
X	char **undfnames;
X} *module;
XFILE *output;
Xchar *malloc(), *realloc(), *adlib(), *libs;
Xint optimize, listnames;
Xdouble metoo();
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	register i, n;
X	int ovinit;	/* initial ov number, IN_BASE or UNCOMMITTED */
X	int j;		/* redundant-module index */
X	int nobj;	/* number of modules, used for malloc()ing */
X	long ovtext;	/* total size of text of UNCOMMITTED modules */
X	int ov;		/* overlay number, used in for loop */
X	int max_ovs;	/* max number of ovs mkovmake can make */
X	int ovs_used;	/* number of ovs actually used */
X	int modsleftout;/* number of modules not assigned to an ov */
X	unsigned max_ovsize;	/* sizeof biggest overlay, multiple of 8k */
X	unsigned bigovmod;	/* sizeof biggest module not assigned to base */
X	unsigned ovspace;	/* space occupied in current ov */
X	unsigned basesize;	/* limit on base, if optimizing */
X	int mostroutines;	/* module with biggest global text routines
X				   per kb text ratio, if optimizing base */
X	double baseopt;		/* the best such ratio so far */
X	int wannabe;	/* module that most wants to be on the overlay,
X			   if optimizing */
X	double affinity;/* metoo(ov,wannabe) */
X	double affinn;	/* metoo(ov,n) */
X	int Zused;	/* -Z option specified somewhere used in -O2 */
X	long tmpl;
X	char *makename, *program;
X	char *arg, switchc;
X
X	/* Usage */
X	if (argc == 1)
X	{
Xusage:		fprintf(stderr,
X		 "usage:  mkovmake [-On [basesize] [-n]] [-fmakefile] [-sovsize] [-vmax_ovs]\n");
X		fprintf(stderr, "\t\t[-oprogram] [-llibs ...] bases.o ... -Z ovmodules.o ...\n");
X		exit(1);
X	}
X
X	/* Set defaults */
X	Zused = listnames = bigovmod = ovtext = nobj = optimize = 0;
X	output = stdout;
X	max_ovsize = basesize = UNCOMMITTED;
X	ovinit = IN_BASE;
X	max_ovs = NOVL;
X	program = "$(PROGRAM)";
X	libs = malloc(2);
X	libs[0] = 0;
X	/* First parsing: get options, count object modules */
X	for (i = 1; i < argc; ++i)
X	{
X		if (argv[i][0] != '-')
X		{
X			if (isobj(argv[i]))
X				++nobj;
X			else if (isarc(argv[i]))
X				adlib(argv[i]);
X			else
X			{
X				fprintf(stderr, "mkovmake:  %s: unknown file type.\n",
X				 argv[i]);
X				exit(5);
X			}
X		}
X		else
X		{
X			switchc = argv[i][1];
X			arg = argv[i] + 2;
X			if (!arg[0])
X				arg = argv[++i];
X			switch (switchc)
X			{
X			case 'O':
X				optimize = 1; /* Use given BASE */
X				if (arg[0] == '2')
X				{
X					optimize = 2; /* Determine BASE */
X					if (isdigit(argv[i+1][0]))
X					{
X						basesize = atoi(argv[++i]);
X						if (index(argv[i],'k')
X						 || index(argv[i],'K'))
X							basesize *= 1024;
X						if (basesize < 10)
X							basesize *= 8192;
X					}
X				}
X				else
X					--i; /* no argument */
X				break;
X			case 'n':
X				++listnames;
X				--i; /* no argument */
X				break;
X			case 'Z':
X				if (optimize != 2 && !nobj)
X					fprintf(stderr, "Nothing in the BASE?  Ok...\n");
X				++Zused;
X				--i; /* no argument */
X				break;
X			case 'f':
X				makename = arg;
X				if ((output = fopen(makename, "w")) == NULL)
X				{
X					fprintf(stderr,
X				 	"%s: cannot open for output.\n", makename);
X					exit(2);
X				}
X				break;
X			case 's':
X				max_ovsize = atoi(arg);
X				if (index(arg,'k') || index(arg,'K'))
X					max_ovsize *= 1024;
X				if (max_ovsize < 10)
X					max_ovsize *= 8192;
X				break;
X			case 'v':
X				max_ovs = atoi(arg);
X				if (max_ovs > NOVL)
X				{
X					fprintf(stderr,
X					 "mkovmake:  can only use %d overlays.\n",
X					 NOVL);
X					max_ovs = NOVL;
X				}
X				break;
X			case 'o':
X				program = arg;
X				break;
X			case 'l':
X				adlib("-l");
X				adlib(arg);
X				break;
X			default:
X				goto usage;
X			}
X		}
X	}
X	if (!libs[0])
X	{
X		free(libs);
X		libs = "$(LIBS) ";
X	}
X	if (!Zused && optimize == 2)
X		ovinit = UNCOMMITTED;
X
X	/* Second parsing: malloc for module[] array and load its members */
X	if (!(module = (struct modstruct *) malloc(sizeof(struct modstruct) * ++nobj)))
X	{
X		fprintf(stderr, "mkovmake:  not enough memory for module list.\n");
X		fprintf(stderr, "mkovmake:  can't use mkovmake!  Help!\n");
X		exit(6);
X	}
X	for (i = 1, n = 0; i < argc; ++i)
X	{
X		for (j = 1; j < i; ++j)
X			if (strequ(argv[i], argv[j]))
X				break;
X		if (argv[i][0] == '-' && argv[i][1] == 'Z')
X			ovinit = UNCOMMITTED;
X		else if (j == i && isobj(argv[i]))
X		{
X			module[n].name = argv[i];
X			module[n].overlay = ovinit;
X			getnames(n);  /* gets sizeof text and name lists */
X			if (ovinit != IN_BASE)
X			{
X				ovtext += module[n].text;
X				if (module[n].text > bigovmod)
X					bigovmod = module[n].text;
X			}
X			++n;
X		}
X	}
X	module[n].name = "";
X	if (max_ovsize == UNCOMMITTED)
X	{
X		max_ovsize = (unsigned) (ovtext / (7680L * max_ovs) + 1) * 8192;
X		if (bigovmod > max_ovsize)
X			max_ovsize = (bigovmod / 8192 + 1) * 8192;
X		fprintf(output, "# Using %dk overlays.\n", max_ovsize/1024);
X	}
X
X	/*
X	 * Optimizer levels:
X	 * 1: use given BASE, all other modules are UNCOMMITTED.
X	 * 2: determine BASE, all modules are UNCOMMITTED.
X	 * 3: programmer gets COMMITTED.
X	 */
X	if (optimize == 2)
X	{
X		if (basesize == UNCOMMITTED)
X		{
X			/* is this a fudge or what?? */
X			tmpl = ((tmpl = 2048 + nlibs()*2048L + ovtext/5)
X			 > 24576L) ? 24576L : tmpl;
X			basesize = (65536L - max_ovsize - tmpl);
X			fprintf(output, "# Using %u-byte base, without libraries.\n",
X			 basesize);
X			/* If enough people are interested, I'll make a version
X			   of this that adds up routines used within libraries */
X		}
X		n = -1;
X		while (module[++n].name[0])
X			if (module[n].overlay == IN_BASE)
X				basesize -= module[n].text;
X		if (basesize < 0)
X		{
X			fprintf(stderr, "mkovmake:  specified modules don't fit in base.\n");
X			fprintf(stderr, "mkovmake:  specify fewer modules or larger base.\n");
X			exit(9);
X		}
X		do /* load the base */
X		{
X			baseopt = 0.;
X			n = -1;
X			while(module[++n].name[0])
X				if (module[n].overlay != IN_BASE
X				 && module[n].text
X				 && module[n].text <= basesize
X				 && (double) (sizeof(module[n].textnames)-1)
X				 / module[n].text > baseopt)
X				{
X					mostroutines = n;
X					baseopt = (double)
X					 (sizeof(module[n].textnames)-1)
X					 / module[n].text;
X				}
X			if (baseopt)
X			{
X				module[mostroutines].overlay = IN_BASE;
X				basesize -= module[mostroutines].text;
X			}
X		} while(baseopt);
X	}
X	listmodules(IN_BASE);
X
X	/*
X	 * overlay packing:
X	 * If not optimizing, just pack modules until no more can fit.
X	 * Otherwise, add a module only if it's the one thats to be on
X	 *	the ov the most, using metoo().
X	 */
X	for (ov = 1; ov <= max_ovs; ++ov)
X	{
X		ovspace = 0;
Xaddmod:		n = -1;
X		while (module[++n].name[0])
X		{
X			if (module[n].overlay == UNCOMMITTED
X			 && module[n].text + ovspace <= max_ovsize)
X			{
X				module[n].overlay = ov;
X				ovspace += module[n].text;
X				/* optimizer needs one */
X				if (optimize && module[n].text)
X					break;
X			}
X		}
X		if (!ovspace) /* max_ovsize is too small for a module */
X			break;
X		if (optimize && module[n].name[0])
X		{
X			for (;;) /* only escape is the goto! yuck! */
X			{
X				affinity = 0.;
X				n = -1;
X				while (module[++n].name[0])
X				{
X					if (module[n].overlay == UNCOMMITTED
X					 && module[n].text
X					 && module[n].text + ovspace <= max_ovsize
X					 && (affinn = metoo(ov,n)) > affinity)
X					{
X						wannabe = n;
X						affinity = affinn;
X					}
X				}
X				if (!affinity)
X					goto addmod; /* will another mod fit? */
X				module[wannabe].overlay = ov;
X				ovspace += module[wannabe].text;
X			}
X		}
X		listmodules(ov);
X	}
X	ovs_used = ov;
X
X	/* And what if they just don't all fit? */
X	n = modsleftout = 0;
X	while (module[n].name[0])
X		if (module[n++].overlay == UNCOMMITTED)
X			++modsleftout;
X	if (modsleftout)
X	{
X		fprintf(stderr, "\nAfter %d overlay", ovs_used-1);
X		if (ovs_used != 2)  fprintf(stderr, "s");
X		fprintf(stderr, ", the following ");
X		if (modsleftout == 1)
X			fprintf(stderr, "module was\n");
X		else
X			fprintf(stderr, "%d modules were\n", modsleftout);
X		fprintf(stderr,
X		 "left out of the BASE and OVerlay definitions:\n");
X		n = -1;
X		while (module[++n].name[0])
X			if (module[n].overlay == UNCOMMITTED)
X				fprintf(stderr, "  %s\n", module[n].name);
X		fprintf(stderr,
X		 "\nYou can 1) Use more or bigger overlays,\n");
X		fprintf(stderr, "  2) Use a smaller base, or\n");
X		fprintf(stderr, "  3) \"Go buy a VAX.\"\n");
X		fclose(output);
X		exit(3);
X	}
X
X	fprintf(output,
X	 "%s:\n\t/bin/ld -i -X -o %s /lib/crt0.o \\\n\t", program, program);
X	fprintf(output, "$(BASE) ");
X	for (ov = 1; ov < ovs_used; ++ov)
X	{
X		if (ov % 4 == 1)
X			fprintf(output, "\\\n\t");
X		fprintf(output, "-Z $(OV%d) ", ov);
X	}
X	fprintf(output, "\\\n\t-Y %s-lc\n", libs);
X	fclose(output);
X	free((char *) module);
X	free(libs);
X	exit(0);
X}
X
X/*
X * listmodules(ov)
X *	lists modules in overlay ov (ov=0 is BASE), each line
X *	preceded by a tab and not exceeding LISTWIDTH characters.
X */
X
X#define LISTWIDTH	60
X
Xlistmodules(ov)
Xint ov;
X{
X	int currentwidth = 0, n = -1, namelength;
X	unsigned listovspace = 0;
X
X	if (ov == IN_BASE)
X		fprintf(output, "\nBASE=\t");
X	else
X		fprintf(output, "OV%d=\t", ov);
X	while (module[++n].name[0])
X	{
X		if (module[n].overlay == ov)
X		{
X			namelength = strlen(module[n].name);
X			if (currentwidth + namelength > LISTWIDTH)
X			{
X				fprintf(output, "\\\n\t");
X				currentwidth = 0;
X			}
X			currentwidth += (namelength + 1);
X			fprintf(output, "%s ", module[n].name);
X			listovspace += module[n].text;
X		}
X	}
X	fprintf(output, "\n# %u bytes.\n\n", listovspace);
X}
X
X/*
X * metoo()	returns how much a module wants to be on an overlay.
X */
Xdouble
Xmetoo(ov, mod)
Xint ov, mod;
X{
X	int n, postnews;
X
X	if (!module[mod].text)
X		return(0.);
X	postnews = 0;
X	n = -1;
X	while (module[++n].name[0])
X		if (module[n].overlay == ov)
X			postnews += ilikeu(n, mod) + ilikeu(mod, n);
X	return((double) postnews / module[mod].text);
X}
X
X/*
X * ilikeu()	returns how much one module likes another.
X *	Just like life, it's not necessarily symmetrical.
X */
Xilikeu(me, you)
Xint me, you;
X{
X	int friendly;
X	char **ineed, **youhave;
X
X	friendly = 0;  /* Who are you? */
X	ineed = module[me].undfnames;
X	youhave = module[you].textnames;
X	while(**ineed)
X	{
X		while(**youhave)
X		{
X			if (strnequ(*ineed, *youhave++, N_NAMELENGTH))
X			{
X				++friendly;
X				break;
X			}
X		}
X		++ineed;
X	}
X	return(friendly);
X}
X
X/*
X * adlib(s)	adds s onto libs.
X */
Xchar *
Xadlib(s)
Xchar *s;
X{
X	char *morelibs;
X
X	if (!(morelibs = realloc(libs, strlen(libs)+strlen(s)+3)))
X	{
X		fprintf(stderr, "mkovmake:  not enough memory for library names.\n");
X		exit(7);
X	}
X	strcat(morelibs, s);
X	if (s[0] != '-')
X		strcat(morelibs, " ");
X	libs = morelibs;
X	return(morelibs);
X}
X
X/*
X * nlibs()	How many libs are there?
X */
Xnlibs()
X{
X	int i=0;
X	char *s;
X	s = libs;
X	while (*s)
X		if (*s++ == ' ')
X			++i;
X	return(i);
X}
X
X/*
X * getnames(n)	opens object module n and gets size of text,
X *	and name lists if using optimizer.
X */
Xgetnames(n)
Xint n;
X{
X	struct exec exp;
X	struct nlist namentry;
X	FILE *obj;
X	long offset;
X	int nundf, ntext;
X
X	if ((obj = fopen(module[n].name,"r")) == NULL)
X	{
X		fprintf(stderr, "mkovmake:  cannot open %s.\n", module[n].name);
X		exit(8);
X	}
X	fseek(obj, 0L, 0);
X	fread((char *)&exp, 1, sizeof(struct exec), obj);
X	module[n].text = exp.a_text;
X	if (!optimize)
X	{
X		fclose(obj);
X		return(0);
X	}
X
X	offset = (long)sizeof(struct exec) + ((long)exp.a_text+exp.a_data)*2;
X	fseek(obj, offset, 0);
X
X	ntext = nundf = 0;
X	while (fread((char *)&namentry, sizeof(struct nlist), 1, obj) == 1)
X	{
X		if (namentry.n_type & N_EXT)
X		{
X			switch (namentry.n_type&N_TYPE)
X			{
X			case N_UNDF:
X				if (!namentry.n_value)
X					++nundf;
X				break;
X			case N_TEXT:
X				++ntext;
X				break;
X			}
X		}
X	}
X	module[n].textnames = (char **) malloc(++ntext * 2);
X	module[n].undfnames = (char **) malloc(++nundf * 2);
X	if (!module[n].textnames || !module[n].undfnames)
X	{
Xnosyms:		fprintf(stderr, "mkovmake:  not enough memory for symbols list.\n");
X		fprintf(stderr, "mkovmake:  can't optimize.\n");
X		optimize = 0;
X		fclose(obj);
X		return(1);
X	}
X
X	ntext = nundf = 0;
X	fseek(obj, offset, 0);
X	while (fread((char *)&namentry, sizeof(struct nlist), 1, obj) == 1)
X	{
X		if (namentry.n_type & N_EXT)
X		{
X			switch (namentry.n_type&N_TYPE)
X			{
X			case N_UNDF:
X				if (!namentry.n_value)
X				{
X					if (!(module[n].undfnames[nundf] 
X					 = malloc(N_NAMELENGTH)))
X						goto nosyms;
X					strncpy(module[n].undfnames[nundf++],
X					 namentry.n_name, N_NAMELENGTH);
X					if (listnames)
X						pname(n,namentry.n_name,0);
X				}
X				break;
X			case N_TEXT:
X				if (!(module[n].textnames[ntext]
X				 = malloc(N_NAMELENGTH)))
X					goto nosyms;
X				strncpy(module[n].textnames[ntext++],
X				 namentry.n_name, N_NAMELENGTH);
X				if (listnames)
X					pname(n,namentry.n_name,1);
X				break;
X			}
X		}
X	}
X	module[n].undfnames[nundf] = "";
X	module[n].textnames[ntext] = "";
X	fclose(obj);
X	return(0);
X}
X
X/*
X * pname(n,s,t)
X *	prints global Text(t=1) and Undf(t=0) name s encountered in module n.
X *	(takes care of possible lack of null terminator)
X */
Xpname(n,s,t)
Xint n,t;
Xchar *s;
X{
X	char buf[N_NAMELENGTH+1];
X	strncpy(buf, s, N_NAMELENGTH);
X	buf[N_NAMELENGTH] = 0;
X	if (t)
X		fprintf(stderr, "%s: T %s\n", module[n].name, buf);
X	else
X		fprintf(stderr, "%s: U %s\n", module[n].name, buf);
X}
END_OF_FILE
if test 13602 -ne `wc -c <'mkovmake.c'`; then
    echo shar: \"'mkovmake.c'\" unpacked with wrong size!
fi
# end of 'mkovmake.c'
fi
if test -f 'mkovmake.man' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mkovmake.man'\"
else
echo shar: Extracting \"'mkovmake.man'\" \(7252 characters\)
sed "s/^X//" >'mkovmake.man' <<'END_OF_FILE'
X./" mkovmake	by dennisf at ndcvx.cc.nd.edu
X./"	June 1990
X./"
X.TH MKOVMAKE 8 "June 30, 1990"
X.SH NAME
Xmkovmake \- optimizing overlay makefile generator
X.SH SYNOPSIS
X.B mkovmake
X.RB [ \-O\fIn\fP
X.RI [ basesize ]
X.RB [ \-n ]]
X.RB [ \-f
X.IR makefile ]
X.RB [ \-s
X.IR ovsize ]
X.if n .ti +.5i
X.RB [ \-v
X.IR "max ov's" ]
X.RB [ \-o
X.IR program ]
X.RB [ \-l
X.IR "libraries ..." ]
X.ti +.5i
X.RI [ archives ".a ...]"
X.IR basemodules ".o ..."
X.B \-Z
X.IR ovmodules ".o ..."
X.SH DESCRIPTION
X.PP
X.I Mkovmake
Xproduces an overlay makefile (see
X.IR make (1))
Xfor a given set of object modules (see
X.IR ld (1)).
XIt is intended to be used inside makefiles in order to avoid
Xcomputing module sizes and base/overlay structures each time
Xchanges are made in the source.
X.I Mkovmake
Xcan be included, as shown in the examples below, inside makefiles
Xof distributed sources so that the base and overlays would be
Xautomatically constructed whenever the program is made by a PDP-11.
XThe makefile generated contains the
X.I make
Xentry necessary for loading the modules together into an 
Xautomatic-overlay executable.
X.PP
XThere are several options to allow various levels of user involvement
Xin the construction process.  These options set the sizes of various
Xcomponents or the name of either the generated makefile or the 
X.I make
Xentry inside it.  If these options are not used, 
X.I mkovmake
Xwill guess at the best sizes and use standard names, respectively.
X.SH OPTIONS
X.TP
X.BI \-O n
XUse optimizer level 
X.IR n .
X.RS
X.TP
X.B \-O1
XPut only those modules listed before the
X.B \-Z
Xin the base, and construct optimal overlays for the remaining modules.
XThe algorithm of optimization for overlays is to iteratively add the module
Xwith the greatest number of "ties" with the modules currently on the overlay.
XA "tie" is a match between a global undefined symbol (see
X.IR nm (1))
Xin one module with
Xa global text symbol in another.  This measure is on a per-kbyte of text
Xbasis, and modules are added until no more will fit.  If
X.I n
Xis not specified, level
X.B 1
Xoptimization is assumed.
X.TP
X.B \-O2
XOptimize both the base and the overlays.  If a
X.B \-Z
Xflag is used, modules before it will be placed in the base, plus those
Xmodules with the greatest number of global text symbols per kbyte of text,
Xuntil no more modules will fit.  If no 
X.B \-Z
Xappears on the command line, 
X.I mkovmake
Xwill assume no initial base preference and will examine all modules for
Xbase and overlay optimization.  This is recommended for beginners.
X.TP
X.I basesize
XIf level-2 optimization is specified and the following argument begins 
Xwith a number, it will be used as the size of the base, without libraries.
XIf not used, 
X.I mkovmake
Xwill guess at how much room the libraries will take up, upto 24k.  
XIf 
X.I basesize
Xis followed by the letter "k" or "K", it will be multiplied by 1024.
XIf it is less than 10, it will be multiplied by 8192.
X.TP
X.B \-n
XList the global text and undefined symbols as they are encountered,
Xpreceded by the module name and a "T" for text or "U" for undefined.
X.LP
XIf no optimization is specified, modules will be
Xpacked on overlays
Xas they appear in the command line until no more fit.
X.RE
X.TP
X.BI \-f makefile
XSpecify the name of the generated makefile.  If not specified, 
X.B stdout
Xwill be used.
X.TP
X.BI \-s ovsize
XSpecify the maximum size of overlays.  Just as 
X.I basesize
Xabove, if followed by a "k" or "K", 
X.I ovsize
Xwill be multiplied by 1024, and if less than 10, it will be multiplied
Xby 8192.  If 
X.I ovsize
Xis not specified, 
X.I mkovmake
Xwill compute the total amount of text that is not already assigned
Xto the base, and guess at the size of overlays.
X.I Mkovmake
Xguesses, pessimisticly, that 1/16th of each overlay will be left
Xblank.
X.TP
X.ne 3
X.BI \-v "max ov's"
XSpecify the maximum number of overlays to use.  The default is
X.SM NOVL,
X15.
X.TP
X.BI \-o program
XThe name of the program being made.  This is used in the 
X.I make
Xentry generated after the base and overlay definitions.  If not used,
Xthe makefile macro
X.SM $(PROGRAM)
Xwill be inserted.
X.TP
X.BI \-l libraries " ..."
X.PD 0
X.TP
X.IR archives ".a ..."
X.PD
XExtra libraries or archives, such as 
X.I termlib
Xor
X.I m
Xcan be specified, and will be placed in the generated
X.I make
Xentry preceding the 
X.I c
Xlibrary.  If not used, 
X.SM $(LIBS)
Xwill be inserted.  Multiple libraries and archives can be specified
Xand will be placed together in the order 
Xthey appear on the command line.
X.TP
X.ne 3
X\fIbasemodules\fR.o ... \fB\-Z \fIovmodules\fR.o ...
XSpecify modules to be placed in the base and overlays, respectively.
X.I Mkovmake
Xwill ignore all redundancies, so 
X.IR ovmodules .o
Xmay be a macro of all modules, while
X.IR basemodules .o
Xmay be a subset.  If using level-2 optimization, only one list, the
Xmacro of all modules, is necessary.
X.SH EXAMPLES
X.PP
XIf 
X.I
Xmkovmake
Xis being used inside a makefile, the following lines can be inserted
Xto automatically construct the base and overlay definitions and
Xload the result.  The macro
X.SM $(OBJS)
Xis the list of all modules, 
X.B mybigprogram
Xis the program being made, and 
X.B termlib
Xis a library that has to be loaded with the object modules:
X.nf
X.ta +.5i
X	mkovmake \-fOvmakefile \-O2 $(OBJS) \-omybigprogram \-ltermlib
X	make \-f Ovmakefile
X.fi
X.PP
XIf it is known that 
X.SM $(BASE)
Xis a macro of the only modules that are wanted in the base,
X.SM $(GAME)
Xis the program being made, and
X.SM $(LIBS)
Xcontains libraries (with \-l prefixed) to be loaded with the modules,
Xthe following lines can be used:
X.nf
X	mkovmake \-fOvmakefile \-O \-o$(GAME) $(LIBS) $(BASE) \-Z $(OBJS)
X	make \-f Ovmakefile
X.fi
X.PP
XIf the user just wants a sample optimal makefile for the modules in
Xthe current working directory,
X.nf
X	mkovmake \-O2 *.o
X.fi
X.SH "SEE ALSO"
Xmake(1), nm(1), ld(1), strip(1), a.out(5), nlist(3)
X.SH DIAGNOSTICS
X.TP
X.B mkovmake: " unknown file type."
XA command-line argument not recognized as an option argument didn't
Xend in
X.B .o
Xor
X.BR .a .
X.TP
X.B mkovmake: " not enough memory for ..."
X.I mkovmake
Xfailed to use
X.IR malloc (2)
Xto clear space for a needed list.
X.TP
X.B mkovmake: " specified modules don't fit in base."
XLevel-2 optimization was used, and some modules were specified to
Xbe put in the base.  But these modules were too big.  Use
X.I basesize
Xto increase the base allotment, or reduce the number of base modules.
X.SH BUGS
X.PP
XCertain pathological cases may cause unpredictable results.  In
Xparticular, if the argument to an 
X.BR \-f ,
X.BR \-o ,
Xor
X.B \-l
Xoption is separated from the 
X.BR f ,
X.BR o ,
Xor
X.B l
Xby a space or tab, and the argument ends, for some reason, in
X.BR .o ,
Xthe second parsing of the command line will think it's a name of
Xan object module and attempt to open it.  Otherwise, options and
Xnames of modules may be freely mixed.
X.PP
X.I Mkovmake
Xassumes that all arguments ending with 
X.B .o 
Xor 
X.B .a 
Xare simple object modules or archives, respectively, rather than
Xlooking at the magic number and complaining if not.
X.PP
XThere is no way to tell
X.I mkovmake
Xto put a certain group of modules together on an overlay.
X.PP
X.I Mkovmake
Xis incapable of telling how
X.I often
Xa routine is called, or whether an executable could be loaded even
Xwithout overlays.
X.SH AUTHOR
X.nf
XDennis T. Flaherty,
XU of Notre Dame
Xdennisf at ndcvx.cc.nd.edu
END_OF_FILE
if test 7252 -ne `wc -c <'mkovmake.man'`; then
    echo shar: \"'mkovmake.man'\" unpacked with wrong size!
fi
# end of 'mkovmake.man'
fi
echo shar: End of shell archive.
exit 0


--
Dennis Flaherty              dennisf at ndcvx.cc.nd.edu
U of Notre Dame      Dept. of Electrical Engineering
  Notre Dame *tells* me what opinions to have.



More information about the Comp.bugs.2bsd mailing list