|
|
1.1 root 1: /*
2: * static char addr1_ID[] = "@(#) addr1.c: 1.6 12/10/83";
3: */
4:
5: #include <stdio.h>
6: #include <filehdr.h>
7: #include <reloc.h>
8: #include <syms.h>
9: #include <linenum.h>
10: #include "systems.h"
11: #include "gendefs.h"
12: #include "symbols.h"
13: #include "codeout.h"
14:
15: /*
16: *
17: * "addr1.c" is a file containing routines for implementing the
18: * various addressing modes from the intermediate file. The
19: * majority of the routines are passed a pointer to a
20: * character string and a pointer to the code buffer.
21: * The array "modes" is initialized to contain the addresses
22: * of the functions that implement the various addressing modes.
23: * Indexing this array with the addressing mode will give the
24: * correct routine for implementing that mode.
25: *
26: */
27:
28: #define outblock(a,b,c) fwrite((char *)(a),b,1,c)
29:
30: extern char
31: cfile[];
32:
33: extern unsigned short
34: line,
35: cline;
36:
37: extern short
38: type,
39: transvec,
40: sttop;
41:
42: extern int
43: setsym();
44:
45: extern long
46: newdot,
47: symbent,
48: gsymbent;
49:
50: extern long
51: getindx();
52:
53: extern symbol
54: *dot;
55:
56: extern FILHDR
57: filhead;
58:
59: extern upsymins
60: *lookup();
61:
62: extern stent
63: *pop();
64: static stent
65: *popptr;
66:
67: extern FILE
68: #if !ONEPROC
69: *fdstring,
70: #endif
71: *fdline,
72: *fdsymb,
73: *fdgsymb;
74:
75: symbol *savsym;
76:
77: unsigned short
78: lineent;
79:
80: short filedef = NO;
81:
82: #if FLEXNAMES
83: extern char *strtab; /* String table; referenced for symbol */
84: /* name to pass to getindx. */
85: #endif
86:
87: SYMENT sment;
88:
89: AUXENT axent;
90:
91: static short
92: dimcnt;
93:
94: static LINENO
95: lnent;
96:
97: /*ARGSUSED*/
98:
99: setmagic(sym,code)
100: symbol *sym;
101: codebuf *code;
102: {
103: filhead.f_magic = (short)(code->cvalue);
104: }
105:
106: setfile(sym,code)
107: upsymins sym;
108: codebuf *code;
109: {
110: register char c;
111: register char *auxchar;
112: register short index = 0;
113:
114: filedef = YES;
115:
116: sym = *lookup(".file",INSTALL,USRNAME);
117: define(sym.stp,code);
118:
119: sment.n_numaux = 1;
120: auxchar = ((union auxent *)(&axent))->x_file.x_fname;
121: #if ONEPROC
122: while (*auxchar++ = cfile[index++]) ;
123: #else
124: while (((c = getc(fdstring)) != '\n') && (index < FILNMLEN)) {
125: *auxchar++ = c;
126: cfile[index++] = c;
127: }
128: #endif
129: for ( ; index < FILNMLEN; index++)
130: *auxchar++ = '\0';
131:
132: cfile[index] = '\0';
133: code->cvalue = (long)C_FILE;
134: setscl(NULLSYM,code);
135: endef(NULLSYM,code);
136: } /* setfile */
137:
138: /*ARGSUSED*/
139:
140: newstmt(sym,code)
141: symbol *sym;
142: codebuf *code;
143: {
144: line = (unsigned short)(code->cvalue);
145: dot->value = newdot; /* resynchronize */
146: } /* newstmt */
147:
148: /*
149: *
150: * "lineno" is a function that creates a line number entry with
151: * the value of the program counter. A preliminary line number
152: * entry is created by writing to the file whose descriptor
153: * appears in "fdline". The preliminary line number entry contains
154: * the value of the program counter and the line number itself.
155: *
156: */
157:
158: lineno(sym,code)
159: register symbol *sym;
160: register codebuf *code;
161: {
162: if (sym != NULLSYM)
163: code->cvalue += sym->value;
164: lnent.l_lnno = cline = (unsigned short)(code->cvalue);
165: lnent.l_addr.l_paddr = newdot;
166: outblock(&lnent,LINESZ,fdline);
167: lineent++;
168: }
169:
170: /*
171: *
172: * "linenum" and "lineval" work in a pair to implement the two
173: * operand version of the ".ln" pseudo operation. This operation
174: * will generate two intermediate file entries. "linenum"
175: * evaluates the line number and stores it in the global
176: * variable "savline". "lineval" evaluates its argument to
177: * use it as the address for the line number. This address
178: * and the line number from "savline" are written to the file
179: * whose descriptor appears in "fdline" as a completed line
180: * number entry.
181: *
182: */
183:
184: linenum(sym,code)
185: register symbol *sym;
186: register codebuf *code;
187: {
188: if (sym != NULLSYM)
189: code->cvalue += sym->value;
190: lnent.l_lnno = cline = (unsigned short)(code->cvalue);
191: }
192:
193: lineval(sym,code)
194: register symbol *sym;
195: register codebuf *code;
196: {
197: if (sym != NULLSYM)
198: code->cvalue += sym->value;
199: lnent.l_addr.l_paddr = code->cvalue;
200: outblock(&lnent,LINESZ,fdline);
201: lineent++;
202: }
203:
204: /*
205: *
206: * The functions "define", "setval", "settyp", "setscl", "settag",
207: * "setlno", "setsiz", "setdim1" through "setdim5", "xform", and
208: * "endef" are all involved in creating the symbol table entries
209: * that appear in the object file. The call to "define" will
210: * initialize the symbol table entry. The calls to subsequent
211: * functions will store values into various fields of that entry.
212: * The call to "endef" will write out the completed symbol table
213: * entry to an intermediate file. The symbol table entry will be
214: * constructed in a structure called "sment". The auxiliary
215: * symbol table entry (if necessary) will be constructed in the
216: * structure "axent". The completed symbol table entry will be
217: * written either to the file whose descriptor appears in "fdsymb"
218: * or the file whose descriptor appears in "fdgsymb".
219: *
220: */
221:
222: /*
223: *
224: * "define" is a function that performs initialization of a symbol
225: * table entry to be written to the object file.
226: * The arguments to this function is a pointer to the symbol for
227: * which the entry is to be created. The symbol name is stored
228: * into the object file symbol table entry, and the remainder
229: * of the fields for the entry are set to zero.
230: *
231: */
232:
233: /*ARGSUSED*/
234:
235: define(sym,code)
236: register symbol *sym;
237: codebuf *code;
238: {
239: register short index;
240:
241: savsym = sym;
242: #if FLEXNAMES
243: /* Copy the internal symbol table entry for the name to the */
244: /* structure which will be written to the symbol table file. */
245:
246: if (sym->_name.tabentry.zeroes == 0)
247: {
248: sment.n_zeroes = 0L;
249: sment.n_offset = sym->_name.tabentry.offset;
250: }
251: else
252: {
253: #endif
254: for(index = 0; (index < SYMNMLEN) && (sment.n_name[index] = sym->_name.name[index]); index++)
255: ;
256:
257: for(; index < SYMNMLEN; index++)
258: sment.n_name[index] = '\0';
259: #if FLEXNAMES
260: }
261: #endif
262: sment.n_value = 0L;
263: sment.n_scnum = 0;
264: sment.n_type = 0;
265: sment.n_sclass = 0;
266: sment.n_numaux = 0;
267: axent.x_sym.x_tagndx = 0L;
268: axent.x_sym.x_misc.x_lnsz.x_lnno = 0;
269: axent.x_sym.x_misc.x_lnsz.x_size = 0;
270: for(index = 0; index < DIMNUM; ++index)
271: axent.x_sym.x_fcnary.x_ary.x_dimen[index] = 0;
272: axent.x_sym.x_tvndx = 0;
273: #if TRANVEC
274: if (transvec && (sym->styp & TVDEF)) {
275: sment.n_numaux = 1; /* we can do this since transfer */
276: axent.x_sym.x_tvndx = N_TV; /* vectors are always */
277: /* functions in .def's */
278: }
279: #endif
280: }
281:
282: /*
283: *
284: * "setval" is a function that sets the value field of a symbol
285: * table entry. The arguments are evaluated and the result is
286: * stored into the value field of the symbol table entry, and
287: * the section number is set according to the type of the result.
288: *
289: */
290:
291: setval(sym,code)
292: register symbol *sym;
293: register codebuf *code;
294: {
295: register short stype;
296:
297: if (sym != NULLSYM) {
298: code->cvalue += sym->value;
299: stype = sym->styp & TYPE;
300: }
301: else
302: stype = ABS;
303: sment.n_value = code->cvalue;
304: switch (stype){
305: case ABS:{
306: sment.n_scnum = N_ABS;
307: break;
308: }
309: case TXT:{
310: sment.n_scnum = 1;
311: break;
312: }
313: case DAT:{
314: sment.n_scnum = 2;
315: break;
316: }
317: case BSS:{
318: sment.n_scnum = 3;
319: break;
320: }
321: }
322: }
323:
324: /*
325: *
326: * "settyp" is a function that sets the type and derived type
327: * field in a symbol table entry. The arguments are evaluated to
328: * yield the numeric value to be stored into the type and derived
329: * type word. This value is stored into the appropriate field
330: * of "sment".
331: *
332: */
333:
334: settyp(sym,code)
335: register symbol *sym;
336: register codebuf *code;
337: {
338: if (sym != NULLSYM)
339: code->cvalue += sym->value;
340: sment.n_type = (short)(code->cvalue);
341: }
342:
343: /*
344: *
345: * "setscl" is a function that sets the storage class field in a
346: * symbol table entry. The arguments are evaluated to yield a
347: * value to be stored into the appropriate field of "sment".
348: *
349: */
350:
351: setscl(sym,code)
352: register symbol *sym;
353: register codebuf *code;
354: {
355: if (sym != NULLSYM)
356: code->cvalue += sym->value;
357: sment.n_sclass = (char)(code->cvalue);
358: }
359:
360: /*
361: *
362: * "settag" is a function that sets the tag field in an auxiliary
363: * symbol table entry. The argument to this function is the
364: * name of a structure, union, or enumeration tag. This name
365: * is passed to "getindx" to obtain the symbol table index of
366: * the tag entry. If it is found, a field in the symbol table
367: * entry is set indicating the presence of an auxiliary entry
368: * and the tag field of the auxiliary entry is set to the index.
369: * If the tag was not found, "yyerror" is called to print a
370: * diagnostic message.
371: *
372: */
373:
374: /*ARGSUSED*/
375:
376: settag(sym,code)
377: register symbol *sym;
378: codebuf *code;
379: {
380: register long index;
381: char *nameptr; /* We need a pointer to the name string */
382: /* to pass to getindx. */
383:
384: #if FLEXNAMES
385: if (sym->_name.tabentry.zeroes == 0)
386: nameptr = &strtab[sym->_name.tabentry.offset];
387: else
388: #endif
389: nameptr = sym->_name.name;
390: if ( ((index = getindx(nameptr,C_STRTAG)) < 0) &&
391: ((index = getindx(nameptr,C_UNTAG)) < 0) &&
392: ((index = getindx(nameptr,C_ENTAG)) < 0))
393: yyerror("Illegal structure, union, or enumeration tag");
394: sment.n_numaux = 1;
395: axent.x_sym.x_tagndx = index;
396: }
397:
398: /*
399: *
400: * "setlno" sets the line number field in an auxiliary symbol
401: * table entry. A field is set in the symbol table entry to
402: * indicate the presence of an auxiliary entry. The arguments
403: * are evaluated to obtain the value of the line number and
404: * this value is stored into the appropriate field of the
405: * auxiliary symbol table entry.
406: *
407: *
408: */
409:
410: setlno(sym,code)
411: register symbol *sym;
412: register codebuf *code;
413: {
414: sment.n_numaux = 1;
415: if (sym != NULLSYM)
416: code->cvalue += sym->value;
417: axent.x_sym.x_misc.x_lnsz.x_lnno = (unsigned short)(code->cvalue);
418: }
419:
420: /*
421: *
422: * "setsiz" sets the size field in an auxiliary symbol table entry.
423: * The arguments are evaluated to obtain the size of the object
424: * described by this symbol table entry. This value is stored into
425: * the appropriate field of the auxiliary symbol table entry and
426: * a field is set in the basic symbol table entry to indicate the
427: * presence of the auxiliary entry.
428: *
429: */
430:
431: setsiz(sym,code)
432: register symbol *sym;
433: register codebuf *code;
434: {
435: sment.n_numaux = 1;
436: if (sym != NULLSYM)
437: code->cvalue += sym->value;
438: axent.x_sym.x_misc.x_lnsz.x_size = (unsigned short)(code->cvalue);
439: }
440:
441: /* indicate that the function was expanded inline */
442: inline(sym,codeptr)
443: symbol *sym;
444: codebuf *codeptr;
445: {
446: axent.x_sym.x_misc.x_lnsz.x_size |= 0x1;
447: }
448:
449: /*
450: *
451: * "setdim1" and "setdim2" set the fields for array dimensions
452: * one through four in an auxiliary symbol table entry. The
453: * arguments to each function are evaluated to obtain the values
454: * for the array dimensions. The function "setdim1" set a field
455: * in the basic symbol table entry to indicate the presence of
456: * an auxiliary entry. The array dimensions are stored into the
457: * appropriate fields of the auxiliary symbol table entry.
458: *
459: */
460:
461: setdim1(sym,code)
462: register symbol *sym;
463: register codebuf *code;
464: {
465: sment.n_numaux = 1;
466: if (sym != NULLSYM)
467: code->cvalue += sym->value;
468: axent.x_sym.x_fcnary.x_ary.x_dimen[dimcnt=0] = (unsigned short)(code->cvalue);
469: }
470:
471: setdim2(sym,code)
472: register symbol *sym;
473: register codebuf *code;
474: {
475: if (sym != NULLSYM)
476: code->cvalue += sym->value;
477: if (++dimcnt < DIMNUM)
478: axent.x_sym.x_fcnary.x_ary.x_dimen[dimcnt] = (unsigned short)(code->cvalue);
479: else
480: werror("Too many array dimensions for symbolic debug");
481: }
482:
483: /*
484: * "dfaxent" defines an auxillary entry into the symbol table for
485: * the ".text." , ".data" , and ".bss" symbols. It is called from
486: * "symout" in file "obj.c". These auxillary entries allow the
487: * link editor to know the size of each of these sections in the
488: * original source code.
489: *
490: */
491:
492: dfaxent(size,nrel,nlin)
493: long size;
494: unsigned short nrel,
495: nlin;
496: {
497: sment.n_numaux = 1;
498: axent.x_scn.x_scnlen = size;
499: axent.x_scn.x_nreloc = nrel;
500: axent.x_scn.x_nlinno = nlin;
501: }
502:
503: /*
504: *
505: * "xform" is a function called by "endef" that performs any final
506: * transformations necessary on a symbol table entry before it is
507: * written out to a temporary file. The present transformations
508: * are as follows:
509: *
510: * 1. The section number for structure tags, union tags,
511: * enumeration tags, typedefs, and file names is set to
512: * indicate a special symbolic debugging symbol.
513: *
514: * 2. If the symbol table entry is for a function, a zero
515: * line number entry is generated that points to the symbol
516: * table entry. The index of the next entry to be
517: * generated appears in the global variable "symbent".
518: *
519: * 3. If the symbol table entry is for a function, a enu-
520: * meration tag, a union tag, or a structure tag
521: * "setsym" is called to remember the symbol table index
522: * for the associated auxiliary entry.
523: *
524: * 4. If the symbol table entry is for a end block, a
525: * end function, or a end of structure, pop is called
526: * to enter the symbol table index of the next symbol
527: * table entry onto the symbol table element stack.
528: *
529: */
530:
531: xform()
532: {
533:
534: switch (sment.n_sclass) {
535: case C_STRTAG:
536: case C_UNTAG:
537: case C_ENTAG:
538: setsym(-1);
539: /* No Break */
540: case C_TPDEF:
541: case C_FILE:
542: sment.n_scnum = N_DEBUG;
543: break;
544: case C_BLOCK: /* handles ".bb" and ".eb" */
545: if (sment.n_name[1] == 'b')
546: setsym(-1);
547: else
548: pop()->fwdindex = symbent + 1L
549: + sment.n_numaux;
550: break;
551: case C_FCN: /* handles ".bf" and ".ef" */
552: if (sment.n_name[1] == 'e') {
553: popptr = pop();
554: popptr->fwdindex = symbent + 1L
555: + sment.n_numaux;
556: if (sttop > 0)
557: aerror("Unbalanced Symbol Table Entries-Too Many Scope Beginnings");
558: } /* ".ef" */
559: break;
560: case C_EOS:
561: /* get around auxiliary entry */
562: pop()->fwdindex = symbent + 1L + sment.n_numaux;
563: break;
564: default:
565: /* process function entry */
566: if (ISFCN(sment.n_type)) {
567: popptr = NULL;
568: lnent.l_lnno = 0;
569: lnent.l_addr.l_symndx = symbent;
570: outblock(&lnent,LINESZ,fdline);
571: lineent++;
572: sment.n_numaux = 1;
573: setsym(0);
574: }
575: break;
576: } /* switch */
577: } /* xform */
578:
579: /*
580: *
581: * "endef" is a function that completes processing of a symbol
582: * table entry and writes it out to an intermediate file
583: * The arguments to this function are absolutely meaningless.
584: * The function "xform" is called to perform any final
585: * transformations necessary on the entry. A decision is made
586: * as to whether or not the symbol is a global symbol. It is
587: * global if the ".def" for it appears in the data section and
588: * it has a storage class of "C_EXT". If it is global, the
589: * entry will be written to the file whose descriptor appears
590: * in "fdgsymb" and the count "gsymbent" will be incremented.
591: * If it is not global, the entry will be written to the file
592: * whose descriptor appears in "fdsymb" and the count "symbent"
593: * will be incremented.
594: *
595: */
596:
597: /*ARGSUSED*/
598:
599: endef(sym,code)
600: symbol *sym;
601: codebuf *code;
602: {
603: FILE *fd;
604: register long *count;
605:
606: if (sment.n_sclass == (char) C_EFCN) {
607: if (popptr == NULL) {
608: popptr = pop();
609: popptr->fwdindex = symbent;
610: if (sttop > 0)
611: aerror("Unbalanced Symbol Table Entries-Too Many Scope Beginnings");
612: } /* popptr == NULL */
613: popptr->fcnlen = newdot - savsym->value;
614: /* don't put out this symbol table entry */
615: return;
616: } /* sment.n_sclass == C_EFCN */
617: xform();
618: if ((dot->styp == DAT) && (sment.n_sclass == C_EXT)) {
619: fd = fdgsymb;
620: count = &gsymbent;
621: }
622: else
623: {
624: fd = fdsymb;
625: count = &symbent;
626: putindx(savsym,sment.n_sclass,symbent);
627: }
628: outblock(&sment,SYMESZ,fd);
629: (*count)++;
630: if (sment.n_numaux != 0){
631: outblock(&axent,AUXESZ,fd);
632: (*count)++;
633: }
634: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.