4 * (C) Copyright 1989-1995
12 * - lkpsym: Use StoreString for sym construction
13 * - change symeq() to do length-independent string compare
14 * - change hash() to do length-independent hash calculation
28 * The module lksym.c contains the functions that operate
29 * on the symbol structures.
31 * lksym.c contains the following functions:
42 * lksym.c contains no local/static variables.
45 /*)Function VOID syminit()
47 * The function syminit() is called to clear the hashtable.
50 * int h computed hash value
51 * sym ** spp pointer to an array of
52 * sym structure pointers
55 * sym * symhash[] array of pointers to NHASH
62 * (1) The symbol hash tables are cleared
72 while (spp < &symhash[NHASH])
76 /*)Function sym * newsym()
78 * The function newsym() is called to evaluate the symbol
79 * definition/reference directive from the .rel file(s).
80 * If the symbol is not found in the symbol table a new
81 * symbol structure is created. Evaluation of the
82 * directive determines if this is a reference or a definition.
83 * Multiple definitions of the same variable will be flagged
84 * as an error if the values are not identical. A symbol
85 * definition places the symbol value and area extension
86 * into the symbols data structure. And finally, a pointer
87 * to the symbol structure is placed into the head structure
88 * symbol list. Refer to the description of the header, symbol,
89 * area, and areax structures in lkdata.c for structure and
93 * int c character from input text
94 * int i evaluation value
95 * char id[] symbol name
96 * int nglob number of symbols in this header
97 * sym * tsp pointer to symbol structure
98 * sym ** s list of pointers to symbol structures
101 * areax *axp Pointer to the current
103 * head *headp The pointer to the first
104 * head structure of a linked list
105 * int lkerr error flag
108 * Addr_T eval() lkeval.c
109 * VOID exit() c_library
110 * int fprintf() c_library
112 * char getnb() lklex.c
113 * sym * lkpsym() lksym.c
116 * A symbol structure is created and/or modified.
117 * If structure space allocation fails linker will abort.
118 * Several severe errors (these are internal errors
119 * indicating a corrupted .rel file or corrupted
120 * assembler or linker) will terminated the linker.
124 * Find/Create a global symbol entry.
129 * | `----- sp->s_type
130 * `------------ sp->s_id
136 register unsigned i ;
137 register unsigned nglob ;
145 c = getnb();get();get();
147 tsp->s_type |= S_REF;
149 fprintf(stderr, "Non zero S_REF\n");
155 if (tsp->s_type & S_DEF && tsp->s_addr != i) {
156 fprintf(stderr, "Multiple definition of %8s\n", id);
159 tsp->s_type |= S_DEF;
161 * Set value and area extension link.
166 fprintf(stderr, "Invalid symbol type %c for %8s\n", c, id);
170 * Place pointer in header symbol list
173 fprintf(stderr, "No header defined\n");
178 for (i=0; i < nglob ;++i) {
184 fprintf(stderr, "Header symbol list overflow\n");
189 /*)Function sym * lkpsym(id,f)
191 * char * id symbol name string
192 * int f f == 0, lookup only
193 * f != 0, create if not found
195 * The function lookup() searches the symbol hash tables for
196 * a symbol name match returning a pointer to the sym structure.
197 * If the symbol is not found then a sym structure is created,
198 * initialized, and linked to the appropriate hash table if f != 0.
199 * A pointer to this new sym structure is returned or a NULL
200 * pointer is returned if f == 0.
203 * int h computed hash value
204 * sym * sp pointer to a sym structure
207 * sym * symhash[] array of pointers to NHASH
208 * linked symbol lists
212 * VOID * new() lksym.c
213 * int symeq() lksym.c
216 * If the function new() fails to allocate space
217 * for the new sym structure the linker terminates.
224 register struct sym *sp;
230 if (symeq(id, sp->s_id))
236 sp = (struct sym *) new (sizeof(struct sym));
237 sp->s_sp = symhash[h];
239 sp->s_id = StoreString( id ); /* JLH */
243 /*)Function Addr_T symval(tsp)
245 * sym * tsp pointer to a symbol structure
247 * The function symval() returns the value of the
248 * relocated symbol by adding the variable definition
249 * value to the areax base address.
252 * Addr_T val relocated address value
266 register struct sym *tsp;
272 val += tsp->s_axp->a_addr;
277 /*)Function VOID symdef(fp)
279 * FILE * fp file handle for output
281 * The function symdef() scans the hashed symbol table
282 * searching for variables referenced but not defined.
283 * Undefined variables are linked to the default
284 * area "_CODE" and reported as referenced by the
285 * appropriate module.
288 * int i hash table index loop variable
289 * sym * sp pointer to linked symbol structure
292 * area *areap The pointer to the first
293 * area structure of a linked list
294 * sym *symhash[NHASH] array of pointers to NHASH
295 * linked symbol lists
301 * Undefined variables have their areas set to "_CODE".
308 register struct sym *sp;
311 for (i=0; i<NHASH; ++i) {
314 if (sp->s_axp == NULL)
315 sp->s_axp = areap->a_axp;
316 if ((sp->s_type & S_DEF) == 0)
323 /*)Function VOID symmod(fp,tsp)
325 * FILE * fp output file handle
326 * sym * tsp pointer to a symbol structure
328 * The function symmod() scans the header structures
329 * searching for a reference to the symbol structure
330 * pointer to by tsp. The function then generates an error
331 * message whichs names the module having referenced the
332 * undefined variable.
336 * sym ** p pointer to a list of pointers
337 * to symbol structures
340 * head *headp The pointer to the first
341 * head structure of a linked list
342 * head *hp Pointer to the current
344 * int lkerr error flag
347 * int fprintf() c_library
350 * Error output generated.
361 if ((hp = headp) != NULL) {
364 for (i=0; i<hp->h_nglob; ++i) {
366 fprintf(fp, "\n?ASlink-Warning-Undefined Global '%s' ", tsp->s_id);
367 fprintf(fp, "referenced by module '%s'\n", hp->m_id);
376 /*)Function int symeq(p1, p2)
378 * char * p1 name string
379 * char * p2 name string
381 * The function symeq() compares the two name strings for a match.
382 * The return value is 1 for a match and 0 for no match.
388 * char ccase[] an array of characters which
389 * perform the case translation function
401 register char *p1, *p2;
404 return (strcmp( p1, p2 ) == 0);
406 return (strcmpi( p1, p2 ) == 0);
410 /*)Function int hash(p)
412 * char * p pointer to string to hash
414 * The function hash() computes a hash code using the sum
415 * of all characters mod table size algorithm.
418 * int h accumulated character sum
422 * char ccase[] an array of characters which
423 * perform the case translation function
452 /*)Function VOID * new(n)
454 * unsigned int n allocation size in bytes
456 * The function new() allocates n bytes of space and returns
457 * a pointer to this memory. If no space is available the
458 * linker is terminated.
461 * char * p a general pointer
462 * char * q a general pointer
468 * int fprintf() c_library
469 * VOID * malloc() c_library
472 * Memory is allocated, if allocation fails
473 * the linker is terminated.
481 register unsigned int i;
483 if ((p = (char *) malloc(n)) == NULL) {
484 fprintf(stderr, "Out of space!\n");
487 for (i=0,q=p; i<n; i++) {