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
111 * char getSid() lklex.c
113 * char getnb() lklex.c
114 * sym * lkpsym() lksym.c
117 * A symbol structure is created and/or modified.
118 * If structure space allocation fails linker will abort.
119 * Several severe errors (these are internal errors
120 * indicating a corrupted .rel file or corrupted
121 * assembler or linker) will terminated the linker.
125 * Find/Create a global symbol entry.
130 * | `----- sp->s_type
131 * `------------ sp->s_id
137 register unsigned i ;
138 register unsigned nglob ;
144 getSid(id); // old: getid(id, -1);
146 c = getnb();get();get();
148 tsp->s_type |= S_REF;
150 fprintf(stderr, "Non zero S_REF\n");
156 if (tsp->s_type & S_DEF && tsp->s_addr != i) {
157 fprintf(stderr, "Multiple definition of %8s\n", id);
160 tsp->s_type |= S_DEF;
162 * Set value and area extension link.
167 fprintf(stderr, "Invalid symbol type %c for %8s\n", c, id);
171 * Place pointer in header symbol list
174 fprintf(stderr, "No header defined\n");
179 for (i=0; i < nglob ;++i) {
185 fprintf(stderr, "Header symbol list overflow\n");
190 /*)Function sym * lkpsym(id,f)
192 * char * id symbol name string
193 * int f f == 0, lookup only
194 * f != 0, create if not found
196 * The function lookup() searches the symbol hash tables for
197 * a symbol name match returning a pointer to the sym structure.
198 * If the symbol is not found then a sym structure is created,
199 * initialized, and linked to the appropriate hash table if f != 0.
200 * A pointer to this new sym structure is returned or a NULL
201 * pointer is returned if f == 0.
204 * int h computed hash value
205 * sym * sp pointer to a sym structure
208 * sym * symhash[] array of pointers to NHASH
209 * linked symbol lists
213 * VOID * new() lksym.c
214 * int symeq() lksym.c
217 * If the function new() fails to allocate space
218 * for the new sym structure the linker terminates.
225 register struct sym *sp;
231 if (symeq(id, sp->s_id))
237 sp = (struct sym *) new (sizeof(struct sym));
238 sp->s_sp = symhash[h];
240 sp->s_id = StoreString( id ); /* JLH */
244 /*)Function Addr_T symval(tsp)
246 * sym * tsp pointer to a symbol structure
248 * The function symval() returns the value of the
249 * relocated symbol by adding the variable definition
250 * value to the areax base address.
253 * Addr_T val relocated address value
267 register struct sym *tsp;
273 val += tsp->s_axp->a_addr;
278 /*)Function VOID symdef(fp)
280 * FILE * fp file handle for output
282 * The function symdef() scans the hashed symbol table
283 * searching for variables referenced but not defined.
284 * Undefined variables are linked to the default
285 * area "_CODE" and reported as referenced by the
286 * appropriate module.
289 * int i hash table index loop variable
290 * sym * sp pointer to linked symbol structure
293 * area *areap The pointer to the first
294 * area structure of a linked list
295 * sym *symhash[NHASH] array of pointers to NHASH
296 * linked symbol lists
302 * Undefined variables have their areas set to "_CODE".
309 register struct sym *sp;
312 for (i=0; i<NHASH; ++i) {
315 if (sp->s_axp == NULL)
316 sp->s_axp = areap->a_axp;
317 if ((sp->s_type & S_DEF) == 0)
324 /*)Function VOID symmod(fp,tsp)
326 * FILE * fp output file handle
327 * sym * tsp pointer to a symbol structure
329 * The function symmod() scans the header structures
330 * searching for a reference to the symbol structure
331 * pointer to by tsp. The function then generates an error
332 * message whichs names the module having referenced the
333 * undefined variable.
337 * sym ** p pointer to a list of pointers
338 * to symbol structures
341 * head *headp The pointer to the first
342 * head structure of a linked list
343 * head *hp Pointer to the current
345 * int lkerr error flag
348 * int fprintf() c_library
351 * Error output generated.
362 if ((hp = headp) != NULL) {
365 for (i=0; i<hp->h_nglob; ++i) {
367 fprintf(fp, "\n?ASlink-Warning-Undefined Global '%s' ", tsp->s_id);
368 fprintf(fp, "referenced by module '%s'\n", hp->m_id);
377 /*)Function int symeq(p1, p2)
379 * char * p1 name string
380 * char * p2 name string
382 * The function symeq() compares the two name strings for a match.
383 * The return value is 1 for a match and 0 for no match.
389 * char ccase[] an array of characters which
390 * perform the case translation function
402 register char *p1, *p2;
405 return (strcmp( p1, p2 ) == 0);
407 return (as_strcmpi( p1, p2 ) == 0);
411 /*)Function int hash(p)
413 * char * p pointer to string to hash
415 * The function hash() computes a hash code using the sum
416 * of all characters mod table size algorithm.
419 * int h accumulated character sum
423 * char ccase[] an array of characters which
424 * perform the case translation function
453 /*)Function VOID * new(n)
455 * unsigned int n allocation size in bytes
457 * The function new() allocates n bytes of space and returns
458 * a pointer to this memory. If no space is available the
459 * linker is terminated.
462 * char * p a general pointer
463 * char * q a general pointer
469 * int fprintf() c_library
470 * VOID * malloc() c_library
473 * Memory is allocated, if allocation fails
474 * the linker is terminated.
483 if ((p = (char *) calloc(n, 1)) == NULL) {
484 fprintf(stderr, "Out of space!\n");