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