summaryrefslogtreecommitdiff
path: root/src/icont/lmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/icont/lmem.c')
-rw-r--r--src/icont/lmem.c224
1 files changed, 224 insertions, 0 deletions
diff --git a/src/icont/lmem.c b/src/icont/lmem.c
new file mode 100644
index 0000000..8e091a5
--- /dev/null
+++ b/src/icont/lmem.c
@@ -0,0 +1,224 @@
+/*
+ * lmem.c -- memory initialization and allocation; also parses arguments.
+ */
+
+#include "link.h"
+#include "tproto.h"
+#include "tglobals.h"
+
+/*
+ * Prototypes.
+ */
+
+static struct lfile *alclfile (char *name);
+
+void dumplfiles(void);
+
+/*
+ * Memory initialization
+ */
+
+struct gentry **lghash; /* hash area for global table */
+struct ientry **lihash; /* hash area for identifier table */
+struct fentry **lfhash; /* hash area for field table */
+
+struct lentry *lltable; /* local table */
+struct centry *lctable; /* constant table */
+struct ipc_fname *fnmtbl; /* table associating ipc with file name */
+struct ipc_line *lntable; /* table associating ipc with line number */
+
+char *lsspace; /* string space */
+word *labels; /* label table */
+char *codeb; /* generated code space */
+
+struct ipc_fname *fnmfree; /* free pointer for ipc/file name table */
+struct ipc_line *lnfree; /* free pointer for ipc/line number table */
+word lsfree; /* free index for string space */
+char *codep; /* free pointer for code space */
+
+struct fentry *lffirst; /* first field table entry */
+struct fentry *lflast; /* last field table entry */
+struct gentry *lgfirst; /* first global table entry */
+struct gentry *lglast; /* last global table entry */
+
+/*
+ * linit - scan the command line arguments and initialize data structures.
+ */
+void linit()
+ {
+ struct gentry **gp;
+ struct ientry **ip;
+ struct fentry **fp;
+
+ llfiles = NULL; /* Zero queue of files to link. */
+
+ /*
+ * Allocate the various data structures that are used by the linker.
+ */
+ lghash = (struct gentry **) tcalloc(ghsize, sizeof(struct gentry *));
+ lihash = (struct ientry **) tcalloc(ihsize, sizeof(struct ientry *));
+ lfhash = (struct fentry **) tcalloc(fhsize, sizeof(struct fentry *));
+
+ lltable = (struct lentry *) tcalloc(lsize, sizeof(struct lentry));
+ lctable = (struct centry *) tcalloc(csize, sizeof(struct centry));
+
+ lnfree = lntable = (struct ipc_line*)tcalloc(nsize,sizeof(struct ipc_line));
+
+ lsspace = (char *) tcalloc(stsize, sizeof(char));
+ lsfree = 0;
+
+ fnmtbl = (struct ipc_fname *) tcalloc(fnmsize, sizeof(struct ipc_fname));
+ fnmfree = fnmtbl;
+
+ labels = (word *) tcalloc(maxlabels, sizeof(word));
+ codep = codeb = (char *) tcalloc(maxcode, 1);
+
+ lffirst = NULL;
+ lflast = NULL;
+ lgfirst = NULL;
+ lglast = NULL;
+
+ /*
+ * Zero out the hash tables.
+ */
+ for (gp = lghash; gp < &lghash[ghsize]; gp++)
+ *gp = NULL;
+ for (ip = lihash; ip < &lihash[ihsize]; ip++)
+ *ip = NULL;
+ for (fp = lfhash; fp < &lfhash[fhsize]; fp++)
+ *fp = NULL;
+
+ /*
+ * Install "main" as a global variable in order to insure that it
+ * is the first global variable. iconx/start.s depends on main
+ * being global number 0.
+ */
+ putglobal(instid("main"), F_Global, 0, 0);
+ }
+
+#ifdef DeBugLinker
+ /*
+ * dumplfiles - print the list of files to link. Used for debugging only.
+ */
+ void dumplfiles()
+ {
+ struct lfile *p,*lfls;
+
+ fprintf(stderr,"lfiles:\n");
+ lfls = llfiles;
+ while (p = getlfile(&lfls))
+ fprintf(stderr,"'%s'\n",p->lf_name);
+ fflush(stderr);
+ }
+#endif /* DeBugLinker */
+
+/*
+ * alsolink - create an lfile structure for the named file and add it to the
+ * end of the list of files (llfiles) to generate link instructions for.
+ */
+void alsolink(name)
+char *name;
+ {
+ struct lfile *nlf, *p;
+ char file[MaxPath];
+
+ if (!pathfind(file, ipath, name, U1Suffix))
+ quitf("cannot resolve reference to file '%s'",name);
+
+ nlf = alclfile(file);
+ if (llfiles == NULL) {
+ llfiles = nlf;
+ }
+ else {
+ p = llfiles;
+ while (p->lf_link != NULL) {
+ if (strcmp(p->lf_name,file) == 0)
+ return;
+ p = p->lf_link;
+ }
+ if (strcmp(p->lf_name,file) == 0)
+ return;
+ p->lf_link = nlf;
+ }
+ }
+
+/*
+ * getlfile - return a pointer (p) to the lfile structure pointed at by lptr
+ * and move lptr to the lfile structure that p points at. That is, getlfile
+ * returns a pointer to the current (wrt. lptr) lfile and advances lptr.
+ */
+struct lfile *getlfile(lptr)
+struct lfile **lptr;
+ {
+ struct lfile *p;
+
+ if (*lptr == NULL)
+ return (struct lfile *)NULL;
+ else {
+ p = *lptr;
+ *lptr = p->lf_link;
+ return p;
+ }
+ }
+
+/*
+ * alclfile - allocate an lfile structure for the named file, fill
+ * in the name and return a pointer to it.
+ */
+static struct lfile *alclfile(name)
+char *name;
+ {
+ struct lfile *p;
+
+ p = (struct lfile *) alloc(sizeof(struct lfile));
+ p->lf_link = NULL;
+ p->lf_name = salloc(name);
+ return p;
+ }
+
+/*
+ * lmfree - free memory used by the linker
+ */
+void lmfree()
+ {
+ struct fentry *fp, *fp1;
+ struct gentry *gp, *gp1;
+ struct rentry *rp, *rp1;
+ struct ientry *ip, *ip1;
+ int i;
+
+ for (i = 0; i < ihsize; ++i)
+ for (ip = lihash[i]; ip != NULL; ip = ip1) {
+ ip1 = ip->i_blink;
+ free((char *)ip);
+ }
+
+ free((char *) lghash); lghash = NULL;
+ free((char *) lihash); lihash = NULL;
+ free((char *) lfhash); lfhash = NULL;
+ free((char *) lltable); lltable = NULL;
+ free((char *) lctable); lctable = NULL;
+ free((char *) lntable); lntable = NULL;
+ free((char *) lsspace); lsspace = NULL;
+ free((char *) fnmtbl); fnmtbl = NULL;
+ free((char *) labels); labels = NULL;
+ free((char *) codep); codep = NULL;
+
+ for (fp = lffirst; fp != NULL; fp = fp1) {
+ for(rp = fp->f_rlist; rp != NULL; rp = rp1) {
+ rp1 = rp->r_link;
+ free((char *)rp);
+ }
+ fp1 = fp->f_nextentry;
+ free((char *)fp);
+ }
+ lffirst = NULL;
+ lflast = NULL;
+
+ for (gp = lgfirst; gp != NULL; gp = gp1) {
+ gp1 = gp->g_next;
+ free((char *)gp);
+ }
+ lgfirst = NULL;
+ lglast = NULL;
+ }