1 /****************************************************************************
2 *
3 *                            Open Watcom Project
4 *
5 *    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
6 *
7 *  ========================================================================
8 *
9 *    This file contains Original Code and/or Modifications of Original
10 *    Code as defined in and that are subject to the Sybase Open Watcom
11 *    Public License version 1.0 (the 'License'). You may not use this file
12 *    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
13 *    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
14 *    provided with the Original Code and Modifications, and is also
15 *    available at www.sybase.com/developer/opensource.
16 *
17 *    The Original Code and all software distributed under the License are
18 *    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
19 *    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
20 *    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
21 *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
22 *    NON-INFRINGEMENT. Please see the License for the specific language
23 *    governing rights and limitations under the License.
24 *
25 *  ========================================================================
26 *
27 * Description:  symbol table access
28 *
29 ****************************************************************************/
30 
31 #include <time.h>
32 
33 #include "globals.h"
34 #include "memalloc.h"
35 #include "parser.h"
36 #include "segment.h"
37 #include "extern.h"
38 #include "fixup.h"
39 #include "fastpass.h"
40 #include "myassert.h"
41 #include "macro.h"
42 #include "types.h"
43 #include "proc.h"
44 #include "input.h"
45 
46 #if defined(__WATCOMC__) && !defined(__FLAT__)
47 #define HASH_MAGNITUDE 12  /* for 16bit model */
48 #else
49 #define HASH_MAGNITUDE 15  /* is 15 since v1.94, previously 12 */
50 #endif
51 
52 /* size of global hash table for symbol table searches. This affects
53  * assembly speed.
54  */
55 #if HASH_MAGNITUDE==12
56 #define GHASH_TABLE_SIZE 2003
57 #else
58 #define GHASH_TABLE_SIZE 8009
59 #endif
60 
61 /* size of local hash table */
62 #define LHASH_TABLE_SIZE 127
63 
64 /* use memcpy()/memcmpi() directly?
65  * this may speed-up things, but not with OW.
66  * MSVC is a bit faster then.
67  */
68 #define USEFIXSYMCMP 0 /* 1=don't use a function pointer for string compare */
69 #define USESTRFTIME 0 /* 1=use strftime() */
70 
71 #if USEFIXSYMCMP
72 #define SYMCMP( x, y, z ) ( ModuleInfo.case_sensitive ? memcmp( x, y, z ) : _memicmp( x, y, z ) )
73 #else
74 #define SYMCMP( x, y, z ) SymCmpFunc( x, y, z )
75 #endif
76 
77 extern struct asym *FileCur;  /* @FileCur symbol    */
78 extern struct asym *LineCur;  /* @Line symbol       */
79 extern struct asym *symCurSeg;/* @CurSeg symbol     */
80 
81 extern void   UpdateLineNumber( struct asym *, void * );
82 extern void   UpdateWordSize( struct asym *, void * );
83 extern void   UpdateCurPC( struct asym *sym, void *p );
84 
85 static struct asym   *gsym_table[ GHASH_TABLE_SIZE ];
86 static struct asym   *lsym_table[ LHASH_TABLE_SIZE ];
87 
88 StrCmpFunc SymCmpFunc;
89 
90 static struct asym   **gsym;      /* pointer into global hash table */
91 static struct asym   **lsym;      /* pointer into local hash table */
92 static unsigned      SymCount;    /* Number of symbols in global table */
93 static char          szDate[12];  /* value of @Date symbol */
94 static char          szTime[12];  /* value of @Time symbol */
95 
96 #if USESTRFTIME
97 #if defined(__WATCOMC__) || defined(__UNIX__) || defined(__CYGWIN__) || defined(__DJGPP__)
98 static const char szDateFmt[] = "%D"; /* POSIX date (mm/dd/yy) */
99 static const char szTimeFmt[] = "%T"; /* POSIX time (HH:MM:SS) */
100 #else
101 /* v2.04: MS VC won't understand POSIX formats */
102 static const char szDateFmt[] = "%x"; /* locale's date */
103 static const char szTimeFmt[] = "%X"; /* locale's time */
104 #endif
105 #endif
106 
107 static struct asym *symPC; /* the $ symbol */
108 
109 struct tmitem {
110     const char *name;
111     char *value;
112     struct asym **store;
113 };
114 
115 /* table of predefined text macros */
116 static const struct tmitem tmtab[] = {
117     /* @Version contains the Masm compatible version */
118     /* v2.06: value of @Version changed to 800 */
119     //{"@Version",  "615", NULL },
120     {"@Version",  "800", NULL },
121     {"@Date",     szDate, NULL },
122     {"@Time",     szTime, NULL },
123     {"@FileName", ModuleInfo.name, NULL },
124     {"@FileCur",  NULL, &FileCur },
125     /* v2.09: @CurSeg value is never set if no segment is ever opened.
126      * this may have caused an access error if a listing was written.
127      */
128     {"@CurSeg",   "", &symCurSeg }
129 };
130 
131 struct eqitem {
132     const char *name;
133     uint_32 value;
134     void (* sfunc_ptr)( struct asym *, void * );
135     struct asym **store;
136 };
137 
138 /* table of predefined numeric equates */
139 static const struct eqitem eqtab[] = {
140     { "__JWASM__", _JWASM_VERSION_INT_, NULL, NULL },
141     { "$",         0,                   UpdateCurPC, &symPC },
142     { "@Line",     0,                   UpdateLineNumber, &LineCur },
143     { "@WordSize", 0,                   UpdateWordSize, NULL }, /* must be last (see SymInit()) */
144 };
145 
hashpjw(const char * s)146 static unsigned int hashpjw( const char *s )
147 /******************************************/
148 {
149     unsigned h;
150     unsigned g;
151 
152 #if HASH_MAGNITUDE==12
153     for( h = 0; *s; ++s ) {
154         h = (h << 4) + (*s | ' ');
155         g = h & ~0x0fff;
156         h ^= g;
157         h ^= g >> 12;
158     }
159 #else
160     for( h = 0; *s; ++s ) {
161         h = (h << 5) + (*s | ' ');
162         g = h & ~0x7fff;
163         h ^= g;
164         h ^= g >> 15;
165     }
166 #endif
167     return( h );
168 }
169 
SymSetCmpFunc(void)170 void SymSetCmpFunc( void )
171 /************************/
172 {
173     SymCmpFunc = ( ModuleInfo.case_sensitive == TRUE ? memcmp : (StrCmpFunc)_memicmp );
174     return;
175 }
176 
177 /* reset local hash table */
178 
SymClearLocal(void)179 void SymClearLocal( void )
180 /************************/
181 {
182     memset( &lsym_table, 0, sizeof( lsym_table ) );
183     return;
184 }
185 
186 /* store local hash table in proc's list of local symbols */
187 
SymGetLocal(struct asym * proc)188 void SymGetLocal( struct asym *proc )
189 /***********************************/
190 {
191     int i;
192     struct dsym  **l = &((struct dsym *)proc)->e.procinfo->labellist;
193 
194     for ( i = 0; i < LHASH_TABLE_SIZE; i++ ) {
195         if ( lsym_table[i] ) {
196             *l = (struct dsym *)lsym_table[i];
197             l = &(*l)->e.nextll;
198         }
199     }
200     *l = NULL;
201 
202     return;
203 }
204 
205 /* restore local hash table.
206  * - proc: procedure which will become active.
207  * fixme: It might be necessary to reset the "defined" flag
208  * for local labels (not for params and locals!). Low priority!
209  */
210 
SymSetLocal(struct asym * proc)211 void SymSetLocal( struct asym *proc )
212 /***********************************/
213 {
214     int i;
215     struct dsym *l;
216 
217     SymClearLocal();
218     for ( l = ((struct dsym *)proc)->e.procinfo->labellist; l; l = l->e.nextll ) {
219         DebugMsg1(("SymSetLocal(%s): label=%s\n", proc->name, l->sym.name ));
220         i = hashpjw( l->sym.name ) % LHASH_TABLE_SIZE;
221         lsym_table[i] = &l->sym;
222     }
223     return;
224 }
225 
SymAlloc(const char * name)226 struct asym *SymAlloc( const char *name )
227 /***************************************/
228 {
229     int len = strlen( name );
230     struct asym *sym;
231 
232     sym = LclAlloc( sizeof( struct dsym ) );
233     memset( sym, 0, sizeof( struct dsym ) );
234 #if 1
235     /* the tokenizer ensures that identifiers are within limits, so
236      * this check probably is redundant */
237     if( len > MAX_ID_LEN ) {
238         EmitError( IDENTIFIER_TOO_LONG );
239         len = MAX_ID_LEN;
240     }
241 #endif
242     sym->name_size = len;
243     sym->list = ModuleInfo.cref;
244     sym->mem_type = MT_EMPTY;
245     if ( len ) {
246         sym->name = LclAlloc( len + 1 );
247         memcpy( sym->name, name, len );
248         sym->name[len] = NULLC;
249     } else
250         sym->name = "";
251     return( sym );
252 }
253 
SymFind(const char * name)254 struct asym *SymFind( const char *name )
255 /**************************************/
256 /* find a symbol in the local/global symbol table,
257  * return ptr to next free entry in global table if not found.
258  * Note: lsym must be global, thus if the symbol isn't
259  * found and is to be added to the local table, there's no
260  * second scan necessary.
261  */
262 {
263     int i;
264     int len;
265 
266     len = strlen( name );
267     i = hashpjw( name );
268 
269     if ( CurrProc ) {
270         for( lsym = &lsym_table[ i % LHASH_TABLE_SIZE ]; *lsym; lsym = &((*lsym)->nextitem ) ) {
271             if ( len == (*lsym)->name_size && SYMCMP( name, (*lsym)->name, len ) == 0 ) {
272                 DebugMsg1(("SymFind(%s): found in local table, state=%u, local=%u\n", name, (*lsym)->state, (*lsym)->scoped ));
273                 return( *lsym );
274             }
275         }
276     }
277 
278     for( gsym = &gsym_table[ i % GHASH_TABLE_SIZE ]; *gsym; gsym = &((*gsym)->nextitem ) ) {
279         if ( len == (*gsym)->name_size && SYMCMP( name, (*gsym)->name, len ) == 0 ) {
280             DebugMsg1(("SymFind(%s): found, state=%u memtype=%X lang=%u\n", name, (*gsym)->state, (*gsym)->mem_type, (*gsym)->langtype ));
281             return( *gsym );
282         }
283     }
284 
285     return( NULL );
286 }
287 
288 #if 0
289 /* Search a symbol */
290 
291 struct asym *SymSearch( const char *name )
292 /****************************************/
293 {
294     return( *SymFind( name ) );
295 }
296 #endif
297 
298 /* SymLookup() creates a global label if it isn't defined yet */
299 
SymLookup(const char * name)300 struct asym *SymLookup( const char *name )
301 /****************************************/
302 {
303     struct asym      *sym;
304 
305     sym = SymFind( name );
306     if( sym == NULL ) {
307         sym = SymAlloc( name );
308         DebugMsg1(("SymLookup(%s): created new symbol, CurrProc=%s\n", name, CurrProc ? CurrProc->sym.name : "NULL" ));
309         //sym->next = *gsym;
310         *gsym = sym;
311         ++SymCount;
312     }
313 
314     DebugMsg1(("SymLookup(%s): found, state=%u, defined=%u\n", name, sym->state, sym->isdefined));
315 
316     return( sym );
317 }
318 
319 /* SymLookupLocal() creates a local label if it isn't defined yet.
320  * called by LabelCreate() [see labels.c]
321  */
SymLookupLocal(const char * name)322 struct asym *SymLookupLocal( const char *name )
323 /*********************************************/
324 {
325     //struct asym      **sym_ptr;
326     struct asym      *sym;
327 
328     sym = SymFind( name );
329     if ( sym == NULL ) {
330         sym = SymAlloc( name );
331         sym->scoped = TRUE;
332         /* add the label to the local hash table */
333         //sym->next = *lsym;
334         *lsym = sym;
335         DebugMsg1(("SymLookupLocal(%s): local symbol created in %s\n", name, CurrProc->sym.name));
336     } else if( sym->state == SYM_UNDEFINED && sym->scoped == FALSE ) {
337         /* if the label was defined due to a FORWARD reference,
338          * its scope is to be changed from global to local.
339          */
340         /* remove the label from the global hash table */
341         *gsym = sym->nextitem;
342         SymCount--;
343         sym->scoped = TRUE;
344         /* add the label to the local hash table */
345         //sym->next = *lsym;
346         sym->nextitem = NULL;
347         *lsym = sym;
348         DebugMsg1(("SymLookupLocal(%s): label moved into %s's local namespace\n", sym->name, CurrProc->sym.name ));
349     }
350 
351     DebugMsg1(("SymLookupLocal(%s): found, state=%u, defined=%u\n", name, sym->state, sym->isdefined));
352     return( sym );
353 }
354 
355 /* free state-specific info of a symbol */
356 
free_ext(struct asym * sym)357 static void free_ext( struct asym *sym )
358 /**************************************/
359 {
360     DebugMsg(("free_ext: item=%p name=%s state=%u\n", sym, sym->name, sym->state ));
361     switch( sym->state ) {
362     case SYM_INTERNAL:
363         if ( sym->isproc )
364             DeleteProc( (struct dsym *)sym );
365         break;
366     case SYM_EXTERNAL:
367         if ( sym->isproc )
368             DeleteProc( (struct dsym *)sym );
369         sym->first_size = 0;
370         /* The altname field may contain a symbol (if weak == FALSE).
371          * However, this is an independant item and must not be released here
372          */
373 #ifdef DEBUG_OUT /* to be removed, this can't happen anymore. */
374         if ( sym->mem_type == MT_TYPE && *sym->type->name == NULLC ) {
375             DebugMsg(( "free_ext: external with private type: %s\n", sym->name ));
376             SymFree( sym->type );
377         }
378 #endif
379         break;
380     case SYM_SEG:
381         if ( ((struct dsym *)sym)->e.seginfo->internal )
382             LclFree( ((struct dsym *)sym)->e.seginfo->CodeBuffer );
383         LclFree( ((struct dsym *)sym)->e.seginfo );
384         break;
385     case SYM_GRP:
386         DeleteGroup( (struct dsym *)sym );
387         break;
388     case SYM_TYPE:
389         DeleteType( (struct dsym *)sym );
390         break;
391     case SYM_MACRO:
392         ReleaseMacroData( (struct dsym *)sym );
393         LclFree( ((struct dsym *)sym)->e.macroinfo );
394         break;
395     case SYM_TMACRO:
396         if ( sym->predefined == FALSE )
397             LclFree( sym->string_ptr );
398         break;
399 #ifdef DEBUG_OUT
400     case SYM_STACK:
401         /* to be removed, this can't happen anymore. */
402         if ( sym->mem_type == MT_TYPE && *sym->type->name == NULLC ) {
403             DebugMsg(( "free_ext: case SYM_STACK, sym=%s with private type\n", sym->name ));
404             /* symbol has a "private" type */
405             SymFree( sym->type );
406         }
407         break;
408 #endif
409     }
410 }
411 
412 /* free a symbol.
413  * the symbol is not unlinked from hash table chains,
414  * hence it is assumed that this is either not needed
415  * or done by the caller.
416  */
417 
SymFree(struct asym * sym)418 void SymFree( struct asym *sym )
419 /******************************/
420 {
421     //DebugMsg(("SymFree: free %p, name=%s, state=%u\n", sym, sym->name, sym->state));
422     free_ext( sym );
423 #if FASTMEM==0
424     if ( sym->state != SYM_EXTERNAL ) { /* external backpatches are cleared in PassOneChecks() */
425         struct fixup *fix;
426         for( fix = sym->bp_fixup ; fix; ) {
427             struct fixup *next = fix->nextbp;
428             DebugMsg(("SymFree: free backpatch fixup %p [count=%u]\n", fix, fix->count ));
429             /* v2.14: free fixup only if not referenced anymore */
430             fix->count--;
431             if ( !fix->count )
432                 LclFree( fix );
433             fix = next;
434         }
435     }
436     if ( sym->name_size ) LclFree( sym->name );
437 #endif
438     LclFree( sym );
439     return;
440 }
441 
442 /* add a symbol to local table and set the symbol's name.
443  * the previous name was "", the symbol wasn't in a symbol table.
444  * Called by:
445  * - ParseParams() in proc.c for procedure parameters.
446  */
SymAddLocal(struct asym * sym,const char * name)447 struct asym *SymAddLocal( struct asym *sym, const char *name )
448 /************************************************************/
449 {
450     struct asym *sym2;
451     /* v2.10: ignore symbols with state SYM_UNDEFINED! */
452     //if( SymFind( name ) ) {
453     if( ( sym2 = SymFind( name ) ) && sym2->state != SYM_UNDEFINED ) {
454         /* shouldn't happen */
455         EmitErr( SYMBOL_ALREADY_DEFINED, name );
456         return( NULL );
457     }
458 #if FASTMEM==0
459     if ( sym->name_size ) LclFree( sym->name );
460 #endif
461     sym->name_size = strlen( name );
462     sym->name = LclAlloc( sym->name_size + 1 );
463     memcpy( sym->name, name, sym->name_size + 1 );
464     sym->nextitem = NULL;
465     *lsym = sym;
466     return( sym );
467 }
468 
469 /* add a symbol to the global symbol table.
470  * Called by:
471  * - RecordDirective() in types.c to add bitfield fields (which have global scope).
472  */
473 
SymAddGlobal(struct asym * sym)474 struct asym *SymAddGlobal( struct asym *sym )
475 /*******************************************/
476 {
477     if( SymFind( sym->name ) ) {
478         EmitErr( SYMBOL_ALREADY_DEFINED, sym->name );
479         return( NULL );
480     }
481     sym->nextitem = NULL;
482     *gsym = sym;
483     SymCount++;
484     return( sym );
485 }
486 
SymCreate(const char * name)487 struct asym *SymCreate( const char *name )
488 /****************************************/
489 /* Create symbol and optionally insert it into the symbol table */
490 {
491     struct asym *sym;
492 
493     if( SymFind( name ) ) {
494         EmitErr( SYMBOL_ALREADY_DEFINED, name );
495         return( NULL );
496     }
497     sym = SymAlloc( name );
498     *gsym = sym;
499     SymCount++;
500     return( sym );
501 }
502 
SymLCreate(const char * name)503 struct asym *SymLCreate( const char *name )
504 /*****************************************/
505 /* Create symbol and insert it into the local symbol table.
506  * This function is called by LocalDir() and ParseParams()
507  * in proc.c ( for LOCAL directive and PROC parameters ).
508  */
509 {
510     struct asym *sym;
511 
512     /* v2.10: ignore symbols with state SYM_UNDEFINED */
513     //if( SymFind( name ) ) {
514     if( ( sym = SymFind( name ) ) && sym->state != SYM_UNDEFINED ) {
515         EmitErr( SYMBOL_ALREADY_DEFINED, name );
516         return( NULL );
517     }
518     sym = SymAlloc( name );
519     *lsym = sym;
520     return( sym );
521 }
522 
SymMakeAllSymbolsPublic(void)523 void SymMakeAllSymbolsPublic( void )
524 /**********************************/
525 {
526     int i;
527     struct asym  *sym;
528 
529     for( i = 0; i < GHASH_TABLE_SIZE; i++ ) {
530         for( sym = gsym_table[i]; sym; sym = sym->nextitem ) {
531             if ( sym->state == SYM_INTERNAL &&
532                 /* v2.07: MT_ABS is obsolete */
533                 //sym->mem_type != MT_ABS &&  /* no EQU or '=' constants */
534                 sym->isequate == FALSE &&     /* no EQU or '=' constants */
535                 sym->predefined == FALSE && /* no predefined symbols ($) */
536                 sym->included == FALSE && /* v2.09: symbol already added to public queue? */
537                 //sym->scoped == FALSE && /* v2.09: no procs that are marked as "private" */
538                 sym->name[1] != '&' && /* v2.10: no @@ code labels */
539                 sym->ispublic == FALSE ) {
540                 sym->ispublic = TRUE;
541                 AddPublicData( sym );
542             }
543         }
544     }
545 }
546 
547 #ifdef DEBUG_OUT
548 static void DumpSymbols( void );
549 #endif
550 
SymFini(void)551 void SymFini( void )
552 /******************/
553 {
554 #if FASTMEM==0 || defined( DEBUG_OUT )
555     unsigned i;
556 #endif
557 
558 #ifdef DEBUG_OUT
559     if ( Options.dump_symbols_hash ) {
560         for( i = 0; i < GHASH_TABLE_SIZE; i++ ) {
561             struct asym  *sym = gsym_table[i];
562             if ( sym ) {
563                 printf("%4u ", i );
564                 for( ; sym; sym = sym->nextitem ) {
565                     printf("%-16s ", sym->name );
566                 }
567                 printf("\n" );
568             }
569         }
570     }
571     DumpSymbols();
572 #endif
573 
574 #if FASTMEM==0 || defined( DEBUG_OUT )
575     /* free the symbol table */
576     for( i = 0; i < GHASH_TABLE_SIZE; i++ ) {
577         struct asym  *sym;
578         struct asym  *next;
579         for( sym = gsym_table[i]; sym; ) {
580             next = sym->nextitem;
581             SymFree( sym );
582             SymCount--;
583             sym = next;
584         }
585     }
586     /**/myassert( SymCount == 0 );
587 #endif
588 
589 }
590 
591 /* initialize global symbol table */
592 
SymInit(void)593 void SymInit( void )
594 /******************/
595 {
596     struct asym *sym;
597     int i;
598     time_t    time_of_day;
599     struct tm *now;
600 
601     DebugMsg(("SymInit() enter\n"));
602     SymCount = 0;
603 
604     /* v2.11: ensure CurrProc is NULL - might be a problem if multiple files are assembled */
605     CurrProc = NULL;
606 
607     memset( gsym_table, 0, sizeof(gsym_table) );
608 
609     time_of_day = time( NULL );
610     now = localtime( &time_of_day );
611 #if USESTRFTIME
612     strftime( szDate, 9, szDateFmt, now );
613     strftime( szTime, 9, szTimeFmt, now );
614 #else
615     sprintf( szDate, "%02u/%02u/%02u", now->tm_mon + 1, now->tm_mday, now->tm_year % 100 );
616     sprintf( szTime, "%02u:%02u:%02u", now->tm_hour, now->tm_min, now->tm_sec );
617 #endif
618 
619     for( i = 0; i < sizeof(tmtab) / sizeof(tmtab[0]); i++ ) {
620         sym = SymCreate( tmtab[i].name );
621         sym->state = SYM_TMACRO;
622         sym->isdefined = TRUE;
623         sym->predefined = TRUE;
624         sym->string_ptr = tmtab[i].value;
625         if ( tmtab[i].store )
626             *tmtab[i].store = sym;
627     }
628 
629     for( i = 0; i < sizeof(eqtab) / sizeof(eqtab[0]); i++ ) {
630         sym = SymCreate( eqtab[i].name );
631         sym->state = SYM_INTERNAL;
632         /* v2.07: MT_ABS is obsolete */
633         //sym->mem_type = MT_ABS;
634         sym->isdefined = TRUE;
635         sym->predefined = TRUE;
636         sym->offset = eqtab[i].value;
637         sym->sfunc_ptr = eqtab[i].sfunc_ptr;
638         //sym->variable = TRUE; /* if fixup must be created */
639         if ( eqtab[i].store )
640             *eqtab[i].store = sym;
641     }
642     sym->list   = FALSE; /* @WordSize should not be listed */
643     /* $ is an address (usually). Also, don't add it to the list */
644     symPC->variable = TRUE;
645     symPC->list     = FALSE;
646     LineCur->list   = FALSE;
647 
648     DebugMsg(("SymInit() exit\n"));
649     return;
650 
651 }
652 
SymPassInit(int pass)653 void SymPassInit( int pass )
654 /**************************/
655 {
656     unsigned            i;
657 
658     if ( pass == PASS_1 )
659         return;
660 
661 #if FASTPASS
662     /* No need to reset the "defined" flag if FASTPASS is on.
663      * Because then the source lines will come from the line store,
664      * where inactive conditional lines are NOT contained.
665      */
666     if ( UseSavedState )
667         return;
668 #endif
669     /* mark as "undefined":
670      * - SYM_INTERNAL - internals
671      * - SYM_MACRO - macros
672      * - SYM_TMACRO - text macros
673      */
674     for( i = 0; i < GHASH_TABLE_SIZE; i++ ) {
675         struct asym *sym;
676         for( sym = gsym_table[i]; sym; sym = sym->nextitem ) {
677             if ( sym->predefined == FALSE ) {
678                 /* v2.04: all symbol's "defined" flag is now reset. */
679                 // if ( sym->state == SYM_TMACRO ||
680                 //    sym->state == SYM_MACRO  ||
681                 //    sym->state == SYM_INTERNAL ) {
682                     sym->isdefined = FALSE;
683                 //}
684             }
685         }
686     }
687 }
688 
SymGetCount(void)689 uint_32 SymGetCount( void )
690 /*************************/
691 {
692     return( SymCount );
693 }
694 
695 /* get all symbols in global hash table */
696 
SymGetAll(struct asym ** syms)697 void SymGetAll( struct asym **syms )
698 /**********************************/
699 {
700     struct asym         *sym;
701     unsigned            i, j;
702 
703     /* copy symbols to table */
704     for( i = j = 0; i < GHASH_TABLE_SIZE; i++ ) {
705         for( sym = gsym_table[i]; sym; sym = sym->nextitem ) {
706             syms[j++] = sym;
707         }
708     }
709     return;
710 }
711 
712 /* enum symbols in global hash table.
713  * used for codeview symbolic debug output.
714  */
715 
SymEnum(struct asym * sym,int * pi)716 struct asym *SymEnum( struct asym *sym, int *pi )
717 /***********************************************/
718 {
719     if ( sym == NULL ) {
720         *pi = 0;
721         sym = gsym_table[*pi];
722     } else {
723         sym = sym->nextitem;
724     }
725 
726     /* v2.10: changed from for() to while() */
727     while( sym == NULL && *pi < GHASH_TABLE_SIZE - 1 )
728         sym = gsym_table[++(*pi)];
729 
730     //printf("sym=%X, i=%u\n", sym, *pi );
731     return( sym );
732 }
733 
734 #ifdef DEBUG_OUT
735 
DumpSymbol(struct asym * sym)736 static void DumpSymbol( struct asym *sym )
737 /****************************************/
738 {
739     struct dsym *dir = (struct dsym *)sym;
740     char        *type;
741     uint_64     value = sym->uvalue;
742     //const char  *langtype;
743 
744     switch( sym->state ) {
745     case SYM_UNDEFINED:
746         type = "Undefined";
747         break;
748     case SYM_INTERNAL:
749         if ( sym->isproc )
750             type = "Procedure";
751         //else if ( sym->mem_type == MT_ABS )
752         else if ( sym->segment == NULL ) {
753             type = "Number";
754             value += ((uint_64)(uint_32)sym->value3264) << 32;
755         } else if ( sym->mem_type == MT_NEAR || sym->mem_type == MT_FAR )
756             type = "Code Label";
757         else
758             type = "Data Label";
759         break;
760     case SYM_EXTERNAL:
761         if ( sym->isproc )
762             type = "Proto";
763         else if ( sym->iscomm )
764             type = "Communal";
765         else if ( sym->mem_type == MT_EMPTY )
766             type = "Number (ext)";
767         else if ( sym->mem_type == MT_NEAR || sym->mem_type == MT_FAR )
768             type = "Code (ext)";
769         else
770             type = "Data (ext)";
771         break;
772     case SYM_SEG:
773         type = "Segment";
774         break;
775     case SYM_GRP:
776         type = "Group";
777         break;
778     case SYM_STACK: /* should never be found in global table */
779         type = "Stack Var";
780         break;
781     case SYM_STRUCT_FIELD: /* record bitfields are in global namespace! */
782         type = "Struct Field";
783         break;
784     case SYM_TYPE:
785         switch ( sym->typekind ) {
786         case TYPE_STRUCT:  type = "Structure"; break;
787         case TYPE_UNION:   type = "Union";     break;
788         case TYPE_TYPEDEF: type = "Typedef";   break;
789         case TYPE_RECORD:  type = "Record";    break;
790         default:           type = "Undef Type";break;
791         }
792         break;
793     case SYM_ALIAS:
794         type = "Alias";
795         break;
796     case SYM_MACRO:
797         type = "Macro";
798         break;
799     case SYM_TMACRO:
800         type = "Text";
801         break;
802     //case SYM_CLASS_LNAME: /* never stored in global or local table */
803     //    type = "CLASS";
804     //    break;
805     default:
806         type = "Unknown";
807         break;
808     }
809     printf( "%-12s  %16" I64_SPEC "X %02X %8p %c %8p %s\n", type, value, sym->mem_type, dir->e, sym->ispublic ? 'X' : ' ', sym->name, sym->name );
810 }
811 
DumpSymbols(void)812 static void DumpSymbols( void )
813 /*****************************/
814 {
815     struct asym         *sym;
816     unsigned            i;
817     unsigned            count = 0;
818     unsigned            max = 0;
819     unsigned            num0 = 0;
820     unsigned            num1 = 0;
821     unsigned            num5 = 0;
822     unsigned            num10 = 0;
823     unsigned            curr = 0;
824 
825     DebugMsg(("DumpSymbols enter\n"));
826     if ( Options.dump_symbols ) {
827         printf( "   # Addr     Type                     Value MT    Ext   P  pName   Name\n" );
828         printf( "--------------------------------------------------------------------------------\n" );
829     }
830     for( i = 0; i < GHASH_TABLE_SIZE; i++ ) {
831         for( sym = gsym_table[i], curr = 0; sym; sym = sym->nextitem ) {
832             curr++;
833             if ( Options.dump_symbols ) {
834                 printf("%4u %8p ", i, sym );
835                 DumpSymbol( sym );
836             }
837         }
838         count += curr;
839         if ( curr == 0 )
840             num0++;
841         else if ( curr == 1 )
842             num1++;
843         else if ( curr <= 5 )
844             num5++;
845         else if ( curr <= 10 )
846             num10++;
847         if ( max < curr )
848             max = curr;
849     }
850     if ( Options.quiet == FALSE ) {
851         printf( "%u items in symbol table, expected %u\n", count, SymCount );
852         printf( "max items in a line=%u, lines with 0/1/<=5/<=10 items=%u/%u/%u/%u, \n", max, num0, num1, num5, num10 );
853     }
854 }
855 #endif
856 
857