diff --git a/mozilla/tools/codesighs/autosummary.win.bash b/mozilla/tools/codesighs/autosummary.win.bash index 7488fa90d84..72c7d0fded8 100755 --- a/mozilla/tools/codesighs/autosummary.win.bash +++ b/mozilla/tools/codesighs/autosummary.win.bash @@ -94,6 +94,27 @@ SUMMARYFILE="$3" MYTMPDIR=`mktemp -d ./codesighs.tmp.XXXXXXXX` +# +# Find all object files. +# +ALLOBJSFILE="$MYTMPDIR/allobjs.list" +find ./mozilla -type f -name "*.obj" > $ALLOBJSFILE + + +# +# Get a dump of the symbols in every object file. +# +ALLOBJSYMSFILE="$MYTMPDIR/allobjsyms.list" +xargs -n 1 dumpbin.exe /symbols < $ALLOBJSFILE > $ALLOBJSYMSFILE 2> /dev/null + + +# +# Produce the symdb for the symbols in all object files. +# +SYMDBFILE="$MYTMPDIR/symdb.tsv" +./mozilla/dist/bin/msdump2symdb --input $ALLOBJSYMSFILE | sort > $SYMDBFILE 2> /dev/null + + # # Find all map files. # @@ -105,7 +126,7 @@ find ./mozilla -type f -name "*.map" > $ALLMAPSFILE # Produce the TSV output. # RAWTSVFILE="$MYTMPDIR/raw.tsv" -xargs -n 1 ./mozilla/dist/bin/msmap2tsv --input < $ALLMAPSFILE > $RAWTSVFILE 2> /dev/null +xargs -n 1 ./mozilla/dist/bin/msmap2tsv --symdb $SYMDBFILE --input < $ALLMAPSFILE > $RAWTSVFILE 2> /dev/null # diff --git a/mozilla/tools/codesighs/msdump2symdb.c b/mozilla/tools/codesighs/msdump2symdb.c index 323655830d5..b4941fc73f4 100755 --- a/mozilla/tools/codesighs/msdump2symdb.c +++ b/mozilla/tools/codesighs/msdump2symdb.c @@ -531,6 +531,7 @@ int processLine(Options* inOptions, MSDump_Container* inContainer, const char* i { const char* offsetArg = NULL; const char* classArg = NULL; + unsigned classWords = 1; /* ** This is an section we've seen before, and must list a symbol. @@ -545,6 +546,10 @@ int processLine(Options* inOptions, MSDump_Container* inContainer, const char* i { classArg = skipToArg(classArg, 2); } + if(0 == strncmp(classArg, ".bf or.ef", 9)) + { + classWords = 2; + } if(0 != strncmp(classArg, "Label", 5)) { @@ -571,7 +576,7 @@ int processLine(Options* inOptions, MSDump_Container* inContainer, const char* i const char* symbolArg = NULL; - symbolArg = skipToArg(classArg, 3); + symbolArg = skipToArg(classArg, 3 + (classWords - 1)); /* @@ -767,11 +772,11 @@ int reportContainer(Options* inOptions, MSDump_Container* inContainer) { for(symbolLoop = 0; 0 == retval && symbolLoop < inContainer->mObjects[objectLoop].mSections[sectionLoop].mSymbolCount; symbolLoop++) { - printRes = fprintf(inOptions->mOutput, "%s\t%s\t%s\t%.8X\n", + printRes = fprintf(inOptions->mOutput, "%s\t%s\t%.8X\t%s\n", inContainer->mObjects[objectLoop].mSections[sectionLoop].mSymbols[symbolLoop].mName, inContainer->mObjects[objectLoop].mSections[sectionLoop].mType, - inContainer->mObjects[objectLoop].mObject, - inContainer->mObjects[objectLoop].mSections[sectionLoop].mSymbols[symbolLoop].mSize + inContainer->mObjects[objectLoop].mSections[sectionLoop].mSymbols[symbolLoop].mSize, + inContainer->mObjects[objectLoop].mObject ); if(0 > printRes) @@ -1040,7 +1045,7 @@ void showHelp(Options* inOptions) printf(DESC_NEWLINE "%s\n\n", gSwitches[loop]->mDescription); } - printf("This tool takes the output of \"dumpbin /summary\" to produce a simple\n"); + printf("This tool takes the output of \"dumpbin /symbols\" to produce a simple\n"); printf("tsv db file of symbols and their respective attributes, like size.\n"); } diff --git a/mozilla/tools/codesighs/msmap.h b/mozilla/tools/codesighs/msmap.h index d8d46caf80f..8a5cee6f834 100644 --- a/mozilla/tools/codesighs/msmap.h +++ b/mozilla/tools/codesighs/msmap.h @@ -74,6 +74,7 @@ typedef struct __struct_MSMap_Symbol address mRVABase; char* mObject; MSMap_SymbolScope mScope; + unsigned mSymDBSize; } MSMap_Symbol; diff --git a/mozilla/tools/codesighs/msmap2tsv.c b/mozilla/tools/codesighs/msmap2tsv.c index dab66c68b57..c432a45f989 100644 --- a/mozilla/tools/codesighs/msmap2tsv.c +++ b/mozilla/tools/codesighs/msmap2tsv.c @@ -67,6 +67,85 @@ #define CLEANUP(ptr) do { if(NULL != ptr) { free(ptr); ptr = NULL; } } while(0) +typedef struct __struct_SymDB_Size +/* +** The size of the symbol. +** The size is nested withing a symbols structures to produce a fast +** lookup path. +** The objects are listed in case the client of the symdb needs to +** match the object name in the scenario where multiple symbol +** sizes are present. +** +** mSize The size of the symbol in these objects. +** mObjects A list of objects containing said symbol. +** mObjectCount Number of objects. +*/ +{ + unsigned mSize; + char** mObjects; + unsigned mObjectCount; +} +SymDB_Size; + + +typedef struct __struct_SymDB_Section +/* +** Each section for a symbol has a list of sizes. +** Should there be exactly one size for the symbol, then that +** is the size that should be accepted. +** If there is more than one size, then a match on the object +** should be attempted, held withing each size. +** +** mName The section name. +** mSizes The varoius sizes of the symbol in this section. +** mSizeCount The number of available sizes. +*/ +{ + char* mName; + SymDB_Size* mSizes; + unsigned mSizeCount; +} +SymDB_Section; + + +typedef struct __struct_SymDB_Symbol +/* +** Each symbol has at least one section. +** The section indicates what type of symbol a client may be looking for. +** If there is no match on the section, then the client should not trust +** the symbdb. +** +** mName The mangled name of the symbol. +** mSections Various sections this symbol belongs to. +** mSectionCount The number of sections. +*/ +{ + char* mName; + SymDB_Section* mSections; + unsigned mSectionCount; +} +SymDB_Symbol; + + +typedef struct __struct_SymDB_Container +/* +** The symbol DB container object. +** The goal of the symbol DB is to have exactly one SymDB_Symbol for each +** mangled name, no matter how ever many identical mangled names there +** are in the input. +** The input is already expected to be well sorted, futher this leads to +** the ability to binary search for symbol name matches. +** +** mSymbols The symbols. +** mSymbolCount The number of symbols in the DB. +*/ +{ + SymDB_Symbol* mSymbols; + unsigned mSymbolCount; +} +SymDB_Container; + + typedef struct __struct_Options /* ** Options to control how we perform. @@ -82,6 +161,7 @@ typedef struct __struct_Options ** mAddress Wether or not to output addresses. ** mMatchModules Array of strings which the module name should match. ** mMatchModuleCount Number of items in array. +** mSymDBName Symbol DB filename. */ { const char* mProgramName; @@ -93,6 +173,8 @@ typedef struct __struct_Options int mAddresses; char** mMatchModules; unsigned mMatchModuleCount; + char* mSymDBName; + SymDB_Container* mSymDB; } Options; @@ -117,12 +199,14 @@ static Switch gOutputSwitch = {"--output", "-o", 1, NULL, "Specify output file." static Switch gHelpSwitch = {"--help", "-h", 0, NULL, "Information on usage."}; static Switch gAddressesSwitch = {"--addresses", "-a", 0, NULL, "Output segment addresses." DESC_NEWLINE "Helps reveal symbol ordering." DESC_NEWLINE "Lack of simplifies size diffing."}; static Switch gMatchModuleSwitch = {"--match-module", "-mm", 1, NULL, "Specify a valid module name." DESC_NEWLINE "Multiple specifications allowed." DESC_NEWLINE "If a module name does not match one of the names specified then no output will occur."}; +static Switch gSymDBSwitch = {"--symdb", "-sdb", 1, NULL, "Specify a symbol tsv db input file." DESC_NEWLINE "Such a symdb is produced using the tool msdump2symdb." DESC_NEWLINE "This allows better symbol size approximations." DESC_NEWLINE "The symdb file must be pre-sorted."}; static Switch* gSwitches[] = { &gInputSwitch, &gOutputSwitch, &gAddressesSwitch, &gMatchModuleSwitch, + &gSymDBSwitch, &gHelpSwitch }; @@ -213,6 +297,70 @@ char* lastWord(char* inString) } +int readSymDB(const char* inDBName, SymDB_Container** outDB) +/* +** Intialize the symbol DB. +** Only call if the symbol DB should be initialized. +*/ +{ + int retval = 0; + + /* + ** Initialize out arguments. + */ + if(NULL != outDB) + { + *outDB = NULL; + } + + if(NULL != outDB && NULL != inDBName) + { + /* + ** TODO + */ + } + else + { + retval = __LINE__; + ERROR_REPORT(retval, "(NULL)", "Invalid arguments."); + } + + return retval; +} + + +int fillSymbolSizeFromDB(Options* inOptions, MSMap_Symbol* inoutSymbol, const char* inMangledName) +/* +** If we have a symbol DB, attempt to determine the real size of the symbol +** up front. +** This helps us later in the game to avoid performing size guesses by +** offset. +*/ +{ + int retval = 0; + + /* + ** May need to initialize symdb. + */ + if(NULL == inOptions->mSymDB && NULL != inOptions->mSymDBName) + { + retval = readSymDB(inOptions->mSymDBName, &inOptions->mSymDB); + } + + /* + ** Optional + */ + if(0 == retval && NULL != inOptions->mSymDB) + { + /* + ** TODO + */ + } + + return retval; +} + + char* symdup(const char* inSymbol) /* ** Attempts to demangle the symbol if appropriate. @@ -694,7 +842,15 @@ int readmap(Options* inOptions, MSMap_Module* inModule) char *last = lastWord(current); theSymbol->mObject = strdup(last); - if(NULL == theSymbol->mObject) + if(NULL != theSymbol->mObject) + { + /* + ** Finally, attempt to lookup the actual size of the symbol + ** if there is a symbol DB available. + */ + retval = fillSymbolSizeFromDB(inOptions, theSymbol, symbolBuf); + } + else { retval = __LINE__; ERROR_REPORT(retval, last, "Unable to copy object name."); @@ -1402,6 +1558,16 @@ int initOptions(Options* outOptions, int inArgc, char** inArgv) ERROR_REPORT(retval, current->mValue, "Unable to allocate space for string."); } } + else if(current == &gSymDBSwitch) + { + CLEANUP(outOptions->mSymDBName); + outOptions->mSymDBName = strdup(current->mValue); + if(NULL == outOptions->mSymDBName) + { + retval = __LINE__; + ERROR_REPORT(retval, current->mValue, "Unable to duplicate symbol db name."); + } + } else { retval = __LINE__;