3 Copyright (C) 1989-1995 Alan R. Baldwin
4 721 Berkeley St., Kent, Ohio 44240
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 * - lkpsym: Use StoreString for sym construction
22 * - change symeq() to do length-independent string compare
23 * - change hash() to do length-independent hash calculation
33 * The module lksym.c contains the functions that operate
34 * on the symbol structures.
36 * lksym.c contains the following functions:
47 * lksym.c contains no local/static variables.
50 /*)Function VOID syminit()
52 * The function syminit() is called to clear the hashtable.
55 * int h computed hash value
56 * sym ** spp pointer to an array of
57 * sym structure pointers
60 * sym * symhash[] array of pointers to NHASH
67 * (1) The symbol hash tables are cleared
76 while (spp < &symhash[NHASH])
80 /*)Function sym * newsym()
82 * The function newsym() is called to evaluate the symbol
83 * definition/reference directive from the .rel file(s).
84 * If the symbol is not found in the symbol table a new
85 * symbol structure is created. Evaluation of the
86 * directive determines if this is a reference or a definition.
87 * Multiple definitions of the same variable will be flagged
88 * as an error if the values are not identical. A symbol
89 * definition places the symbol value and area extension
90 * into the symbols data structure. And finally, a pointer
91 * to the symbol structure is placed into the head structure
92 * symbol list. Refer to the description of the header, symbol,
93 * area, and areax structures in lkdata.c for structure and
97 * int c character from input text
98 * int i evaluation value
99 * char id[] symbol name
100 * int nglob number of symbols in this header
101 * sym * tsp pointer to symbol structure
102 * sym ** s list of pointers to symbol structures
105 * areax *axp Pointer to the current
107 * head *headp The pointer to the first
108 * head structure of a linked list
109 * int lkerr error flag
112 * Addr_T eval() lkeval.c
113 * VOID exit() c_library
114 * int fprintf() c_library
115 * char getSid() lklex.c
117 * char getnb() lklex.c
118 * sym * lkpsym() lksym.c
121 * A symbol structure is created and/or modified.
122 * If structure space allocation fails linker will abort.
123 * Several severe errors (these are internal errors
124 * indicating a corrupted .rel file or corrupted
125 * assembler or linker) will terminated the linker.
129 * Find/Create a global symbol entry.
134 * | `----- sp->s_type
135 * `------------ sp->s_id
141 register unsigned i ;
142 register unsigned nglob ;
148 getSid(id); // old: getid(id, -1);
150 c = getnb();get();get();
152 tsp->s_type |= S_REF;
154 fprintf(stderr, "Non zero S_REF\n");
160 if (tsp->s_type & S_DEF && tsp->s_addr != i) {
161 fprintf(stderr, "Multiple definition of %s\n", id);
164 tsp->s_type |= S_DEF;
166 * Set value and area extension link.
171 fprintf(stderr, "Invalid symbol type %c for %s\n", c, id);
175 * Place pointer in header symbol list
178 fprintf(stderr, "No header defined\n");
183 for (i=0; i < nglob ;++i) {
189 fprintf(stderr, "Header symbol list overflow\n");
196 /*)Function sym * lkpsym(id,f)
198 * char * id symbol name string
199 * int f f == 0, lookup only
200 * f != 0, create if not found
202 * The function lookup() searches the symbol hash tables for
203 * a symbol name match returning a pointer to the sym structure.
204 * If the symbol is not found then a sym structure is created,
205 * initialized, and linked to the appropriate hash table if f != 0.
206 * A pointer to this new sym structure is returned or a NULL
207 * pointer is returned if f == 0.
210 * int h computed hash value
211 * sym * sp pointer to a sym structure
214 * sym * symhash[] array of pointers to NHASH
215 * linked symbol lists
219 * VOID * new() lksym.c
220 * int symeq() lksym.c
223 * If the function new() fails to allocate space
224 * for the new sym structure the linker terminates.
228 lkpsym(char *id, int f)
230 register struct sym *sp;
236 if (symeq(id, sp->s_id))
242 sp = (struct sym *) new (sizeof(struct sym));
243 sp->s_sp = symhash[h];
245 sp->s_id = StoreString( id ); /* JLH */
249 /*)Function Addr_T symval(tsp)
251 * sym * tsp pointer to a symbol structure
253 * The function symval() returns the value of the
254 * relocated symbol by adding the variable definition
255 * value to the areax base address.
258 * Addr_T val relocated address value
271 symval(register struct sym *tsp)
277 val += tsp->s_axp->a_addr;
282 /*)Function VOID symdef(fp)
284 * FILE * fp file handle for output
286 * The function symdef() scans the hashed symbol table
287 * searching for variables referenced but not defined.
288 * Undefined variables are linked to the default
289 * area "_CODE" and reported as referenced by the
290 * appropriate module.
293 * int i hash table index loop variable
294 * sym * sp pointer to linked symbol structure
297 * area *areap The pointer to the first
298 * area structure of a linked list
299 * sym *symhash[NHASH] array of pointers to NHASH
300 * linked symbol lists
306 * Undefined variables have their areas set to "_CODE".
312 register struct sym *sp;
315 for (i=0; i<NHASH; ++i) {
318 if (sp->s_axp == NULL)
319 sp->s_axp = areap->a_axp;
320 if ((sp->s_type & S_DEF) == 0)
327 /*)Function VOID symmod(fp,tsp)
329 * FILE * fp output file handle
330 * sym * tsp pointer to a symbol structure
332 * The function symmod() scans the header structures
333 * searching for a reference to the symbol structure
334 * pointer to by tsp. The function then generates an error
335 * message whichs names the module having referenced the
336 * undefined variable.
340 * sym ** p pointer to a list of pointers
341 * to symbol structures
344 * head *headp The pointer to the first
345 * head structure of a linked list
346 * head *hp Pointer to the current
348 * int lkerr error flag
351 * int fprintf() c_library
354 * Error output generated.
358 symmod(FILE *fp, struct sym *tsp)
363 if ((hp = headp) != NULL) {
366 for (i=0; i<hp->h_nglob; ++i) {
368 fprintf(fp, "\n?ASlink-Warning-Undefined Global '%s' ", tsp->s_id);
369 fprintf(fp, "referenced by module '%s'\n", hp->m_id);
378 /*)Function int symeq(p1, p2)
380 * char * p1 name string
381 * char * p2 name string
383 * The function symeq() compares the two name strings for a match.
384 * The return value is 1 for a match and 0 for no match.
390 * char ccase[] an array of characters which
391 * perform the case translation function
402 symeq(register char *p1, register char *p2)
405 return (strncmp( p1, p2, NCPS ) == 0);
407 return (as_strncmpi( p1, p2, NCPS ) == 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
435 hash(register char *p)
446 h += ccase[(unsigned char)(*p++)];
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.
482 if ((p = (char *) calloc(n, 1)) == NULL) {
483 fprintf(stderr, "Out of space!\n");