4 * (C) Copyright 1989-1995
19 * The module lksym.c contains the functions that operate
20 * on the symbol structures.
22 * lksym.c contains the following functions:
33 * lksym.c contains no local/static variables.
36 /*)Function VOID syminit()
38 * The function syminit() is called to clear the hashtable.
41 * int h computed hash value
42 * sym ** spp pointer to an array of
43 * sym structure pointers
46 * sym * symhash[] array of pointers to NHASH
53 * (1) The symbol hash tables are cleared
62 while (spp < &symhash[NHASH])
66 /*)Function sym * newsym()
68 * The function newsym() is called to evaluate the symbol
69 * definition/reference directive from the .rel file(s).
70 * If the symbol is not found in the symbol table a new
71 * symbol structure is created. Evaluation of the
72 * directive determines if this is a reference or a definition.
73 * Multiple definitions of the same variable will be flagged
74 * as an error if the values are not identical. A symbol
75 * definition places the symbol value and area extension
76 * into the symbols data structure. And finally, a pointer
77 * to the symbol structure is placed into the head structure
78 * symbol list. Refer to the description of the header, symbol,
79 * area, and areax structures in lkdata.c for structure and
83 * int c character from input text
84 * int i evaluation value
85 * char id[] symbol name
86 * int nglob number of symbols in this header
87 * sym * tsp pointer to symbol structure
88 * sym ** s list of pointers to symbol structures
91 * areax *axp Pointer to the current
93 * head *headp The pointer to the first
94 * head structure of a linked list
95 * int lkerr error flag
98 * Addr_T eval() lkeval.c
99 * VOID exit() c_library
100 * int fprintf() c_library
102 * char getnb() lklex.c
103 * sym * lkpsym() lksym.c
106 * A symbol structure is created and/or modified.
107 * If structure space allocation fails linker will abort.
108 * Several severe errors (these are internal errors
109 * indicating a corrupted .rel file or corrupted
110 * assembler or linker) will terminated the linker.
114 * Find/Create a global symbol entry.
119 * | `----- sp->s_type
120 * `------------ sp->s_id
126 register unsigned i ;
127 register unsigned nglob ;
135 c = getnb();get();get();
137 tsp->s_type |= S_REF;
139 fprintf(stderr, "Non zero S_REF\n");
145 if (tsp->s_type & S_DEF && tsp->s_addr != i) {
147 fprintf(stderr, "Multiple definition of %s\n", id);
149 fprintf(stderr, "Multiple definition of %.8s\n", id);
153 tsp->s_type |= S_DEF;
155 * Set value and area extension link.
160 fprintf(stderr, "Invalid symbol type %c for %.8s\n", c, id);
164 * Place pointer in header symbol list
167 fprintf(stderr, "No header defined\n");
172 for (i=0; i < nglob ;++i) {
178 fprintf(stderr, "Header symbol list overflow\n");
185 /*)Function sym * lkpsym(id,f)
187 * char * id symbol name string
188 * int f f == 0, lookup only
189 * f != 0, create if not found
191 * The function lookup() searches the symbol hash tables for
192 * a symbol name match returning a pointer to the sym structure.
193 * If the symbol is not found then a sym structure is created,
194 * initialized, and linked to the appropriate hash table if f != 0.
195 * A pointer to this new sym structure is returned or a NULL
196 * pointer is returned if f == 0.
199 * int h computed hash value
200 * sym * sp pointer to a sym structure
203 * sym * symhash[] array of pointers to NHASH
204 * linked symbol lists
208 * VOID * new() lksym.c
209 * int symeq() lksym.c
212 * If the function new() fails to allocate space
213 * for the new sym structure the linker terminates.
220 register struct sym *sp;
226 if (symeq(id, sp->s_id))
232 sp = (struct sym *) new (sizeof(struct sym));
233 sp->s_sp = symhash[h];
235 strncpy(sp->s_id, id, NCPS);
239 /*)Function Addr_T symval(tsp)
241 * sym * tsp pointer to a symbol structure
243 * The function symval() returns the value of the
244 * relocated symbol by adding the variable definition
245 * value to the areax base address.
248 * Addr_T val relocated address value
262 register struct sym *tsp;
268 val += tsp->s_axp->a_addr;
273 /*)Function VOID symdef(fp)
275 * FILE * fp file handle for output
277 * The function symdef() scans the hashed symbol table
278 * searching for variables referenced but not defined.
279 * Undefined variables are linked to the default
280 * area "_CODE" and reported as referenced by the
281 * appropriate module.
284 * int i hash table index loop variable
285 * sym * sp pointer to linked symbol structure
288 * area *areap The pointer to the first
289 * area structure of a linked list
290 * sym *symhash[NHASH] array of pointers to NHASH
291 * linked symbol lists
297 * Undefined variables have their areas set to "_CODE".
304 register struct sym *sp;
307 for (i=0; i<NHASH; ++i) {
310 if (sp->s_axp == NULL)
311 sp->s_axp = areap->a_axp;
312 if ((sp->s_type & S_DEF) == 0)
319 /*)Function VOID symmod(fp,tsp)
321 * FILE * fp output file handle
322 * sym * tsp pointer to a symbol structure
324 * The function symmod() scans the header structures
325 * searching for a reference to the symbol structure
326 * pointer to by tsp. The function then generates an error
327 * message whichs names the module having referenced the
328 * undefined variable.
332 * sym ** p pointer to a list of pointers
333 * to symbol structures
336 * head *headp The pointer to the first
337 * head structure of a linked list
338 * head *hp Pointer to the current
340 * int lkerr error flag
343 * int fprintf() c_library
346 * Error output generated.
357 if ((hp = headp) != NULL) {
360 for (i=0; i<hp->h_nglob; ++i) {
362 fprintf(fp, "\n?ASlink-Warning-Undefined Global %s ", tsp->s_id);
363 fprintf(fp, "referenced by module %s\n", hp->m_id);
372 /*)Function int symeq(p1, p2)
374 * char * p1 name string
375 * char * p2 name string
377 * The function symeq() compares the two name strings for a match.
378 * The return value is 1 for a match and 0 for no match.
384 * char ccase[] an array of characters which
385 * perform the case translation function
397 register char *p1, *p2;
408 if (ccase[(unsigned char)(*p1++)] != ccase[(unsigned char)(*p2++)])
416 /*)Function int hash(p)
418 * char * p pointer to string to hash
420 * The function hash() computes a hash code using the sum
421 * of all characters mod table size algorithm.
424 * int h accumulated character sum
428 * char ccase[] an array of characters which
429 * perform the case translation function
452 h += ccase[(unsigned char)(*p++)];
459 /*)Function VOID * new(n)
461 * unsigned int n allocation size in bytes
463 * The function new() allocates n bytes of space and returns
464 * a pointer to this memory. If no space is available the
465 * linker is terminated.
468 * char * p a general pointer
469 * char * q a general pointer
475 * int fprintf() c_library
476 * VOID * malloc() c_library
479 * Memory is allocated, if allocation fails
480 * the linker is terminated.
488 register unsigned int i;
490 if ((p = (char *) malloc(n)) == NULL) {
491 fprintf(stderr, "Out of space!\n");
494 for (i=0,q=p; i<n; i++) {