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