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