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/>.
24 * With enhancements from
25 * John L. Hartman (JLH)
26 * jhartman@compuserve.com
34 * The module lksym.c contains the functions that operate
35 * on the symbol structures.
37 * lksym.c contains the following functions:
49 * lksym.c contains the static variables:
52 * used by the string store function.
55 /*)Function VOID syminit()
57 * The function syminit() is called to clear the hashtable.
60 * sym ** spp pointer to an array of
61 * sym structure pointers
64 * sym * symhash[] array of pointers to NHASH
71 * (1) The symbol hash tables are cleared
80 while (spp
< &symhash
[NHASH
])
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
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
109 * areax *axp Pointer to the current
111 * head *headp The pointer to the first
112 * head structure of a linked list
113 * int lkerr error flag
116 * a_uint eval() lkeval.c
117 * VOID exit() c_library
118 * int fprintf() c_library
119 * char getSid() lklex.c
121 * int getnb() lklex.c
122 * sym * lkpsym() lksym.c
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.
138 * | `----- sp->s_type
139 * `------------ sp->s_id
152 fprintf(stderr
, "No header defined\n");
156 * Create symbol entry
160 c
= getnb();get();get();
162 tsp
->s_type
|= S_REF
;
164 fprintf(stderr
, "Non zero S_REF\n");
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
))) {
173 "Multiple definition of %s\n", id
);
177 * Set value and area extension link.
181 tsp
->s_type
|= S_DEF
;
182 tsp
->m_id
= hp
->m_id
;
184 fprintf(stderr
, "Invalid symbol type %c for %s\n", c
, id
);
188 * Place pointer in header symbol list
192 for (i
=0; i
< nsym
;++i
) {
198 fprintf(stderr
, "Header symbol list overflow\n");
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.
217 * int h computed hash value
218 * sym * sp pointer to a sym structure
221 * sym * symhash[] array of pointers to NHASH
222 * linked symbol lists
223 * int zflag Disable symbol case sensitivity
227 * char * new() lksym.c
228 * int symeq() lksym.c
231 * If the function new() fails to allocate space
232 * for the new sym structure the linker terminates.
236 lkpsym(char *id
, int f
)
244 if (symeq(id
, sp
->s_id
, zflag
))
250 sp
= (struct sym
*) new (sizeof(struct sym
));
251 sp
->s_sp
= symhash
[h
];
253 sp
->s_id
= strsto(id
); /* JLH */
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.
266 * a_uint val relocated address value
279 symval(struct sym
*tsp
)
285 val
+= tsp
->s_axp
->a_addr
;
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.
301 * int i hash table index loop variable
302 * sym * sp pointer to linked symbol structure
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
314 * Undefined variables have their areas set to "_CODE".
323 for (i
=0; i
<NHASH
; ++i
) {
326 if (sp
->s_axp
== NULL
)
327 sp
->s_axp
= areap
->a_axp
;
328 if ((sp
->s_type
& S_DEF
) == 0)
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.
348 * sym ** p pointer to a list of pointers
349 * to symbol structures
352 * head *headp The pointer to the first
353 * head structure of a linked list
354 * head *hp Pointer to the current
356 * int lkerr error flag
359 * int fprintf() c_library
362 * Error output generated.
366 symmod(FILE *fp
, struct sym
*tsp
)
371 if ((hp
= headp
) != NULL
) {
374 for (i
=0; i
<hp
->h_nsym
; ++i
) {
377 "\n?ASlink-Warning-Undefined Global '%s' ",
380 "referenced by module '%s'\n",
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
406 * char ccase[] an array of characters which
407 * perform the case translation function
418 symeq(char *p1
, char *p2
, int cflag
)
425 * Case Insensitive Compare
428 if (ccase
[*p1
++ & 0x007F] != ccase
[*p2
++ & 0x007F])
433 * Case Sensitive Compare
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
455 * int h accumulated character sum
458 * char ccase[] an array of characters which
459 * perform the case translation function
469 hash(char *p
, int cflag
)
477 * Case Insensitive Hash
479 h
+= ccase
[*p
++ & 0x007F];
482 * Case Sensitive Hash
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
501 * jhartman@compuserve.com
504 * int l string length + 8
505 * char * p string location
511 * char * new() assym.c
512 * char * strncpy() c_library
515 * Space allocated for string, string copied
516 * to space. Out of Space terminates linker.
526 * What we need, including a null, and maybe some extra space for strcat().
529 p
= (char *) new (l
);
532 * Copy the name and terminating null.
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
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
565 * jhartman@compuserve.com
568 * int bytes bytes remaining in buffer area
570 * char * p pointer to head of copied string
571 * char * pnext next location in buffer area
572 * char * q a general pointer
578 * int fprintf() c_library
579 * VOID * malloc() c_library
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.
594 static char * pnext
= NULL
;
595 static int bytes
= 0;
604 * Always an even byte count
610 * For allocations larger than
611 * most structures and short strings
612 * allocate the space directly.
614 p
= (char *) malloc(n
);
617 * For smaller structures and
618 * strings allocate from the hunk.
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
);
634 fprintf(stderr
, "Out of space!\n");
637 for (i
=0,q
=p
; i
<n
; i
++) {
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
654 * jhartman@compuserve.com
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
666 * char * new() assym.c
667 * char * strncpy() c_library
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
681 static char * pnext
= NULL
;
682 static int bytes
= 0;
691 * What we need, including a null.
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
);
706 * Copy the name and terminating null.
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.
726 * char * p a general pointer
727 * char * q a general pointer
733 * int fprintf() c_library
734 * VOID * malloc() c_library
737 * Memory is allocated, if allocation fails
738 * the linker is terminated.
747 if ((p
= (char *) malloc(n
)) == NULL
) {
748 fprintf(stderr
, "Out of space!\n");
751 for (i
=0,q
=p
; i
<n
; i
++) {