/*********************************************************************** * Microsoft (R) 32-Bit Incremental Linker * * Copyright (C) Microsoft Corp 1992-1996. All rights reserved. * * File: symbol.h * * File Comments: * * This include file defines external symbol table data structures. * ***********************************************************************/ #ifndef __SYMBOL_H__ #define __SYMBOL_H__ #include "memory.h" // flags for external table // don't modify EXTERN_DEFINED directly ... use SetDefinedExt() instead // (so we can correctly maintain the linked list of all undefined externs). #define EXTERN_DEFINED 0x00000001 #define EXTERN_COMMON 0x00000002 #define EXTERN_EMITTED 0x00000004 #define EXTERN_COFF_EMITTED 0x08000000 // COFF external emitted #define EXTERN_EXP_CONST 0x00000008 // export with CONSTANT keyword (obs.) #define EXTERN_EXP_BYNAME 0x00000008 // EXTERN_EXP_CONST not used for Mac, so: #define EXTERN_EXP_DATA 0x00002000 // export with DATA keyword (use this) #define EXTERN_FUZZYMATCH 0x00000010 #define EXTERN_COMDAT 0x00000020 #define EXTERN_WEAK 0x00000040 #define EXTERN_LAZY 0x00000080 #define EXTERN_IGNORE 0x00000100 #define EXTERN_FORWARDER 0x00000200 #define EXTERN_EXPORT 0x00000400 #define EXTERN_IMPLIB_ONLY 0x00000800 // specialized attribute for deflib -- // indicates that the symbol should only // go in the import library, not the // export table etc. #define EXTERN_MULT_REFS 0x00001000 // more than one ref to undefined ext // 0x00002000 taken (see above) #define EXTERN_ALIAS 0x00004000 // alias to other extern #define EXTERN_EXP_NONAME 0x00008000 // Don't write name to export name table #define EXTERN_DIRTY 0x00010000 // used by ilink to indicate addr changed #define EXTERN_NEWFUNC 0x00020000 // used by ilink to indicate a new func #define EXTERN_NEWDATA 0x00040000 // used by ilink to indicate a new data #define EXTERN_FUNC_FIXUP 0x00080000 // used by ilink to indicate a non-lego fixup #define EXTERN_PRIVATE 0x00100000 // PRIVATE exports #define EXTERN_RELINK 0x00200000 // used by ilink to indicate relink if sym becomes undef #define EXTERN_NO_REFS 0x00400000 // used by ilink to notify refs need not be recorded // Flags for External Table (Mac specific) #define EXTERN_DUPCON 0x00800000 #define EXTERN_CSECTABLEB 0x01000000 #define EXTERN_CSECTABLEW 0x02000000 #define EXTERN_CSECTABLEL 0x04000000 // 0x08000000 taken (see above) #define EXTERN_REFD 0x20000000 #define EXTERN_ADDTHUNK 0x40000000 #define EXTERN_REF16 0x80000000 #define CSECTABLE_CBEL_MASK 0x0F000000 // symbol name types #define LONGNAME 0 #define SHORTNAME 1 // symbol access macros #define n_name N.ShortName #define n_zeroes N.Name.Short #define n_nptr N.LongName[1] #define n_offset N.Name.Long #define IsLongName(sym) ((sym).n_zeroes == 0) #define SzNameSymPb(sym, pb) ((sym).n_zeroes ? \ strncpy(ShortName, (char *) (sym).n_name, IMAGE_SIZEOF_SHORT_NAME) : \ (char *)((pb)+(sym).n_offset)) #define SzNameSym(sym, blk) SzNameSymPb(sym, (blk).pb) #define SzNameSymPst(sym, pst) SzNameSym(sym, (pst)->blkStringTable) #define SzNamePext(pext, pst) SzNameSymPst((pext)->ImageSymbol, pst) #define CPMODS 4 // count of references (MODS) in each chunk of references typedef struct MODS { struct MODS *pmodsNext; } MODS, *PMODS; #define RgpmodPMODS(pmodsNext) ((MOD **)((pmodsNext)+1)) typedef struct EXTERNAL // External symbol { IMAGE_SYMBOL ImageSymbol; WORD ArchiveMemberIndex; // some clients require that pcon not be invalidated immediately // if an extern becomes undefined ... // hence not unioned with the "Undefined" linked list. PCON pcon; // EXTERN_DEFINED DWORD FinalValue; // cannot union with undefined list vars since value // is lost on an ilink when symbol added to undefined list union { struct { // EXTERN_DEFINED struct EXTERNAL *pextNextDefined; }; struct { // !EXTERN_DEFINED struct EXTERNAL **ppextPrevUndefined; struct EXTERNAL *pextNextUndefined; }; }; union { // On an ilink these fields will be persistent. Even if EXTERN_DEFINED // these fields will still have the references PMOD pmodOnly; // !EXTERN_DEFINED, !EXTERN_MULT_REFS PMODS pmodsFirst; // !EXTERN_DEFINED, EXTERN_MULT_REFS }; DWORD Offset; // offset into jump table char *szOtherName; DWORD Flags; // NOTE: The following fields must not be moved. X86, MIPS ilink rely // on these fields being where they are. union { struct { // The following 3 fields are MAC specific PSEC psecRef; // Used to build thunk table DWORD offThunk; // Used for quick lookup of A5 offset of thunk struct _MACDLL_FSID *pmacdll_fsid; // Used to build DLL stubs }; struct { // The following 2 fields are used for NT PowerPC and PowerMac SHORT ibToc; WORD ppcFlags; union { // The following fields is used for PowerMac DWORD glueValue; // The following field is used for NT PowerPC DWORD dwRestoreToc; }; }; }; } EXTERNAL, *PEXTERNAL, **PPEXTERNAL; __inline BOOL FExportProcPext(PEXTERNAL pext) { return !(pext->Flags & (EXTERN_EXP_CONST | EXTERN_EXP_DATA)); } enum EMODE // export mode as spec'd in .def file or -export option { emodeProcedure, emodeConstant, emodeData }; struct LEXT // list of externals { PEXTERNAL pext; struct LEXT *plextNext; }; typedef LEXT *PLEXT; typedef struct LONG_STRING_LIST // Long name string list { DWORD Offset; struct LONG_STRING_LIST *Left; struct LONG_STRING_LIST *Right; } LONG_STRING_LIST, *PLONG_STRING_LIST; typedef struct ST // symbol table { PHT pht; // underlying dynamic hash table BLK blkStringTable; // long name string table PLONG_STRING_LIST plslFirstLongName;// pointer to binary tree of long names. // UNDONE: Can these be union'd PPEXTERNAL rgpexternalByName; // ptr to symbol table sorted by name PPEXTERNAL rgpexternalByAddr; // ptr to symbol table sorted by addr PPEXTERNAL rgpexternalByMacAddr; // ptr to symbol table sorted by mac addr PPEXTERNAL rgpexternalByModName; // ptr to symbol table sorted by archive member, name PEXTERNAL pextFirstUndefined; // linked list of undefined symbols PPEXTERNAL ppextLastUndefined; // end of list } ST, *PST, **PPST; struct ENM_UNDEF_EXT { // private ENM_BASE enm_base; PEXTERNAL pextNext; // public PEXTERNAL pext; }; struct ENM_MOD_EXT { // private ENM_BASE enm_base; PEXTERNAL pext; PMODS pmods; DWORD ipmod; // public PMOD pmod; }; // symbol table api VOID InitExternalSymbolTable(PPST, DWORD, DWORD); VOID IncrInitExternalSymbolTable(PPST); VOID FreeExternalSymbolTable(PPST); VOID InitEnumerateExternals(PST); VOID TerminateEnumerateExternals(PST); DWORD Cexternal(PST); VOID FuzzyLookup(PST, PST, PLIB, BOOL); PEXTERNAL LookupExternName(PST, SHORT, const char *, PBOOL); PEXTERNAL LookupExternSz(PST, const char *, PBOOL); PEXTERNAL SearchExternSz(PST, const char *); VOID SetDefinedExt(PEXTERNAL, BOOL, PST); PEXTERNAL PexternalEnumerateNext(PST); PPEXTERNAL RgpexternalByAddr(PST); PPEXTERNAL RgpexternalByMacAddr(PST); PPEXTERNAL RgpexternalByModName(PST); PPEXTERNAL RgpexternalByName(PST); VOID AddReferenceExt(PEXTERNAL, PMOD); BOOL FPextRef(PEXTERNAL); VOID AllowInserts(PST); VOID DumpPst(PST); VOID InitEnmUndefExt(ENM_UNDEF_EXT *, PST); BOOL FNextEnmUndefExt(ENM_UNDEF_EXT *); VOID EndEnmUndefExt(ENM_UNDEF_EXT *); VOID InitEnmModExt(ENM_MOD_EXT *, PEXTERNAL); BOOL FNextEnmModExt(ENM_MOD_EXT *); VOID EndEnmModExt(ENM_MOD_EXT *); #endif // __SYMBOL_H__