5e259e350d43f1a510796c0e089d516c5fc8d3eb
[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 }
181
182 /*)Function     sym *   lkpsym(id,f)
183  *
184  *              char *  id              symbol name string
185  *              int     f               f == 0, lookup only
186  *                                      f != 0, create if not found
187  *
188  *      The function lookup() searches the symbol hash tables for
189  *      a symbol name match returning a pointer to the sym structure.
190  *      If the symbol is not found then a sym structure is created,
191  *      initialized, and linked to the appropriate hash table if f != 0.
192  *      A pointer to this new sym structure is returned or a NULL
193  *      pointer is returned if f == 0.
194  *
195  *      local variables:
196  *              int     h               computed hash value
197  *              sym *   sp              pointer to a sym structure
198  *
199  *      global varaibles:
200  *              sym * symhash[]         array of pointers to NHASH
201  *                                      linked symbol lists
202  *
203  *      functions called:
204  *              int     hash()          lksym.c
205  *              VOID *  new()           lksym.c
206  *              int     symeq()         lksym.c
207  *
208  *      side effects:
209  *              If the function new() fails to allocate space
210  *              for the new sym structure the linker terminates.
211  */
212
213 struct sym *
214 lkpsym(id, f)
215 char *id;
216 {
217         register struct sym *sp;
218         register int h;
219
220         h = hash(id);
221         sp = symhash[h];
222         while (sp != NULL) {
223                 if (symeq(id, sp->s_id))
224                         return (sp);
225                 sp = sp->s_sp;
226         }
227         if (f == 0)
228                 return (NULL);
229         sp = (struct sym *) new (sizeof(struct sym));
230         sp->s_sp = symhash[h];
231         symhash[h] = sp;
232         sp->s_id = StoreString( id );   /* JLH */
233         return (sp);
234 }
235
236 /*)Function     addr_t  symval(tsp)
237  *
238  *              sym *   tsp             pointer to a symbol structure
239  *
240  *      The function symval() returns the value of the
241  *      relocated symbol by adding the variable definition
242  *      value to the areax base address.
243  *
244  *      local variables:
245  *              addr_t  val             relocated address value
246  *
247  *      global variables:
248  *              none
249  *
250  *      functions called:
251  *              none
252  *
253  *      side effects:
254  *              none
255  */
256
257 addr_t
258 symval(tsp)
259 register struct sym *tsp;
260 {
261         register addr_t val;
262
263         val = tsp->s_addr;
264         if (tsp->s_axp) {
265                 val += tsp->s_axp->a_addr;
266         }
267         return(val);
268 }
269
270 /*)Function     VOID    symdef(fp)
271  *
272  *              FILE *  fp              file handle for output
273  *
274  *      The function symdef() scans the hashed symbol table
275  *      searching for variables referenced but not defined.
276  *      Undefined variables are linked to the default
277  *      area "_CODE" and reported as referenced by the
278  *      appropriate module.
279  *
280  *      local variables:
281  *              int     i               hash table index loop variable
282  *              sym *   sp              pointer to linked symbol structure
283  *
284  *      global variables:
285  *              area    *areap          The pointer to the first
286  *                                      area structure of a linked list
287  *              sym *symhash[NHASH]     array of pointers to NHASH
288  *                                      linked symbol lists
289  *
290  *      functions called:
291  *              symmod()                lksym.c
292  *
293  *      side effects:
294  *              Undefined variables have their areas set to "_CODE".
295  */
296
297 VOID
298 symdef(fp)
299 FILE *fp;
300 {
301         register struct sym *sp;
302         register int i;
303
304         for (i=0; i<NHASH; ++i) {
305                 sp = symhash[i];
306                 while (sp) {
307                         if (sp->s_axp == NULL)
308                                 sp->s_axp = areap->a_axp;
309                         if ((sp->s_type & S_DEF) == 0)
310                                 symmod(fp, sp);
311                         sp = sp->s_sp;
312                 }
313         }
314 }
315
316 /*)Function     VOID    symmod(fp,tsp)
317  *
318  *              FILE *  fp              output file handle
319  *              sym *   tsp             pointer to a symbol structure
320  *
321  *      The function symmod() scans the header structures
322  *      searching for a reference to the symbol structure
323  *      pointer to by tsp.  The function then generates an error
324  *      message whichs names the module having referenced the
325  *      undefined variable.
326  *
327  *      local variables:
328  *              int     i               loop counter
329  *              sym **  p               pointer to a list of pointers
330  *                                      to symbol structures
331  *
332  *      global variables:
333  *              head    *headp          The pointer to the first
334  *                                      head structure of a linked list
335  *              head    *hp             Pointer to the current
336  *                                      head structure
337  *              int     lkerr           error flag
338  *
339  *      functions called:
340  *              int     fprintf()       c_library
341  *
342  *      side effects:
343  *              Error output generated.
344  */
345
346 VOID
347 symmod(fp, tsp)
348 FILE *fp;
349 struct sym *tsp;
350 {
351         register int i;
352         struct sym **p;
353
354         if ((hp = headp) != NULL) {
355             while(hp) {
356                 p = hp->s_list;
357                 for (i=0; i<hp->h_nglob; ++i) {
358                     if (p[i] == tsp) {
359                         fprintf(fp, "\n?ASlink-Warning-Undefined Global '%s' ", tsp->s_id);
360                         fprintf(fp, "referenced by module '%s'\n", hp->m_id);
361                         lkerr++;
362                     }
363                 }
364             hp = hp->h_hp;
365             }
366         }
367 }
368
369 /*)Function     int     symeq(p1, p2)
370  *
371  *              char *  p1              name string
372  *              char *  p2              name string
373  *
374  *      The function symeq() compares the two name strings for a match.
375  *      The return value is 1 for a match and 0 for no match.
376  *
377  *      local variables:
378  *              int     h               loop counter
379  *
380  *      global variables:
381  *              char    ccase[]         an array of characters which
382  *                                      perform the case translation function
383  *
384  *      functions called:
385  *              none
386  *
387  *      side effects:
388  *              none
389  *
390  */
391
392 int
393 symeq(p1, p2)
394 register char *p1, *p2;
395 {
396 #if     CASE_SENSITIVE
397                 return (strcmp( p1, p2 ) == 0);
398 #else
399                 return (strcmpi( p1, p2 ) == 0);
400 #endif
401 }
402
403 /*)Function     int     hash(p)
404  *
405  *              char *  p               pointer to string to hash
406  *
407  *      The function hash() computes a hash code using the sum
408  *      of all characters mod table size algorithm.
409  *
410  *      local variables:
411  *              int     h               accumulated character sum
412  *              int     n               loop counter
413  *
414  *      global variables:
415  *              char    ccase[]         an array of characters which
416  *                                      perform the case translation function
417  *
418  *      functions called:
419  *              none
420  *
421  *      side effects:
422  *              none
423  *
424  */
425  
426 int
427 hash(p)
428 register char *p;
429 {
430         register int h;
431
432         h = 0;
433         while (*p) {
434
435 #if     CASE_SENSITIVE
436                 h += *p++;
437 #else
438                 h += ccase[*p++];
439 #endif
440
441         };
442         return (h&HMASK);
443 }
444
445 /*)Function     VOID *  new(n)
446  *
447  *              unsigned int    n       allocation size in bytes
448  *
449  *      The function new() allocates n bytes of space and returns
450  *      a pointer to this memory.  If no space is available the
451  *      linker is terminated.
452  *
453  *      local variables:
454  *              char *  p               a general pointer
455  *              char *  q               a general pointer
456  *
457  *      global variables:
458  *              none
459  *
460  *      functions called:
461  *              int     fprintf()       c_library
462  *              VOID *  malloc()        c_library
463  *
464  *      side effects:
465  *              Memory is allocated, if allocation fails
466  *              the linker is terminated.
467  */
468
469 VOID *
470 new(n)
471 unsigned int n;
472 {
473         register char *p,*q;
474         register unsigned int i;
475
476         if ((p = (char *) malloc(n)) == NULL) {
477                 fprintf(stderr, "Out of space!\n");
478                 lkexit(1);
479         }
480         for (i=0,q=p; i<n; i++) {
481                 *q++ = 0;
482         }
483         return (p);
484 }