|
|
1.1 root 1: static char ID[] = "@(#) syms.c: 1.18 10/5/83";
2: #include "system.h"
3: #include <stdio.h>
4: #include <fatal.h>
5: #include <signal.h>
6: #if !NOSDP
7: #include "sdp1.h"
8: #include "sdpsrc/hd/define2.h"
9: #include "sdpsrc/hd/define4.h"
10: #include "sdpsrc/hd/struct.h"
11: #endif
12: #include "structs.h"
13: #include "paths.h"
14: #include "extrns.h"
15: #if TRVEC
16: #include "tv.h"
17: #include "ldtv.h"
18: #endif
19: #include "sgsmacros.h"
20: #include "instr.h"
21: #include "ldmacros.h"
22:
23:
24:
25: /*
26: * ***** NOTICE ***** NOTICE ***** NOTICE *******
27: * *
28: * This version of syms.c is designed to *
29: * permit multiple aux entries per symbol *
30: * *
31: * This version of syms.c uses a one-way *
32: * circular list to link all symbols that *
33: * hash to the same hashtab[] entry *
34: * *
35: * ***** NOTICE ***** NOTICE ***** NOTICE *******
36: */
37:
38: #if NOSDP && !UNIX
39: #define HASHSIZE 1021
40: #else
41: #define HASHSIZE 521
42: #endif
43: /*
44: * VAX cc bug KLUDGE
45: */
46: #define abs(x) (x < 0 ? -x : x)
47:
48: ITEMID hashtab[HASHSIZE];
49:
50: #if NOSDP
51: #if UNIX
52: #define MAXEXTRA 100
53: #define XSMTBSZ 100
54: #define XAXTBSZ 50
55: #define MYSMTBSZ 200
56: #define MYAXTBSZ 100
57: #else
58: #if AR16WR
59: #define MAXEXTRA 20
60: #define XSMTBSZ 80
61: #define XAXTBSZ 40
62: #define MYSMTBSZ 400
63: #define MYAXTBSZ 200
64: #endif
65: #if AR32W
66: #define MAXEXTRA 100
67: #define XSMTBSZ 800
68: #define XAXTBSZ 400
69: #define MYSMTBSZ 4000
70: #define MYAXTBSZ 2000
71: #endif
72: #if AR32WR
73: #define MAXEXTRA 10
74: #define XSMTBSZ 400
75: #define XAXTBSZ 200
76: #define MYSMTBSZ 2000
77: #define MYAXTBSZ 1000
78: #endif
79: #endif
80: int xsymcnt = 0;
81: int xauxcnt = 0;
82: SYMTAB *xsymptr[MAXEXTRA];
83: AUXTAB *xauxptr[MAXEXTRA];
84: SYMTAB mysymtab[MYSMTBSZ+1];
85: AUXTAB myauxtab[MYAXTBSZ+1];
86: #else
87: extern HEADER global_frames[MAXATTACH];
88: static char sdpname[sizeof(TMPDIR)+20] = "";
89: static char auxname[sizeof(TMPDIR)+20] = "";
90:
91: static int sdp_called = 0; /* indicates when syminit() has been called */
92: static int aux_called = 0; /* indicates when auxinit() has been called */
93: /*eject*/
94: syminit()
95: {
96:
97: /*
98: * Initialize the Software Demand Paging System
99: */
100:
101: if( sdp_called )
102: lderror(2,0,NULL,"Attempt to re-initialize SDP symbol space");
103:
104: sprintf( sdpname, "%s/%s", TMPDIR, "ldXXXXXX" );
105: mktemp( sdpname );
106:
107: sdp_called++;
108:
109: if( sdpinit(sdpname, CREATE, SYMSPACE) != SYMSPACE )
110: lderror(2,0,NULL,"Failed to initialize SDP symbol space");
111: else
112: sdp_called++;
113:
114: auxinit(); /* initialize aux entry space */
115: }
116:
117:
118:
119: symfini()
120: {
121: char buf[sizeof(sdpname)*2 + 20];
122:
123: /*
124: * Ignore BREAK, HANGUP, and QUIT signals, to insure that the cleanup
125: * is done
126: */
127:
128: signal(SIGINT, SIG_IGN);
129: signal(SIGQUIT, SIG_IGN);
130:
131: if( sdp_called == 2 ) {
132: sdp_called--;
133: if( sdpterm(SYMSPACE) < 0 )
134: lderror(2,0,NULL,"Failed to close SDP symbol space");
135: }
136:
137: if( sdp_called != 1 )
138: return;
139: sdp_called--;
140:
141: #if TS || RT
142: sprintf(buf, "rm -r %s", sdpname);
143: #else
144: sprintf(buf, "rm -r %s; rmdir %s", sdpname, sdpname);
145: #endif
146:
147: if( fork() == 0 ) {
148: execl("/bin/sh", "sh", "-c", buf, 0);
149: lderror(0,0,NULL, "Execl(%s) failed", buf);
150: _exit(127);
151: }
152:
153: auxfini(); /* close aux entry space */
154: }
155: /*eject*/
156: #endif
157: hash(name)
158: register char *name;
159: {
160:
161: /*
162: * Compute hash value for a symbol name
163: */
164:
165: register unsigned hashval;
166: register int tmp; /* VAX CC BUG KLUDGE */
167:
168: hashval = 0;
169: while (*name)
170: hashval = hashval * 10 + *name++; /*used to be 13*/
171:
172: /*
173: * Because of a bug in the current VAX compiler, the following
174: * line has temporarily been replaced by the KLUDGE following
175: * this comment. The define of abs() is also added above
176: *
177: * return( (int) (hashval % HASHSIZE) );
178: */
179:
180: tmp = (int) hashval;
181: tmp = abs(tmp);
182: return ( tmp % HASHSIZE );
183: }
184: /*eject*/
185: SYMTAB *
186: findsym(name)
187: char *name;
188: {
189:
190: /*
191: * Return a pointer to the ld symbol table entry for a symbol.
192: *
193: * NULL indicates that the symbol does not exist
194: */
195:
196: register SYMTAB *p; /* ld symbol table entry */
197: register int chain; /* size of a collision chain */
198: int hashval; /* hashtab[] index for the sym */
199: register ITEMID acid, /* SDP id for ld symbol entry */
200: base; /* head of collision chain */
201:
202:
203: /*
204: * All symbols that hash to the same value are connected in a one-way,
205: * circular linked list. The most recently referenced symbol on
206: * the chain is considered the head of the chain, and its id is
207: * stored in the hash table
208: *
209: * Get the head of the collision chain, and walk down it looking for
210: * a match
211: */
212:
213: hashval = hash(name);
214: if( (acid = hashtab[hashval]) == 0 )
215: return( NULL );
216: base = acid;
217: chain = 1;
218:
219: do {
220: char sym_space[9];
221: char *sym_name;
222: #if NOSDP
223: p = getsym(acid);
224: #else
225: p = (SYMTAB *) lock(acid, MISPARTITION, RNLY);
226: #endif
227: if (p->smnamelength == 9)
228: {
229: strncpy( sym_space, p->sment.n_name, 8 );
230: sym_space[8] = '\0';
231: sym_name = sym_space;
232: }
233: #if FLEXNAMES
234: else if (p->smnamelength > 9)
235: sym_name = p->sment.n_nptr;
236: #endif
237: else
238: sym_name = p->sment.n_name;
239:
240: if (equal( sym_name, name, p->smnamelength ))
241: {
242: maxchain = max(maxchain,chain);
243: nwalks += (chain - 1);
244: hashtab[hashval] = acid;
245: return( p );
246: }
247: #if !NOSDP
248: unlock(acid, RNLY);
249: #endif
250:
251: acid = p->smchainid;
252: chain++;
253:
254: }
255: while( acid != base );
256:
257: nfwalks += (chain - 1);
258:
259: return( NULL ); /* not found */
260: }
261: /*eject*/
262: AUXTAB *
263: findaux(sym, ndx)
264: SYMTAB *sym;
265: int ndx;
266: {
267:
268: /*
269: * Return a pointer to the ndx'th aux entry for the ld symbol table
270: * entry given by sym
271: *
272: * NULL indicates that no such aux entry exists
273: */
274:
275: register AUXTAB *a; /* pointer to a symbol aux entry*/
276: ITEMID acid; /* SDP id for ld aux entry */
277:
278: #if DEBUG
279: if( dflag > 15 )
280: fprintf( stderr, "\nfindaux %s ", SYMNAME( sym->sment ));
281: #endif
282:
283: /*
284: * All aux entries belonging to a symbol are linked together in a
285: * one-way linked list. The entries are ordered by aux-entry
286: * number: the first aux entry is the head of the list; it is
287: * linked to the 2'nd aux entry, which is linked to the 3'rd, etc
288: *
289: * Get the head of the aux entry list, and walk down it looking for
290: * the specified aux entry
291: */
292:
293: acid = sym->smauxid;
294:
295: while( acid != 0 ) {
296:
297: #if NOSDP
298: a = getaux(acid);
299: #else
300: a = (AUXTAB *) lock(acid, MISPARTITION, RNLY);
301: #endif
302:
303: if( a->axord == ndx )
304: return( a );
305: #if !NOSDP
306: unlock(acid, RNLY);
307: #endif
308:
309: acid = a->axchainid;
310:
311: }
312:
313: return( NULL ); /* not found */
314: }
315: /*eject*/
316: SYMTAB *
317: makesym(sym, filp)
318: register SYMENT *sym;
319: INFILE *filp;
320: {
321:
322: /*
323: * Given a (new) *.o symbol table entry, add it to the ld
324: * symbol table
325: *
326: * A ld symbol table entry is built and initialized. Appropriate
327: * entries are made in the hash table and in the SDP address space
328: *
329: * The address of the ld symbol table entry is returned
330: */
331:
332: register SYMTAB *p; /* pointer to a ld symbol entry */
333: register ITEMID acid; /* SDP id of a ld symbol entry */
334: int hashval; /* index into hash table for sym*/
335: int auxcnt;
336: char *name;
337:
338: name = PTRNAME( sym );
339: if( (p = findsym(name)) == NULL ) {
340: /*
341: * Case 1: The symbol is not in the ld symbol table.
342: * Add a new entry, making it the head of the
343: * collision chain
344: * Update the hash table
345: */
346: #if NOSDP
347: if (numldsyms >= MYSMTBSZ + (xsymcnt * XSMTBSZ)) {
348: if (xsymcnt >= MAXEXTRA)
349: lderror(2,0,"internal error: ","symbol table overflow");
350: xsymptr[xsymcnt++] = (SYMTAB *) myalloc(XSMTBSZ * SYMSIZ);
351: }
352: acid = ++numldsyms;
353: p = getsym(acid);
354: #else
355: numldsyms++;
356: acid = allocate(SYMSIZ, SYMSPACE, MISPARTITION);
357: p = (SYMTAB *) lock(acid, MISPARTITION, WRTN);
358: zero( p, SYMSIZ );
359: #endif
360: p->sment = *sym;
361: p->smnamelength = strlen( name ) + 1;
362: #if FLEXNAMES
363: if ((sym->n_zeroes == 0L) && ((filp == NULL)
364: || (filp && (filp->flstrings == NULL))))
365: p->sment.n_nptr = savefn(sym->n_nptr);
366: #endif
367: p->sment.n_numaux = 0;
368: p->smmyacid = acid;
369:
370: hashval = hash(name);
371: if( hashtab[hashval] > 0 ) {
372: SYMTAB *p2;
373: #if NOSDP
374: p2 = getsym(hashtab[hashval]);
375: #else
376: p2 = (SYMTAB *) lock(hashtab[hashval], HITPARTITION, WRTN);
377: #endif
378: p->smchainid = p2->smchainid;
379: p2->smchainid = acid;
380: #if !NOSDP
381: unlock(hashtab[hashval], WRTN);
382: #endif
383: ncolisns++;
384: }
385: else
386: p->smchainid = acid;
387:
388: hashtab[hashval] = acid;
389: return( p );
390: }
391:
392: /*
393: * Case 2: The symbol is already in the symbol table
394: * Update the existing entry
395: */
396:
397: if( sym->n_scnum != 0 ) {
398: /*
399: * The makesym() argument 'sym' is the defining entry
400: * for the symbol
401: */
402: if( p->sment.n_scnum == 0 ) {
403:
404: /*
405: * The existing ld symbol table entry
406: * was from a reference
407: *
408: * Merge the information from the function
409: * argument and the ld symbol table
410: *
411: * The ld symbol table entry may have a ld-
412: * generated aux entry. If so, carry this
413: * entry over.
414: */
415: #if COMMON
416: if (Mflag && p->sment.n_value > 0)
417: lderror(0,0,NULL, "Symbol %s in %s is multiply defined.",
418: name,curfilnm );
419: #endif
420: p->sment.n_value = sym->n_value;
421: p->sment.n_scnum = sym->n_scnum;
422: p->sment.n_type = sym->n_type;
423: p->sment.n_sclass = sym->n_sclass;
424: }
425: else if( p->sment.n_scnum != -1 )
426: lderror(1,0,NULL, "Symbol %s in %s is multiply defined. First defined in %s",
427: name, curfilnm, p->smscnptr->isfilptr->flname );
428: }
429:
430: #if COMMON
431: else if (sym->n_value > 0) /* & sym->n_scnum == 0 => common sym */
432: {
433: if (Mflag && (p->sment.n_scnum != 0 ||
434: (p->sment.n_scnum == 0 && p->sment.n_value > 0)))
435: lderror(0, 0, NULL, "Symbol %s in %s is multiply defined.",
436: name, curfilnm);
437:
438: /* set value for .common symbol */
439:
440: if ( p->sment.n_scnum == N_UNDEF )
441: {
442: if ( !tflag && ( p->sment.n_value > 0 )
443: && ( p->sment.n_value != sym->n_value ))
444: {
445: lderror(0, 0, NULL,
446: "Multiply defined symbol %s, in %s, has more than one size",
447: PTRNAME(sym), curfilnm);
448: }
449:
450: p->sment.n_value = /* max of old & new val */
451: (p->sment.n_value > sym->n_value) ?
452: p->sment.n_value : sym->n_value;
453:
454: if (sym->n_type != T_NULL && p->sment.n_type == T_NULL)
455: p->sment.n_type = sym->n_type;
456: }
457: }
458: #endif
459: return( p );
460: }
461: /*eject*/
462: AUXTAB *
463: makeaux(sym, aux, ndx)
464: register SYMTAB *sym; /* symbol table entry to which the aux entry belongs */
465: register AUXENT *aux; /* new aux entry */
466: int ndx; /* number of aux entries already added to entry */
467: {
468:
469: /*
470: * Given a (*.o) aux entry, add it to an existing ld symbol
471: * table entry
472: *
473: * The address of the ld aux entry is returned
474: */
475:
476: register AUXTAB *a;
477: register int tvndx;
478: ITEMID acid;
479:
480: #if DEBUG
481: if( dflag > 15 )
482: fprintf( stderr, "\nmakeaux %s ", SYMNAME( sym->sment ) );
483: else if( dflag > 2 )
484: fprintf(stderr, "makeaux: %s (%d) : %08lx %04x %04x %08lx %08lx %04x\n",
485: SYMNAME(sym->sment), ndx,
486: aux->x_sym.x_tagndx, aux->x_sym.x_misc.x_lnsz.x_lnno,
487: aux->x_sym.x_misc.x_lnsz.x_size,
488: aux->x_sym.x_fcnary.x_fcn.x_lnnoptr,
489: aux->x_sym.x_fcnary.x_fcn.x_endndx,
490: aux->x_sym.x_tvndx);
491: #endif
492:
493: /*
494: * Add the new aux entry to the symbol table entry
495: */
496:
497: if( (acid = sym->smauxid) == 0 ) {
498: /*
499: * Add the first aux entry for a symbol
500: */
501: if( ndx != 0 )
502: lderror(1,0,NULL,"Making aux entry %d for symbol %s out of sequence",
503: ndx+1, SYMNAME( sym->sment ));
504: #if NOSDP
505: if (numldaux >= MYAXTBSZ + (xauxcnt * XAXTBSZ)) {
506: if (xauxcnt >= MAXEXTRA)
507: lderror(2,0,"internal error: ","aux table overflow");
508: xauxptr[xauxcnt++] = (AUXTAB *) myalloc(XAXTBSZ * AUXSIZ);
509: }
510: acid = ++numldaux;
511: a = getaux(acid);
512: #else
513: numldaux++;
514: acid = allocate(AUXSIZ, AUXSPACE, MISPARTITION);
515: a = (AUXTAB *) lock(acid, MISPARTITION, WRTN);
516:
517: zero( a, AUXSIZ );
518: #endif
519: a->axent = *aux;
520: a->axord = 1;
521: a->axmyacid = acid;
522: a->axchainid = 0;
523:
524: sym->sment.n_numaux++;
525: sym->smauxid = acid;
526:
527: return( a );
528: }
529:
530: #if NOSDP
531: a = getaux(acid);
532: #else
533: a = (AUXTAB *) lock(acid, MISPARTITION, WRTN);
534: #endif
535:
536:
537: if( ndx == 0 ) {
538: /*
539: * The symbol table entry already has a aux entry.
540: *
541: * This occurs when ld generates an aux entry for
542: * the symbol, to contain a tv slot index.
543: *
544: * Merge this ld-entry with the entry obtained from
545: * the input file
546: *
547: * Two cases: due to a tv ref in an earlier
548: * input file, the aux entry in the symbol
549: * table is a dummy one and should be
550: * overwritten except for the tvndx.
551: *
552: * (2) we are doing subsystem linking and
553: * we are getting dummy and real auxents
554: * in an unknown order. in this case
555: * we have to test to see which one is
556: * the dummy and either overwrite it
557: * or throw it away. We have this info
558: * in psymtab() and should be an arg
559: * to makeaux(). However a KLUDGE is
560: * to see which one is all 0's except
561: * for the tvndx and call that one the
562: * dummy. This should be cleaned up
563: * and made reasonable later.
564: */
565:
566: /* if incoming is not dummy */
567: if ( ! ( (aux->x_sym.x_tagndx == 0L) &&
568: (aux->x_sym.x_misc.x_fsize == 0L) &&
569: (aux->x_sym.x_fcnary.x_fcn.x_lnnoptr == 0L) &&
570: (aux->x_sym.x_fcnary.x_fcn.x_endndx == 0L) ) ) {
571: tvndx = a->axent.x_sym.x_tvndx;
572: a->axent = *aux;
573: if (tvndx != N_TV)
574: a->axent.x_sym.x_tvndx = tvndx;
575: }
576:
577: return( a );
578: }
579:
580: /*
581: * Step down the chain of aux entries, to the correct position for the
582: * new entry
583: */
584:
585: while( a->axord != ndx ) {
586: #if NOSDP
587: acid = a->axchainid;
588: a = getaux(acid);
589: #else
590: unlock(acid, RNLY);
591: acid = a->axchainid;
592: a = (AUXTAB *) lock(acid, MISPARTITION, RNLY);
593: #endif
594: }
595:
596: if( a->axchainid != 0 ) {
597: /*
598: * Overwriting an existing aux entry (but not the first aux
599: * entry). Warn the user
600: */
601: lderror(0,0,NULL,"Overwriting aux entry %d of symbol %s",
602: ndx+1, SYMNAME( sym->sment ));
603:
604: #if NOSDP
605: acid = a->axchainid;
606: a = getaux(acid);
607: #else
608: unlock(acid, RNLY);
609: acid = a->axchainid;
610: a = (AUXTAB *) lock(acid, MISPARTITION, WRTN);
611: #endif
612:
613: a->axent = *aux;
614:
615: return( a );
616: }
617: else {
618: /*
619: * Add the new aux entry at the end of the list
620: */
621: #if NOSDP
622: if (numldaux >= MYAXTBSZ + (xauxcnt * XAXTBSZ)) {
623: if (xauxcnt >= MAXEXTRA)
624: lderror(2,0,"internal error: ","aux table overflow");
625: xauxptr[xauxcnt++] = (AUXTAB *) myalloc(XAXTBSZ * AUXSIZ);
626: }
627: acid = a->axchainid = ++numldsyms;
628: a = getaux(acid);
629: #else
630: numldaux++;
631: a->axchainid = allocate(AUXSIZ, AUXSPACE, MISPARTITION);
632: unlock(acid, WRTN);
633: acid = a->axchainid;
634: a = (AUXTAB *) lock(acid, MISPARTITION, WRTN);
635:
636: zero( a, AUXSIZ );
637: #endif
638: a->axent = *aux;
639: a->axord = ndx + 1;
640: a->axmyacid = acid;
641: a->axchainid = 0;
642:
643: sym->sment.n_numaux++;
644:
645: return( a );
646: }
647: }
648:
649: ITEMID
650: putsym(sym, changed)
651: SYMTAB *sym;
652: int changed;
653: {
654:
655: /*
656: * Return a ld symbol table entry to the SDP empire ("unlock")
657: * Return the SDP access ID
658: */
659:
660: #if DEBUG
661: if( dflag > 15 )
662: fprintf( stderr, "\n putsym %s ", SYMNAME( sym->sment ));
663: #endif
664:
665: #if !NOSDP
666: unlock(sym->smmyacid, (changed ? WRTN : RNLY));
667: #endif
668: return( sym->smmyacid );
669: }
670:
671:
672: ITEMID
673: putaux(aux, changed)
674: AUXTAB *aux;
675: int changed;
676: {
677:
678: /*
679: * Return an auxiliary entry to the SDP empire ("unlock")
680: *
681: * Return the SDP access ID
682: */
683:
684: #if DEBUG
685: if( dflag > 15 )
686: fprintf( stderr, "\n putaux %8lx ", aux->axmyacid );
687: #endif
688:
689: #if !NOSDP
690: unlock(aux->axmyacid, (changed ? WRTN : RNLY));
691: #endif
692: return( aux->axmyacid );
693: }
694:
695:
696:
697: SYMTAB *
698: getsym(acid)
699: register ITEMID acid;
700: {
701:
702: /*
703: * Return a pointer to an ld symbol table entry, given the
704: * SDP access ID
705: */
706:
707: #if DEBUG
708: if( dflag > 15 )
709: fprintf( stderr, "\n getsym %8lx ", acid );
710: #endif
711:
712: #if NOSDP
713: if (acid <= 0)
714: lderror(2,0,"internal error: ","negative symbol table id");
715: if (acid <= MYSMTBSZ)
716: return(&mysymtab[acid]);
717: acid -= (MYSMTBSZ + 1);
718: if (acid < xsymcnt * XSMTBSZ)
719: return( (SYMTAB *) ( (long) xsymptr[acid/XSMTBSZ] + ((acid % XSMTBSZ) * SYMSIZ)) );
720: lderror(2,0,"internal error: ","invalid symbol table id");
721: #else
722: return( (SYMTAB *) lock(acid, MISPARTITION, RNLY) );
723: #endif
724: }
725:
726: AUXTAB *
727: getaux(acid)
728: ITEMID acid;
729: {
730:
731: /*
732: * Return a pointer to a ld aux entry, given the
733: * SDP access ID
734: */
735:
736: #if DEBUG
737: if( dflag > 15 )
738: fprintf( stderr, "\n getaux %8lx ", acid );
739: #endif
740:
741: #if NOSDP
742: if (acid <= 0)
743: lderror(2,0,"internal error: ","negative aux table id");
744: if (acid <= MYAXTBSZ)
745: return(&myauxtab[acid]);
746: acid -= (MYAXTBSZ + 1);
747: if (acid < xauxcnt * XAXTBSZ)
748: return( (AUXTAB *) ( (long) xauxptr[acid/XAXTBSZ] + ((acid % XAXTBSZ) * AUXSIZ)) );
749: lderror(2,0,"internal error: ","invalid aux table id");
750: #else
751: return( (AUXTAB *) lock(acid, MISPARTITION, RNLY) );
752: #endif
753: }
754: /*eject*/
755: long
756: #if FLEXNAMES
757: psymtab(fdes, numsyms, filp, symbuf,strtabptr)
758: char *strtabptr; /* pointer to string table with long symbol names, if
759: one exists */
760: #else
761: psymtab(fdes, numsyms, filp, symbuf, strtabptr)
762: #endif
763: FILE *fdes; /* pointer to the file, positioned to the symbol table */
764: long numsyms; /* total number of symbol table entries for the file */
765: INFILE *filp; /* pointer to the infilist entry for the file */
766: register SYMENT *symbuf;
767: {
768:
769: /*
770: * This routine is called during the scanning of the LDFILE list.
771: *
772: * Every *.o and archive library member which is to be link edited
773: * is processed exactly once by this function:
774: *
775: * 1. Add all ld symbols from the file to ld's cumulative
776: * ld symbol table
777: * ********** for FLEXNAMES ***********
778: * 1a. When there is a long symbol name, change the
779: * offset of the name in the symbol table to a pointer
780: * to the name
781: * ************************************
782: * 2. Compute and return the number of local symbol table
783: * entries (locals, statics, functions, etc.) for this
784: * file
785: */
786:
787:
788: register SYMENT *sym; /* input file symbol table entry */
789: register AUXENT *aux; /* symbol aux entry */
790: register SYMTAB *symp; /* ld symbol table entry pointer */
791: register long n;
792: long locsyms, /* nbr local symbols from input file */
793: relsyms, /* nbr relocatable symbols */
794: l;
795: int i; /* for-loop index */
796: char tmp_numaux,
797: tmp_sclass;
798: SYMENT lsymbuf;
799: AUXENT lauxbuf;
800:
801: sym = &lsymbuf;
802: aux = &lauxbuf;
803:
804: locsyms = 0L;
805: relsyms = 0L;
806:
807: for( n = 0L; n < numsyms; n++ ) {
808:
809: #if !PORTAR && !PORT5AR
810: if (symbuf != NULL)
811: sym = symbuf++;
812: else
813: #endif
814: if (fread(sym,SYMESZ,1,fdes) != 1)
815: lderror(2,0,NULL,"fail to read symbol table of file %s",
816: filp->flname);
817:
818: #if FLEXNAMES
819: /* this symbol has a long name - change offset to ptr */
820: if (sym->n_zeroes == 0L)
821: {
822: if (strtabptr == NULL)
823: lderror( 2, 90, NULL, "no string table in file %s", filp->flname );
824: sym->n_nptr = strtabptr + sym->n_offset;
825: }
826: #endif
827:
828: switch( sym->n_sclass ) {
829:
830: /*
831: * Symbols of type C_EXT are global, and must be added
832: * to ld's cumulative symbol table
833: */
834: case C_EXT:
835: relsyms++;
836: symp = makesym(sym, filp);
837:
838: if( sym->n_scnum > 0 )
839: symp->smscnptr = sectnum(sym->n_scnum,filp);
840:
841:
842: /*
843: * Functions, although added to ld's symbol
844: * table, must be put in the "local symbol"
845: * section of the final output file
846: */
847: if( ISFCN(sym->n_type) ) {
848: symp->smoutndx = locsyms;
849: locsyms += (long) (sym->n_numaux + 1);
850: symp->smlocflg = 1;
851: }
852:
853: n += (long) sym->n_numaux;
854: tmp_numaux = sym->n_numaux;
855: for( i = 0; i < tmp_numaux; i++ ) {
856: #if !PORTAR && !PORT5AR
857: if (symbuf != NULL)
858: aux = (AUXENT *) symbuf++;
859: else
860: #endif
861: if (fread(aux,AUXESZ,1,fdes) != 1)
862: lderror(2,0,NULL,"fail to read aux entries of file %s",
863: filp->flname);
864:
865: #if TRVEC
866: if ( i == 0 && (ISFCN( sym->n_type ) || (sym->n_type == 0)))
867: if (aux->x_sym.x_tvndx == N_TV) {
868: aux->x_sym.x_tvndx = P_TV;
869: tvspec.tvosptr->oshdr.s_size += TVENTSZ;
870: }
871: #endif
872: putaux( makeaux(symp, aux, i), 1 );
873: }
874:
875: PUTSYM(symp, 1);
876: break;
877:
878: case C_FILE:
879: #if DMERT || XL
880: if (!dmertplib)
881: #endif
882: locsyms += 1 + (long) sym->n_numaux;
883: if (sym->n_numaux) {
884: n += sym->n_numaux;
885: #if !PORTAR && !PORT5AR
886: if (symbuf != NULL)
887: symbuf++;
888: else
889: #endif
890: if (fseek( fdes, (long) (AUXESZ) * sym->n_numaux, 1 ) != 0)
891: lderror( 2, 0, NULL, "fail to skip aux entry of %s", filp->flname);
892: }
893: break;
894:
895: case C_STAT:
896: #if UNIX
897: relsyms++;
898: locsyms += 1 + sym->n_numaux;
899: if (sym->n_numaux == 1) {
900: n++;
901: #if !PORTAR && !PORT5AR
902: if (symbuf != NULL)
903: symbuf++;
904: else
905: #endif
906: if (fseek( fdes, (long) AUXESZ, 1 ) != 0)
907: lderror( 2, 0, NULL, "fail to skip the aux entry of %s", filp->flname);
908: };
909: continue;
910: #endif
911:
912: case C_HIDDEN:
913: relsyms++;
914:
915: default:
916: #if DMERT || XL
917: if (!dmertplib)
918: #endif
919: #if UNIX || XL
920: if (!xflag)
921: #endif
922: locsyms++;
923:
924: if( sym->n_numaux > 0 ) {
925:
926: #if DMERT || XL
927: if (!dmertplib)
928: #endif
929: #if UNIX || XL
930: if (!xflag)
931: #endif
932: locsyms += (long) sym->n_numaux;
933: n += (long) sym->n_numaux;
934: tmp_sclass = sym->n_sclass;
935: tmp_numaux = sym->n_numaux;
936: #if !PORTAR && !PORT5AR
937: if (symbuf != NULL)
938: aux = (AUXENT *) symbuf++;
939: else
940: #endif
941: if (fread(aux,AUXESZ,1,fdes) != 1)
942: lderror(2,0,NULL,"fail to read aux entries of %s",
943: filp->flname);
944:
945: /*
946: * Skip all aux entries after the first
947: */
948: if( tmp_numaux > 1 )
949: #if !PORTAR && !PORT5AR
950: if (symbuf != NULL)
951: symbuf++;
952: else
953: #endif
954: if (fseek(fdes, (long) (AUXESZ * (tmp_numaux-1)), 1) != 0)
955: lderror(2,0,NULL,"fail to skip the aux entry of %s",
956: filp->flname);
957:
958: /*
959: * Skip all members of structures and
960: * unions
961: */
962: if( ISTAG(tmp_sclass) ) {
963: l = aux->x_sym.x_fcnary.x_fcn.x_endndx - n - 1;
964: #if DMERT || XL
965: if (!dmertplib)
966: #endif
967: #if UNIX || XL
968: if (!xflag)
969: #endif
970: locsyms += l;
971: n = aux->x_sym.x_fcnary.x_fcn.x_endndx - 1;
972: #if !PORTAR && !PORT5AR
973: if (symbuf != NULL)
974: symbuf += l;
975: else
976: #endif
977: if (fseek(fdes, l * SYMESZ, 1) != 0)
978: lderror(2,0,NULL,"fail to skip the mem of struct of %s",
979: filp->flname);
980: }
981: #if TRVEC
982:
983: /*
984: * Increment size of .tv if this
985: * symbol needs a slot in the tv.
986: */
987: if( aflag && tvflag && (tmp_sclass == C_STAT) && (aux->x_sym.x_tvndx == N_TV) )
988: tvspec.tvosptr->oshdr.s_size += TVENTSZ;
989: #endif
990: }
991: }
992: }
993:
994: if( relsyms > maxrelocsms )
995: maxrelocsms = relsyms;
996:
997: return( locsyms );
998: }
999: /*eject*/
1000: SYMTAB *
1001: loopsym(sym, changed)
1002: SYMTAB *sym;
1003: int changed;
1004: {
1005:
1006: /*
1007: * Loop through all symbol table entries
1008: */
1009:
1010: #if NOSDP
1011: static long ndx;
1012: if (sym == NULL) ndx = 0;
1013: if (ndx < numldsyms)
1014: return(getsym(++ndx));
1015: else
1016: return(NULL);
1017: #else
1018: static long offset, /* offset of next symbol in page */
1019: page; /* SDP page number */
1020: register ITEMID acid;
1021: /*
1022: * WARNING: this implementation of loopsym() is extremely dependent
1023: * upon knowing exactly how SDP does things. In particular, it
1024: * is dependent upon symbol table entries being in one SDP space,
1025: * separate from aux entries. Anyone touching SDP
1026: * defines or code should check this function for accuracy.
1027: */
1028:
1029: #if DEBUG
1030: if( dflag > 15 )
1031: fprintf( stderr, "\nloopsym %8s ", sym->sment.n_name );
1032: #endif
1033:
1034: /*
1035: * This routine is used as follows:
1036: *
1037: * For the first call to this routine, sym is set to NULL.
1038: * For all subsequent calls, sym equals the value returned by
1039: * the previous call.
1040: * When sym again equals NULL, the entire table has been searched.
1041: */
1042:
1043: if( sym == NULL ) {
1044: /*
1045: * Build the itemid for first entry in symbol table
1046: */
1047: page = 1L;
1048: offset = 0L;
1049: acid = BUILDPN(page, SYMSPACE) + offset;
1050: if ( global_frames[SYMSPACE].maxpage == 0L )
1051: return( NULL ); /* no symbols */
1052: return( (SYMTAB *) lock(acid, MISPARTITION, RNLY) );
1053: }
1054:
1055: /*
1056: * Find the next symbol table entry:
1057: *
1058: */
1059:
1060: unlock(sym->smmyacid, (changed ? WRTN : RNLY));
1061:
1062: offset += (long) SYMSIZ;
1063: if ( (offset + (long) SYMSIZ) > (long) PAGESIZE ) {
1064: offset = 0L;
1065: if ( ++page > global_frames[SYMSPACE].maxpage )
1066: return(NULL);
1067: } else {
1068: /*
1069: * are we past the last entry on the last page?
1070: */
1071: if ( (page == global_frames[SYMSPACE].curpage) &&
1072: (offset == global_frames[SYMSPACE].curoffset) )
1073: return(NULL);
1074: }
1075: acid = BUILDPN(page, SYMSPACE) + offset;
1076: return( (SYMTAB *) lock(acid, MISPARTITION, RNLY) );
1077: #endif
1078: }
1079: /*eject*/
1080: AUXTAB *
1081: loopaux(sym, aux, changed)
1082: SYMTAB *sym;
1083: AUXTAB *aux;
1084: int changed;
1085: {
1086:
1087: /*
1088: * Loop through all the aux entries for a given ld symbol table entry
1089: *
1090: *
1091: * This routine is used as follows:
1092: *
1093: * For the first call to this routine, aux is set to NULL.
1094: * For all subsequent calls, aux equals the value returned by
1095: * the previous call.
1096: * When aux again equals NULL, all aux entries have been returned
1097: */
1098:
1099: #if DEBUG
1100: if( dflag > 15 )
1101: fprintf( stderr, "\nloopaux %s ", SYMNAME( sym->sment ) );
1102: #endif
1103:
1104: if( aux == NULL ) {
1105: /*
1106: * Get the first aux entry, pointed to by the ld symbol
1107: * table entry
1108: */
1109: if( sym->smauxid != 0 )
1110: #if NOSDP
1111: return(getaux(sym->smauxid));
1112: #else
1113: return( (AUXTAB *) lock(sym->smauxid, MISPARTITION, WRTN) );
1114: #endif
1115:
1116: return( NULL );
1117: }
1118:
1119: /*
1120: * Find the next aux entry
1121: */
1122:
1123: #if NOSDP
1124: if (aux->axchainid != 0)
1125: return(getaux(aux->axchainid));
1126: #else
1127: unlock(aux->axmyacid, (changed ? WRTN : RNLY));
1128:
1129: if( aux->axchainid != 0 )
1130: return( (AUXTAB *) lock(aux->axchainid, MISPARTITION, WRTN) );
1131: #endif
1132:
1133: return( NULL );
1134: }
1135: /*eject*/
1136: INSECT *
1137: sectnum(i, fp)
1138: int i;
1139: INFILE *fp;
1140: {
1141:
1142: /*
1143: * Called by psymtab to retrieve a pointer to the i-th section header
1144: */
1145:
1146: register INSECT *sptr;
1147:
1148: if (i == 0)
1149: return(NULL);
1150:
1151:
1152: for ( sptr = fp->flishead; sptr != NULL; sptr = sptr->isnext )
1153: if ( sptr->isecnum == i)
1154: return(sptr);
1155: return(NULL);
1156: }
1157: /*eject*/
1158: ITEMID
1159: add_dot(dot_val, dot_sec)
1160: long dot_val;
1161: INSECT *dot_sec;
1162: {
1163: register SYMTAB *sym;
1164: register ITEMID acid;
1165: static int count = 0;
1166:
1167: /*
1168: * This is a special-purpose "makesym()" designed for exclusive use
1169: * in assignment expressions. It will create a symbol table entry
1170: * having the following characteristics:
1171: *
1172: * n_name: .dotnnn 001 <= nnn <= 999
1173: * n_value: dot_val
1174: * n_scnum: 0
1175: * n_type: T_NULL
1176: * n_sclass: C_NULL
1177: * n_numaux: 0
1178: *
1179: * smscnptr: dot_sec
1180: * smlocflg: 1
1181: *
1182: * The symbol table entry will NOT appear in the hash table, and hence
1183: * will not be accessible except thorugh the stored itemid returned
1184: * by this function
1185: */
1186:
1187: #if NOSDP
1188: if (numldsyms >= MYSMTBSZ + (xsymcnt * XSMTBSZ)) {
1189: if (xsymcnt >= MAXEXTRA)
1190: lderror(2,0,"internal error: ","symbol table overflow");
1191: xsymptr[xsymcnt++] = (SYMTAB *) myalloc(XSMTBSZ * SYMSIZ);
1192: }
1193: acid = ++numldsyms;
1194: sym = getsym(acid);
1195: #else
1196: acid = allocate(SYMSIZ, SYMSPACE, MISPARTITION);
1197: sym = (SYMTAB *) lock(acid, MISPARTITION, WRTN);
1198:
1199: zero(sym, SYMSIZ);
1200: #endif
1201: sprintf(sym->sment.n_name, ".dot%03d", ++count);
1202: sym->sment.n_value = dot_val;
1203: sym->smscnptr = dot_sec;
1204: sym->smmyacid = acid;
1205: sym->smchainid = acid;
1206: sym->smlocflg = 1;
1207:
1208: #if !NOSDP
1209: unlock(acid, WRTN);
1210: #endif
1211:
1212: return( acid );
1213:
1214: }
1215:
1216: #if !NOSDP
1217: auxinit()
1218: {
1219: /* initialize SDP */
1220:
1221: if ( aux_called )
1222: lderror(2,0,NULL,"attempt to re-initialize SDP aux space");
1223:
1224: sprintf( auxname, "%s/%s", TMPDIR, "ldXXXXXX");
1225: mktemp(auxname);
1226: aux_called++;
1227: if ( sdpinit(auxname, CREATE, AUXSPACE) != AUXSPACE )
1228: lderror(2,0,NULL,"failure to initialize SDP aux space");
1229: else
1230: aux_called++;
1231: }
1232:
1233: auxfini()
1234: {
1235:
1236: char buf[sizeof(auxname)*2+20];
1237:
1238: if ( aux_called == 2 ) {
1239: aux_called--;
1240: if ( sdpterm(AUXSPACE) < 0 )
1241: lderror(2,0,NULL,"failure in closing SDP aux space");
1242: }
1243:
1244: if ( aux_called != 1)
1245: return;
1246: aux_called--;
1247:
1248: #if TS || RT
1249: sprintf(buf, "rm -r %s", auxname);
1250: #else
1251: sprintf(buf, "rm -r %s; rmdir %s", auxname, auxname);
1252: #endif
1253:
1254: if ( fork() == 0 ) {
1255: execl("/bin/sh", "sh", "-c", buf, 0);
1256: lderror(0,0,NULL, "failure in the execl of %s",buf);
1257: _exit(127);
1258: }
1259: }
1260: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.