50c21f871f41db32a3d47ae2219bef83f841ff94
[fw/sdcc] / as / link / z80 / lksym.c
1 /* lksym.c */
2
3 /*
4  * (C) Copyright 1989-1995
5  * All Rights Reserved
6  *
7  * Alan R. Baldwin
8  * 721 Berkeley St.
9  * Kent, Ohio  44240
10  */
11
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include "aslink.h"
16
17 /*)Module       lksym.c
18  *
19  *      The module lksym.c contains the functions that operate
20  *      on the symbol structures.
21  *
22  *      lksym.c contains the following functions:
23  *              int     hash()
24  *              sym *   lkpsym()
25  *              VOID *  new()
26  *              sym *   newsym()
27  *              VOID    symdef()
28  *              int     symeq()
29  *              VOID    syminit()
30  *              VOID    symmod()
31  *              Addr_T  symval()
32  *
33  *      lksym.c contains no local/static variables.
34  */
35
36 /*)Function     VOID    syminit()
37  *
38  *      The function syminit() is called to clear the hashtable.
39  *
40  *      local variables:
41  *              int     h               computed hash value
42  *              sym **  spp             pointer to an array of
43  *                                      sym structure pointers
44  *
45  *      global variables:
46  *              sym * symhash[]         array of pointers to NHASH
47  *                                      linked symbol lists
48  *
49  *      functions called:
50  *              none
51  *
52  *      side effects:
53  *              (1)     The symbol hash tables are cleared
54  */
55
56 VOID
57 syminit()
58 {
59         struct sym **spp;
60
61         spp = &symhash[0];
62         while (spp < &symhash[NHASH])
63                 *spp++ = NULL;
64 }
65
66 /*)Function     sym *   newsym()
67  *
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
80  *      linkage details.
81  *
82  *      local variables:
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
89  *
90  *      global variables:
91  *              areax   *axp            Pointer to the current
92  *                                      areax structure
93  *              head    *headp          The pointer to the first
94  *                                      head structure of a linked list
95  *              int     lkerr           error flag
96  *
97  *      functions called:
98  *              Addr_T  eval()          lkeval.c
99  *              VOID    exit()          c_library
100  *              int     fprintf()       c_library
101  *              char    getSid()        lklex.c
102  *              char    get()           lklex.c
103  *              char    getnb()         lklex.c
104  *              sym *   lkpsym()        lksym.c
105  *
106  *      side effects:
107  *              A symbol structure is created and/or modified.
108  *              If structure space allocation fails linker will abort.
109  *              Several severe errors (these are internal errors
110  *              indicating a corrupted .rel file or corrupted
111  *              assembler or linker) will terminated the linker.
112  */
113
114 /*
115  * Find/Create a global symbol entry.
116  *
117  * S xxxxxx Defnnnn
118  *   |      |  |
119  *   |      |  `-- sp->s_addr
120  *   |      `----- sp->s_type
121  *   `------------ sp->s_id
122  *
123  */
124 struct sym *
125 newsym()
126 {
127     register unsigned i ;
128     register unsigned nglob ;
129         register int c ;
130         struct sym *tsp;
131         struct sym **s;
132         char id[NCPS];
133
134         getSid(id);     // old: getid(id, -1);
135         tsp = lkpsym(id, 1);
136         c = getnb();get();get();
137         if (c == 'R') {
138                 tsp->s_type |= S_REF;
139                 if (eval()) {
140                         fprintf(stderr, "Non zero S_REF\n");
141                         lkerr++;
142                 }
143         } else
144         if (c == 'D') {
145                 i = eval();
146                 if (tsp->s_type & S_DEF && tsp->s_addr != i) {
147 #ifdef SDK
148                         fprintf(stderr, "Multiple definition of %s\n", id);
149 #else
150                         fprintf(stderr, "Multiple definition of %.8s\n", id);
151 #endif
152                         lkerr++;
153                 }
154                 tsp->s_type |= S_DEF;
155                 /*
156                  * Set value and area extension link.
157                  */
158                 tsp->s_addr = i;
159                 tsp->s_axp = axp;
160         } else {
161                 fprintf(stderr, "Invalid symbol type %c for %.8s\n", c, id);
162                 lkexit(1);
163         }
164         /*
165          * Place pointer in header symbol list
166          */
167         if (headp == NULL) {
168                 fprintf(stderr, "No header defined\n");
169                 lkexit(1);
170         }
171         nglob = hp->h_nglob;
172         s = hp->s_list;
173         for (i=0; i < nglob ;++i) {
174                 if (s[i] == NULL) {
175                         s[i] = tsp;
176                         return(tsp);
177                 }
178         }
179         fprintf(stderr, "Header symbol list overflow\n");
180         lkexit(1);
181
182         /* Never reached */
183         return(0);
184 }
185
186 /*)Function     sym *   lkpsym(id,f)
187  *
188  *              char *  id              symbol name string
189  *              int     f               f == 0, lookup only
190  *                                      f != 0, create if not found
191  *
192  *      The function lookup() searches the symbol hash tables for
193  *      a symbol name match returning a pointer to the sym structure.
194  *      If the symbol is not found then a sym structure is created,
195  *      initialized, and linked to the appropriate hash table if f != 0.
196  *      A pointer to this new sym structure is returned or a NULL
197  *      pointer is returned if f == 0.
198  *
199  *      local variables:
200  *              int     h               computed hash value
201  *              sym *   sp              pointer to a sym structure
202  *
203  *      global varaibles:
204  *              sym * symhash[]         array of pointers to NHASH
205  *                                      linked symbol lists
206  *
207  *      functions called:
208  *              int     hash()          lksym.c
209  *              VOID *  new()           lksym.c
210  *              int     symeq()         lksym.c
211  *
212  *      side effects:
213  *              If the function new() fails to allocate space
214  *              for the new sym structure the linker terminates.
215  */
216
217 struct sym *
218 lkpsym(id, f)
219 char *id;
220 {
221         register struct sym *sp;
222         register int h;
223
224         h = hash(id);
225         sp = symhash[h];
226         while (sp != NULL) {
227                 if (symeq(id, sp->s_id))
228                         return (sp);
229                 sp = sp->s_sp;
230         }
231         if (f == 0)
232                 return (NULL);
233         sp = (struct sym *) new (sizeof(struct sym));
234         sp->s_sp = symhash[h];
235         symhash[h] = sp;
236         sp->s_id = StoreString( id );   /* JLH */
237         return (sp);
238 }
239
240 /*)Function     Addr_T  symval(tsp)
241  *
242  *              sym *   tsp             pointer to a symbol structure
243  *
244  *      The function symval() returns the value of the
245  *      relocated symbol by adding the variable definition
246  *      value to the areax base address.
247  *
248  *      local variables:
249  *              Addr_T  val             relocated address value
250  *
251  *      global variables:
252  *              none
253  *
254  *      functions called:
255  *              none
256  *
257  *      side effects:
258  *              none
259  */
260
261 Addr_T
262 symval(tsp)
263 register struct sym *tsp;
264 {
265         register Addr_T val;
266
267         val = tsp->s_addr;
268         if (tsp->s_axp) {
269                 val += tsp->s_axp->a_addr;
270         }
271         return(val);
272 }
273
274 /*)Function     VOID    symdef(fp)
275  *
276  *              FILE *  fp              file handle for output
277  *
278  *      The function symdef() scans the hashed symbol table
279  *      searching for variables referenced but not defined.
280  *      Undefined variables are linked to the default
281  *      area "_CODE" and reported as referenced by the
282  *      appropriate module.
283  *
284  *      local variables:
285  *              int     i               hash table index loop variable
286  *              sym *   sp              pointer to linked symbol structure
287  *
288  *      global variables:
289  *              area    *areap          The pointer to the first
290  *                                      area structure of a linked list
291  *              sym *symhash[NHASH]     array of pointers to NHASH
292  *                                      linked symbol lists
293  *
294  *      functions called:
295  *              symmod()                lksym.c
296  *
297  *      side effects:
298  *              Undefined variables have their areas set to "_CODE".
299  */
300
301 VOID
302 symdef(fp)
303 FILE *fp;
304 {
305         register struct sym *sp;
306         register int i;
307
308         for (i=0; i<NHASH; ++i) {
309                 sp = symhash[i];
310                 while (sp) {
311                         if (sp->s_axp == NULL)
312                                 sp->s_axp = areap->a_axp;
313                         if ((sp->s_type & S_DEF) == 0)
314                                 symmod(fp, sp);
315                         sp = sp->s_sp;
316                 }
317         }
318 }
319
320 /*)Function     VOID    symmod(fp,tsp)
321  *
322  *              FILE *  fp              output file handle
323  *              sym *   tsp             pointer to a symbol structure
324  *
325  *      The function symmod() scans the header structures
326  *      searching for a reference to the symbol structure
327  *      pointer to by tsp.  The function then generates an error
328  *      message whichs names the module having referenced the
329  *      undefined variable.
330  *
331  *      local variables:
332  *              int     i               loop counter
333  *              sym **  p               pointer to a list of pointers
334  *                                      to symbol structures
335  *
336  *      global variables:
337  *              head    *headp          The pointer to the first
338  *                                      head structure of a linked list
339  *              head    *hp             Pointer to the current
340  *                                      head structure
341  *              int     lkerr           error flag
342  *
343  *      functions called:
344  *              int     fprintf()       c_library
345  *
346  *      side effects:
347  *              Error output generated.
348  */
349
350 VOID
351 symmod(fp, tsp)
352 FILE *fp;
353 struct sym *tsp;
354 {
355     register int i;
356         struct sym **p;
357
358         if ((hp = headp) != NULL) {
359             while(hp) {
360                 p = hp->s_list;
361                 for (i=0; i<hp->h_nglob; ++i) {
362                     if (p[i] == tsp) {
363                         fprintf(fp, "\n?ASlink-Warning-Undefined Global '%s' ", tsp->s_id);
364                         fprintf(fp, "referenced by module '%s'\n", hp->m_id);
365                         lkerr++;
366                     }
367                 }
368             hp = hp->h_hp;
369             }
370         }
371 }
372
373 /*)Function     int     symeq(p1, p2)
374  *
375  *              char *  p1              name string
376  *              char *  p2              name string
377  *
378  *      The function symeq() compares the two name strings for a match.
379  *      The return value is 1 for a match and 0 for no match.
380  *
381  *      local variables:
382  *              int     h               loop counter
383  *
384  *      global variables:
385  *              char    ccase[]         an array of characters which
386  *                                      perform the case translation function
387  *
388  *      functions called:
389  *              none
390  *
391  *      side effects:
392  *              none
393  *
394  */
395
396 int
397 symeq(p1, p2)
398 register char *p1, *p2;
399 {
400 #if     CASE_SENSITIVE
401                 return (strncmp( p1, p2, NCPS ) == 0);
402 #else
403                 return (as_strncmpi( p1, p2, NCPS ) == 0);
404 #endif
405 }
406
407 /*)Function     int     hash(p)
408  *
409  *              char *  p               pointer to string to hash
410  *
411  *      The function hash() computes a hash code using the sum
412  *      of all characters mod table size algorithm.
413  *
414  *      local variables:
415  *              int     h               accumulated character sum
416  *              int     n               loop counter
417  *
418  *      global variables:
419  *              char    ccase[]         an array of characters which
420  *                                      perform the case translation function
421  *
422  *      functions called:
423  *              none
424  *
425  *      side effects:
426  *              none
427  *
428  */
429  
430 int
431 hash(p)
432 register char *p;
433 {
434         register int h, n;
435
436         h = 0;
437         n = NCPS;
438         do {
439
440 #if     CASE_SENSITIVE
441                 h += *p++;
442 #else
443                 h += ccase[(unsigned char)(*p++)];
444 #endif
445
446         } while (--n);
447         return (h&HMASK);
448 }
449
450 /*)Function     VOID *  new(n)
451  *
452  *              unsigned int    n       allocation size in bytes
453  *
454  *      The function new() allocates n bytes of space and returns
455  *      a pointer to this memory.  If no space is available the
456  *      linker is terminated.
457  *
458  *      local variables:
459  *              char *  p               a general pointer
460  *              char *  q               a general pointer
461  *
462  *      global variables:
463  *              none
464  *
465  *      functions called:
466  *              int     fprintf()       c_library
467  *              VOID *  malloc()        c_library
468  *
469  *      side effects:
470  *              Memory is allocated, if allocation fails
471  *              the linker is terminated.
472  */
473
474 VOID *
475 new(n)
476 unsigned int n;
477 {
478         register char *p;
479
480         if ((p = (char *) calloc(n, 1)) == NULL) {
481                 fprintf(stderr, "Out of space!\n");
482                 lkexit(1);
483         }
484         return (p);
485 }