From 1c1ace2db012919f23b6de5400ab192b9277dfc6 Mon Sep 17 00:00:00 2001 From: Bill Hoffman Date: Mon, 16 Nov 2015 15:31:10 -0500 Subject: De-duplicate symbols listed in generated module definition files MS tools have a limit on the number of symbols that can be listed in a `.def` file. If multiple `.obj` files provide a symbol then avoid listing it more than once in the generated `.def` file to avoid counting toward the limit. --- Source/bindexplib.cxx | 61 ++++++++++++++++++++++++++++++++++----------------- Source/bindexplib.h | 29 ++++++++++++++++++++++++ Source/cmcmd.cxx | 8 ++++--- 3 files changed, 75 insertions(+), 23 deletions(-) create mode 100644 Source/bindexplib.h diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx index dc4db63..64621e0 100644 --- a/Source/bindexplib.cxx +++ b/Source/bindexplib.cxx @@ -70,7 +70,7 @@ * Author: Valery Fine 16/09/96 (E-mail: fine@vxcern.cern.ch) *---------------------------------------------------------------------- */ - +#include "bindexplib.h" #include #include #include @@ -173,15 +173,17 @@ public: */ DumpSymbols(ObjectHeaderType* ih, - FILE* fout, bool is64) { + std::set& symbols, + std::set& dataSymbols, + bool is64) + :Symbols(symbols), DataSymbols(dataSymbols) + { this->ObjectImageHeader = ih; this->SymbolTable = (SymbolTableType*) ((DWORD_PTR)this->ObjectImageHeader + this->ObjectImageHeader->PointerToSymbolTable); - this->FileOut = fout; this->SectionHeaders = GetSectionHeaderOffset(this->ObjectImageHeader); - this->ImportFlag = true; this->SymbolCount = this->ObjectImageHeader->NumberOfSymbols; this->Is64Bit = is64; } @@ -296,10 +298,6 @@ public: symbol.erase(0,1); } } - if (this->ImportFlag) { - this->ImportFlag = false; - fprintf(this->FileOut,"EXPORTS \n"); - } /* Check whether it is "Scalar deleting destructor" and "Vector deleting destructor" @@ -319,11 +317,11 @@ public: SectionHeaders[pSymbolTable->SectionNumber-1].Characteristics; if (!pSymbolTable->Type && (SectChar & IMAGE_SCN_MEM_WRITE)) { // Read only (i.e. constants) must be excluded - fprintf(this->FileOut, "\t%s \t DATA\n", symbol.c_str()); + this->DataSymbols.insert(symbol); } else { if ( pSymbolTable->Type || !(SectChar & IMAGE_SCN_MEM_READ)) { - fprintf(this->FileOut, "\t%s\n", symbol.c_str()); + this->Symbols.insert(symbol); } else { // printf(" strange symbol: %s \n",symbol.c_str()); } @@ -340,11 +338,7 @@ public: symbol = stringTable + pSymbolTable->N.Name.Long; while (isspace(symbol[0])) symbol.erase(0,1); if (symbol[0] == '_') symbol.erase(0,1); - if (!this->ImportFlag) { - this->ImportFlag = true; - fprintf(this->FileOut,"IMPORTS \n"); - } - fprintf(this->FileOut, "\t%s DATA \n", symbol.c_str()+1); + this->DataSymbols.insert(symbol); } } @@ -357,8 +351,8 @@ public: } } private: - bool ImportFlag; - FILE* FileOut; + std::set& Symbols; + std::set& DataSymbols; DWORD_PTR SymbolCount; PIMAGE_SECTION_HEADER SectionHeaders; ObjectHeaderType* ObjectImageHeader; @@ -367,7 +361,9 @@ private: }; bool -DumpFile(const char* filename, FILE *fout) +DumpFile(const char* filename, + std::set& symbols, + std::set& dataSymbols) { HANDLE hFile; HANDLE hFileMapping; @@ -415,7 +411,7 @@ DumpFile(const char* filename, FILE *fout) * and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0; */ DumpSymbols - symbolDumper((PIMAGE_FILE_HEADER) lpFileBase, fout, + symbolDumper((PIMAGE_FILE_HEADER) lpFileBase, symbols, dataSymbols, (dosHeader->e_magic == IMAGE_FILE_MACHINE_AMD64)); symbolDumper.DumpObjFile(); } else { @@ -424,7 +420,8 @@ DumpFile(const char* filename, FILE *fout) (cmANON_OBJECT_HEADER_BIGOBJ*) lpFileBase; if(h->Sig1 == 0x0 && h->Sig2 == 0xffff) { DumpSymbols - symbolDumper((cmANON_OBJECT_HEADER_BIGOBJ*) lpFileBase, fout, + symbolDumper((cmANON_OBJECT_HEADER_BIGOBJ*) lpFileBase, symbols, + dataSymbols, (dosHeader->e_magic == IMAGE_FILE_MACHINE_AMD64)); symbolDumper.DumpObjFile(); } else { @@ -437,3 +434,27 @@ DumpFile(const char* filename, FILE *fout) CloseHandle(hFile); return true; } + +bool bindexplib::AddObjectFile(const char* filename) +{ + if(!DumpFile(filename, this->Symbols, this->DataSymbols)) + { + return false; + } + return true; +} + +void bindexplib::WriteFile(FILE* file) +{ + fprintf(file,"EXPORTS \n"); + for(std::set::const_iterator i = this->DataSymbols.begin(); + i!= this->DataSymbols.end(); ++i) + { + fprintf(file, "\t%s \t DATA\n", i->c_str()); + } + for(std::set::const_iterator i = this->Symbols.begin(); + i!= this->Symbols.end(); ++i) + { + fprintf(file, "\t%s\n", i->c_str()); + } +} diff --git a/Source/bindexplib.h b/Source/bindexplib.h new file mode 100644 index 0000000..8661a4a --- /dev/null +++ b/Source/bindexplib.h @@ -0,0 +1,29 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef bindexplib_h +#define bindexplib_h + +#include "cmStandardIncludes.h" + + +class bindexplib +{ +public: + bindexplib() {} + bool AddObjectFile(const char* filename); + void WriteFile(FILE* file); +private: + std::set Symbols; + std::set DataSymbols; +}; +#endif diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index be492ed..54a1590 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -35,8 +35,7 @@ #include // required for atoi #if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE) -// defined in binexplib.cxx -bool DumpFile(const char* filename, FILE *fout); +#include "bindexplib.h" #endif void CMakeCommandUsage(const char* program) @@ -240,13 +239,16 @@ int cmcmd::ExecuteCMakeCommand(std::vector& args) return 1; } std::string objfile; + bindexplib deffile; while(cmSystemTools::GetLineFromStream(fin, objfile)) { - if (!DumpFile(objfile.c_str(), fout)) + if( !deffile.AddObjectFile(objfile.c_str())) { return 1; } } + deffile.WriteFile(fout); + fclose(fout); return 0; } #endif -- cgit v0.12