summaryrefslogtreecommitdiff
path: root/ld/ld.c
diff options
context:
space:
mode:
Diffstat (limited to 'ld/ld.c')
-rw-r--r--ld/ld.c187
1 files changed, 187 insertions, 0 deletions
diff --git a/ld/ld.c b/ld/ld.c
new file mode 100644
index 0000000..c19b98d
--- /dev/null
+++ b/ld/ld.c
@@ -0,0 +1,187 @@
+/* ld.c - linker for Introl format (6809 C) object files 6809/8086/80386 */
+
+/* Copyright (C) 1994 Bruce Evans */
+
+#include "const.h"
+#include "byteord.h"
+#include "type.h"
+#include "globvar.h"
+
+#ifdef STDC_HEADERS_MISSING
+extern int errno;
+char *strcat P((char *dest, const char *src));
+unsigned long strtoul P((const char *s, char **endptr, int base));
+#else
+#undef NULL
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#ifdef POSIX_HEADERS_MISSING
+#define R_OK 0
+int access P((const char *path, int amode));
+#else
+#undef NULL
+#include <unistd.h>
+#endif
+
+#define MAX_LIBS (NR_STDLIBS + 5)
+#define NR_STDLIBS 1
+
+PUBLIC long text_base_address; /* XXX */
+
+PRIVATE bool_t flag[128];
+PRIVATE char *libs[MAX_LIBS] = {
+#ifdef MC6809
+ "/usr/local/lib/m09/",
+#else
+ /* One of the following values will be inserted at run time. */
+# define std386lib "/usr/local/lib/i386/"
+# define std86lib "/usr/local/lib/i86/"
+#endif
+ 0
+};
+PRIVATE int lastlib = NR_STDLIBS;
+
+FORWARD char *buildname P((char *pre, char *mid, char *suf));
+FORWARD char *expandlib P((char *fn));
+
+PRIVATE char *buildname(pre, mid, suf)
+char *pre;
+char *mid;
+char *suf;
+{
+ char *name;
+
+ name = ourmalloc(strlen(pre) + strlen(mid) + strlen(suf) + 1);
+ strcpy(name, pre);
+ strcat(name, mid);
+ strcat(name, suf);
+ return name;
+}
+
+PRIVATE char *expandlib(fn)
+char *fn;
+{
+ char *path;
+ int i;
+
+#ifndef MC6809
+ libs[0] = flag['3'] ? std386lib : std86lib;
+#endif
+
+ for (i = lastlib - 1; i >= 0; --i)
+ {
+ path = ourmalloc(strlen(libs[i]) + strlen(fn) + 1);
+ strcpy(path, libs[i]);
+ strcat(path, fn);
+ if (access(path, R_OK) == 0)
+ return path;
+ ourfree(path);
+ }
+ return NULL;
+}
+
+PUBLIC int main(argc, argv)
+int argc;
+char **argv;
+{
+ register char *arg;
+ int argn;
+ static char crtprefix[] = "crt";
+ static char crtsuffix[] = ".o";
+ char *infilename;
+ static char libprefix[] = "lib";
+ static char libsuffix[] = ".a";
+ char *outfilename;
+ char *tfn;
+
+ ioinit(argv[0]);
+ objinit();
+ syminit();
+ typeconv_init(BIG_ENDIAN, LONG_BIG_ENDIAN);
+#ifndef MC6809
+ flag['z'] = flag['3'] = sizeof(char *) >= 4;
+#endif
+ outfilename = NULL;
+ for (argn = 1; argn < argc; ++argn)
+ {
+ arg = argv[argn];
+ if (*arg != '-')
+ readsyms(arg, flag['t']);
+ else
+ switch (arg[1])
+ {
+ case '0': /* use 16-bit libraries */
+ case '3': /* use 32-bit libraries */
+ case 'M': /* print symbols linked */
+ case 'i': /* separate I & D output */
+ case 'm': /* print modules linked */
+#ifdef BSD_A_OUT
+ case 'r': /* relocatable output */
+#endif
+ case 's': /* strip symbols */
+ case 't': /* trace modules linked */
+ case 'z': /* unmapped zero page */
+ if (arg[2] == 0)
+ flag[(int) arg[1]] = TRUE;
+ else if (arg[2] == '-' && arg[3] == 0)
+ flag[(int) arg[1]] = FALSE;
+ else
+ usage();
+ if (arg[1] == '0') /* flag 0 is negative logic flag 3 */
+ flag['3'] = !flag['0'];
+ break;
+ case 'C': /* startfile name */
+ tfn = buildname(crtprefix, arg + 2, crtsuffix);
+ if ((infilename = expandlib(tfn)) == NULL)
+ fatalerror(tfn); /* XXX - need to describe failure */
+ readsyms(infilename, flag['t']);
+ break;
+ case 'L': /* library path */
+ if (lastlib < MAX_LIBS)
+ libs[lastlib++] = arg + 2;
+ else
+ fatalerror("too many library paths");
+ break;
+ case 'O': /* library file name */
+ if ((infilename = expandlib(arg + 2)) == NULL)
+ fatalerror(arg); /* XXX */
+ readsyms(infilename, flag['t']);
+ break;
+ case 'T': /* text base address */
+ if (arg[2] != 0 || ++argn >= argc)
+ usage();
+ errno = 0;
+ text_base_address = strtoul(argv[argn], (char **) NULL, 16);
+ if (errno != 0)
+ use_error("invalid text address");
+ break;
+ case 'l': /* library name */
+ tfn = buildname(libprefix, arg + 2, libsuffix);
+ if ((infilename = expandlib(tfn)) == NULL)
+ fatalerror(tfn); /* XXX */
+ readsyms(infilename, flag['t']);
+ break;
+ case 'o': /* output file name */
+ if (arg[2] != 0 || ++argn >= argc || outfilename != NULL)
+ usage();
+ outfilename = argv[argn];
+ break;
+ default:
+ usage();
+ }
+ }
+ linksyms(flag['r']);
+ if (outfilename == NULL)
+ outfilename = "a.out";
+ writebin(outfilename, flag['i'], flag['3'], flag['s'],
+ flag['z'] & flag['3']);
+ if (flag['m'])
+ dumpmods();
+ if (flag['M'])
+ dumpsyms();
+ flusherr();
+ return errcount ? 1 : 0;
+}