1 
2 /* linksyms.c - write binary file for linker */
3 
4 /* Copyright (C) 1994 Bruce Evans */
5 
6 #include "syshead.h"
7 #include "const.h"
8 #include "obj.h"
9 #include "type.h"
10 #undef EXTERN
11 #include "globvar.h"
12 
13 FORWARD void linkrefs P((struct modstruct *modptr));
14 PUBLIC bool_t reloc_output = 0;
15 
16 /* link all symbols connected to entry symbols */
17 
linksyms(argreloc_output)18 PUBLIC void linksyms(argreloc_output)
19 bool_pt argreloc_output;
20 {
21     char needlink;
22     struct entrylist *elptr;
23     struct modstruct *modptr;
24     struct symstruct *symptr;
25 
26 #ifdef REL_OUTPUT
27     reloc_output = argreloc_output;
28     if (argreloc_output)
29     {
30 	if (modfirst->modnext != NUL_PTR)
31 	    fatalerror("relocatable output only works for one input file");
32 	for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext)
33 	    modptr->loadflag = TRUE;
34 	return;
35     }
36 #endif
37     if ((symptr = findsym("_start")) != NUL_PTR ||
38         (symptr = findsym("_main")) != NUL_PTR)
39 	entrysym(symptr);
40     do
41     {
42 	if ((elptr = entryfirst) == NUL_PTR)
43 	    fatalerror("no start symbol");
44 	for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext)
45 	    modptr->loadflag = FALSE;
46 	for (; elptr != NUL_PTR; elptr = elptr->elnext)
47 	    linkrefs(elptr->elsymptr->modptr);
48 	if ((symptr = findsym("start")) != NUL_PTR)
49 	    linkrefs(symptr->modptr);
50 	needlink = FALSE;
51 	{
52 	    struct redlist *prlptr = 0;
53 	    struct redlist *rlptr;
54 
55 	    for (rlptr = redfirst; rlptr != NUL_PTR;
56 		 rlptr = (prlptr = rlptr)->rlnext)
57 		if (rlptr->rlmodptr->loadflag &&
58 		    rlptr->rlmodptr->class > rlptr->rlsymptr->modptr->class)
59 		{
60 		    rlptr->rlsymptr->modptr = rlptr->rlmodptr;
61 		    rlptr->rlsymptr->value = rlptr->rlvalue;
62 		    if (rlptr == redfirst)
63 			redfirst = rlptr->rlnext;
64 		    else
65 			prlptr->rlnext = rlptr->rlnext;
66 		    needlink = TRUE;
67 		}
68 	}
69     }
70     while (needlink);
71 }
72 
linkrefs(modptr)73 PRIVATE void linkrefs(modptr)
74 struct modstruct *modptr;
75 {
76     register struct symstruct **symparray;
77     register struct symstruct *symptr;
78 
79     modptr->loadflag = TRUE;
80     for (symparray = modptr->symparray;
81 	 (symptr = *symparray) != NUL_PTR; ++symparray)
82 	if (symptr->modptr->loadflag == FALSE)
83 	    linkrefs(symptr->modptr);
84 }
85 
86