1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- /* 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("_start")) != NUL_PTR ||
- (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);
- }
|