diff options
author | Robert de Bath <rdebath@poboxes.com> | 1996-11-03 22:33:35 +0100 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2013-10-23 23:33:35 +0200 |
commit | c218c617b5be443b7968308506969ad2b726d73c (patch) | |
tree | 0051f396af56133d24fcf2ab757fabc78c1a09bf /ld/linksyms.c | |
parent | 0936b9aeab611665645a4e6bafaded7ca76dd189 (diff) | |
parent | 0d2fbe9b1bd284ce2cad55be17e8f2c896031a25 (diff) | |
download | dev86-c218c617b5be443b7968308506969ad2b726d73c.tar.gz |
Import Dev86src-0.0.8.tar.gzv0.0.8
Diffstat (limited to 'ld/linksyms.c')
-rw-r--r-- | ld/linksyms.c | 84 |
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); +} + |