struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / sdas / linksrc / lksym.c
blob330b88e37be1e210f8a6fab87f7af199c154d6bb
1 /* lksym.c */
3 /*
4 * Copyright (C) 1989-2009 Alan R. Baldwin
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
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.
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/>.
20 * Alan R. Baldwin
21 * 721 Berkeley St.
22 * Kent, Ohio 44240
24 * With enhancements from
25 * John L. Hartman (JLH)
26 * jhartman@compuserve.com
30 #include "aslink.h"
32 /*)Module lksym.c
34 * The module lksym.c contains the functions that operate
35 * on the symbol structures.
37 * lksym.c contains the following functions:
38 * int hash()
39 * sym * lkpsym()
40 * char * new()
41 * sym * newsym()
42 * char * strsto()
43 * VOID symdef()
44 * int symeq()
45 * VOID syminit()
46 * VOID symmod()
47 * a_uint symval()
49 * lksym.c contains the static variables:
50 * char * pnext
51 * int bytes
52 * used by the string store function.
55 /*)Function VOID syminit()
57 * The function syminit() is called to clear the hashtable.
59 * local variables:
60 * sym ** spp pointer to an array of
61 * sym structure pointers
63 * global variables:
64 * sym * symhash[] array of pointers to NHASH
65 * linked symbol lists
67 * functions called:
68 * none
70 * side effects:
71 * (1) The symbol hash tables are cleared
74 VOID
75 syminit(void)
77 struct sym **spp;
79 spp = &symhash[0];
80 while (spp < &symhash[NHASH])
81 *spp++ = NULL;
84 /*)Function sym * newsym()
86 * The function newsym() is called to evaluate the symbol
87 * definition/reference directive from the .rel file(s).
88 * If the symbol is not found in the symbol table a new
89 * symbol structure is created. Evaluation of the
90 * directive determines if this is a reference or a definition.
91 * Multiple definitions of the same variable will be flagged
92 * as an error if the values are not identical. A symbol
93 * definition places the symbol value and area extension
94 * into the symbols data structure. And finally, a pointer
95 * to the symbol structure is placed into the head structure
96 * symbol list. Refer to the description of the header, symbol,
97 * area, and areax structures in lkdata.c for structure and
98 * linkage details.
100 * local variables:
101 * int c character from input text
102 * int i evaluation value
103 * char id[] symbol name
104 * int nglob number of symbols in this header
105 * sym * tsp pointer to symbol structure
106 * sym ** s list of pointers to symbol structures
108 * global variables:
109 * areax *axp Pointer to the current
110 * areax structure
111 * head *headp The pointer to the first
112 * head structure of a linked list
113 * int lkerr error flag
115 * functions called:
116 * a_uint eval() lkeval.c
117 * VOID exit() c_library
118 * int fprintf() c_library
119 * char getSid() lklex.c
120 * int get() lklex.c
121 * int getnb() lklex.c
122 * sym * lkpsym() lksym.c
124 * side effects:
125 * A symbol structure is created and/or modified.
126 * If structure space allocation fails linker will abort.
127 * Several severe errors (these are internal errors
128 * indicating a corrupted .rel file or corrupted
129 * assembler or linker) will terminated the linker.
133 * Find/Create a global symbol entry.
135 * S xxxxxx Defnnnn
136 * | | |
137 * | | `-- sp->s_addr
138 * | `----- sp->s_type
139 * `------------ sp->s_id
142 struct sym *
143 newsym(void)
145 a_uint ev;
146 int c, i, nsym;
147 struct sym *tsp;
148 struct sym **s;
149 char id[NCPS];
151 if (headp == NULL) {
152 fprintf(stderr, "No header defined\n");
153 lkexit(ER_FATAL);
156 * Create symbol entry
158 getSid(id);
159 tsp = lkpsym(id, 1);
160 c = getnb();get();get();
161 if (c == 'R') {
162 tsp->s_type |= S_REF;
163 if (eval()) {
164 fprintf(stderr, "Non zero S_REF\n");
165 lkerr++;
167 } else
168 if (c == 'D') {
169 ev = eval();
170 if (tsp->s_type & S_DEF &&
171 !(tsp->s_addr == ev && tsp->s_axp && tsp->s_axp->a_bap && ((tsp->s_axp->a_bap->a_flag & A3_ABS) == A3_ABS))) {
172 fprintf(stderr,
173 "Multiple definition of %s\n", id);
174 lkerr++;
177 * Set value and area extension link.
179 tsp->s_addr = ev;
180 tsp->s_axp = axp;
181 tsp->s_type |= S_DEF;
182 tsp->m_id = hp->m_id;
183 } else {
184 fprintf(stderr, "Invalid symbol type %c for %s\n", c, id);
185 lkexit(ER_FATAL);
188 * Place pointer in header symbol list
190 nsym = hp->h_nsym;
191 s = hp->s_list;
192 for (i=0; i < nsym ;++i) {
193 if (s[i] == NULL) {
194 s[i] = tsp;
195 return(tsp);
198 fprintf(stderr, "Header symbol list overflow\n");
199 lkexit(ER_FATAL);
200 return(NULL);
203 /*)Function sym * lkpsym(id,f)
205 * char * id symbol name string
206 * int f f == 0, lookup only
207 * f != 0, create if not found
209 * The function lookup() searches the symbol hash tables for
210 * a symbol name match returning a pointer to the sym structure.
211 * If the symbol is not found then a sym structure is created,
212 * initialized, and linked to the appropriate hash table if f != 0.
213 * A pointer to this new sym structure is returned or a NULL
214 * pointer is returned if f == 0.
216 * local variables:
217 * int h computed hash value
218 * sym * sp pointer to a sym structure
220 * global varaibles:
221 * sym * symhash[] array of pointers to NHASH
222 * linked symbol lists
223 * int zflag Disable symbol case sensitivity
225 * functions called:
226 * int hash() lksym.c
227 * char * new() lksym.c
228 * int symeq() lksym.c
230 * side effects:
231 * If the function new() fails to allocate space
232 * for the new sym structure the linker terminates.
235 struct sym *
236 lkpsym(char *id, int f)
238 struct sym *sp;
239 int h;
241 h = hash(id, zflag);
242 sp = symhash[h];
243 while (sp != NULL) {
244 if (symeq(id, sp->s_id, zflag))
245 return (sp);
246 sp = sp->s_sp;
248 if (f == 0)
249 return (NULL);
250 sp = (struct sym *) new (sizeof(struct sym));
251 sp->s_sp = symhash[h];
252 symhash[h] = sp;
253 sp->s_id = strsto(id); /* JLH */
254 return (sp);
257 /*)Function a_uint symval(tsp)
259 * sym * tsp pointer to a symbol structure
261 * The function symval() returns the value of the
262 * relocated symbol by adding the variable definition
263 * value to the areax base address.
265 * local variables:
266 * a_uint val relocated address value
268 * global variables:
269 * none
271 * functions called:
272 * none
274 * side effects:
275 * none
278 a_uint
279 symval(struct sym *tsp)
281 a_uint val;
283 val = tsp->s_addr;
284 if (tsp->s_axp) {
285 val += tsp->s_axp->a_addr;
287 return(val);
290 /*)Function VOID symdef(fp)
292 * FILE * fp file handle for output
294 * The function symdef() scans the hashed symbol table
295 * searching for variables referenced but not defined.
296 * Undefined variables are linked to the default
297 * area "_CODE" and reported as referenced by the
298 * appropriate module.
300 * local variables:
301 * int i hash table index loop variable
302 * sym * sp pointer to linked symbol structure
304 * global variables:
305 * area *areap The pointer to the first
306 * area structure of a linked list
307 * sym *symhash[NHASH] array of pointers to NHASH
308 * linked symbol lists
310 * functions called:
311 * symmod() lksym.c
313 * side effects:
314 * Undefined variables have their areas set to "_CODE".
317 VOID
318 symdef(FILE *fp)
320 struct sym *sp;
321 int i;
323 for (i=0; i<NHASH; ++i) {
324 sp = symhash[i];
325 while (sp) {
326 if (sp->s_axp == NULL)
327 sp->s_axp = areap->a_axp;
328 if ((sp->s_type & S_DEF) == 0)
329 symmod(fp, sp);
330 sp = sp->s_sp;
335 /*)Function VOID symmod(fp,tsp)
337 * FILE * fp output file handle
338 * sym * tsp pointer to a symbol structure
340 * The function symmod() scans the header structures
341 * searching for a reference to the symbol structure
342 * pointed to by tsp. The function then generates an error
343 * message whichs names the module having referenced the
344 * undefined variable.
346 * local variables:
347 * int i loop counter
348 * sym ** p pointer to a list of pointers
349 * to symbol structures
351 * global variables:
352 * head *headp The pointer to the first
353 * head structure of a linked list
354 * head *hp Pointer to the current
355 * head structure
356 * int lkerr error flag
358 * functions called:
359 * int fprintf() c_library
361 * side effects:
362 * Error output generated.
365 VOID
366 symmod(FILE *fp, struct sym *tsp)
368 int i;
369 struct sym **p;
371 if ((hp = headp) != NULL) {
372 while(hp) {
373 p = hp->s_list;
374 for (i=0; i<hp->h_nsym; ++i) {
375 if (p[i] == tsp) {
376 fprintf(fp,
377 "\n?ASlink-Warning-Undefined Global '%s' ",
378 tsp->s_id);
379 fprintf(fp,
380 "referenced by module '%s'\n",
381 hp->m_id);
382 lkerr++;
385 hp = hp->h_hp;
390 /*)Function int symeq(p1, p2, cflag)
392 * int cflag case sensitive flag
393 * char * p1 name string
394 * char * p2 name string
396 * The function symeq() compares the two name strings for a match.
397 * The return value is 1 for a match and 0 for no match.
399 * cflag == 0 case sensitive compare
400 * cflag != 0 case insensitive compare
402 * local variables:
403 * int n loop counter
405 * global variables:
406 * char ccase[] an array of characters which
407 * perform the case translation function
409 * functions called:
410 * none
412 * side effects:
413 * none
418 symeq(char *p1, char *p2, int cflag)
420 int n;
422 n = strlen(p1) + 1;
423 if(cflag) {
425 * Case Insensitive Compare
427 do {
428 if (ccase[*p1++ & 0x007F] != ccase[*p2++ & 0x007F])
429 return (0);
430 } while (--n);
431 } else {
433 * Case Sensitive Compare
435 do {
436 if (*p1++ != *p2++)
437 return (0);
438 } while (--n);
440 return (1);
443 /*)Function int hash(p, cflag)
445 * char * p pointer to string to hash
446 * int cflag case sensitive flag
448 * The function hash() computes a hash code using the sum
449 * of all characters mod table size algorithm.
451 * cflag == 0 case sensitive hash
452 * cflag != 0 case insensitive hash
454 * local variables:
455 * int h accumulated character sum
457 * global variables:
458 * char ccase[] an array of characters which
459 * perform the case translation function
461 * functions called:
462 * none
464 * side effects:
465 * none
469 hash(char *p, int cflag)
471 int h;
473 h = 0;
474 while (*p) {
475 if(cflag) {
477 * Case Insensitive Hash
479 h += ccase[*p++ & 0x007F];
480 } else {
482 * Case Sensitive Hash
484 h += *p++;
487 return (h&HMASK);
490 #if decus
492 /*)Function char * strsto(str)
494 * char * str pointer to string to save
496 * Allocate space for "str", copy str into new space.
497 * Return a pointer to the allocated string.
499 * This function based on code by
500 * John L. Hartman
501 * jhartman@compuserve.com
503 * local variables:
504 * int l string length + 8
505 * char * p string location
507 * global variables:
508 * none
510 * functions called:
511 * char * new() assym.c
512 * char * strncpy() c_library
514 * side effects:
515 * Space allocated for string, string copied
516 * to space. Out of Space terminates linker.
519 char *
520 strsto(char *str)
522 int l;
523 char *p;
526 * What we need, including a null, and maybe some extra space for strcat().
528 l = strlen(str) + 8;
529 p = (char *) new (l);
532 * Copy the name and terminating null.
534 strncpy(p, str, l);
535 return(p);
539 * This code is optimized for the PDP-11 (decus)
540 * which has a limited program space of 56K Bytes !
541 * Short strings and small structures are allocated
542 * from a memory hunk in new() to reduce the overhead
543 * from allocations directly by malloc(). Longer
544 * allocations are made directly by malloc.
545 * PDP-11 addressing requires that variables
546 * are allocated on a word boundary, (strings donot
547 * have this restriction,) all allocations will have
548 * at most 1 extra byte to maintain the word boundary
549 * requirement.
552 /*)Function char * new(n)
554 * unsigned int n allocation size in bytes
556 * The function new() allocates n bytes of space and returns
557 * a pointer to this memory. If no space is available the
558 * linker is terminated.
560 * Allocate space for "str", copy str into new space.
561 * Return a pointer to the allocated string.
563 * This function based on code by
564 * John L. Hartman
565 * jhartman@compuserve.com
567 * local variables:
568 * int bytes bytes remaining in buffer area
569 * int i loop counter
570 * char * p pointer to head of copied string
571 * char * pnext next location in buffer area
572 * char * q a general pointer
574 * global variables:
575 * none
577 * functions called:
578 * int fprintf() c_library
579 * VOID * malloc() c_library
581 * side effects:
582 * Memory is allocated, if allocation fails
583 * the linker is terminated.
587 * To avoid wasting memory headers on small allocations, we
588 * allocate a big chunk and parcel it out as required.
589 * These static variables remember our hunk.
592 #define STR_SPC 1024
593 #define STR_MIN 16
594 static char * pnext = NULL;
595 static int bytes = 0;
597 char *
598 new(unsigned int n)
600 char *p,*q;
601 unsigned int i;
604 * Always an even byte count
606 n = (n+1) & 0xFFFE;
608 if (n > STR_MIN) {
610 * For allocations larger than
611 * most structures and short strings
612 * allocate the space directly.
614 p = (char *) malloc(n);
615 } else {
617 * For smaller structures and
618 * strings allocate from the hunk.
620 if (n > bytes) {
622 * No space. Allocate a new hunk.
623 * We lose the pointer to any old hunk.
624 * We don't care, as the pieces are never deleted.
626 pnext = (char *) malloc (STR_SPC);
627 bytes = STR_SPC;
629 p = pnext;
630 pnext += n;
631 bytes -= n;
633 if (p == NULL) {
634 fprintf(stderr, "Out of space!\n");
635 lkexit(ER_FATAL);
637 for (i=0,q=p; i<n; i++) {
638 *q++ = 0;
640 return (p);
643 #else
645 /*)Function char * strsto(str)
647 * char * str pointer to string to save
649 * Allocate space for "str", copy str into new space.
650 * Return a pointer to the allocated string.
652 * This function based on code by
653 * John L. Hartman
654 * jhartman@compuserve.com
656 * local variables:
657 * int l string length + 8
658 * int bytes bytes remaining in buffer area
659 * char * p pointer to head of copied string
660 * char * pnext next location in buffer area
662 * global variables:
663 * none
665 * functions called:
666 * char * new() assym.c
667 * char * strncpy() c_library
669 * side effects:
670 * Space allocated for string, string copied
671 * to space. Out of Space terminates assembler.
675 * To avoid wasting memory headers on small allocations, we
676 * allocate a big chunk and parcel it out as required.
677 * These static variables remember our hunk
680 #define STR_SPC 1024
681 static char * pnext = NULL;
682 static int bytes = 0;
684 char *
685 strsto(char *str)
687 int l;
688 char *p;
691 * What we need, including a null.
693 l = strlen(str) + 8;
695 if (l > bytes) {
697 * No space. Allocate a new hunk.
698 * We lose the pointer to any old hunk.
699 * We don't care, as the strings are never deleted.
701 pnext = (char *) new (STR_SPC);
702 bytes = STR_SPC;
706 * Copy the name and terminating null.
708 p = pnext;
709 strncpy(p, str, l);
711 pnext += l;
712 bytes -= l;
714 return(p);
717 /*)Function char * new(n)
719 * unsigned int n allocation size in bytes
721 * The function new() allocates n bytes of space and returns
722 * a pointer to this memory. If no space is available the
723 * linker is terminated.
725 * local variables:
726 * char * p a general pointer
727 * char * q a general pointer
729 * global variables:
730 * none
732 * functions called:
733 * int fprintf() c_library
734 * VOID * malloc() c_library
736 * side effects:
737 * Memory is allocated, if allocation fails
738 * the linker is terminated.
741 char *
742 new(unsigned int n)
744 char *p,*q;
745 unsigned int i;
747 if ((p = (char *) malloc(n)) == NULL) {
748 fprintf(stderr, "Out of space!\n");
749 lkexit(ER_FATAL);
751 for (i=0,q=p; i<n; i++) {
752 *q++ = 0;
754 return (p);
757 #endif