//========= Copyright Valve Corporation, All rights reserved. ============// /***************************************************************************** DUMPOBJ.CPP *****************************************************************************/ #include "..\toollib\toollib.h" typedef struct section_s { int size; char* name; section_s* nextPtr; } section_t; typedef struct obj_s { char* filename; section_t* sectionPtr; obj_s* nextPtr; } obj_t; obj_t* g_obj_head; char g_sectionName[128]; bool g_bVerbose; typedef struct { char* filename; int size; } entry_t; /*********************************************************** _SortCallback ***********************************************************/ int _SortCallback(const void *a, const void *b) { entry_t* aPtr; entry_t* bPtr; aPtr = (entry_t*)a; bPtr = (entry_t*)b; return (aPtr->size-bPtr->size); } /*********************************************************** FreeInfo ***********************************************************/ void FreeInfo() { obj_t* objPtr; obj_t* nextObjPtr; section_t* sectionPtr; section_t* nextSectionPtr; objPtr = g_obj_head; while (objPtr) { nextObjPtr = objPtr->nextPtr; sectionPtr = objPtr->sectionPtr; while (sectionPtr) { nextSectionPtr = sectionPtr->nextPtr; TL_Free(sectionPtr->name); TL_Free(sectionPtr); sectionPtr = nextSectionPtr; } TL_Free(objPtr->filename); TL_Free(objPtr); objPtr = nextObjPtr; } } /*********************************************************** AnalyzeData ***********************************************************/ void AnalyzeData() { obj_t* objPtr; section_t* sectionPtr; char* sections[128]; int totals[128]; int numSections; int i; int index; int numEntries; entry_t* entries; int total; printf("\n"); memset(totals, 0, sizeof(totals)); // determine unique sections numSections = 0; objPtr = g_obj_head; while (objPtr) { sectionPtr = objPtr->sectionPtr; while (sectionPtr) { for (i=0; iname)) break; } if (i >= numSections) { // add it sections[numSections] = sectionPtr->name; numSections++; assert(numSections < 128); index = numSections-1; } else index = i; totals[index] += sectionPtr->size; sectionPtr = sectionPtr->nextPtr; } objPtr = objPtr->nextPtr; } if (g_sectionName[0]) { // dump only matching section printf("Section: %s\n", g_sectionName); printf("-------------------------\n"); // tally entries numEntries = 0; objPtr = g_obj_head; while (objPtr) { sectionPtr = objPtr->sectionPtr; while (sectionPtr) { if (!stricmp(g_sectionName, sectionPtr->name)) numEntries++; sectionPtr = sectionPtr->nextPtr; } objPtr = objPtr->nextPtr; } // fill entries if (numEntries) { entries = (entry_t*)TL_Malloc(numEntries*sizeof(entry_t)); numEntries = 0; objPtr = g_obj_head; while (objPtr) { sectionPtr = objPtr->sectionPtr; while (sectionPtr) { if (!stricmp(g_sectionName, sectionPtr->name)) { entries[numEntries].size = sectionPtr->size; entries[numEntries].filename = objPtr->filename; numEntries++; } sectionPtr = sectionPtr->nextPtr; } objPtr = objPtr->nextPtr; } // sort qsort(entries, numEntries, sizeof(entry_t), _SortCallback); // display results int total = 0; for (i=0; ifilename = (char*)TL_Malloc((int)strlen(objFilename)+1); strcpy(objPtr->filename, objFilename); // link it in objPtr->nextPtr = g_obj_head; g_obj_head = objPtr; // read the results TL_LoadScriptFile(logFilename); while (1) { token = TL_GetToken(true); if (!token || !token[0]) break; if (!stricmp(token, "summary")) break; else TL_SkipRestOfLine(); } while (1) { token = TL_GetToken(true); if (!token || !token[0]) break; sscanf(token, "%x", &size); token = TL_GetToken(true); if (!token || !token[0]) break; strcpy(name, token); // add new section node sectionPtr = (section_t*)TL_Malloc(sizeof(section_t)); sectionPtr->name = (char*)TL_Malloc((int)strlen(name)+1); strcpy(sectionPtr->name, name); sectionPtr->size = size; // link it in sectionPtr->nextPtr = objPtr->sectionPtr; objPtr->sectionPtr = sectionPtr; } TL_FreeScriptFile(); } /***************************************************************************** Usage *****************************************************************************/ void Usage(void) { printf("usage: dumpobj <*.obj> [-s section] [-r] [-v]\n"); exit(-1); } /***************************************************************************** main *****************************************************************************/ int main(int argc, char* argv[]) { tlfile_t** filelist; int filecount; int i; int recurse; int section; FILE* fp; char* vcvarsPath; char batFilename[TL_MAXPATH]; char txtFilename[TL_MAXPATH]; batFilename[0] = '\0'; txtFilename[0] = '\0'; TL_Setup("DUMPOBJ",argc,argv); // find critical path to vcvars32.bat vcvarsPath = "c:\\Program Files\\Microsoft Visual Studio .Net 2003\\Vc7\\bin\\vcvars32.bat"; if (!TL_Exists(vcvarsPath)) TL_Error("Cannot find: %s\n", vcvarsPath); if (argc < 2) Usage(); recurse = TL_CheckParm("r"); filecount = TL_FindFiles2(argv[1], recurse != 0, &filelist); g_bVerbose = TL_CheckParm("v") != 0; section = TL_CheckParm("s"); if (section && section+1 < argc) strcpy(g_sectionName, argv[section+1]); else g_sectionName[0] = '\0'; strcpy(batFilename,"c:\\"); TL_TempFilename(batFilename); TL_ReplaceDosExtension(batFilename, ".bat"); strcpy(txtFilename,"c:\\"); TL_TempFilename(txtFilename); TL_ReplaceDosExtension(txtFilename, ".txt"); if (filecount) { // create bat file fp = fopen(batFilename, "wt+"); if (!fp) TL_Error("Could not open bat file '%s'", batFilename); fprintf(fp, "@echo off\n"); fprintf(fp, "@call \"%s\" > nul: \n", vcvarsPath); fprintf(fp, "@dumpbin %%1 > %s\n", txtFilename); fclose(fp); } for (i=0; ifilename, batFilename, txtFilename); if (filecount) AnalyzeData(); if (filecount) { FreeInfo(); unlink(batFilename); unlink(txtFilename); } TL_FreeFileList(filecount,filelist); TL_End(false); return (0); }