summaryrefslogtreecommitdiff
path: root/ld/linksyms.c
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>1996-11-03 22:33:35 +0100
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:33:35 +0200
commitc218c617b5be443b7968308506969ad2b726d73c (patch)
tree0051f396af56133d24fcf2ab757fabc78c1a09bf /ld/linksyms.c
parent0936b9aeab611665645a4e6bafaded7ca76dd189 (diff)
parent0d2fbe9b1bd284ce2cad55be17e8f2c896031a25 (diff)
downloaddev86-c218c617b5be443b7968308506969ad2b726d73c.tar.gz
Import Dev86src-0.0.8.tar.gzv0.0.8
Diffstat (limited to 'ld/linksyms.c')
-rw-r--r--ld/linksyms.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/ld/linksyms.c b/ld/linksyms.c
new file mode 100644
index 0000000..b5304a3
--- /dev/null
+++ b/ld/linksyms.c
@@ -0,0 +1,84 @@
+
+/* linksyms.c - write binary file for linker */
+
+/* Copyright (C) 1994 Bruce Evans */
+
+#include "syshead.h"
+#include "const.h"
+#include "obj.h"
+#include "type.h"
+#undef EXTERN
+#include "globvar.h"
+
+FORWARD void linkrefs P((struct modstruct *modptr));
+PUBLIC bool_t reloc_output = 0;
+
+/* link all symbols connected to entry symbols */
+
+PUBLIC void linksyms(argreloc_output)
+bool_pt argreloc_output;
+{
+ char needlink;
+ struct entrylist *elptr;
+ struct modstruct *modptr;
+ struct symstruct *symptr;
+
+#ifdef REL_OUTPUT
+ reloc_output = argreloc_output;
+ if (argreloc_output)
+ {
+ if (modfirst->modnext != NUL_PTR)
+ fatalerror("relocatable output only works for one input file");
+ for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext)
+ modptr->loadflag = TRUE;
+ return;
+ }
+#endif
+ if ((symptr = findsym("_main")) != NUL_PTR)
+ entrysym(symptr);
+ do
+ {
+ if ((elptr = entryfirst) == NUL_PTR)
+ fatalerror("no start symbol");
+ for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext)
+ modptr->loadflag = FALSE;
+ for (; elptr != NUL_PTR; elptr = elptr->elnext)
+ linkrefs(elptr->elsymptr->modptr);
+ if ((symptr = findsym("start")) != NUL_PTR)
+ linkrefs(symptr->modptr);
+ needlink = FALSE;
+ {
+ struct redlist *prlptr = 0;
+ struct redlist *rlptr;
+
+ for (rlptr = redfirst; rlptr != NUL_PTR;
+ rlptr = (prlptr = rlptr)->rlnext)
+ if (rlptr->rlmodptr->loadflag &&
+ rlptr->rlmodptr->class > rlptr->rlsymptr->modptr->class)
+ {
+ rlptr->rlsymptr->modptr = rlptr->rlmodptr;
+ rlptr->rlsymptr->value = rlptr->rlvalue;
+ if (rlptr == redfirst)
+ redfirst = rlptr->rlnext;
+ else
+ prlptr->rlnext = rlptr->rlnext;
+ needlink = TRUE;
+ }
+ }
+ }
+ while (needlink);
+}
+
+PRIVATE void linkrefs(modptr)
+struct modstruct *modptr;
+{
+ register struct symstruct **symparray;
+ register struct symstruct *symptr;
+
+ modptr->loadflag = TRUE;
+ for (symparray = modptr->symparray;
+ (symptr = *symparray) != NUL_PTR; ++symparray)
+ if (symptr->modptr->loadflag == FALSE)
+ linkrefs(symptr->modptr);
+}
+