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: defines symbol structures asym and dsym, 28 * and prototypes of functions in symbols.c. 29 * This file is included by parser.h. 30 * 31 ****************************************************************************/ 32 33 34 #ifndef _SYMBOLS_H_ 35 #define _SYMBOLS_H_ 36 37 /* 38 * SYM_LIB - library paths are no longer added to the symbol table 39 * SYM_LNAME has been removed. It was used for the null-entry in the LNAME table only 40 * v2.01: SYM_PROC has been removed. 41 * v2.01: SYM_LIB has been removed. 42 */ 43 enum sym_state { 44 SYM_UNDEFINED, 45 SYM_INTERNAL, /* 1 internal label */ 46 SYM_EXTERNAL, /* 2 external */ 47 SYM_SEG, /* 3 segment */ 48 SYM_GRP, /* 4 group */ 49 SYM_STACK, /* 5 stack variable - in local symbol tables only */ 50 SYM_STRUCT_FIELD, /* 6 struct member - not in symbol table - except record fields */ 51 SYM_TYPE, /* 7 structure, union, typedef, record */ 52 SYM_ALIAS, /* 8 alias name */ 53 SYM_MACRO, /* 9 macro */ 54 SYM_TMACRO, /* 10 text macro */ 55 SYM_CLASS_LNAME /* 11 lname item for segm class - not in symbol table */ 56 }; 57 58 /* v2.04: MT_SHORT removed */ 59 /* v2.07: MT_ABS (0xC2) removed */ 60 61 enum memtype { 62 MT_SIZE_MASK = 0x1F, /* if MT_SPECIAL==0 then bits 0-4 = size - 1 */ 63 MT_FLOAT = 0x20, /* bit 5=1 */ 64 MT_SIGNED = 0x40, /* bit 6=1 */ 65 MT_BYTE = 1 - 1, 66 MT_SBYTE = MT_BYTE | MT_SIGNED, 67 MT_WORD = 2 - 1, 68 MT_SWORD = MT_WORD | MT_SIGNED, 69 MT_DWORD = 4 - 1, 70 MT_SDWORD= MT_DWORD | MT_SIGNED, 71 MT_REAL4 = MT_DWORD | MT_FLOAT, 72 MT_FWORD = 6 - 1, 73 MT_QWORD = 8 - 1, 74 MT_SQWORD= MT_QWORD | MT_SIGNED, 75 MT_REAL8 = MT_QWORD | MT_FLOAT, 76 MT_TBYTE = 10 - 1, 77 MT_REAL10= MT_TBYTE | MT_FLOAT, 78 MT_OWORD = 16 - 1, 79 #if AVXSUPP 80 MT_YMMWORD = 32 - 1, 81 #endif 82 MT_PROC = 0x80, /* symbol is a TYPEDEF PROTO, state=SYM_TYPE, typekind=TYPE_TYPEDEF, prototype is stored in target_type */ 83 MT_NEAR = 0x81, 84 MT_FAR = 0x82, 85 MT_EMPTY = 0xC0, 86 MT_BITS = 0xC1, /* record field */ 87 MT_PTR = 0xC3, /* v2.05: changed, old value 0x83 */ 88 MT_TYPE = 0xC4, /* symbol has user-defined type (struct, union, record) */ 89 MT_SPECIAL = 0x80, /* bit 7 */ 90 MT_SPECIAL_MASK = 0xC0, /* bit 6+7 */ 91 MT_ADDRESS = 0x80, /* bit 7=1, bit 6 = 0 */ 92 }; 93 94 #define IS_SIGNED(x) (((x) & MT_SPECIAL_MASK) == MT_SIGNED) 95 96 /* symbols can be 97 * - "labels" (data or code, internal, external, stack) 98 * mem_type is MT_BYTE..MT_OWORD, MT_NEAR, MT_FAR, MT_PTR 99 * - constants (EQU) or assembly time variables ("="), 100 * mem_type "usually" is MT_EMPTY. 101 * - types (STRUCT, UNION, TYPEDEF, RECORD), mem_type = MT_TYPE 102 * - preprocessor items (macros and text macros), which have no 103 * mem_type (MT_EMPTY). 104 */ 105 struct macro_instance; 106 107 typedef void (* internal_func)( struct asym *, void * ); 108 109 struct debug_info { 110 uint_32 start_line; /* procs's start line */ 111 uint_32 end_line; /* procs's last line */ 112 uint_32 ln_fileofs; /* file offset to line numbers */ 113 uint_16 line_numbers;/* line numbers in function */ 114 uint_16 file; /* proc's start file */ 115 unsigned next_proc; /* index next proc */ 116 unsigned next_file; /* index next file */ 117 }; 118 119 struct asym { 120 /* v2.11: name changed from 'next' to 'nextitem' */ 121 struct asym *nextitem; /* next symbol in hash line */ 122 char *name; /* symbol name */ 123 union { 124 int_32 offset; /* used by SYM_INTERNAL (labels), SYM_TYPE, SYM_STACK, v2.11: SYM_SEG */ 125 int_32 value; /* used by SYM_INTERNAL (equates) */ 126 uint_32 uvalue; /* v2.01: equates (they are 33-bit!) */ 127 char *string_ptr;/* used by SYM_TMACRO */ 128 struct asym *substitute;/* v2.04b: used by SYM_ALIAS */ 129 /* func_ptr: used by SYM_MACRO if predefined==1 */ 130 ret_code (* func_ptr)( struct macro_instance *, char *, struct asm_tok * ); 131 //int_32 max_offset; /* used by SYM_SEG; v2.11 field moved */ 132 int_32 class_lname_idx;/* used by SYM_CLASS_LNAME */ 133 }; 134 struct asym *segment; /* used by SYM_INTERNAL, SYM_EXTERNAL */ 135 enum sym_state state; 136 enum memtype mem_type; 137 unsigned char used:1, /* symbol has been referenced */ 138 isdefined:1, /* symbol is "defined" in this pass */ 139 scoped:1, /* symbol is local label or SYM_STACK */ 140 /* v2.07: removed */ 141 //isglobal:1, /* symbol has been added to the globals queue */ 142 #if DLLIMPORT 143 iat_used:1, /* v2.07: IAT entry of symbol used (SYM_EXTERNAL + isproc==1 only) */ 144 #endif 145 isequate:1, /* symbol has been defined with EQU */ 146 predefined:1, /* symbol is predefined */ 147 variable:1, /* symbol is variable (defined by '=' directive) */ 148 ispublic:1; /* symbol has been added to the publics queue */ 149 unsigned char list:1, /* symbol is to be listed */ 150 isarray:1, /* symbol is an array (total_length is valid) */ 151 isdata:1, /* field first_size is valid */ 152 isproc:1, /* symbol is PROC or PROTO; has proc_info extension */ 153 #if FASTPASS 154 issaved:1, /* assembly-time variables only: symbol has been saved */ 155 #endif 156 //#if FASTMEM==0 /* v2.09: obsolete */ 157 // isstatic:1, /* symbol stored in static memory */ 158 //#endif 159 fwdref:1, /* symbol was forward referenced */ 160 included:1; /* COFF: static symbol added to public queue. ELF:symbol added to symbol table (SYM_INTERNAL) */ 161 union { 162 /* for SYM_INTERNAL (data labels, memtype != NEAR|FAR), SYM_STRUCT_FIELD */ 163 uint_32 first_size; /* size of 1st initializer's dimension in bytes */ 164 /* for SYM_INTERNAL (memtype == NEAR|FAR), 165 * SYM_GRP (Ofssize), 166 * SYM_EXTERNAL (Ofssize, comm, weak, isfar, is_ptr, ptr_memtype), 167 * SYM_STACK (Ofssize, isfar, is_vararg, is_ptr, ptr_memtype ), 168 * SYM_TYPE, TYPE_TYPEDEF (Ofssize, isfar, is_ptr, ptr_memtype ) 169 */ 170 struct { 171 unsigned char Ofssize; /* offset size (USE16, USE32) */ 172 unsigned char is_ptr; /* PTR indirection */ 173 union { 174 unsigned char ptr_memtype;/* pointer target type */ 175 unsigned char asmpass; /* SYM_INTERNAL (mem_type NEAR|FAR) */ 176 }; 177 unsigned char seg_ofssize:2; /* SYM_EXTERNAL only */ 178 unsigned char iscomm:1; /* is communal */ 179 unsigned char weak:1; /* 1 if an unused "externdef" */ 180 unsigned char isfar:1; /* SYM_EXTERNAL, SYM_TYPE, SYM_STACK */ 181 unsigned char is_vararg:1;/* SYM_STACK, VARARG param */ 182 }; 183 /* for SYM_MACRO */ 184 struct { 185 unsigned char mac_vararg:1,/* accept additional params */ 186 isfunc:1, /* it's a macro function */ 187 #if MACROLABEL 188 label:1, /* macro is "label-aware" */ 189 #endif 190 #if VARARGML 191 mac_multiline:1, /* v2.11: vararg arguments may be on multiple lines */ 192 #endif 193 purged:1; /* macro has been PURGEd */ 194 }; 195 }; 196 union { 197 /* for SYM_INTERNAL (data labels only), SYM_STRUCT_FIELD */ 198 uint_32 first_length; /* size of 1st initializer's dimension in item units */ 199 /* SYM_TYPE (TYPEKIND_STRUCT or TYPEKIND_UNION) */ 200 uint_32 max_mbr_size; /* max size members */ 201 /* SYM_STACK, SYM_TYPE (TYPEKIND_TYPEDEF), SYM_EXTERNAL, SYM_INTERNAL (code labels) */ 202 struct asym *target_type; /* set if ptr_memtype is MT_TYPE */ 203 /* SYM_TMACRO (if it's a register variable for FASTCALL) */ 204 uint_16 regist[2]; 205 }; 206 union { 207 /* for SYM_INTERNAL, SYM_STRUCT_FIELD, 208 * SYM_TYPE, SYM_STACK, 209 * SYM_EXTERNAL (comm=1) 210 * SYM_TMACRO: size of buffer allocated for the text in string_ptr 211 */ 212 uint_32 total_size; /* total number of bytes (sizeof) */ 213 /* for SYM_INTERNAL, isequate=1 (numeric equates) */ 214 int_32 value3264; /* high bits for equates */ 215 #if DLLIMPORT 216 struct dll_desc *dll; /* SYM_EXTERNAL (isproc=1) */ 217 #endif 218 /* for SYM_SEG,SYM_GRP; v2.11: moved here to make segment's offset field contain "local start offset" (=0) */ 219 int_32 max_offset; 220 }; 221 union { 222 /* SYM_INTERNAL, SYM_STRUCT_FIELD, 223 * SYM_STACK, SYM_EXTERNAL (comm==1): 224 * total number of elements (LENGTHOF) 225 */ 226 uint_32 total_length; 227 struct asym *altname; /* SYM_EXTERNAL (comm==0): alternative name */ 228 struct debug_info *debuginfo;/* SYM_INTERNAL (isproc==1): debug info (COFF) */ 229 internal_func sfunc_ptr; /* SYM_INTERNAL+predefined */ 230 struct { /* SYM_TYPE */ 231 /* codeview type index (used after assembly steps) 232 * v2.04: moved from first_length, were it didn't work anymore 233 * since the addition of field max_mbr_size. 234 */ 235 uint_16 cvtyperef; 236 uint_8 typekind; 237 }; 238 }; 239 #if (MAX_ID_LEN <= 255) 240 uint_8 name_size; 241 #else 242 uint_16 name_size; 243 #endif 244 enum lang_type langtype; 245 #ifdef DEBUG_OUT 246 union { 247 struct asym *type; /* set if memtype is MT_TYPE */ 248 struct dsym *ttype; /* for easier debugging */ 249 }; 250 #else 251 struct asym *type; /* set if memtype is MT_TYPE */ 252 #endif 253 union { 254 /* SYM_INTERNAL, SYM_UNDEFINED, SYM_EXTERNAL: backpatching fixup */ 255 struct fixup *bp_fixup; 256 /* for SYM_EXTERNAL */ 257 unsigned ext_idx; /* table index ( for coff and elf ) */ 258 struct { 259 /* omf indices are 16-bit only! */ 260 uint_16 ext_idx1; /* omf: (external definition) index */ 261 uint_16 ext_idx2; /* omf: (external definition) index for weak external */ 262 }; 263 }; 264 }; 265 266 /*---------------------------------------------------------------------------*/ 267 /* Structures for grpdef, segdef, externdef, pubdef, included library, */ 268 /* procedure and symbolic integer constants. */ 269 /*---------------------------------------------------------------------------*/ 270 271 struct seg_item { 272 struct seg_item *next; 273 struct dsym *seg; 274 }; 275 276 struct grp_info { 277 struct seg_item *seglist; /* list of segments in the group */ 278 int grp_idx; /* its group index (OMF) */ 279 int lname_idx; /* LNAME index (OMF only) */ 280 unsigned numseg; /* OMF: number of segments in the group */ 281 }; 282 283 typedef uint_8 * (* FlushSegFunc)( struct dsym *, uint_8 *, unsigned, void * ); 284 285 struct seg_info { 286 struct asym *group; /* segment's group or NULL */ 287 uint_32 start_loc; /* starting offset of current ledata or lidata */ 288 union { 289 uint_32 current_loc; /* current offset in current ledata or lidata */ 290 uint_32 reloc_offset; /* ELF: reloc file offset */ 291 uint_32 start_offset; /* BIN: start offset in group */ 292 }; 293 #ifdef __I86__ 294 uint_8 huge *CodeBuffer; 295 #else 296 uint_8 *CodeBuffer; 297 #endif 298 uint_32 bytes_written; /* initialized bytes in segment */ 299 union { 300 struct asym *label_list; /* linked list of labels in this seg */ 301 FlushSegFunc flushfunc; /* to flush the segment buffer */ 302 }; 303 struct { 304 struct fixup *head; /* fixup queue head */ 305 struct fixup *tail; /* fixup queue tail */ 306 } FixupList; 307 union { 308 void *LinnumQueue; /* for COFF line numbers */ 309 uint_32 fileoffset; /* used by BIN + ELF */ 310 uint_32 num_linnums; /* used by COFF (after LinnumQueue has been read) */ 311 }; 312 uint_32 num_relocs; /* used by COFF/ELF */ 313 unsigned seg_idx; /* segment #; v2.12: changed from short to unsigned */ 314 enum seg_type segtype; /* segment's type (code, data, ...) */ 315 int lname_idx; /* segment's name LNAME index (OMF only) */ 316 struct asym *clsym; /* segment's class name (stored in an asym item) */ 317 union { 318 uint_16 abs_frame; /* ABS seg, frame number (OMF,BIN) */ 319 #if COMDATSUPP 320 uint_16 comdat_number; /* associated COMDAT segno (COFF) */ 321 uint_16 comdat_idx; /* lname index of COMDAT symbol (OMF) */ 322 #endif 323 }; 324 union { 325 uint_32 abs_offset; /* ABS seg, offset (OMF only) */ 326 char *aliasname; /* ALIAS name (COFF/ELF only) */ 327 }; 328 unsigned char Ofssize; /* segment's offset size */ 329 unsigned char characteristics;/* used by COFF/ELF/PE */ 330 unsigned char alignment; /* is value 2^x */ 331 332 unsigned char readonly:1; /* if segment is readonly */ 333 unsigned char info:1; /* if segment is info only (COFF/ELF) */ 334 unsigned char force32:1; /* force 32bit segdef (OMF only) */ 335 unsigned char data_in_code:1; /* data items in code segm (OMF only) */ 336 unsigned char internal:1; /* internal segment with private buffer */ 337 unsigned char written:1; /* code/data just written */ 338 unsigned char linnum_init:1; /* v2.10: linnum data emitted for segment? */ 339 unsigned char combine:3; /* combine type, see omfspec.h */ 340 #if COMDATSUPP 341 unsigned char comdat_selection:3; /* if > 0, it's a COMDAT (COFF/OMF) */ 342 #endif 343 }; 344 345 #define MAX_SEGALIGNMENT 0xFF 346 347 /* PROC item */ 348 349 struct proc_info { 350 uint_16 *regslist; /* PROC: list of registers to be saved */ 351 struct dsym *paralist; /* list of parameters */ 352 struct dsym *locallist; /* PROC: list of local variables */ 353 struct dsym *labellist; /* PROC: list of local labels */ 354 unsigned parasize; /* total no. of bytes used by parameters */ 355 unsigned localsize; /* PROC: total no. of bytes used by local variables */ 356 char *prologuearg; /* PROC: prologuearg attribute */ 357 #if AMD64_SUPPORT 358 struct asym *exc_handler; /* PROC: exc handler set by FRAME */ 359 int ReservedStack; /* PROC: win64: additional reserved stack */ 360 #endif 361 uint_32 prolog_list_pos;/* PROC: prologue list pos */ 362 union { 363 unsigned char flags; 364 struct { 365 unsigned char has_vararg:1;/* last param is VARARG */ 366 unsigned char pe_type:1; /* PROC: prolog-epilog type, 1=use LEAVE */ 367 unsigned char isexport:1; /* PROC: EXPORT attribute set */ 368 //unsigned char init_done:1; /* has ParseProc() been called? v2.11: obsolete */ 369 unsigned char forceframe:1;/* PROC: FORCEFRAME prologuearg? */ 370 unsigned char loadds:1; /* PROC: LOADDS prologuearg? */ 371 unsigned char stackparam:1;/* PROC: 1=stack params exists ( not just register params ) */ 372 #if AMD64_SUPPORT 373 unsigned char isframe:1; /* PROC: FRAME attribute set? */ 374 #endif 375 #if STACKBASESUPP 376 unsigned char fpo:1; 377 #endif 378 }; 379 }; 380 uint_8 size_prolog; /* PROC: v2.10: prologue size */ 381 #if STACKBASESUPP 382 uint_16 basereg; /* PROC: v2.11: stack base register */ 383 #endif 384 }; 385 386 /* macro parameter */ 387 388 struct mparm_list { 389 //const char *label; /* name of parameter */ 390 char *deflt; /* optional default parm */ 391 unsigned char required:1; /* is parm required (REQ) */ 392 }; 393 394 /* macro line */ 395 396 struct srcline { 397 struct srcline *next; 398 uint_8 ph_count; /* placeholders contained in this line */ 399 char line[1]; 400 }; 401 402 /* macro item */ 403 404 struct macro_info { 405 uint_16 parmcnt; /* no of params */ 406 union { 407 uint_16 localcnt; /* no of locals */ 408 uint_16 autoexp; /* auto-expansion flags if predefined macro */ 409 }; 410 struct mparm_list *parmlist; /* array of parameter items */ 411 struct srcline *data; /* prepared macro source lines */ 412 #ifdef DEBUG_OUT 413 uint_32 count; /* no of times the macro was invoked */ 414 #endif 415 unsigned srcfile; /* sourcefile index */ 416 }; 417 418 /* STRUCT field */ 419 420 struct sfield { 421 struct asym sym; /* field symbol ( state=SYM_STRUCT_FIELD ) */ 422 struct sfield *next; /* next field in STRUCT,UNION,RECORD */ 423 //char *init_dir; /* v2.09: removed ; previously: not used by record fields */ 424 char ivalue[1]; /* v2.09: type changed from char * to char[] */ 425 }; 426 427 enum type_kind { 428 TYPE_NONE, 429 TYPE_STRUCT, 430 TYPE_UNION, 431 TYPE_TYPEDEF, 432 TYPE_RECORD 433 }; 434 435 struct struct_info { 436 struct sfield *head; /* STRUCT/UNION/RECORD: start of field list */ 437 struct sfield *tail; /* STRUCT/UNION/RECORD: current/next field */ 438 /* v2.08: typekind moved to struct asym */ 439 //#ifdef __WATCOMC__ 440 // enum type_kind typekind; 441 //#else 442 // uint_8 typekind; 443 //#endif 444 uint_8 alignment; /* STRUCT: 1,2,4,8,16 or 32 */ 445 union { 446 uint_8 flags; 447 struct { 448 unsigned char isInline:1; /* STRUCT/UNION: inline (unused) */ 449 unsigned char isOpen:1; /* STRUCT/UNION: set until the matching ENDS is found */ 450 unsigned char OrgInside:1; /* STRUCT: struct contains an ORG */ 451 }; 452 }; 453 }; 454 455 /* dsym originally was a "directive_node" 456 * However, currently all symbols except SYM_STRUCT_FIELDs are allocated as a dsym. 457 * the additional 3 fields are used differently depending on symbol's type. 458 */ 459 460 struct dsym { 461 struct asym sym; 462 union { 463 struct seg_info *seginfo; /* SYM_SEG (segments) */ 464 struct grp_info *grpinfo; /* SYM_GRP (groups) */ 465 struct proc_info *procinfo; /* SYM_INTERNAL|SYM_EXTERNAL (procs, isproc=1) */ 466 struct struct_info *structinfo;/* SYM_TYPE (structs, unions, records [, typedefs]) */ 467 struct macro_info *macroinfo; /* SYM_MACRO (macros) */ 468 /* SYM_STACK, SYM_INTERNAL (code labels, isproc=0) 469 * used to save the local hash table (contains PROC locals: params, 470 * locals, labels). Details see SymGetLocal(), SymSetLocal() in symbols.c 471 */ 472 struct dsym *nextll; 473 } e; 474 /* next item in linked lists of certain symbol types. 475 * - SYM_UNDEFINED -> TAB_UNDEF 476 * - SYM_EXTERNAL -> TAB_EXT 477 * - SYM_SEG -> TAB_SEG 478 * - SYM_GRP -> TAB_GRP 479 * - SYM_ALIAS: -> TAB_ALIAS 480 * for SYM_INTERNAL: 481 * linked list of labels for current segment (used for BackPatch) 482 */ 483 struct dsym *next; 484 union { 485 /* for SYM_UNDEFINED, SYM_EXTERNAL, SYM_ALIAS and SYM_GRP: 486 * predecessor of current symbol with the same state, to allow fast removes. 487 * Actually, the only symbols which may change the state and thus 488 * have a chance to be removed are SYM_UNDEFINED and SYM_EXTERNAL ( weak=TRUE ) 489 * during pass one. 490 */ 491 struct dsym *prev; 492 /* used by PROC symbols (SYM_INTERNAL) for linked list, TAB_PROC */ 493 struct dsym *nextproc; 494 /* used by PROC locals (SYM_STACK) for linked list */ 495 struct dsym *nextlocal; 496 /* used by PROC params (SYM_STACK) for linked list */ 497 struct dsym *nextparam; 498 /* used by SYM_EXTERNAL (weak=FALSE) if altname is set */ 499 /* v2.11: removed; member is in use for SYM_EXTERNAL */ 500 //struct dsym *nextext; 501 }; 502 }; 503 504 extern struct asym *SymAlloc( const char * ); 505 extern void SymFree( struct asym * ); 506 507 extern struct asym *SymCreate( const char * ); 508 extern struct asym *SymLCreate( const char * ); 509 extern struct asym *SymAddGlobal( struct asym * ); 510 extern struct asym *SymAddLocal( struct asym *, const char * ); 511 extern struct asym *SymLookup( const char * ); 512 extern struct asym *SymLookupLocal( const char * ); 513 514 extern struct asym *SymFind( const char *name ); 515 #define SymSearch(x) SymFind(x) 516 517 extern void SymInit( void ); 518 extern void SymFini( void ); 519 extern void SymPassInit( int pass ); 520 extern void SymMakeAllSymbolsPublic( void ); 521 extern void SymGetAll( struct asym ** ); 522 extern struct asym *SymEnum( struct asym *, int * ); 523 extern uint_32 SymGetCount( void ); 524 525 #if defined(__WATCOMC__) 526 typedef int (__watcall * StrCmpFunc)(const void *, const void *, size_t ); 527 #else 528 typedef int (* StrCmpFunc)(const void *, const void *, size_t ); 529 #endif 530 extern StrCmpFunc SymCmpFunc; 531 532 extern void SymSetCmpFunc( void ); 533 extern void SymClearLocal( void ); 534 extern void SymSetLocal( struct asym * ); 535 extern void SymGetLocal( struct asym * ); 536 537 #endif 538