NT4/private/sdktools/vctools/cvpack/compact.h
2020-09-30 17:12:29 +02:00

525 lines
14 KiB
C

/* compact.h - types and macro definition cvpack
*
*/
#define STRICT
#define NOMINMAX // windef.h
#define NOGDI // wingdi.h
#define NOIME // ime.h
#define NOUSER // winuser.h
#define NOHELP
#define NOPROFILER
#define NOSYSPARAMSINFO
#define NONLS // winnls.h
#define NOSERVICE // winsvc.h
#include "windows.h"
#if __cplusplus
#define INLINE inline
#else
#define INLINE __inline
#endif
#include <assert.h>
#include <fcntl.h>
#include <io.h>
#include <limits.h>
#include <malloc.h>
#include <process.h>
#include <share.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <tchar.h>
#include <sys\stat.h>
#include <sys\types.h>
#include "bufio.h"
#include "fileio.h"
#define _vmhnd_t unsigned char *
// ddbdumps.c
#if DBG //{
extern char DbArray[50];
void DDHeapUsage(char *);
void * __cdecl TrapMalloc(size_t);
#else //}{
#define DDHeapUsage(Modulename)
#define TrapMalloc(size) malloc(size)
#endif
#include "cvinfo.h"
#include "cvtdef.h"
#include "cvexefmt.h"
#include "vbuf.h"
#include "defines.h"
#include "padmacro.h"
// define DASSERT macro
#if DBG
#define DASSERT(ex) assert(ex)
#else
#define DASSERT(ex)
#endif
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned long ulong;
typedef unsigned int uint;
typedef uint bool_t;
typedef ulong uoff32_t;
typedef long off32_t;
typedef ushort uoff16_t;
typedef short off16_t;
// message ordinals
#include "msg.h"
typedef ushort (*LPFNHASH) (SYMPTR, ulong *, ushort *, ushort *, ulong *, ushort);
#define MAXCDF 254 // The maximum number of code segments to allow
// in a single module.
#define MAXSTRLEN 256 // The maximum string length to convert
#define MAXNUMERICLEN 18 // Longest Numeric possible (LF_REAL128)
#define GTYPE_INC 512 // number of type string pointers per buffer
#define POOLSIZE 32
#define POOL2SIZE 900
#define RECURSE_INC 5
#define ZEROARGTYPE 0xFFFF // Magic type index that causes a LF_ARGLIST
#if DBG
#define BreakOnIndex(a) IndexBreak (a)
#else
#define BreakOnIndex(a)
#endif
#if defined (STATS)
#define COUNTER(a) long a;
#define COUNT(a) a++;
#else
#define COUNTER(a)
#define COUNT(a)
#endif
#define TRUE 1
#define FALSE 0
#define LOCAL
typedef enum FWD_t {
FWD_none,
FWD_local,
FWD_global,
FWD_globalfwd
} FWD_t;
#define cbAlign 0x1000
#define cbTypeAlign 0xC000
// This hash table is used to hash local structures, class, unions
// and enums so that they can be quickly found for satisfying forward
// references. The hash is the sum of characters in the name.
typedef struct HSFWD {
uchar *pName;
TYPPTR pType;
CV_typ_t index;
ushort SatisfyFwdRef:1;
ushort WarnIsOut:1;
struct HSFWD *Next;
} HSFWD;
#define HASH_FWD 512 // hash size for forward definition
typedef struct TypeIndexEntry {
uchar *TypeString;
CV_typ_t CompactedIndex;
CV_typ_t ForwardIndex;
ushort Count; // count of recursive index offsets
ushort Hash;
union {
ushort *IndexString;
uchar Index[RECURSE_INC];
} IndexUnion; // offsets of recursive indices
union {
uchar GlobalIndex;
uchar *GlobalIndexString;
};
struct {
ushort IsBeingMatched :1; // being matched
ushort IsMatched :1;
ushort IsInserted :1; // in string hash table
ushort IsMalloced :1; // allocated string?
ushort IsPool :1; // memory is allocated from pool one
ushort IsPool2 :1; // memory is allocated from pool two
ushort IsBeingDone :1; // in the process?
ushort IsDone :1; // done, not inserted
ushort LargeList :1; // list
ushort WasSkipped :1; // was skipped by LF_SKIP record
ushort IsNewFormat :1; // string is in C7 fromat
ushort IsPreComp :1; // is from precompiled types table
ushort IsForward :1; // true if in progress forward ref
ushort IsBeingFreed :1; // true if allocated strings being freed
ushort InputWasFwd :1; // was a forward decl UDT on input
ushort IsParameter :1; // true if OLF_PARAMETER (compacted index
// is referenced index
} flags;
} TENTRY;
extern TENTRY *ModuleIndexTable;
typedef enum GPS_t {
GPS_intable, // symbol is in the global symbol table
GPS_added, // symbol added to the global table
GPS_noadd // symbol in table but different
} GPS_t;
/* get the length of a type string */
#define LENGTH(type) (*(ushort UNALIGNED *)(type + 1))
#define C7LENGTH(type) (*(ushort *)(type))
#define LNGTHSZ 2 // The size of the length field
#define RECTYPSZ 2 // The size of the record type field
#define MAXC6NUMERICGROWTH 1 // Maximum growth to convert
// C6 Numeric to C7 Numeric
#define MAXPAD 3 // Maximum number of bytes to pad to 4 byte boundry
// definition of in core list of modules
typedef struct ModuleListType {
ushort ModuleIndex;
char *pName; // length of module name
ulong signature; // precompiled types signature
ulong ModulesAddr;
ulong ModuleSize;
ulong SymbolsAddr;
ulong SymbolSize;
ulong SrcLnAddr;
ulong SrcLnSize;
ulong PreCompAddr;
ushort PreCompSize;
struct ModuleListType *next;
} MOD;
typedef MOD *PMOD;
typedef struct PACKDATA {
ushort iMod; // index of module to be packed
long iDir; // index of beginning directory entry
PMOD pMod; // pointer to module entry
} PACKDATA;
// externs for global variables
extern int exefile; // the .exe file
extern bool_t verifyDebug; // verify debug data correctness
extern bool_t logo; // print logo and compression numbers
extern bool_t verbose; // print packer stats at end of pack
extern bool_t strip; // just strip the cv info
extern bool_t fDelete; // delete symbols and types
extern bool_t NeedsBanner; // false if banner already printed
extern bool_t PackingPreComp; // true if packing a precompiled types file
extern bool_t IsMFCobol; // True if packing MF COBOL
extern ulong InitialTypeInfoSize;
extern ulong InitialSymInfoSize;
extern ulong FinalSymInfoSize;
ulong cSST; // count of subsection tables
extern uchar fLinearExe;
extern ushort cMod; // count of number of modules in file
ushort cTypeSeg; // count of number of type segments
ushort iTypeSeg; // index into type segment pointer array
uchar **pTypeSeg; // pointer to array of type segment pointers
size_t maxPublicsSub; // maximum publics subsection size
size_t maxSymbolsSub; // maximum symbols subsection size
size_t maxSrcLnSub; // maximum symbols subsection size
size_t maxModSub; // maximum symbols subsection size
ulong maxTypes; // maximum types subsection size
ulong maxPublics; // maximum publics subsection size
ulong maxSymbols; // maximum symbols subsection size
ulong maxSrcLn; // maximum SrcLnSeg/sstModule subsection size
ulong maxMod; // maximum publics subsection size
uchar *pTypes; // pointer to types table read buffer
uchar *pPublics; // pointer to publics table read buffer
uchar *pSymbols; // pointer to symbols table read buffer
uchar *pSrcLn; // pointer to sourcelins table read buffer
oldsmd *pSSTMOD; // pointer to sourcelins table read buffer
extern uchar **pGType[]; // array of pointers to global type pointers
PMOD pCurMod; // pointer to current module being packed
PMOD pRefMod; // pointer to referenced module
extern VBuf SymBuf;
extern VBuf TypeBuf;
extern OMFDirEntry *pDir; // directory read from exe
extern _vmhnd_t Libraries;
extern _vmhnd_t SegMap;
extern _vmhnd_t SegName;
_vmhnd_t FileIndex;
extern ulong LibSize;
extern ulong SegMapSize;
extern ulong SegNameSize;
ulong FileIndexSize;
long filepos;
long lfoDir;
long lfoBase;
extern char *ModAddr;
extern ushort cSeg;
extern ushort segnum[MAXCDF];
extern OMFDirHeader DirHead;
extern PACKDATA *PackOrder;
extern CV_typ_t maxPreComp; // maximum precompiled type for this module
extern PMOD ModuleList;
extern char *pDbgFile;
/* link_* - define i/o thunks for the case when cvpack is embedded in linker.
*/
#ifdef CVPACKLIB
int __cdecl link_chsize(int, long);
int __cdecl link_close (int);
void __cdecl link_exit (int);
long __cdecl link_lseek (int, long, int);
int __cdecl link_open (const char *, int, ...);
int __cdecl link_read (int, void *, unsigned int);
long __cdecl link_tell (int);
int __cdecl link_write (int, const void *, unsigned int);
#else
#define link_chsize FileChSize
#define link_close(x) FileClose ( x, TRUE )
#define link_lseek FileSeek
#define link_open FileOpen
#define link_read FileRead
#define link_tell FileTell
#define link_write FileWrite
#define link_exit exit
#endif
// compact6.c
CV_typ_t _fastcall C6GetCompactedIndex (CV_typ_t);
CV_typ_t _fastcall C6GetCompactedIndexRecur (CV_typ_t);
// compact7.c
void IndexBreak (CV_typ_t);
CV_typ_t _fastcall C7GetCompactedIndex (CV_typ_t);
CV_typ_t _fastcall CompactList (CV_typ_t, ushort);
uchar _fastcall CompactPtr (TENTRY *);
void PackPreComp (PMOD);
void _fastcall AddFwdRef(CV_typ_t OldIndex, HSFWD *pHash);
void _fastcall PickUpFwdRefs(void);
// error.c
void ErrorExit(unsigned, const char *, const char *);
const char *FormatMod(PMOD);
void Warn(unsigned, const char *, const char *);
// engine.c
bool_t CompactOneModule (ushort);
uchar *GetSymString (ushort);
bool_t SegmentPresent (ushort);
extern ulong ulCVTypeSignature; // The signature from the modules type segment
extern ushort usCurFirstNonPrim; // The current first non primitive type index
// module.c
void FixupExeFile (void);
OMFDirEntry *GetNextModuleEntry (OMFDirEntry *);
void ReadDir (void);
// obsolete.c
void ConvertObsolete (ushort);
// recurse.c
#if 1 // { GTW: inlined parts of this function.
bool_t _fastcall IdenticalTree_(TENTRY *, CV_typ_t, TYPPTR, CV_typ_t);
#else
bool_t IdenticalTree (TENTRY *, CV_typ_t, TYPPTR, CV_typ_t);
#endif
CV_typ_t _fastcall AddRecursiveType (CV_typ_t);
// tables.c
ushort AddrHash (SYMPTR, ushort *, ushort *, ushort);
ushort AddSearchSym (uchar *, ushort);
void _fastcall AddTypeToStringTable (uchar *, CV_typ_t);
void _fastcall AddTypeToTypeTable (TENTRY *);
void CleanUpTables (void);
ushort ComDat (uchar *);
void C7ReadTypes (ulong, bool_t);
void C6ReadTypes (uchar *, ulong);
void DoDerivationList (CV_typ_t, CV_typ_t);
FWD_t _fastcall FindFwdRef (TENTRY *, HSFWD **, bool_t);
void ClearHashFwdLocal();
void ReadTDB(char *szTdbToRead);
extern int TDBStayedResident;
extern int NeedToClearTDB;
extern void InitModTypeTable (void);
#if 1 // { GTW: inline FreeAllocStrings guard.
void FreeAllocStrings_ (TENTRY *);
#else
void FreeAllocStrings (TENTRY *);
#endif // }
void FreeStrings (CV_typ_t);
INLINE TENTRY *GetRawTypeEntry (CV_typ_t);
TENTRY *GetTypeEntry (CV_typ_t, CV_typ_t *);
CV_typ_t GetRecursiveIndex (TENTRY *, CV_typ_t);
void InitializeTables (void);
void _fastcall InsertIntoTypeSegment (TENTRY *);
bool_t IsFwdRef (TYPPTR);
bool_t LinkScope (uchar *, ulong);
void _fastcall MatchIndex (TENTRY *);
GPS_t _fastcall PackSymbol (SYMPTR, LPFNHASH);
GPS_t PackPublic (SYMPTR, LPFNHASH);
void PrepareGlobalTypeTable (void);
bool_t SegmentPresent (ushort);
ushort DWordXorShift (SYMPTR, ulong *, ushort *, ushort *, ulong *, ushort);
void WriteStaticSym (OMFDirEntry *, long);
#define HASHFUNC DWordXorShift
void WriteGlobalSym (OMFDirEntry *, long);
void WritePublics (OMFDirEntry *, long);
extern CV_typ_t MaxIndex; // Maximum index for module
extern CV_typ_t PreviousMaxIndex;
extern HSFWD **HTLocalFwd;
extern bool_t NoMoTypes;
// stack.c
#if 0 // { GTW inlined.
void SetRecursiveRoot (ushort);
void Push (ushort);
void Pop (void);
#endif // }
extern CV_typ_t RecursiveRoot;
// utils.c
ushort getshortvalue (uchar **);
short SkipNumericLeaf (uchar *);
void *CAlloc (uint);
void *Alloc (uint);
void *PoolAlloc (void);
void PoolFree (void *);
void *Pool2Alloc (void);
void Pool2Free (void *);
void *NoErrorRealloc (void *, uint);
uchar *GetScratchString (uint);
ulong C6GetLWordFromNumeric (uchar **, ushort *);
#if 1 // { GTW: inline version.
ushort C7SizeOfNumeric_(uchar *);
#else // }{
ushort C7SizeOfNumeric (uchar *);
#endif
ushort C7SizeOfNumeric (uchar *);
ushort C7StoreLWordAsNumeric (uchar *, ulong);
// utils6.c
ushort C6GetWordFromNumeric (uchar **, ushort *);
ulong C6GetLWordFromNumeric (uchar **, ushort *);
ushort ConvertNumeric (uchar **, uchar **);
// symbols6.c
void C6CalcNewSizeOfSymbols (uchar *, ulong);
void C6RewriteAndFixupSymbols (uchar *, OMFDirEntry *, char *, PMOD);
ushort C6CnvtSymbol (uchar *pC7Sym, uchar *pC6Sym);
// symbols7.c
void C7CalcNewSizeOfSymbols (uchar *, ulong, ushort *, ushort *);
void C7RewriteAndFixupSymbols (uchar *, OMFDirEntry *, PMOD,
ushort *, ushort *);
void C7RewritePublics (uchar *, OMFDirEntry *);
// cnvtprim.c
ushort C6MapPrimitive (ushort);
// main.c
void Banner (void);
extern bool_t IDEFeedback;
extern char *pDbgFilename; // dbg file name
int OpenOutputFile (char *path, char* pDefExt, int CreateFlag);
// type7.c
void CheckDouble (TENTRY *);
void DumpLocalList (CV_typ_t);
void DumpGlobalList (CV_typ_t);
void DumpFull (void);
void DumpPartial (void);
void DumpPartialType (CV_typ_t, TYPPTR, bool_t);
void DumpFullType (ushort, TYPPTR, bool_t);
#undef _HEAP_MAXREQ
// _HEAP_MAXREQ should always < 64K, regardless of host environment
#define _HEAP_MAXREQ 0xFFE8
#include "inlines.h"
#pragma warning(4:4124) // __fastcall with stack checking is inefficient