|
|
1.1 root 1: static char ID[] = "@(#) ld1.c: 1.21 12/10/83";
2: #include "system.h"
3:
4: #include <stdio.h>
5:
6: #if TS || RT
7: #if PORTAR || PORT5AR
8: #define TABSZ 2000
9: #endif
10: #include <ar.h>
11: #else
12: #include <archive.h>
13: #endif
14:
15: #include "structs.h"
16: #include "extrns.h"
17: #include "list.h"
18: #include "ldfcn.h"
19: #include "params.h"
20: #include "sgsmacros.h"
21: #include "reloc.h"
22: #if DMERT || XL
23: #include "aouthdr.h"
24: #include "magic.h"
25: #endif
26: #include "ldmacros.h"
27:
28: #if AR32W && !UNIX
29: #define MAXSCNBS 20
30: #define MAXSYMBS 120
31: #else
32: #define MAXSCNBS 4
33: #if AR16WR
34: #define MAXSYMBS 30
35: #else
36: #define MAXSYMBS 60
37: #endif
38: #endif
39:
40: #if TRVEC
41: #define OKMAGIC(x) ((unsigned short) x == (unsigned short) magic)
42: #else
43: #include "sgs.h"
44: #define OKMAGIC ISMAGIC
45: #endif
46:
47: #if M32
48: unsigned short macflags = 0;
49: #endif
50:
51: int lo_scnh, hi_scnh;
52:
53: /*eject*/
54: psymdef()
55: {
56:
57: /*
58: * Process the symlist, to define/undefine global symbols
59: */
60:
61: #if !ONEPROC
62: ACTITEM a;
63: #endif
64: ACTITEM *ap;
65:
66: #if DEBUG
67: if( dflag > 2 )
68: fprintf( stderr, "\nDFNSYM data structures:" );
69: #endif
70:
71: #if ONEPROC
72: ap = (ACTITEM *) symlist.head;
73: while( ap ) {
74: #else
75: ap = &a;
76: while( symcnt-- ) {
77: fread( &a, 1, sizeof(ACTITEM), trnfdes );
78: ap->dfnsym.aiinflnm = (char *) ((int) ap->dfnsym.aiinflnm + (int) strbase);
79: ap->dfnsym.aisymbol = (char *) ((int) ap->dfnsym.aisymbol + (int) strbase);
80:
81: #endif
82: #if DEBUG
83: if( dflag > 2 )
84: fprintf( stderr, "\n\t%04x AIDFNSYM (%s) %d (%s) %s %08lx",
85: ap->dfnsym.ainext, ap->dfnsym.aiinflnm,
86: ap->dfnsym.aiinlnno, ap->dfnsym.aisymbol,
87: (ap->dfnsym.aideflag ? "DEF" : "UNDEF"),
88: ap->dfnsym.aidefval );
89: #endif
90:
91: if( ap->dfnsym.aideflag ) {
92: lderror(1, ap->dfnsym.aiinlnno, ap->dfnsym.aiinflnm,
93: "inimplemented feature: value definition for symbol %.8s",
94: ap->dfnsym.aisymbol );
95: }
96: else
97: undefsm( ap->dfnsym.aisymbol );
98: #if ONEPROC
99: ap = ap->ldlbry.ainext;
100: #endif
101: }
102: }
103: /*eject*/
104: pmemreg()
105: {
106:
107: /*
108: * Input the MEMLIST and REGLIST built during PASS 1
109: */
110:
111: #if USEREGIONS
112: register REGION *rptr;
113: #endif
114: register MEMTYPE *mptr;
115: ADDRESS length;
116:
117: /*
118: * If no MEMORY directives are supplied, use a default, otherwise check
119: * for proper usage
120: */
121:
122: #if ONEPROC
123: if (memlist.head == NULL ) {
124: #else
125: if( memcnt == 0 ) {
126: #endif
127: mptr = (MEMTYPE *) myalloc(sizeof(MEMTYPE));
128: copy(mptr->mtname, "*dfltmem", 8);
129: #if PAGING
130: if (zflag)
131: memorg = max(memorg, NONULLORG);
132: #endif
133: mptr->mtorig = memorg;
134: mptr->mtlength = (MEMSIZE - memorg);
135: mptr->mtattr=15; /* all attrs set */
136: listadd( l_MEM, &memlist, mptr );
137: }
138: else {
139: #if DEBUG
140: if( dflag > 2 )
141: fprintf( stderr, "\nMEMTYPE data structures:" );
142: #endif
143: #if !ONEPROC
144: while( memcnt-- ) {
145: mptr = (MEMTYPE *) myalloc(sizeof(MEMTYPE));
146: fread( mptr, 1, sizeof(MEMTYPE), trnfdes );
147: mptr->mtnext = NULL;
148: #if DEBUG
149: if( dflag > 2 )
150: fprintf( stderr, "\n\t%04x (%8.8s) %08lx %08lx %d %04x %04x",
151: mptr->mtnext, mptr->mtname, mptr->mtorig, mptr->mtlength, mptr->mtattr,
152: mptr->mtaddrhd, mptr->mtaddrtl );
153: #endif
154: listadd( l_MEM, &memlist, mptr );
155: }
156: #endif
157: mptr = (MEMTYPE *) memlist.head;
158: while ( mptr->mtnext ) {
159: length = mptr->mtorig + mptr->mtlength;
160: if( length > mptr->mtnext->mtorig ) {
161: lderror(1,0,NULL, "memory types %.8s and %.8s overlap",
162: mptr->mtname, mptr->mtnext->mtname);
163: free( mptr->mtnext );
164: mptr->mtnext = mptr->mtnext->mtnext;
165: }
166: mptr = mptr->mtnext;
167: }
168: }
169:
170: #if USEREGIONS
171: /*
172: * If no REGIONS directives are supplied, use a default, otherwise check
173: * for proper usage
174: */
175:
176: #if ONEPROC
177: if( reglist.head == NULL ) {
178: #else
179: if( regcnt == 0 ) {
180: #endif
181: if( (! iflag) && (! tvflag) ) {
182: /*
183: * No separate I and D space. No tv
184: */
185: rptr = (REGION *) myalloc(sizeof(REGION));
186: copy(rptr->rgname, "*dfltrgn", 8);
187: rptr->rgorig = 0L;
188: rptr->rglength = REGSIZE;
189: rptr->rgvaddr = 0L;
190: listadd(l_REG, ®list, rptr);
191: }
192: else if( ! tvflag ) {
193: /*
194: * Separate I and D space. No tv
195: */
196: rptr = (REGION *) myalloc(sizeof(REGION));
197: copy(rptr->rgname, "RTEXT", 8);
198: rptr->rgorig = 0L;
199: rptr->rglength = REGSIZE;
200: rptr->rgvaddr = 0L;
201: listadd(l_REG, ®list, rptr);
202: rptr = (REGION *) myalloc(sizeof(REGION));
203: copy(rptr->rgname, "RDATA", 8);
204: rptr->rgorig = REGSIZE + 2;
205: rptr->rglength = REGSIZE - 2;
206: rptr->rgvaddr = 2L;
207: listadd(l_REG, ®list, rptr);
208: }
209: }
210: else {
211: #if DEBUG
212: if( dflag > 2 )
213: fprintf( stderr, "\nREGION data structures:" );
214: #endif
215: #if !ONEPROC
216: while( regcnt-- ) {
217: rptr = (REGION *) myalloc(sizeof(REGION));
218: fread( rptr, 1, sizeof(REGION), trnfdes );
219: rptr->rgnext = NULL;
220: #if DEBUG
221: if( dflag > 2 )
222: fprintf( stderr, "\n\t%04x (%8.8s) %08lx %08lx %08lx %04x %04x",
223: rptr->rgnext, rptr->rgname, rptr->rgorig,
224: rptr->rglength, rptr->rgvaddr,
225: rptr->rgaddrhd, rptr->rgaddrtl );
226: #endif
227: listadd( l_REG, ®list, rptr );
228: }
229: #endif
230: rptr = (REGION *) reglist.head;
231: while( rptr->rgnext ) {
232: length = rptr->rgorig + rptr->rglength;
233: if( length > rptr->rgnext->rgorig ) {
234: lderror(2,0,NULL,"Can't allocate space for overlap regions %.8s and %.8s",
235: rptr->rgname, rptr->rgnext->rgname);
236: }
237: rptr = rptr->rgnext;
238: }
239: }
240: #endif
241:
242: }
243: /*eject*/
244: ploadfil()
245: {
246:
247: /*
248: * Process the LDFILE list
249: */
250:
251: extern LDFILE *myldopen();
252: extern long sgetl();
253: #if !ONEPROC
254: ACTITEM a;
255: #endif
256: ACTITEM *ap;
257: ARCHDR ahdr;
258: SCNHDR scnbuf[MAXSCNBS];
259: SYMENT symbuf[MAXSYMBS];
260: LDFILE fdesbuf;
261: register LDFILE *fdes;
262: #if AR16WR
263: char fbuf[BUFSIZ];
264: #endif
265: register int done, count;
266:
267: /*
268: * For each separate file to go into some output section:
269: * 1. Make sure the file is of valid type (i.e., "good magic")
270: * 2. Input the file and section headers
271: * 3. Scan the symbol table, counting globals, etc.
272: */
273:
274: #if DEBUG
275: if( dflag > 2 )
276: fprintf( stderr, "\nLDFILE data structures:" );
277: #endif
278: #if ONEPROC
279: ap = (ACTITEM *) ldfilist.head;
280: while ( ap ) {
281: #else
282: ap = &a;
283: while( ldfcnt-- ) {
284: fread( &a, 1, sizeof(ACTITEM), trnfdes );
285: ap->ldlbry.aiinflnm = (char *) ((int) ap->ldlbry.aiinflnm + (int) strbase);
286: ap->ldlbry.aifilnam = (char *) ((int) ap->ldlbry.aifilnam + (int) strbase);
287: #endif
288: #if DEBUG
289: if( dflag > 2 )
290: fprintf( stderr, "\n\t%04x AILDFILE (%s) %d (%s)",
291: ap->ldlbry.ainext, ap->ldlbry.aiinflnm,
292: ap->ldlbry.aiinlnno, ap->ldlbry.aifilnam );
293: #endif
294: /*
295: * The same file can appear many times on the ldlist
296: * sequence, since the input sections from it can go
297: * into many different output sections
298: *
299: * Process a NON-ARCHIVE file exactly ONCE; but,
300: * process an ARCHIVE file each time it is given
301: */
302: if( (ap->ldlbry.aitype == AILDFILE) && fndinfil(ap->ldlbry.aifilnam) ) {
303: #if ONEPROC
304: ap = ap->ldlbry.ainext;
305: #endif
306: continue;
307: }
308:
309: #if AR16WR
310: if( (fdes = myldopen(ap->ldlbry.aifilnam,&ahdr,&fdesbuf,fbuf)) == NULL )
311: #else
312: if( (fdes = myldopen(ap->ldlbry.aifilnam,&ahdr,&fdesbuf)) == NULL )
313: #endif
314: lderror(1, ap->ldlbry.aiinlnno, ap->ldlbry.aiinflnm, "Can't open file %s",
315: ap->ldlbry.aifilnam);
316: else if( OKMAGIC(TYPE(fdes))) {
317: #if DMERT || XL
318: if (HEADER(fdes).f_opthdr >= sizeof(AOUTHDR)) {
319: short o_magic;
320: if (FREAD(&o_magic,sizeof(o_magic),1,fdes) != 1)
321: lderror(2,0,NULL,"fail to read magic number of pfile %s",
322: ap->ldlbry.aifilnam);
323: if (o_magic == (short) PLIBMAGIC)
324: dmertplib = 1;
325: }
326: #endif
327: lo_scnh = 1;
328: if ((hi_scnh = getrec2(scnbuf,fdes,1)) == 0)
329: lderror(2,0,NULL,"fail to read section headers of file %s",
330: ap->ldlbry.aifilnam);
331: loadobjf(fdes,ap->ldlbry.aifilnam,-1,scnbuf,NULL);
332: #if DMERT || XL
333: dmertplib = 0;
334: #endif
335: fclose(IOPTR(fdes));
336: }
337: else if( TYPE(fdes) == USH_ARTYPE ) {
338: #if PORTAR
339: /* Read in the archive symbol table and search it
340: * for unresolved symbol references. Keep passing
341: * over the symbol table, loading in archive members
342: * as you go until one complete pass is made with no
343: * additional loads of an archive member.
344: */
345:
346: typedef union { long l;
347: char c[sizeof(long)/sizeof(char)];
348: } longchar;
349: longchar arsymtab[TABSZ], sym_count;
350: char * arsymnmptr[TABSZ];
351: char found_one;
352: long sym_ar_size;
353: int strtabsz;
354: char *j,*strtabptr;
355: int i;
356: struct ar_hdr arheader;
357:
358: /* read archive header */
359: if (fseek(IOPTR(fdes),(long)SARMAG,0) != OKFSEEK
360: || FREAD(&arheader,sizeof(struct ar_hdr),1,fdes) != 1
361: || strncmp(arheader.ar_fmag,ARFMAG,sizeof(arheader.ar_fmag))
362: || sscanf(arheader.ar_size, "%ld", &sym_ar_size) !=1)
363: lderror(2,0,NULL,
364: "can't read archive header from archive %s",
365: ap->ldlbry.aifilnam);
366: if (arheader.ar_name[0] != '/')
367: lderror(2,0,NULL,
368: "archive symbol directory is missing from archive %s\nexecute 'ar ts %s' to restore archive symbol directory",
369: ap->ldlbry.aifilnam,ap->ldlbry.aifilnam);
370:
371: /* figure out number of archive symbols */
372: if (FREAD(sym_count.c,sizeof(sym_count.c),1,fdes) != 1)
373: lderror(2,0,NULL,
374: "can't read archive symbol directory number of symbols from archive %s",
375: ap->ldlbry.aifilnam);
376: sym_count.l = sgetl( sym_count.c );
377: /* check to make sure that you have a symbol table */
378: if ( sym_count.l <= 0 )
379: lderror(2,0,NULL,
380: "archive symbol table is empty in archive %s\nexecute 'ar ts %s' to restore archive symbol table",
381: ap->ldlbry.aifilnam,ap->ldlbry.aifilnam);
382: if ( sym_count.l > TABSZ )
383: lderror(2,0,NULL,
384: "archive symbol directory in archive %s is too large",
385: ap->ldlbry.aifilnam);
386:
387: /* read in the archive symbol directory */
388:
389: if (FREAD(arsymtab,sizeof(longchar),sym_count.l,fdes)
390: != sym_count.l)
391: lderror(2,0,NULL,
392: "can't read archive symbol directory of archive %s",
393: ap->ldlbry.aifilnam);
394: /* read in the symbol names string table */
395:
396: strtabsz = sym_ar_size - (sym_count.l + 1) *
397: sizeof(longchar);
398: strtabptr = myalloc(strtabsz);
399: if ((FREAD(strtabptr,strtabsz,1,fdes) != 1) ||
400: strtabptr[strtabsz - 1] != '\0')
401: lderror(2,0,NULL,
402: "can't read archive string table of archive %s",
403: ap->ldlbry.aifilnam);
404: j = strtabptr; /* ptr for walking thru string table */
405: for (i=0; i<sym_count.l; i++) {
406: if (j > (strtabptr + strtabsz - 1))
407: lderror(2,0,NULL,
408: "too few symbol names in string table for archive %s",
409: ap->ldlbry.aifilnam);
410: arsymtab[i].l = sgetl(arsymtab[i].c);
411: arsymnmptr[i] = j;
412: while (*++j != '\0');
413: j++;
414: }
415:
416: /* loop thru symbol table until you can't find any more
417: unresolved symbols which are satisfied by this
418: archive */
419: found_one = 1;
420: while (found_one) {
421: struct ar_hdr memberhdr;
422: SYMTAB *symptr;
423: int i;
424: found_one = 0;
425: for (i=0; i < sym_count.l; i++) {
426: symptr = findsym(arsymnmptr[i]);
427: if (symptr != NULL) /* found one ?? */
428: if ( symptr->sment.n_value == 0
429: && symptr->sment.n_scnum==0) {
430: PUTSYM(symptr,0);
431: /* seek to the archive location */
432: OFFSET(fdes) = arsymtab[i].l
433: + sizeof(struct ar_hdr);
434: /* read this member's archive header */
435: if (FSEEK(fdes,-(int)(sizeof(struct ar_hdr)),BEGINNING)
436: != OKFSEEK ||
437: FREAD(&memberhdr,sizeof(struct ar_hdr),1,fdes) != 1 ||
438: strncmp(memberhdr.ar_fmag,ARFMAG,
439: sizeof(memberhdr.ar_fmag)))
440: lderror(2,0,NULL,
441: "can't read archive header of archive %s",
442: ap->ldlbry.aifilnam);
443: if (sscanf(memberhdr.ar_size,"%ld",&ar_size) != 1)
444: lderror(2,0,NULL,
445: "invalid archive size for file %s",
446: ap->ldlbry.aifilnam);
447: /* read this member's header */
448: if (FREAD(&(HEADER(fdes)),FILHSZ, 1, fdes) != 1)
449: lderror(2,0,NULL,
450: "can't read file header of archive %s",
451: ap->ldlbry.aifilnam);
452: if (OKMAGIC(HEADER(fdes).f_magic)) {
453: /* bind this member */
454: loadobjf(fdes,ap->ldlbry.aifilnam,-1,NULL,NULL);
455: found_one = 1;
456: }
457: }
458: #if !NODSP
459: else
460: PUTSYM(symptr,0);
461: #endif
462: } /* end of for */
463: } /* end of while */
464:
465: /* we are done with this archive */
466: fclose(IOPTR(fdes));
467: #endif
468: #if PORT5AR
469: /* Read in the archive symbol table and search it
470: * for unresolved symbol references. Keep passing
471: * over the symbol table, loading in archive members
472: * as you go until one complete pass is made with no
473: * additional loads of an archive member.
474: */
475: #if ONEPROC
476: struct ar_sym arsymtab[TABSZ];
477: #else
478: struct ar_sym *arsymtab;
479: #endif
480: struct ar_hdr arheader;
481: long sym_count;
482: char found_one;
483:
484: /* read archive header */
485: fseek(IOPTR(fdes),0L,0);
486: if (FREAD(&arheader,sizeof(struct ar_hdr),1,fdes)
487: != 1)
488: lderror(2,0,NULL,
489: "can't read archive header from archive %s",
490: ap->ldlbry.aifilnam);
491:
492: /* figure out number of archive symbols */
493: sym_count = sgetl( arheader.ar_syms );
494: #if !ONEPROC
495: arsymtab = (struct ar_sym *) myalloc(sym_count * sizeof(struct ar_sym));
496: #endif
497: /* check to make sure that you have a symbol table */
498: if (sym_count <= 0)
499: lderror(2,0,NULL,
500: "archive symbol table is empty in archive %s\nexecute 'ar ts %s' to restore archive symbol table",
501: ap->ldlbry.aifilnam,ap->ldlbry.aifilnam);
502:
503: /* read in the archive symbol table */
504: if (FREAD(arsymtab,sizeof(struct ar_sym),sym_count,fdes)
505: != sym_count)
506: lderror(2,0,NULL,
507: "can't read archive symbol table of archive %s",
508: ap->ldlbry.aifilnam);
509:
510: found_one = 1; /* loop thru symbol table until you can't
511: find any more unresolved symbols which
512: are satisfied by this archive */
513: while (found_one) {
514: SYMTAB *symptr;
515: int i;
516: short j;
517: long location;
518: char sym_name[sizeof(arsymtab->sym_name)+1];
519:
520: found_one = 0;
521: for (i=0; i<=sym_count; i++) {
522: strncpy(sym_name,arsymtab[i].sym_name,
523: sizeof(arsymtab->sym_name));
524: j = sizeof(arsymtab->sym_name);
525: while (sym_name[j-1] == ' ' &&
526: j >= 1) j--;
527: sym_name[j] = '\0';
528: symptr = findsym(sym_name);
529: if (symptr != NULL) /* found one ?? */
530: if (symptr->sment.n_value == 0 && symptr->sment.n_scnum == 0) {
531: PUTSYM(symptr,0);
532: /* seek to the archive location */
533: location = sgetl( arsymtab[i].sym_ptr );
534: OFFSET(fdes) = location +
535: sizeof(struct arf_hdr);
536: /* read this member's header */
537: FSEEK(fdes,0L,BEGINNING);
538: if (FREAD(&(HEADER(fdes)),
539: FILHSZ,1,fdes) != 1)
540: lderror(2,0,NULL,
541: "can't read file header of archive %s",
542: ap->ldlbry.aifilnam);
543:
544: if (OKMAGIC(HEADER(fdes).f_magic)) {
545: /* bind this member */
546: loadobjf(fdes,ap->ldlbry.aifilnam,-1,
547: NULL,NULL);
548: found_one = 1;
549: }
550: }
551: #if !NOSDP
552: else
553: PUTSYM(symptr, 0);
554: #endif
555: };
556: };
557:
558: /* we are done with this archive */
559: fclose(IOPTR(fdes));
560: #endif
561: #if !PORTAR && !PORT5AR
562: /*
563: * Search each member of the archive library
564: * to see if it will resolve any unsatisfied
565: * references
566: */
567: done = count = 0;
568: while( ! done ) {
569: if ( OKMAGIC(HEADER(fdes).f_magic)) {
570: lo_scnh = 1;
571: if ((hi_scnh = getrec2(scnbuf,fdes,1)) == 0)
572: lderror(2,0,NULL,"fail to read section headers of library %s member %d",
573: ap->ldlbry.aifilnam,count);
574: if (HEADER(fdes).f_nsyms > MAXSYMBS ||
575: getrec3(symbuf,fdes) == FAILURE) {
576: if( libsrch(fdes,NULL) )
577: loadobjf(fdes, ap->ldlbry.aifilnam,count,scnbuf,NULL);
578: }
579: else {
580: if( libsrch(fdes,symbuf) )
581: loadobjf(fdes, ap->ldlbry.aifilnam,count,scnbuf,symbuf);
582: }
583: }
584: else {
585: if (FSEEK(fdes,HEADER(fdes).f_symptr+
586: (HEADER(fdes).f_nsyms * SYMESZ),BEGINNING) != OKFSEEK)
587: lderror(2,0,NULL,"fail to seek to the end of library %s member %d",
588: ap->ldlbry.aifilnam,count);
589: }
590: done = myldclose(&ahdr,fdes);
591: count++;
592: }
593: #endif
594: }
595: else
596: procspecobj(fdes, ap);
597: #if ONEPROC
598: ap = ap->ldlbry.ainext;
599: #endif
600: }
601: }
602: #if !PORTAR && !PORT5AR
603: /*eject*/
604: libsrch(fdes,symbuf)
605: LDFILE *fdes;
606: SYMENT *symbuf;
607: {
608:
609: /*
610: * Return true if current member of archive file defines an
611: * undefined symbol
612: */
613:
614: register int i;
615: register SYMTAB *symp;
616: SYMENT *symbol;
617: SYMENT symbolbuf;
618:
619: if ( !OKMAGIC(HEADER(fdes).f_magic) )
620: return (0);
621:
622: if (symbuf == NULL) {
623: if (FSEEK(fdes,HEADER(fdes).f_symptr,0) != OKFSEEK)
624: lderror(2,0,NULL,"fail to seek to symbol table when search libraries");
625: symbol = &symbolbuf;
626: }
627:
628: for( i = 0; i < HEADER(fdes).f_nsyms; i++ ) {
629: if (symbuf == NULL) {
630: if (FREAD(symbol,SYMESZ,1,fdes) != 1)
631: lderror(2,0,NULL,"fail to read symbol table when search libraries");
632: }
633: else {
634: symbol = symbuf++;
635: }
636: if( (symbol->n_sclass == C_EXT) && (symbol->n_scnum > 0) ) {
637: if( (symp = findsym(PTRNAME(symbol))) != NULL ) {
638: if( symp->sment.n_scnum == 0 ) { /*undefined*/
639: PUTSYM(symp, 0);
640: return(1);
641: }
642: PUTSYM(symp, 0);
643: }
644: }
645: /*
646: * skip auxilliary entries for efficiency and
647: * to avoid misinterpreting garbage sment
648: */
649:
650: if ( (int) symbol->n_numaux > 0 ) {
651: if (symbuf == NULL) {
652: if (fseek(IOPTR(fdes),(long) (SYMESZ * (int) symbol->n_numaux), 1) != OKFSEEK)
653: lderror(2,0,NULL,"fail to skip aux entries when search libraries");
654: }
655: else {
656: symbuf++;
657: }
658: i += (int) symbol->n_numaux;
659: }
660: }
661:
662: return(0);
663: }
664: #endif
665: /*eject*/
666: loadobjf(fdes,fnamp,filndx,scnbuf,symbuf)
667: LDFILE *fdes; /* file descriptor */
668: char *fnamp; /* name of the file */
669: int filndx; /* member number within library */
670: SCNHDR *scnbuf;
671: SYMENT *symbuf;
672: {
673:
674: /*
675: * Given a file descriptor which has been "seeked" to the beginning
676: * of the file header, build the INFILE and INSECT structures
677: * and process the symbol table.
678: */
679:
680: #if FLEXNAMES
681: char *strtabptr;
682: int strtabsz;
683: #endif
684: register int s;
685: register INSECT *sptr;
686: register INFILE *filptr;
687:
688: filptr = (INFILE *) myalloc(sizeof(INFILE));
689:
690: curfilnm = fnamp;
691: filptr->flname = fnamp;
692: filptr->flfilndx = filndx;
693: filptr->flfiloff = OFFSET(fdes);
694: #if DMERT || XL
695: if (dmertplib)
696: filptr->flplib = 1;
697: else
698: filptr->flplib = 0;
699: #endif
700:
701: /*
702: * Build an INSECT data structure for every section in the
703: * input file. Check for two special cases:
704: *
705: * 1. Sections with illegal names - names that conflict
706: * predefined ld section names - are not processed,
707: * and yield an error message
708: * 2. Sections which are "padding sections" (see add_pad())
709: * are skipped. They exist only to provide certain
710: * physical alignment in the file
711: */
712:
713: for( s = 1; s <= HEADER(fdes).f_nscns; s++ ) {
714: sptr = (INSECT *) myalloc(sizeof(INSECT));
715: if (scnbuf == NULL) {
716: if (FSEEK(fdes,(long) (FILHSZ+HEADER(fdes).f_opthdr+
717: (s-1) * SCNHSZ),BEGINNING) != OKFSEEK ||
718: FREAD(&sptr->ishdr,SCNHSZ,1,fdes) != 1)
719: lderror(2,0,NULL,"fail to read section headers of file %s",fnamp);
720: }
721: else {
722: if (s < lo_scnh || s > hi_scnh) {
723: lo_scnh = s;
724: if ((hi_scnh = getrec2(scnbuf,fdes,s)) == 0)
725: lderror(2,0,NULL,"fail to read section header of file %s",
726: fnamp);
727: hi_scnh = hi_scnh + lo_scnh - 1;
728: }
729: sptr->ishdr = scnbuf[s-lo_scnh];
730: }
731: if( ! OKSCNNAME(sptr->ishdr.s_name) ) {
732: lderror(1,0,NULL, "file %s has a section name which is a reserved ld identifier: %.8s",
733: fnamp, sptr->ishdr.s_name);
734: continue;
735: }
736: if ( equal(sptr->ishdr.s_name, _TV, 8) )
737: ++usrdeftv;
738:
739: if( sptr->ishdr.s_flags & (STYP_COPY | STYP_INFO))
740: sptr->ishdr.s_flags |= STYP_DSECT;
741: /* COPY and INFO sections require the same treatment
742: as DSECT sections */
743:
744: if( sptr->ishdr.s_flags & STYP_PAD ) {
745: free( sptr );
746: continue;
747: }
748: sptr->isecnum = (short) s;
749: #if DMERT || XL
750: if (dmertplib) {
751: sptr->ishdr.s_relptr = 0;
752: sptr->ishdr.s_nreloc = 0;
753: sptr->ishdr.s_lnnoptr = 0;
754: sptr->ishdr.s_nlnno = 0;
755: }
756: #endif
757: listadd(l_IS,filptr,sptr);
758: }
759: #if FLEXNAMES
760: strtabsz = 0L;
761: strtabptr = strtabread(fdes, fnamp, &strtabsz);
762: if (strtabptr && (strtabsz <= MAXKEEPSIZE))
763: filptr->flstrings = strtabptr;
764: else
765: filptr->flstrings = NULL;
766: #endif
767:
768: if (symbuf == NULL)
769: if (FSEEK(fdes,HEADER(fdes).f_symptr,BEGINNING) != OKFSEEK)
770: lderror(2,0,NULL,"fail to seek to symbol table of file %s",fnamp);
771: #if FLEXNAMES
772: filptr->flnlsyms = psymtab(IOPTR(fdes),HEADER(fdes).f_nsyms,filptr,symbuf,strtabptr);
773: #else
774: filptr->flnlsyms = psymtab(IOPTR(fdes),HEADER(fdes).f_nsyms,filptr,symbuf);
775: #endif
776: listadd(l_IF,&infilist,filptr);
777:
778: #if FLEXNAMES
779: if (strtabptr && (strtabsz > MAXKEEPSIZE))
780: free( strtabptr );
781: #endif
782:
783: /*
784: * Error check: warn the user about files which have no relocation
785: * information in them
786: *
787: * Such files are, however, permitted
788: */
789:
790: if( HEADER(fdes).f_flags & F_RELFLG ) {
791: if( TYPE(fdes) == ARTYPE )
792: lderror(0,0,NULL, "library %s, member has no relocation information",
793: fnamp);
794: else
795: lderror(0,0,NULL, "file %s has no relocation information",
796: fnamp);
797: }
798:
799: #if M32
800: /* macflags is used to remember if any input file had F_BM32B on */
801: macflags |= HEADER(fdes).f_flags & F_BM32B ;
802: #endif
803:
804: }
805:
806: #if FLEXNAMES
807: char *
808: strtabread(fdes,fnamp,sizeptr)
809: LDFILE *fdes; /* file descriptor */
810: char *fnamp; /* name of the file */
811: int *sizeptr; /* ptr to size of string table read */
812: {
813: /*
814: * Given the file descriptor and the name of the file read the string table
815: * if there is one and return a pointer to it, otherwise return null.
816: */
817: long symtabend;
818: char *strtabptr;
819: symtabend = HEADER(fdes).f_symptr + SYMESZ * HEADER(fdes).f_nsyms;
820: if (TYPE(fdes) == USH_ARTYPE ) {
821: if (ar_size > symtabend) {
822: if (FSEEK(fdes, symtabend, BEGINNING) != OKFSEEK ||
823: FREAD(sizeptr,sizeof(*sizeptr),1,fdes) != 1)
824: lderror(2,0,NULL,
825: "fail to read string table of file %s", fnamp);
826: if (*sizeptr > 4) {
827: strtabptr = myalloc(*sizeptr);
828: if (FREAD(&strtabptr[4], *sizeptr - 4, 1, fdes) != 1)
829: lderror(2, 0, NULL,
830: "fail to read string table of file %s",
831: fnamp);
832: else
833: return(strtabptr);
834: }
835: else
836: return(NULL);
837: }
838: else
839: return(NULL);
840: }
841: else {
842: /* not a member of an archive so it must be a
843: * regular object file or a DMERT public library
844: * (both of which are processed the same way
845: */
846:
847: if (FSEEK(fdes,symtabend,BEGINNING) == OKFSEEK &&
848: FREAD(sizeptr,sizeof(*sizeptr),1,fdes) == 1) {
849: /* read string table */
850: if (*sizeptr > 4) {
851: strtabptr = myalloc(*sizeptr);
852: if (FREAD(&strtabptr[4], *sizeptr - 4, 1, fdes) != 1)
853: lderror(2,0,NULL,
854: "fail to read string table of file %s",
855: fnamp);
856: else
857: return(strtabptr);
858: }
859: else
860: return(NULL);
861: }
862: else
863: return(NULL);
864: }
865: }
866: #endif
867: #if COMMON
868: /*eject*/
869: pf77comm()
870: {
871: /* process F77 common data declarations, undefined (i.e., unitialized
872: * common) data is placed into the bss section. common data is indicated
873: * by an undefined external variable with a non zero value. the value
874: * indicates the size of the common data region.
875: */
876:
877: register SYMTAB *symp;
878: long symsize;
879: register INSECT *sptr;
880: INFILE *fptr;
881:
882: /* look thru the symbol table to see if there are some symbols
883: * which are undefined and have non-zero values. allocate all
884: * such symbols to an imaginary bss segment defined in the
885: * COMF77 file.
886: */
887:
888: /* initialize the dummy section to which common data is allocated */
889:
890: fptr = (INFILE *)myalloc(sizeof(INFILE));
891: fptr->flname = COMF77;
892: fptr->flfiloff = 0L;
893:
894: sptr = (INSECT *)myalloc(sizeof(INSECT));
895:
896: listadd(l_IS,fptr,sptr);
897: listadd(l_IF,&infilist,fptr);
898:
899: strcpy(sptr->ishdr.s_name,".bss");
900: sptr->ishdr.s_paddr = 0;
901: sptr->ishdr.s_vaddr = 0;
902: sptr->ishdr.s_size = 0;
903: sptr->ishdr.s_scnptr = NULL;
904: sptr->ishdr.s_relptr = NULL;
905: sptr->ishdr.s_lnnoptr = NULL;
906: sptr->ishdr.s_nreloc = 0;
907: sptr->ishdr.s_nlnno = 0;
908: sptr->ishdr.s_flags = 0;
909:
910: sptr->isoutsec = NULL;
911: sptr->isincnxt = NULL;
912: sptr->isdispl = 0;
913: sptr->isrldisp = 0;
914: sptr->islndisp = 0;
915: sptr->isnewvad = 0;
916: sptr->isnewpad = 0;
917: sptr->isecnum = 1;
918: sptr->isfillfg = 0;
919:
920:
921: symp = NULL;
922: while ((symp = loopsym(symp,1)) != NULL) {
923: if (symp->sment.n_sclass == C_EXT &&
924: symp->sment.n_scnum == N_UNDEF &&
925: symp->sment.n_value > 0) { /* we have a common symbol */
926:
927: /* assign this common symbol to the dummy section */
928:
929: symp->smscnptr = sptr;
930: symp->sment.n_scnum = 1;
931:
932: /* align common symbol on optimal boundary */
933:
934: symsize = symp->sment.n_value;
935: if (symsize == 1) {}
936: else if (symsize == 2) {
937: sptr->ishdr.s_size += 1;
938: sptr->ishdr.s_size &= (~1);
939: }
940: #if XL
941: else if (symsize <= 4) {
942: sptr->ishdr.s_size += 3;
943: sptr->ishdr.s_size &= (~3);
944: }
945: else if (symsize <= 8) {
946: sptr->ishdr.s_size += 7;
947: sptr->ishdr.s_size &= (~7);
948: }
949: #endif
950: else
951: {
952: sptr->ishdr.s_size += COM_ALIGN;
953: sptr->ishdr.s_size &= (~COM_ALIGN);
954: }
955:
956: /* increase size of dummy bss section */
957:
958: symp->sment.n_value = sptr->ishdr.s_size;
959: sptr->ishdr.s_size += symsize;
960: }
961: }
962: /* round up the section size to be a multiple of 4 bytes */
963: sptr->ishdr.s_size += 03L;
964: sptr->ishdr.s_size &= (~03L);
965: }
966: #endif
967:
968:
969:
970:
971: LDFILE *
972: #if AR16WR
973: myldopen(filename,arhdr,ldptr,fbuf)
974: #else
975: myldopen(filename,arhdr,ldptr)
976: #endif
977: char *filename;
978: ARCHDR *arhdr;
979: LDFILE *ldptr;
980: #if AR16WR
981: char *fbuf;
982: #endif
983: {
984:
985: /*
986: * Open the file. If it is an arch file, read in the arch header
987: * and file header. Otherwise just read in the file header.
988: */
989:
990: #if PORTAR || PORT5AR
991: unsigned short type;
992: char atype[SARMAG];
993: #else
994: unsigned short type,
995: atype;
996: #endif
997: int count;
998:
999: if ((IOPTR(ldptr)=fopen(filename, "r")) == NULL)
1000: return(NULL);
1001:
1002: #if AR16WR
1003: setbuf( IOPTR(ldptr), fbuf );
1004: #endif
1005:
1006: #if PORTAR || PORT5AR
1007: if (FREAD(atype,SARMAG,1,ldptr) != 1)
1008: atype[0] = '\0';
1009: OFFSET(ldptr) = 0L;
1010: FSEEK(ldptr,0L,0);
1011: #endif
1012:
1013: if (FREAD(&type, sizeof(type), 1, ldptr) != 1) {
1014: fclose(IOPTR(ldptr));
1015: return(NULL);
1016: }
1017: count = sizeof(type);
1018:
1019: #if PORT5AR || PORTAR
1020: if (strncmp(atype,ARMAG,SARMAG) == 0) {
1021: TYPE(ldptr) = USH_ARTYPE;
1022: OFFSET(ldptr) = 0L;
1023: FSEEK(ldptr,0L,0);
1024: #else
1025: if ( sizeof(ARTYPE) != sizeof(type) ) {
1026: if ( FREAD(&atype, sizeof(atype), 1, ldptr) != 1)
1027: atype = type;
1028: else
1029: count += sizeof(atype);
1030: } else {
1031: atype = type;
1032: }
1033:
1034: if ( (atype == USH_ARTYPE) ||
1035: (type == USH_ARTYPE) ) {
1036: TYPE(ldptr) = USH_ARTYPE;
1037: OFFSET(ldptr) = ARCHSZ + sizeof(ARMAG);
1038: if (getrec1(arhdr,ldptr) == FAILURE)
1039: return(NULL);
1040: #endif
1041: } else {
1042: TYPE(ldptr) = type;
1043: OFFSET(ldptr) = 0L;
1044: HEADER(ldptr).f_magic = type;
1045: #if !PORTAR && !PORT5AR
1046: if (count > sizeof(type))
1047: HEADER(ldptr).f_nscns = atype;
1048: #endif
1049: if ( FREAD( (char *) (&(HEADER(ldptr)))+count,FILHSZ-count,1,ldptr ) != 1)
1050: return(NULL);
1051: }
1052:
1053: return(ldptr);
1054: }
1055: #if !PORTAR && !PORT5AR
1056: /*eject*/
1057: myldclose(arhdr,fdes)
1058: ARCHDR *arhdr;
1059: LDFILE *fdes;
1060: {
1061: OFFSET(fdes) += arhdr->ar_size + ARCHSZ;
1062:
1063: if (arhdr->ar_size & 01) {
1064: OFFSET(fdes) += 1;
1065: if (fseek(IOPTR(fdes),1L,1) != 0) {
1066: fclose(IOPTR(fdes));
1067: return(SUCCESS);
1068: }
1069: }
1070:
1071: if (getrec1(arhdr,fdes) == SUCCESS)
1072: return(FAILURE);
1073:
1074: fclose(IOPTR(fdes));
1075: return(SUCCESS);
1076: }
1077: /*eject*/
1078: getrec1(arhdr,fdes)
1079: ARCHDR *arhdr;
1080: LDFILE *fdes;
1081: {
1082:
1083: /*
1084: * if the file is an arch file, read in arch header and file
1085: * header. Otherwise just read in file header.
1086: */
1087:
1088: if (TYPE(fdes) == USH_ARTYPE)
1089: if (FREAD(arhdr,ARCHSZ,1,fdes) != 1)
1090: return(FAILURE);
1091:
1092: if (FREAD(&(HEADER(fdes)),FILHSZ,1,fdes) != 1)
1093: return(FAILURE);
1094:
1095: return(SUCCESS);
1096: }
1097: #endif
1098: /*eject*/
1099: getrec2(shdrbuf,fdes,start_scnh)
1100: SCNHDR *shdrbuf;
1101: LDFILE *fdes;
1102: int start_scnh;
1103: {
1104:
1105: /*
1106: * read in section headers and store them in the buffer
1107: */
1108:
1109: int i, lim;
1110:
1111: if (start_scnh != 1 || HEADER(fdes).f_opthdr > 0)
1112: if (FSEEK(fdes,(long) (FILHSZ+HEADER(fdes).f_opthdr+(SCNHSZ*(start_scnh-1))),BEGINNING) != OKFSEEK)
1113: return(FAILURE);
1114:
1115: lim = HEADER(fdes).f_nscns - start_scnh + 1;
1116: if (lim > MAXSCNBS) lim = MAXSCNBS;
1117: for (i = 0; i < lim; i++) {
1118: if (FREAD(shdrbuf++,SCNHSZ,1,fdes) != 1)
1119: return(FAILURE);
1120: }
1121:
1122:
1123: return(lim);
1124: }
1125: #if !PORT5AR && !PORTAR
1126: /*eject*/
1127: getrec3(symbuf,fdes)
1128: SYMENT *symbuf;
1129: LDFILE *fdes;
1130: {
1131:
1132: /*
1133: * read in the symbol table and store it in the buffer.
1134: */
1135:
1136: int i, lim;
1137:
1138: if (FSEEK(fdes,HEADER(fdes).f_symptr,BEGINNING) != OKFSEEK)
1139: return(FAILURE);
1140:
1141: lim = (HEADER(fdes).f_nsyms < MAXSYMBS ? HEADER(fdes).f_nsyms : MAXSYMBS);
1142: for (i = 0; i < lim; i++) {
1143: if (FREAD(symbuf++,SYMESZ,1,fdes) != 1)
1144: return(FAILURE);
1145: }
1146:
1147: return(SUCCESS);
1148: }
1149: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.