mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
331 lines
7.4 KiB
331 lines
7.4 KiB
/** cvpack - types compactor for codeview debug information.
|
|
|
|
/** The purpose of this program is to remove referenced types
|
|
* information from the $$types section of each module, and to
|
|
* remove duplicate type strings across modules. The result is a
|
|
* compacted global types section (as opposed to a type section for
|
|
* each module) which are all referenced by symbols and contains no
|
|
* duplicates. Duplicate global symbols are compacted into a global
|
|
* symbol table. All of the public symbol tables are compacted into
|
|
* a single global publics table.
|
|
*/
|
|
|
|
#include "compact.h"
|
|
|
|
|
|
#include "version.h"
|
|
#include <process.h>
|
|
#include <fcntl.h>
|
|
|
|
#ifdef WINDOWS
|
|
|
|
#include "winstuff.h"
|
|
|
|
/*
|
|
* Externals and forwards
|
|
*/
|
|
|
|
void ProcessWinArgs(char *pszCmdLine, char *pszExeFile);
|
|
|
|
#endif
|
|
|
|
#if defined (OS2)
|
|
#define INCL_DOS
|
|
#define INCL_SUB
|
|
#define INCL_DOSERRORS
|
|
#include <os2.h>
|
|
#endif
|
|
|
|
|
|
void _CRTAPI1 main (int, char **);
|
|
LOCAL void ProcessArgs (int, char **);
|
|
LOCAL void OpenExe (char *);
|
|
|
|
extern int _fDosExt;
|
|
|
|
|
|
#define SwapSize 11000
|
|
|
|
int exefile; // the exefile we're working on
|
|
bool_t verifyDebug = FALSE; // verify debug data correctness
|
|
bool_t logo = TRUE; // suppress logo and compression numbers
|
|
bool_t delete = FALSE; // delete symbols and types
|
|
bool_t runMpc = FALSE;
|
|
bool_t NeedsBanner = TRUE; // false if banner displayed
|
|
bool_t fVerbose = FALSE; // TRUE if verbose output is desired
|
|
bool_t FDebug = FALSE;
|
|
|
|
#ifndef WINDOWS
|
|
|
|
void _CRTAPI1 main(int argc, char **argv)
|
|
|
|
#else
|
|
|
|
int PASCAL
|
|
WinMain( HANDLE hInstance,
|
|
HANDLE hPrevInstance,
|
|
LPSTR lpCmdLine,
|
|
int nCmdShow)
|
|
|
|
#endif
|
|
{
|
|
ushort i;
|
|
ushort nMod = 0;
|
|
|
|
#if !defined (WINDOWS)
|
|
|
|
// print startup microsoft banner and process the arguments
|
|
|
|
ProcessArgs (argc, argv);
|
|
if ((logo == TRUE) && (NeedsBanner == TRUE)) {
|
|
Banner ();
|
|
}
|
|
OpenExe (argv[argc-1]);
|
|
#if defined (OS2)
|
|
DosError (HARDERROR_ENABLE | EXCEPTION_DISABLE);
|
|
#endif
|
|
|
|
#else
|
|
char szExeFile[_MAX_PATH];
|
|
char szMsg[128];
|
|
|
|
|
|
ProcessWinArgs (lpCmdLine, szExeFile );
|
|
|
|
// report version number
|
|
|
|
sprintf (szMsg, "Microsoft Debugging Information Compactor Version %d.%02d.%02d",
|
|
rmj, rmm, rup);
|
|
ReportVersion (szMsg, "Copyright\xa9 1987-1992 Microsoft Corporation",
|
|
rmj, rmm, rup);
|
|
|
|
if ((exefile = open (szExeFile, O_RDWR | O_BINARY)) == -1) {
|
|
if ((exefile = open (szExeFile, O_RDONLY | O_BINARY)) == -1) {
|
|
ErrorExit (ERR_EXEOPEN, NULL, NULL);
|
|
}
|
|
else {
|
|
ErrorExit (ERR_READONLY, NULL, NULL);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
// initialize virtual memory manager and compaction tables
|
|
|
|
InitializeTables ();
|
|
if (VmStart (0, SwapSize, _VM_ALLSWAP) == FALSE) {
|
|
ErrorExit (ERR_NOMEM, NULL, NULL);
|
|
}
|
|
|
|
// verify exe file and read subsection directory table
|
|
|
|
ReadDir ();
|
|
|
|
// do the compaction of files in packorder
|
|
|
|
for (i = 0; i < cMod; i++) {
|
|
if (fVerbose) printf("%d\n", i);
|
|
CompactOneModule (i);
|
|
|
|
#if defined (WINDOWS)
|
|
sprintf (szMsg, "%% Complete: %d", (int)((i*100)/cMod));
|
|
ReportProgress (szMsg);
|
|
#endif
|
|
#if DBG
|
|
if (FDebug) {
|
|
extern void UniqueType(void);
|
|
|
|
UniqueType();
|
|
}
|
|
#endif
|
|
}
|
|
free (pSSTMOD);
|
|
free (pTypes);
|
|
free (pPublics);
|
|
free (pSymbols);
|
|
free (pSrcLn);
|
|
|
|
CleanUpTables ();
|
|
|
|
// fixup the publics and symbols with the newly assigned type indices,
|
|
// and write new global types section to file
|
|
|
|
FixupExeFile ();
|
|
VmEnd ();
|
|
close (exefile);
|
|
|
|
#if defined (WINDOWS)
|
|
ComputeChecksum( szExeFile );
|
|
#else
|
|
ComputeChecksum( argv[argc-1] );
|
|
#endif
|
|
|
|
#ifndef WIN32
|
|
#if !defined (WINDOWS)
|
|
if (runMpc) {
|
|
#if !defined (OS2) && !defined (DOSX32)
|
|
if (_fDosExt == FALSE) {
|
|
execlp("mpc", "mpc", argv[argc - 1], NULL);
|
|
|
|
// If we returned from the execlp(), something is wrong.
|
|
|
|
ErrorExit (ERR_NOMPC, NULL, NULL);
|
|
}
|
|
else {
|
|
spawnlp (P_WAIT, "mpc", "mpc", argv[argc - 1], NULL);
|
|
}
|
|
#else
|
|
execlp("mpc", "mpc", argv[argc - 1], NULL);
|
|
|
|
// If we returned from the execlp(), something is wrong.
|
|
|
|
ErrorExit (ERR_NOMPC, NULL, NULL);
|
|
|
|
#endif
|
|
}
|
|
exit(0);
|
|
#else
|
|
AppExit(0);
|
|
return 0;
|
|
#endif
|
|
#else
|
|
exit(0);
|
|
#endif
|
|
|
|
}
|
|
|
|
#if !defined (WINDOWS)
|
|
|
|
/** ProcessArgs - process command line arguments
|
|
*
|
|
* ProcessArgs (arc, argv)
|
|
*
|
|
* Entry argc = argument count
|
|
* argv = pointer to argument list
|
|
*
|
|
* Exit
|
|
*
|
|
* Returns none
|
|
*/
|
|
|
|
|
|
LOCAL void ProcessArgs (int argc, char **argv)
|
|
{
|
|
int iRet;
|
|
|
|
// skip program name
|
|
|
|
argc--;
|
|
++argv;
|
|
|
|
while (argc && (**argv == '/' || **argv == '-')) {
|
|
switch (toupper (*++*argv)) {
|
|
case 'D':
|
|
FDebug = TRUE;
|
|
break;
|
|
|
|
case 'N':
|
|
logo = FALSE;
|
|
break;
|
|
|
|
case 'P':
|
|
runMpc = TRUE; // pcode
|
|
break;
|
|
|
|
case 'H':
|
|
iRet = spawnlp (P_WAIT, "qh.exe", "qh","-u", "cvpack.exe",NULL);
|
|
// qh returns 3 if no help was found on the topic.
|
|
// qh returns -ve exit codes if some system level
|
|
// error occured. Both cases , print usage message
|
|
if (iRet == 3 || iRet < 0) {
|
|
ErrorExit (ERR_USAGE, NULL, NULL);
|
|
exit (0);
|
|
}
|
|
break;
|
|
|
|
case 'M':
|
|
// preserve minimum information (publics and srcModule)
|
|
delete = TRUE;
|
|
break;
|
|
|
|
case 'V':
|
|
fVerbose = TRUE;
|
|
break;
|
|
|
|
case '?':
|
|
default:
|
|
ErrorExit (ERR_USAGE, NULL, NULL);
|
|
break;
|
|
}
|
|
argv++;
|
|
argc--;
|
|
}
|
|
if (argc != 1) {
|
|
ErrorExit (ERR_USAGE, NULL, NULL);
|
|
}
|
|
}
|
|
|
|
|
|
void Banner (void)
|
|
{
|
|
printf ("Microsoft Debugging Information Compactor Version %d.%02d.%02d\n" \
|
|
"Copyright(c) 1987-1992 Microsoft Corporation\n\n", \
|
|
rmj, rmm, rup);
|
|
NeedsBanner = FALSE;
|
|
}
|
|
|
|
LOCAL void OpenExe (char *path)
|
|
{
|
|
char outpath[_MAX_PATH];
|
|
char drive[_MAX_DRIVE];
|
|
char dir[_MAX_DIR];
|
|
char fname[_MAX_FNAME];
|
|
char ext[_MAX_EXT];
|
|
|
|
// try to open the exe file
|
|
|
|
strcpy (outpath, path);
|
|
|
|
// Build output file by splitting path and rebuilding with
|
|
// new extension.
|
|
|
|
_splitpath( outpath, drive, dir, fname, ext);
|
|
if (ext[0] == 0) {
|
|
strcpy (ext, ".exe" );
|
|
}
|
|
_makepath (outpath, drive, dir, fname, ext);
|
|
|
|
|
|
if ((exefile = open (outpath, O_RDWR | O_BINARY)) == -1) {
|
|
if ((exefile = open (outpath, O_RDONLY | O_BINARY)) == -1) {
|
|
ErrorExit (ERR_EXEOPEN, NULL, NULL);
|
|
}
|
|
else {
|
|
ErrorExit (ERR_READONLY, NULL, NULL);
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
|
|
/*
|
|
* ProcessWinArgs(char *pszCmdLine, char *pszExeFile)
|
|
*
|
|
* ENTRY:
|
|
*
|
|
* pszCmdLine Pointer to command line passed to QCVPACKW
|
|
* pszExeFile Pointer to buffer that will receive file name
|
|
* of file to be packed.
|
|
*/
|
|
|
|
void ProcessWinArgs(char *pszCmdLine, char *pszExeFile)
|
|
{
|
|
unsigned short lw, hw;
|
|
|
|
if (sscanf (pszCmdLine, "/CALLBACK:%X:%X %Fs", &hw, &lw,
|
|
(LPSTR)pszExeFile) != 3) {
|
|
ErrorExit(ERR_USAGE, NULL, NULL);
|
|
}
|
|
InitQUtil( (CALLBACK) ( ( (long)hw<<16 ) + lw) );
|
|
}
|
|
#endif
|