|
|
1.1 root 1: static char ID[] = "@(#) slotvec.c: 1.5 9/20/83";
2: #include "system.h"
3:
4: #include <stdio.h>
5: #if !NOSDP
6: #include "sdp1.h"
7: #include "sdpsrc/hd/define4.h"
8: #endif
9: #include "sdpsrc/hd/define2.h"
10: #include "structs.h"
11: #include "paths.h"
12: #include "slotvec.h"
13: #include "extrns.h"
14:
15:
16: /********************************************************************
17: *
18: * This module administers the slot vector used during output of the
19: * object file. A slot is used to store the information needed to permit
20: * the relocation of all references to a single symbol.
21: *
22: * Using a slot vector prevents the link editor from having to look
23: * up each symbol in the global symbol table in order to relocate it.
24: *
25: * The size of the slot vector is dependant on the size of the largest
26: * input symbol table, since it is rebuilt for every input object file.
27: * When the number of slots needed is too large and calloc() fails,
28: * the Software Demand Paging system is used to manipulate the slots.
29: *
30: ********************************************************************/
31:
32: SLOTVEC *svpageptr = NULL; /* pointer to "page-in-core"; array of slots
33: if( sdp_called == 0 ), pageptr points to entire
34: slot vector */
35:
36: #if !NOSDP
37: #if AR16WR
38: #define MYSLTBSZ 1
39: #else
40: #define MYSLTBSZ 2000
41: #endif
42: #define SLTPERPAGE (PAGESIZE/SLOTSIZ)
43:
44: static int sdp_called = 0; /* set to >0 if SDP is used */
45: static long *svpagtable = NULL; /* contains ITEMIDs of the SDP pages */
46: static int pageincore; /* page number currently "locked" in core */
47:
48: static char svname[sizeof(TMPDIR)+20] = ""; /* holds name of directory used by SDP */
49: #endif
50:
51: unsigned svhighslt = 0; /* index of next available slot */
52: static long svhighndx = 0L; /* sym. tbl index of symbol assigned to last assigned slot */
53: /*eject*/
54: svinit(numslots)
55: long numslots; /* number of slots that are needed */
56: {
57: char * calloc();
58:
59: /*
60: * Allocate a slot vector. This vector can be either completely
61: * memory-resident or make use of SDP
62: */
63:
64: register int numpages;
65:
66: #if DEBUG
67: if( dflag )
68: fprintf( stderr, "svinit requested to set up %ld slots\n",
69: numslots);
70: #endif
71:
72: #if NOSDP
73: if( (svpageptr = (SLOTVEC *) calloc((unsigned)numslots, (unsigned)SLOTSIZ)) == NULL ) {
74: lderror(2,0,NULL,"fail to allocate %ld bytes for slotvec table",
75: (long) numslots * (long) SLOTSIZ);
76: }
77:
78: /*
79: * Case 1:
80: * If the number of slots needed is less then 3,000 then try to
81: * make the entire slot vector memory-resident
82: */
83:
84: #else
85: if( numslots < MYSLTBSZ )
86: if( (svpageptr = (SLOTVEC *) calloc((unsigned)numslots, (unsigned)SLOTSIZ)) != NULL ) {
87: allocspc += numslots*SLOTSIZ;
88: pageincore = -1;
89: return;
90: }
91:
92: /*
93: * Case 2:
94: * Use SDP to create the slot vector
95: *
96: * 1. Create the svpagetable, to hold SDP ITEMIDs
97: * 2. Create the SDP Address Space
98: * 3. Define the first page of the vector
99: */
100:
101: if( sdp_called )
102: lderror(2,0,NULL,"attempt to re-initialize the SDP slot space");
103:
104: numpages = (numslots + SLTPERPAGE) / SLTPERPAGE;
105: svpagtable = (long *) myalloc(numpages * sizeof(long));
106:
107: sprintf(svname, "%s/%s", TMPDIR, "ldXXXXX");
108: mktemp(svname);
109:
110: sdp_called++;
111:
112: if( sdpinit(svname, CREATE, SVSPACE) != SVSPACE )
113: lderror(2,0,NULL,"failure to initialize the SDP slot space");
114: else
115: sdp_called++;
116:
117: #if DEBUG
118: if( dflag )
119: fprintf( stderr, "svinit setting up SDP: %d pages on file %s\n",
120: numpages, svname);
121: #endif
122:
123: pageincore = 0;
124: svpagtable[0] = allocate(PAGESIZE, SVSPACE, SVPARTITION);
125: svpageptr = (SLOTVEC *) lock(svpagtable[0],SVPARTITION,WRTN);
126: #endif
127: }
128:
129:
130: #if SDP
131: SLOTVEC *
132: getslot(sltindex, action)
133: unsigned sltindex;
134: int action;
135: {
136:
137: /*
138: * Return the address of the slot whose index is given by "sltindex"
139: */
140:
141: register SLOTVEC *p;
142: register int pagenum;
143: static int unlockact;
144:
145: if( sdp_called == 0 )
146: p = &svpageptr[sltindex];
147: else {
148: pagenum = sltindex / SLTPERPAGE;
149: if( pagenum != pageincore ) {
150: unlock(svpagtable[pageincore], unlockact);
151: if( svpagtable[pagenum] == 0L )
152: svpagtable[pagenum] = allocate(PAGESIZE, SVSPACE, SVPARTITION);
153: svpageptr = (SLOTVEC *) lock(svpagtable[pagenum], SVPARTITION, action);
154: pageincore = pagenum;
155: unlockact = action;
156: }
157: else
158: unlockact = (action==WRTN) ? WRTN : unlockact;
159: p = svpageptr + sltindex - pagenum*SLTPERPAGE;
160: }
161:
162: return(p);
163: }
164: #endif
165: /*eject*/
166: svcreate(symindex, ovaddr, nvaddr, newindex, secnum, flags)
167: long symindex, ovaddr, nvaddr, newindex;
168: int secnum, flags;
169: {
170:
171: /*
172: * Get and initialize the next available slot in the slot vector
173: */
174:
175: register SLOTVEC *p;
176:
177: p = GETSLOT(svhighslt++, WRTN);
178:
179: svhighndx = symindex;
180:
181: p->svsymndx = symindex;
182: p->svovaddr = ovaddr;
183: p->svnvaddr = nvaddr;
184: p->svnewndx = newindex;
185: p->svsecnum = secnum;
186: p->svflags = flags;
187:
188: }
189: /*eject*/
190: SLOTVEC *
191: svread(symndx)
192: long symndx;
193: {
194:
195: /*
196: * Return the pointer to the slot belonging to the symbol whose
197: * old (e.g., input) symbol table index is given by "symndx"
198: *
199: * Return NULL upon a failure to find a slot
200: */
201:
202: register SLOTVEC *p;
203: register unsigned high, low, diff, guess;
204:
205: /*
206: * Optimize: see if asking for the slot of the last symbol given a slot
207: */
208:
209: if( symndx == svhighndx )
210: return(GETSLOT(svhighslt-1, RNLY));
211:
212: /*
213: * Perform a binary search on the slot vector, looking for the
214: * requested slot
215: */
216:
217: high = svhighslt - 1;
218: low = 0;
219:
220: while( (diff = high - low) != 0 ) {
221: guess = low + (diff / 2);
222: p = GETSLOT(guess, RNLY);
223: if( p->svsymndx == symndx )
224: return(p);
225: if( p->svsymndx > symndx ) {
226: if( high == guess )
227: break; /* not found */
228: high = guess;
229: }
230: else {
231: if( low == guess )
232: break; /* not found */
233: low = guess;
234: }
235: }
236:
237: /*
238: * ERROR: the specified symbol was never assigned a slot
239: */
240:
241: return( NULL );
242:
243: }
244: /*eject*/
245: #if !NOSDP
246: svfini()
247: {
248:
249: /*
250: * Do any necessary clean-up with regard to the slot vector
251: */
252:
253: char buf[sizeof(svname)*2 + 20];
254:
255: #if DEBUG
256: if( dflag )
257: fprintf( stderr, "svfini: next avail slot: %u last symbol index: %.2lo\n",
258: svhighslt, svhighndx);
259: #endif
260:
261: if( sdp_called == 0 ) {
262: sdp_called--;
263: if( svpageptr != NULL )
264: free((char *) svpageptr);
265: return;
266: }
267:
268: if( sdp_called == 2 ) {
269: sdp_called--;
270: unlock(svpagtable[pageincore], RNLY);
271: free((char *) svpagtable);
272: if( sdpterm(SVSPACE) < 0 )
273: lderror(2,0,NULL,"failure to close the SDP slot space");
274: }
275:
276: if( sdp_called != 1 )
277: return;
278: sdp_called--;
279:
280: #if TS || RT
281: sprintf(buf, "rm -r %s", svname);
282: #else
283: sprintf(buf, "rm -r %s; rmdir %s", svname, svname);
284: #endif
285:
286: system(buf);
287: }
288: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.