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