[Cmake-commits] CMake branch, next, updated. v3.3.0-rc3-852-g8c93328

Brad King brad.king at kitware.com
Mon Jul 6 11:11:15 EDT 2015


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  8c93328befb1ed614315823da17a99957693a914 (commit)
       via  8f86407cfd4331dc1f2eb67f4f179ed8fe9dea06 (commit)
       via  069aa93b555293679f4b8c07623133ba62a74ee4 (commit)
       via  61bbbdcf9c0d1aed584fb976cd20c55ee9077850 (commit)
       via  de70c922d9c846cf3a6fabfbedd054c02f4b8934 (commit)
       via  8ea69dfef1e81a9811fe8a3d7198580dd21cb48f (commit)
       via  2963cb2a559fd27edd53b7fb7036cba0adc8b9ca (commit)
       via  4ff09893232b26b5c2961fb1e2a31836cad00a35 (commit)
       via  7de8276ca92db0630009eeab865afc445a30e1b8 (commit)
       via  65086ad778b5d8312e4168fc5ed670e545be7d4b (commit)
      from  eefacae6aff8b518c5b644b8148c3de0cdf84a01 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8c93328befb1ed614315823da17a99957693a914
commit 8c93328befb1ed614315823da17a99957693a914
Merge: eefacae 8f86407
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jul 6 11:11:14 2015 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Mon Jul 6 11:11:14 2015 -0400

    Merge topic 'auto_export_dll_symbols' into next
    
    8f86407c Windows: Optionally generate DLL module definition files automatically
    069aa93b bindexplib: Add support for "/bigobj" format objects
    61bbbdcf bindexplib: Fix treatment of some symbols
    de70c922 bindexplib: Teach DumpFile to return errors
    8ea69dfe bindexplib: Build source as part of CMakeLib
    2963cb2a bindexplib: Wrap long lines
    4ff09893 bindexplib: Drop code that CMake does not need
    7de8276c bindexplib: Add copyright/license notice block
    65086ad7 bindexplib: Import original implementation from CERN


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8f86407cfd4331dc1f2eb67f4f179ed8fe9dea06
commit 8f86407cfd4331dc1f2eb67f4f179ed8fe9dea06
Author:     Bill Hoffman <bill.hoffman at kitware.com>
AuthorDate: Fri Jun 19 16:12:43 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jul 6 11:11:02 2015 -0400

    Windows: Optionally generate DLL module definition files automatically
    
    Create target property WINDOWS_EXPORT_ALL_SYMBOLS to automatically
    generate a module definition file from MS-compatible .obj files and give
    it to the linker in order to export all symbols from the .dll part of a
    SHARED library.

diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 9a60a10..b767ed6 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -251,6 +251,7 @@ Properties on Targets
    /prop_tgt/VS_WINRT_EXTENSIONS
    /prop_tgt/VS_WINRT_REFERENCES
    /prop_tgt/WIN32_EXECUTABLE
+   /prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS
    /prop_tgt/XCODE_ATTRIBUTE_an-attribute
    /prop_tgt/XCTEST
 
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 0e6222f..7c7db5e 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -275,6 +275,7 @@ Variables that Control the Build
    /variable/CMAKE_USE_RELATIVE_PATHS
    /variable/CMAKE_VISIBILITY_INLINES_HIDDEN
    /variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD
+   /variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
    /variable/CMAKE_WIN32_EXECUTABLE
    /variable/CMAKE_XCODE_ATTRIBUTE_an-attribute
    /variable/EXECUTABLE_OUTPUT_PATH
diff --git a/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst
new file mode 100644
index 0000000..3f48af8
--- /dev/null
+++ b/Help/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.rst
@@ -0,0 +1,18 @@
+WINDOWS_EXPORT_ALL_SYMBOLS
+--------------------------
+
+This property is implemented only for MS-compatible tools on Windows.
+
+Enable this boolean property to automatically create a module definition
+(``.def``) file with all global symbols found in the input ``.obj`` files
+for a ``SHARED`` library on Windows.  The module definition file will be
+passed to the linker causing all symbols to be exported from the ``.dll``.
+For global *data* symbols, ``__declspec(dllimport)`` must still be used when
+compiling against the code in the ``.dll``.  All other function symbols will
+be automatically exported and imported by callers.  This simplifies porting
+projects to Windows by reducing the need for explicit ``dllexport`` markup,
+even in ``C++`` classes.
+
+This property is initialized by the value of
+the :variable:`CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS` variable if it is set
+when a target is created.
diff --git a/Help/release/dev/auto_export_dll_symbols.rst b/Help/release/dev/auto_export_dll_symbols.rst
new file mode 100644
index 0000000..9db2b5e
--- /dev/null
+++ b/Help/release/dev/auto_export_dll_symbols.rst
@@ -0,0 +1,6 @@
+auto_export_dll_symbols
+-----------------------
+
+* On Windows with MS-compatible tools, CMake learned to optionally
+  generate a module definition (``.def``) file for ``SHARED`` libraries.
+  See the :prop_tgt:`WINDOWS_EXPORT_ALL_SYMBOLS` target property.
diff --git a/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst b/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst
new file mode 100644
index 0000000..1636842
--- /dev/null
+++ b/Help/variable/CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS.rst
@@ -0,0 +1,6 @@
+CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
+--------------------------------
+
+Default value for :prop_tgt:`WINDOWS_EXPORT_ALL_SYMBOLS` target property.
+This variable is used to initialize the property on each target as it is
+created.
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index 13fe8bc..aeaa2bd 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -46,8 +46,10 @@ else()
   set(_PLATFORM_LINK_FLAGS "")
 endif()
 
+set(CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS 1)
 if(CMAKE_GENERATOR MATCHES "Visual Studio 6")
    set (CMAKE_NO_BUILD_TYPE 1)
+   set(CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS 0) # not implemented for VS6
 endif()
 if(NOT CMAKE_NO_BUILD_TYPE AND CMAKE_GENERATOR MATCHES "Visual Studio")
   set (CMAKE_NO_BUILD_TYPE 1)
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 585d19a..bc134e1 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -13,12 +13,14 @@
 #include "cmGlobalVisualStudioGenerator.h"
 
 #include "cmCallVisualStudioMacro.h"
+#include "cmGeneratedFileStream.h"
 #include "cmGeneratorTarget.h"
 #include "cmLocalVisualStudioGenerator.h"
 #include "cmMakefile.h"
 #include "cmSourceFile.h"
 #include "cmTarget.h"
 #include <cmsys/Encoding.hxx>
+#include "cmAlgorithms.h"
 
 //----------------------------------------------------------------------------
 cmGlobalVisualStudioGenerator::cmGlobalVisualStudioGenerator(cmake* cm)
@@ -887,3 +889,71 @@ std::string cmGlobalVisualStudioGenerator::ExpandCFGIntDir(
     }
   return tmp;
 }
+
+void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
+  cmGeneratorTarget* gt, std::vector<cmCustomCommand>& commands,
+  std::string const& configName)
+{
+  std::vector<std::string> outputs;
+  std::string deffile = gt->ObjectDirectory;
+  deffile += "/exportall.def";
+  outputs.push_back(deffile);
+  std::vector<std::string> empty;
+  std::vector<cmSourceFile const*> objectSources;
+  gt->GetObjectSources(objectSources, configName);
+  std::map<cmSourceFile const*, std::string> mapping;
+  for(std::vector<cmSourceFile const*>::const_iterator it
+        = objectSources.begin(); it != objectSources.end(); ++it)
+    {
+    mapping[*it];
+    }
+  gt->LocalGenerator->
+    ComputeObjectFilenames(mapping, gt);
+  std::string obj_dir = gt->ObjectDirectory;
+  std::string cmakeCommand = cmSystemTools::GetCMakeCommand();
+  cmSystemTools::ConvertToWindowsExtendedPath(cmakeCommand);
+  cmCustomCommandLine cmdl;
+  cmdl.push_back(cmakeCommand);
+  cmdl.push_back("-E");
+  cmdl.push_back("__create_def");
+  cmdl.push_back(deffile);
+  std::string obj_dir_expanded = obj_dir;
+  cmSystemTools::ReplaceString(obj_dir_expanded,
+                               this->GetCMakeCFGIntDir(),
+                               configName.c_str());
+  std::string objs_file = obj_dir_expanded;
+  cmSystemTools::MakeDirectory(objs_file.c_str());
+  objs_file += "/objects.txt";
+  cmdl.push_back(objs_file);
+  cmGeneratedFileStream fout(objs_file.c_str());
+  if(!fout)
+    {
+    cmSystemTools::Error("could not open ", objs_file.c_str());
+    return;
+    }
+  for(std::vector<cmSourceFile const*>::const_iterator it
+        = objectSources.begin(); it != objectSources.end(); ++it)
+    {
+    // Find the object file name corresponding to this source file.
+    std::map<cmSourceFile const*, std::string>::const_iterator
+      map_it = mapping.find(*it);
+    // It must exist because we populated the mapping just above.
+    assert(!map_it->second.empty());
+    std::string objFile = obj_dir + map_it->second;
+    // replace $(ConfigurationName) in the object names
+    cmSystemTools::ReplaceString(objFile, this->GetCMakeCFGIntDir(),
+                                 configName.c_str());
+    if(cmHasLiteralSuffix(objFile, ".obj"))
+      {
+      fout << objFile << "\n";
+      }
+    }
+  cmCustomCommandLines commandLines;
+  commandLines.push_back(cmdl);
+  cmCustomCommand command(gt->Target->GetMakefile(),
+                          outputs, empty, empty,
+                          commandLines,
+                          "Auto build dll exports",
+                          ".");
+  commands.push_back(command);
+}
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index 69b4564..022e190 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -102,6 +102,10 @@ public:
                                       const std::string& config) const;
 
   void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
+
+  void AddSymbolExportCommand(
+    cmGeneratorTarget*, std::vector<cmCustomCommand>& commands,
+    std::string const& configName);
 protected:
   virtual void Generate();
 
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index dc3a16d..a0e9e4d 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -1081,6 +1081,14 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
       this->ConvertToOutputFormat(this->ModuleDefinitionFile, SHELL);
     linkOptions.AddFlag("ModuleDefinitionFile", defFile.c_str());
     }
+  if (target.GetType() == cmTarget::SHARED_LIBRARY &&
+      this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    if (target.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+      {
+      linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)/exportall.def");
+      }
+    }
   switch(target.GetType())
     {
     case cmTarget::UNKNOWN_LIBRARY:
@@ -2015,7 +2023,28 @@ void cmLocalVisualStudio7Generator
   // Add pre-link event.
   tool = this->FortranProject? "VFPreLinkEventTool":"VCPreLinkEventTool";
   event.Start(tool);
-  event.Write(target.GetPreLinkCommands());
+  bool addedPrelink = false;
+  if (target.GetType() == cmTarget::SHARED_LIBRARY &&
+      this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    if (target.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+      {
+      addedPrelink = true;
+      std::vector<cmCustomCommand> commands =
+        target.GetPreLinkCommands();
+      cmGlobalVisualStudioGenerator* gg
+        = static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
+      cmGeneratorTarget* gt =
+        this->GlobalGenerator->GetGeneratorTarget(&target);
+      gg->AddSymbolExportCommand(
+        gt, commands, configName);
+      event.Write(commands);
+      }
+    }
+  if (!addedPrelink)
+    {
+    event.Write(target.GetPreLinkCommands());
+    }
   cmsys::auto_ptr<cmCustomCommand> pcc(
     this->MaybeCreateImplibDir(target, configName, this->FortranProject));
   if(pcc.get())
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 660027c..696dcc4 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -18,6 +18,7 @@
 #include "cmSourceFile.h"
 #include "cmTarget.h"
 #include "cmake.h"
+#include "cmAlgorithms.h"
 
 //----------------------------------------------------------------------------
 cmMakefileLibraryTargetGenerator
@@ -563,6 +564,58 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
                           useResponseFileForObjects, buildObjs, depends,
                           useWatcomQuote);
 
+  // maybe create .def file from list of objects
+  if (this->Target->GetType() == cmTarget::SHARED_LIBRARY &&
+      this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    if(this->Target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+      {
+      std::string name_of_def_file =
+        this->Target->GetSupportDirectory();
+      name_of_def_file += std::string("/") +
+        this->Target->GetName();
+      name_of_def_file += ".def";
+      std::string cmd = cmSystemTools::GetCMakeCommand();
+      cmd = this->Convert(cmd, cmLocalGenerator::NONE,
+                          cmLocalGenerator::SHELL);
+      cmd += " -E __create_def ";
+      cmd += this->Convert(name_of_def_file,
+                           cmLocalGenerator::START_OUTPUT,
+                           cmLocalGenerator::SHELL);
+      cmd += " ";
+      std::string objlist_file = name_of_def_file;
+      objlist_file += ".objs";
+      cmd += this->Convert(objlist_file,
+                           cmLocalGenerator::START_OUTPUT,
+                           cmLocalGenerator::SHELL);
+      real_link_commands.push_back(cmd);
+      // create a list of obj files for the -E __create_def to read
+      cmGeneratedFileStream fout(objlist_file.c_str());
+      for(std::vector<std::string>::const_iterator i = this->Objects.begin();
+          i != this->Objects.end(); ++i)
+        {
+        if(cmHasLiteralSuffix(*i, ".obj"))
+          {
+          fout << *i << "\n";
+          }
+        }
+      for(std::vector<std::string>::const_iterator i =
+        this->ExternalObjects.begin();
+          i != this->ExternalObjects.end(); ++i)
+        {
+        fout << *i << "\n";
+        }
+      // now add the def file link flag
+      linkFlags += " ";
+      linkFlags +=
+        this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
+      linkFlags += this->Convert(name_of_def_file,
+                                 cmLocalGenerator::START_OUTPUT,
+                                 cmLocalGenerator::SHELL);
+      linkFlags += " ";
+      }
+    }
+
   cmLocalGenerator::RuleVariables vars;
   vars.TargetPDB = targetOutPathPDB.c_str();
 
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 2fe53bf..88da09b 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -486,6 +486,22 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
                           linkPath,
                           &genTarget,
                           useWatcomQuote);
+  if(this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")
+     && target.GetType() == cmTarget::SHARED_LIBRARY)
+    {
+    if(target.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+      {
+      std::string dllname = targetOutput;
+      std::string name_of_def_file
+        = target.GetSupportDirectory();
+      name_of_def_file += "/" + target.GetName();
+      name_of_def_file += ".def ";
+      vars["LINK_FLAGS"] += " /DEF:";
+      vars["LINK_FLAGS"] += this->GetLocalGenerator()
+        ->ConvertToOutputFormat(name_of_def_file.c_str(),
+                                cmLocalGenerator::SHELL);
+      }
+    }
 
   this->addPoolNinjaVariable("JOB_POOL_LINK", &target, vars);
 
@@ -600,6 +616,44 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
       }
     }
 
+  // maybe create .def file from list of objects
+  if (target.GetType() == cmTarget::SHARED_LIBRARY &&
+      this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    if(target.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+      {
+      std::string cmakeCommand =
+      this->GetLocalGenerator()->ConvertToOutputFormat(
+        cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
+      std::string dllname = targetOutput;
+      std::string name_of_def_file
+        = target.GetSupportDirectory();
+      name_of_def_file += "/" + target.GetName();
+      name_of_def_file += ".def";
+      std::string cmd = cmakeCommand;
+      cmd += " -E __create_def ";
+      cmd += this->GetLocalGenerator()
+        ->ConvertToOutputFormat(name_of_def_file.c_str(),
+                                cmLocalGenerator::SHELL);
+      cmd += " ";
+      cmNinjaDeps objs = this->GetObjects();
+      std::string obj_list_file = name_of_def_file;
+      obj_list_file += ".objs";
+      cmd += this->GetLocalGenerator()
+        ->ConvertToOutputFormat(obj_list_file.c_str(),
+                                cmLocalGenerator::SHELL);
+      preLinkCmdLines.push_back(cmd);
+      // create a list of obj files for the -E __create_def to read
+      cmGeneratedFileStream fout(obj_list_file.c_str());
+      for(cmNinjaDeps::iterator i=objs.begin(); i != objs.end(); ++i)
+        {
+        if(cmHasLiteralSuffix(*i, ".obj"))
+          {
+          fout << *i << "\n";
+          }
+        }
+      }
+    }
   // If we have any PRE_LINK commands, we need to go back to HOME_OUTPUT for
   // the link commands.
   if (!preLinkCmdLines.empty())
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index c7a13bc..8448431 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -429,6 +429,11 @@ void cmTarget::SetMakefile(cmMakefile* mf)
     {
     this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
     }
+  if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY)
+    {
+    this->SetPropertyDefault("WINDOWS_EXPORT_ALL_SYMBOLS", 0);
+    }
+
   if (this->GetType() != INTERFACE_LIBRARY && this->GetType() != UTILITY)
     {
     this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", 0);
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 12a1e42..57ec212 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2466,6 +2466,15 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
                            "%(IgnoreSpecificDefaultLibraries)");
     }
 
+  if (this->Target->GetType() == cmTarget::SHARED_LIBRARY &&
+      this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    if (this->Target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+      {
+      linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)exportall.def");
+      }
+    }
+
   this->LinkOptions[config] = pOptions.release();
   return true;
 }
@@ -2613,8 +2622,25 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
 void
 cmVisualStudio10TargetGenerator::WriteEvents(std::string const& configName)
 {
-  this->WriteEvent("PreLinkEvent",
-                   this->Target->GetPreLinkCommands(), configName);
+  bool addedPrelink = false;
+  if (this->Target->GetType() == cmTarget::SHARED_LIBRARY &&
+      this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS"))
+    {
+    if (this->Target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"))
+      {
+      addedPrelink = true;
+      std::vector<cmCustomCommand> commands =
+        this->Target->GetPreLinkCommands();
+      this->GlobalGenerator->AddSymbolExportCommand(
+        this->GeneratorTarget, commands, configName);
+      this->WriteEvent("PreLinkEvent", commands, configName);
+      }
+    }
+  if (!addedPrelink)
+    {
+    this->WriteEvent("PreLinkEvent",
+                     this->Target->GetPreLinkCommands(), configName);
+    }
   this->WriteEvent("PreBuildEvent",
                    this->Target->GetPreBuildCommands(), configName);
   this->WriteEvent("PostBuildEvent",
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 3ea2186..63838b4 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -34,6 +34,10 @@
 #include <time.h>
 
 #include <stdlib.h> // required for atoi
+#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+// defined in binexplib.cxx
+bool DumpFile(const char* filename, FILE *fout);
+#endif
 
 void CMakeCommandUsage(const char* program)
 {
@@ -211,6 +215,41 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
       return 0;
       }
 
+#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+    else if(args[1] == "__create_def")
+      {
+      if(args.size() < 4)
+        {
+        std::cerr <<
+          "__create_def Usage: -E __create_def outfile.def objlistfile\n";
+        return 1;
+        }
+      FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+");
+      if(!fout)
+        {
+        std::cerr << "could not open output .def file: " << args[2].c_str()
+                  << "\n";
+        return 1;
+        }
+      cmsys::ifstream fin(args[3].c_str(),
+                          std::ios::in | std::ios::binary);
+      if(!fin)
+        {
+        std::cerr << "could not open object list file: " << args[3].c_str()
+                  << "\n";
+        return 1;
+        }
+      std::string objfile;
+      while(cmSystemTools::GetLineFromStream(fin, objfile))
+        {
+        if (!DumpFile(objfile.c_str(), fout))
+          {
+          return 1;
+          }
+        }
+      return 0;
+      }
+#endif
     // run include what you use command and then run the compile
     // command. This is an internal undocumented option and should
     // only be used by CMake itself when running iwyu.
diff --git a/Tests/RunCMake/AutoExportDll/AutoExport.cmake b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
new file mode 100644
index 0000000..3b2b2c5
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
@@ -0,0 +1,7 @@
+project(autoexport)
+set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${autoexport_BINARY_DIR}/bin)
+add_subdirectory(sub)
+add_library(autoexport SHARED hello.cxx world.cxx foo.c)
+add_executable(say say.cxx)
+target_link_libraries(say autoexport autoexport2)
diff --git a/Tests/RunCMake/AutoExportDll/AutoExportBuild-stderr.txt b/Tests/RunCMake/AutoExportDll/AutoExportBuild-stderr.txt
new file mode 100644
index 0000000..d483c2c
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/AutoExportBuild-stderr.txt
@@ -0,0 +1 @@
+^.*$
diff --git a/Tests/RunCMake/AutoExportDll/CMakeLists.txt b/Tests/RunCMake/AutoExportDll/CMakeLists.txt
new file mode 100644
index 0000000..18dfd26
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.2)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake
new file mode 100644
index 0000000..3784a6a
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake
@@ -0,0 +1,26 @@
+include(RunCMake)
+set(RunCMake_TEST_NO_CLEAN TRUE)
+set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/AutoExport-build")
+# start by cleaning up because we don't clean up along the way
+file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+# configure the AutoExport test
+run_cmake(AutoExport)
+unset(RunCMake_TEST_OPTIONS)
+# don't run this test on VS 6 as it is not supported
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 6|Watcom WMake|Borland Makefiles")
+  return()
+endif()
+# we build debug so the say.exe will be found in Debug/say.exe for
+# Visual Studio generators
+if("${RunCMake_GENERATOR}" MATCHES "Visual Studio|Xcode")
+  set(INTDIR "Debug/")
+endif()
+# build AutoExport
+run_cmake_command(AutoExportBuild ${CMAKE_COMMAND} --build
+  ${RunCMake_TEST_BINARY_DIR} --config Debug --clean-first)
+# run the executable that uses symbols from the dll
+if(WIN32)
+  set(EXE_EXT ".exe")
+endif()
+run_cmake_command(AutoExportRun
+  ${RunCMake_BINARY_DIR}/AutoExport-build/bin/${INTDIR}say${EXE_EXT})
diff --git a/Tests/RunCMake/AutoExportDll/foo.c b/Tests/RunCMake/AutoExportDll/foo.c
new file mode 100644
index 0000000..4b1318b
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/foo.c
@@ -0,0 +1,15 @@
+#ifdef _MSC_VER
+#include "windows.h"
+#else
+#define WINAPI
+#endif
+
+int WINAPI foo()
+{
+  return 10;
+}
+
+int bar()
+{
+  return 5;
+}
diff --git a/Tests/RunCMake/AutoExportDll/hello.cxx b/Tests/RunCMake/AutoExportDll/hello.cxx
new file mode 100644
index 0000000..3933fc1
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/hello.cxx
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include "hello.h"
+int Hello::Data = 0;
+void Hello::real()
+{
+  return;
+}
+void hello()
+{
+  printf("hello");
+}
+void Hello::operator delete[](void*) {};
+void Hello::operator delete(void*) {};
diff --git a/Tests/RunCMake/AutoExportDll/hello.h b/Tests/RunCMake/AutoExportDll/hello.h
new file mode 100644
index 0000000..3749b97
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/hello.h
@@ -0,0 +1,18 @@
+#ifndef _MSC_VER
+#define winexport
+#else
+#ifdef autoexport_EXPORTS
+#define winexport
+#else
+#define winexport __declspec(dllimport)
+#endif
+#endif
+
+class Hello
+{
+public:
+  static winexport int Data;
+  void real();
+  static void operator delete[](void*);
+  static void operator delete(void*);
+};
diff --git a/Tests/RunCMake/AutoExportDll/say.cxx b/Tests/RunCMake/AutoExportDll/say.cxx
new file mode 100644
index 0000000..655b3c2
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/say.cxx
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include "hello.h"
+#ifdef _MSC_VER
+#include "windows.h"
+#else
+#define WINAPI
+#endif
+
+extern "C"
+{
+// test __cdecl stuff
+  int WINAPI foo();
+// test regular C
+  int bar();
+}
+
+// test c++ functions
+// forward declare hello and world
+void hello();
+void world();
+
+int main()
+{
+  // test static data (needs declspec to work)
+  Hello::Data = 120;
+  Hello h;
+  h.real();
+  hello();
+  printf(" ");
+  world();
+  printf("\n");
+  foo();
+  printf("\n");
+  bar();
+  printf("\n");
+  return 0;
+}
diff --git a/Tests/RunCMake/AutoExportDll/sub/CMakeLists.txt b/Tests/RunCMake/AutoExportDll/sub/CMakeLists.txt
new file mode 100644
index 0000000..8b70e7d
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/sub/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_library(autoexport2 SHARED sub.cxx)
+if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+  # Try msvc "big" object format.
+  target_compile_options(autoexport2 PRIVATE /bigobj)
+endif()
diff --git a/Tests/RunCMake/AutoExportDll/sub/sub.cxx b/Tests/RunCMake/AutoExportDll/sub/sub.cxx
new file mode 100644
index 0000000..9766b41
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/sub/sub.cxx
@@ -0,0 +1,4 @@
+int sub()
+{
+  return 10;
+}
diff --git a/Tests/RunCMake/AutoExportDll/world.cxx b/Tests/RunCMake/AutoExportDll/world.cxx
new file mode 100644
index 0000000..3a54df3
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/world.cxx
@@ -0,0 +1,6 @@
+#include "stdio.h"
+
+void world()
+{
+  printf("world");
+}
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index bc706d3..743ef4b 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -266,3 +266,6 @@ if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
 endif()
 
 add_RunCMake_test_group(CPack "DEB;RPM")
+# add a test to make sure symbols are exported from a shared library
+# for MSVC compilers CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS property is used
+add_RunCMake_test(AutoExportDll)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=069aa93b555293679f4b8c07623133ba62a74ee4
commit 069aa93b555293679f4b8c07623133ba62a74ee4
Author:     Bill Hoffman <bill.hoffman at kitware.com>
AuthorDate: Thu Jul 2 17:46:25 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jul 6 11:11:01 2015 -0400

    bindexplib: Add support for "/bigobj" format objects

diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index 6a63279..11e3f34 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -78,6 +78,59 @@
 #include <fstream>
 #include <iostream>
 
+typedef struct cmANON_OBJECT_HEADER_BIGOBJ {
+   /* same as ANON_OBJECT_HEADER_V2 */
+    WORD    Sig1;            // Must be IMAGE_FILE_MACHINE_UNKNOWN
+    WORD    Sig2;            // Must be 0xffff
+    WORD    Version;         // >= 2 (implies the Flags field is present)
+    WORD    Machine;         // Actual machine - IMAGE_FILE_MACHINE_xxx
+    DWORD   TimeDateStamp;
+    CLSID   ClassID;         // {D1BAA1C7-BAEE-4ba9-AF20-FAF66AA4DCB8}
+    DWORD   SizeOfData;      // Size of data that follows the header
+    DWORD   Flags;           // 0x1 -> contains metadata
+    DWORD   MetaDataSize;    // Size of CLR metadata
+    DWORD   MetaDataOffset;  // Offset of CLR metadata
+
+    /* bigobj specifics */
+    DWORD   NumberOfSections; // extended from WORD
+    DWORD   PointerToSymbolTable;
+    DWORD   NumberOfSymbols;
+} cmANON_OBJECT_HEADER_BIGOBJ;
+
+typedef struct _cmIMAGE_SYMBOL_EX {
+    union {
+        BYTE     ShortName[8];
+        struct {
+            DWORD   Short;     // if 0, use LongName
+            DWORD   Long;      // offset into string table
+        } Name;
+        DWORD   LongName[2];    // PBYTE  [2]
+    } N;
+    DWORD   Value;
+    LONG    SectionNumber;
+    WORD    Type;
+    BYTE    StorageClass;
+    BYTE    NumberOfAuxSymbols;
+} cmIMAGE_SYMBOL_EX;
+typedef cmIMAGE_SYMBOL_EX UNALIGNED *cmPIMAGE_SYMBOL_EX;
+
+PIMAGE_SECTION_HEADER GetSectionHeaderOffset(PIMAGE_FILE_HEADER
+                                             pImageFileHeader)
+{
+  return (PIMAGE_SECTION_HEADER)
+    ((DWORD_PTR)pImageFileHeader +
+     IMAGE_SIZEOF_FILE_HEADER +
+     pImageFileHeader->SizeOfOptionalHeader);
+}
+
+PIMAGE_SECTION_HEADER GetSectionHeaderOffset(cmANON_OBJECT_HEADER_BIGOBJ*
+                                             pImageFileHeader)
+{
+  return (PIMAGE_SECTION_HEADER)
+      ((DWORD_PTR)pImageFileHeader          +
+       sizeof(cmANON_OBJECT_HEADER_BIGOBJ));
+}
+
 /*
 + * Utility func, strstr with size
 + */
@@ -102,44 +155,64 @@ const char* StrNStr(const char* start, const char* find, size_t &size) {
    return 0;
 }
 
-/*
- *----------------------------------------------------------------------
- * HaveExportedObjects --
- *
- *      Returns >0 if export directives (declspec(dllexport)) exist.
- *
- *----------------------------------------------------------------------
- */
-int
-HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader,
-                    PIMAGE_SECTION_HEADER pSectionHeaders)
+template <
+  // cmANON_OBJECT_HEADER_BIGOBJ or IMAGE_FILE_HEADER
+  class ObjectHeaderType,
+  // cmPIMAGE_SYMBOL_EX or PIMAGE_SYMBOL
+  class SymbolTableType>
+class DumpSymbols
 {
-    static int fImportFlag = 0;  /*  The status is nor defined yet */
-    WORD i;
-    size_t size;
-    char foundExports;
-    const char * rawdata;
+public:
+  /*
+   *----------------------------------------------------------------------
+   * Constructor --
+   *
+   *     Initialize variables from pointer to object header.
+   *
+   *----------------------------------------------------------------------
+   */
 
-    PIMAGE_SECTION_HEADER pDirectivesSectionHeader;
+   DumpSymbols(ObjectHeaderType* ih,
+               FILE* fout) {
+      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;
+   }
 
-    if (fImportFlag) return 1;
+  /*
+   *----------------------------------------------------------------------
+   * HaveExportedObjects --
+   *
+   *      Returns true if export directives (declspec(dllexport)) exist.
+   *
+   *----------------------------------------------------------------------
+   */
 
-    i = 0;
-    foundExports = 0;
-    pDirectivesSectionHeader = 0;
-    for(i = 0; (i < pImageFileHeader->NumberOfSections &&
-                !pDirectivesSectionHeader); i++)
+  bool HaveExportedObjects() {
+     WORD i = 0;
+     size_t size = 0;
+     const char * rawdata = 0;
+     PIMAGE_SECTION_HEADER pDirectivesSectionHeader = 0;
+     PIMAGE_SECTION_HEADER pSectionHeaders = this->SectionHeaders;
+     for(i = 0; (i < this->ObjectImageHeader->NumberOfSections &&
+                 !pDirectivesSectionHeader); i++)
        if (!strncmp((const char*)&pSectionHeaders[i].Name[0], ".drectve",8))
-          pDirectivesSectionHeader = &pSectionHeaders[i];
-   if (!pDirectivesSectionHeader) return 0;
+         pDirectivesSectionHeader = &pSectionHeaders[i];
+     if (!pDirectivesSectionHeader) return 0;
 
-    rawdata=(const char*)
-      pImageFileHeader+pDirectivesSectionHeader->PointerToRawData;
-    if (!pDirectivesSectionHeader->PointerToRawData || !rawdata) return 0;
+     rawdata=(const char*)
+       this->ObjectImageHeader+pDirectivesSectionHeader->PointerToRawData;
+     if (!pDirectivesSectionHeader->PointerToRawData || !rawdata) return 0;
 
-    size = pDirectivesSectionHeader->SizeOfRawData;
-    const char* posImportFlag = rawdata;
-    while ((posImportFlag = StrNStr(posImportFlag, " /EXPORT:", size))) {
+     size = pDirectivesSectionHeader->SizeOfRawData;
+     const char* posImportFlag = rawdata;
+     while ((posImportFlag = StrNStr(posImportFlag, " /EXPORT:", size))) {
        const char* lookingForDict = posImportFlag + 9;
        if (!strncmp(lookingForDict, "_G__cpp_",8) ||
            !strncmp(lookingForDict, "_G__set_cpp_",12)) {
@@ -153,38 +226,44 @@ HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader,
        // ignore DATA exports
        if (strncmp(lookingForDATA, ",DATA", 5)) break;
        posImportFlag = lookingForDATA + 5;
-    }
-    fImportFlag = (int)posImportFlag;
-    return fImportFlag;
-}
-
-
-
-/*
- *----------------------------------------------------------------------
-* DumpExternalsObjects --
-*
-*      Dumps a COFF symbol table from an EXE or OBJ.  We only use
-*      it to dump tables from OBJs.
-*----------------------------------------------------------------------
-*/
-void
-DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable,
-                     PIMAGE_SECTION_HEADER pSectionHeaders,
-                     FILE *fout, DWORD_PTR cSymbols)
-{
-   unsigned i;
-   PSTR stringTable;
-   std::string symbol;
-   DWORD SectChar;
-   static int fImportFlag = -1;  /*  The status is nor defined yet */
-
-   /*
-   * The string table apparently starts right after the symbol table
+     }
+     if(posImportFlag) {
+        return true;
+     }
+     return false;
+  }
+
+  /*
+   *----------------------------------------------------------------------
+   * DumpObjFile --
+   *
+   *      Dump an object file's exported symbols.
+   *----------------------------------------------------------------------
    */
-   stringTable = (PSTR)&pSymbolTable[cSymbols];
-
-   for ( i=0; i < cSymbols; i++ ) {
+  void DumpObjFile() {
+     if(!HaveExportedObjects()) {
+        this->DumpExternalsObjects();
+     }
+  }
+
+  /*
+   *----------------------------------------------------------------------
+   * DumpExternalsObjects --
+   *
+   *      Dumps a COFF symbol table from an OBJ.
+   *----------------------------------------------------------------------
+   */
+  void DumpExternalsObjects() {
+    unsigned i;
+    PSTR stringTable;
+    std::string symbol;
+    DWORD SectChar;
+    /*
+     * The string table apparently starts right after the symbol table
+     */
+    stringTable = (PSTR)&this->SymbolTable[this->SymbolCount];
+    SymbolTableType* pSymbolTable = this->SymbolTable;
+    for ( i=0; i < this->SymbolCount; i++ ) {
       if (pSymbolTable->SectionNumber > 0 &&
           ( pSymbolTable->Type == 0x20 || pSymbolTable->Type == 0x0)) {
          if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
@@ -209,9 +288,9 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable,
                }
             }
             if (symbol[0] == '_') symbol.erase(0,1);
-            if (fImportFlag) {
-               fImportFlag = 0;
-               fprintf(fout,"EXPORTS \n");
+            if (this->ImportFlag) {
+               this->ImportFlag = false;
+               fprintf(this->FileOut,"EXPORTS \n");
             }
             /*
             Check whether it is "Scalar deleting destructor" and
@@ -228,14 +307,15 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable,
                 symbol.compare(0, 4, vectorPrefix) )
             {
                SectChar =
-                pSectionHeaders[pSymbolTable->SectionNumber-1].Characteristics;
+                 this->
+                 SectionHeaders[pSymbolTable->SectionNumber-1].Characteristics;
                if (!pSymbolTable->Type  && (SectChar & IMAGE_SCN_MEM_WRITE)) {
                   // Read only (i.e. constants) must be excluded
-                  fprintf(fout, "\t%s \t DATA\n", symbol.c_str());
+                  fprintf(this->FileOut, "\t%s \t DATA\n", symbol.c_str());
                } else {
                   if ( pSymbolTable->Type  ||
                        !(SectChar & IMAGE_SCN_MEM_READ)) {
-                     fprintf(fout, "\t%s\n", symbol.c_str());
+                     fprintf(this->FileOut, "\t%s\n", symbol.c_str());
                   } else {
                      // printf(" strange symbol: %s \n",symbol.c_str());
                   }
@@ -252,11 +332,11 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable,
             symbol = stringTable + pSymbolTable->N.Name.Long;
             while (isspace(symbol[0]))  symbol.erase(0,1);
             if (symbol[0] == '_') symbol.erase(0,1);
-            if (!fImportFlag) {
-               fImportFlag = 1;
-               fprintf(fout,"IMPORTS \n");
+            if (!this->ImportFlag) {
+               this->ImportFlag = true;
+               fprintf(this->FileOut,"IMPORTS \n");
             }
-            fprintf(fout, "\t%s DATA \n", symbol.c_str()+1);
+            fprintf(this->FileOut, "\t%s DATA \n", symbol.c_str()+1);
          }
       }
 
@@ -266,49 +346,16 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable,
       i += pSymbolTable->NumberOfAuxSymbols;
       pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
       pSymbolTable++;
-   }
-}
-
-/*
-*----------------------------------------------------------------------
-* DumpObjFile --
-*
-*      Dump an object file--either a full listing or just the exported
-*      symbols.
-*----------------------------------------------------------------------
-*/
-void
-DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout)
-{
-   PIMAGE_SYMBOL PCOFFSymbolTable;
-   PIMAGE_SECTION_HEADER PCOFFSectionHeaders;
-   DWORD_PTR COFFSymbolCount;
-
-   PCOFFSymbolTable = (PIMAGE_SYMBOL)
-      ((DWORD_PTR)pImageFileHeader + pImageFileHeader->PointerToSymbolTable);
-   COFFSymbolCount = pImageFileHeader->NumberOfSymbols;
-
-   PCOFFSectionHeaders = (PIMAGE_SECTION_HEADER)
-      ((DWORD_PTR)pImageFileHeader          +
-      IMAGE_SIZEOF_FILE_HEADER +
-      pImageFileHeader->SizeOfOptionalHeader);
-
-
-   int haveExports = HaveExportedObjects(pImageFileHeader,
-                                         PCOFFSectionHeaders);
-   if (!haveExports)
-       DumpExternalsObjects(PCOFFSymbolTable, PCOFFSectionHeaders,
-                            fout, COFFSymbolCount);
-}
-
-/*
-*----------------------------------------------------------------------
-* DumpFile --
-*
-*      Open up a file, memory map it, and call the appropriate
-*      dumping routine
-*----------------------------------------------------------------------
-*/
+    }
+  }
+private:
+  bool ImportFlag;
+  FILE* FileOut;
+  DWORD_PTR SymbolCount;
+  PIMAGE_SECTION_HEADER SectionHeaders;
+  ObjectHeaderType* ObjectImageHeader;
+  SymbolTableType*  SymbolTable;
+};
 
 bool
 DumpFile(const char* filename, FILE *fout)
@@ -358,10 +405,21 @@ DumpFile(const char* filename, FILE *fout)
       * really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C)
       * and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0;
       */
-      DumpObjFile((PIMAGE_FILE_HEADER) lpFileBase, fout);
+      DumpSymbols<IMAGE_FILE_HEADER, IMAGE_SYMBOL>
+        symbolDumper((PIMAGE_FILE_HEADER) lpFileBase, fout);
+      symbolDumper.DumpObjFile();
    } else {
-      printf("unrecognized file format in '%s'\n", filename);
-      return false;
+      // check for /bigobj format
+      cmANON_OBJECT_HEADER_BIGOBJ* h =
+        (cmANON_OBJECT_HEADER_BIGOBJ*) lpFileBase;
+      if(h->Sig1 == 0x0 && h->Sig2 == 0xffff) {
+         DumpSymbols<cmANON_OBJECT_HEADER_BIGOBJ, cmIMAGE_SYMBOL_EX>
+           symbolDumper((cmANON_OBJECT_HEADER_BIGOBJ*) lpFileBase, fout);
+         symbolDumper.DumpObjFile();
+      } else {
+         printf("unrecognized file format in '%s'\n", filename);
+         return false;
+      }
    }
    UnmapViewOfFile(lpFileBase);
    CloseHandle(hFileMapping);

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=61bbbdcf9c0d1aed584fb976cd20c55ee9077850
commit 61bbbdcf9c0d1aed584fb976cd20c55ee9077850
Author:     Bill Hoffman <bill.hoffman at kitware.com>
AuthorDate: Fri Jun 19 16:12:43 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jul 6 11:11:01 2015 -0400

    bindexplib: Fix treatment of some symbols

diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index 4024e2f..6a63279 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -198,7 +198,16 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable,
                symbol = stringTable + pSymbolTable->N.Name.Long;
             }
 
+            // clear out any leading spaces
             while (isspace(symbol[0])) symbol.erase(0,1);
+            // if it starts with _ and has an @ then it is a __cdecl
+            // so remove the @ stuff for the export
+            if(symbol[0] == '_') {
+               std::string::size_type posAt = symbol.find('@');
+               if (posAt != std::string::npos) {
+                  symbol.erase(posAt);
+               }
+            }
             if (symbol[0] == '_') symbol.erase(0,1);
             if (fImportFlag) {
                fImportFlag = 0;
@@ -210,9 +219,13 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable,
             */
             const char *scalarPrefix = "??_G";
             const char *vectorPrefix = "??_E";
+            // original code had a check for
+            // symbol.find("real@") == std::string::npos)
+            // but if this disallows memmber functions with the name real
+            // if scalarPrefix and vectorPrefix are not found then print
+            // the symbol
             if (symbol.compare(0, 4, scalarPrefix) &&
-               symbol.compare(0, 4, vectorPrefix) &&
-               symbol.find("real@") == std::string::npos)
+                symbol.compare(0, 4, vectorPrefix) )
             {
                SectChar =
                 pSectionHeaders[pSymbolTable->SectionNumber-1].Characteristics;
@@ -224,7 +237,7 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable,
                        !(SectChar & IMAGE_SCN_MEM_READ)) {
                      fprintf(fout, "\t%s\n", symbol.c_str());
                   } else {
-                     //                    printf(" strange symbol: %s \n",s);
+                     // printf(" strange symbol: %s \n",symbol.c_str());
                   }
                }
             }

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=de70c922d9c846cf3a6fabfbedd054c02f4b8934
commit de70c922d9c846cf3a6fabfbedd054c02f4b8934
Author:     Bill Hoffman <bill.hoffman at kitware.com>
AuthorDate: Fri Jun 19 16:12:43 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jul 6 11:11:01 2015 -0400

    bindexplib: Teach DumpFile to return errors
    
    This will allow callers to know if it worked.

diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index f14d301..4024e2f 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -296,7 +296,8 @@ DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout)
 *      dumping routine
 *----------------------------------------------------------------------
 */
-void
+
+bool
 DumpFile(const char* filename, FILE *fout)
 {
    HANDLE hFile;
@@ -309,15 +310,15 @@ DumpFile(const char* filename, FILE *fout)
       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
 
    if (hFile == INVALID_HANDLE_VALUE) {
-      fprintf(stderr, "Couldn't open file with CreateFile()\n");
-      return;
+      fprintf(stderr, "Couldn't open file '%s' with CreateFile()\n", filename);
+      return false;
    }
 
    hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    if (hFileMapping == 0) {
       CloseHandle(hFile);
       fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n");
-      return;
+      return false;
    }
 
    lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
@@ -325,13 +326,13 @@ DumpFile(const char* filename, FILE *fout)
       CloseHandle(hFileMapping);
       CloseHandle(hFile);
       fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n");
-      return;
+      return false;
    }
 
    dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
    if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
       fprintf(stderr, "File is an executable.  I don't dump those.\n");
-      return;
+      return false;
    }
    /* Does it look like a i386 COFF OBJ file??? */
    else if (
@@ -346,9 +347,11 @@ DumpFile(const char* filename, FILE *fout)
       */
       DumpObjFile((PIMAGE_FILE_HEADER) lpFileBase, fout);
    } else {
-      printf("unrecognized file format\n");
+      printf("unrecognized file format in '%s'\n", filename);
+      return false;
    }
    UnmapViewOfFile(lpFileBase);
    CloseHandle(hFileMapping);
    CloseHandle(hFile);
+   return true;
 }

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8ea69dfef1e81a9811fe8a3d7198580dd21cb48f
commit 8ea69dfef1e81a9811fe8a3d7198580dd21cb48f
Author:     Bill Hoffman <bill.hoffman at kitware.com>
AuthorDate: Fri Jun 19 16:12:43 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jul 6 11:11:01 2015 -0400

    bindexplib: Build source as part of CMakeLib

diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 6d012fd..069f283 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -430,6 +430,7 @@ if (WIN32)
   set(SRCS ${SRCS}
     cmCallVisualStudioMacro.cxx
     cmCallVisualStudioMacro.h
+    bindexplib.cxx
     )
 
   if(NOT UNIX)
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index 8328213..f14d301 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -71,10 +71,12 @@
 *----------------------------------------------------------------------
 */
 
+#include <cmsys/Encoding.hxx>
 #include <windows.h>
 #include <stdio.h>
 #include <string>
 #include <fstream>
+#include <iostream>
 
 /*
 + * Utility func, strstr with size
@@ -89,7 +91,7 @@ const char* StrNStr(const char* start, const char* find, size_t &size) {
    }
    len = strlen(find);
 
-   while (hint = (const char*) memchr(start, find[0], size-len+1)) {
+   while ((hint = (const char*) memchr(start, find[0], size-len+1))) {
       size -= (hint - start);
       if (!strncmp(hint, find, len))
          return hint;
@@ -169,7 +171,7 @@ HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader,
 void
 DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable,
                      PIMAGE_SECTION_HEADER pSectionHeaders,
-                     FILE *fout, unsigned cSymbols)
+                     FILE *fout, DWORD_PTR cSymbols)
 {
    unsigned i;
    PSTR stringTable;
@@ -295,14 +297,15 @@ DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout)
 *----------------------------------------------------------------------
 */
 void
-DumpFile(LPSTR filename, FILE *fout)
+DumpFile(const char* filename, FILE *fout)
 {
    HANDLE hFile;
    HANDLE hFileMapping;
    LPVOID lpFileBase;
    PIMAGE_DOS_HEADER dosHeader;
 
-   hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
+   hFile = CreateFileW(cmsys::Encoding::ToWide(filename).c_str(),
+                       GENERIC_READ, FILE_SHARE_READ, NULL,
       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
 
    if (hFile == INVALID_HANDLE_VALUE) {

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2963cb2a559fd27edd53b7fb7036cba0adc8b9ca
commit 2963cb2a559fd27edd53b7fb7036cba0adc8b9ca
Author:     Bill Hoffman <bill.hoffman at kitware.com>
AuthorDate: Fri Jun 19 16:12:43 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jul 6 11:11:01 2015 -0400

    bindexplib: Wrap long lines

diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index 33f8161..8328213 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -109,7 +109,8 @@ const char* StrNStr(const char* start, const char* find, size_t &size) {
  *----------------------------------------------------------------------
  */
 int
-HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader, PIMAGE_SECTION_HEADER pSectionHeaders)
+HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader,
+                    PIMAGE_SECTION_HEADER pSectionHeaders)
 {
     static int fImportFlag = 0;  /*  The status is nor defined yet */
     WORD i;
@@ -124,12 +125,14 @@ HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader, PIMAGE_SECTION_HEADER p
     i = 0;
     foundExports = 0;
     pDirectivesSectionHeader = 0;
-    for(i = 0; i < pImageFileHeader->NumberOfSections && !pDirectivesSectionHeader; i++)
+    for(i = 0; (i < pImageFileHeader->NumberOfSections &&
+                !pDirectivesSectionHeader); i++)
        if (!strncmp((const char*)&pSectionHeaders[i].Name[0], ".drectve",8))
           pDirectivesSectionHeader = &pSectionHeaders[i];
    if (!pDirectivesSectionHeader) return 0;
 
-    rawdata=(const char*)pImageFileHeader+pDirectivesSectionHeader->PointerToRawData;
+    rawdata=(const char*)
+      pImageFileHeader+pDirectivesSectionHeader->PointerToRawData;
     if (!pDirectivesSectionHeader->PointerToRawData || !rawdata) return 0;
 
     size = pDirectivesSectionHeader->SizeOfRawData;
@@ -164,7 +167,8 @@ HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader, PIMAGE_SECTION_HEADER p
 *----------------------------------------------------------------------
 */
 void
-DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionHeaders,
+DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable,
+                     PIMAGE_SECTION_HEADER pSectionHeaders,
                      FILE *fout, unsigned cSymbols)
 {
    unsigned i;
@@ -179,7 +183,8 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionH
    stringTable = (PSTR)&pSymbolTable[cSymbols];
 
    for ( i=0; i < cSymbols; i++ ) {
-      if (pSymbolTable->SectionNumber > 0 && ( pSymbolTable->Type == 0x20 || pSymbolTable->Type == 0x0)) {
+      if (pSymbolTable->SectionNumber > 0 &&
+          ( pSymbolTable->Type == 0x20 || pSymbolTable->Type == 0x0)) {
          if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
             /*
             *    The name of the Function entry points
@@ -207,12 +212,14 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionH
                symbol.compare(0, 4, vectorPrefix) &&
                symbol.find("real@") == std::string::npos)
             {
-               SectChar = pSectionHeaders[pSymbolTable->SectionNumber-1].Characteristics;
+               SectChar =
+                pSectionHeaders[pSymbolTable->SectionNumber-1].Characteristics;
                if (!pSymbolTable->Type  && (SectChar & IMAGE_SCN_MEM_WRITE)) {
                   // Read only (i.e. constants) must be excluded
                   fprintf(fout, "\t%s \t DATA\n", symbol.c_str());
                } else {
-                  if ( pSymbolTable->Type  || !(SectChar & IMAGE_SCN_MEM_READ)) {
+                  if ( pSymbolTable->Type  ||
+                       !(SectChar & IMAGE_SCN_MEM_READ)) {
                      fprintf(fout, "\t%s\n", symbol.c_str());
                   } else {
                      //                    printf(" strange symbol: %s \n",s);
@@ -221,7 +228,8 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionH
             }
          }
       }
-      else if (pSymbolTable->SectionNumber == IMAGE_SYM_UNDEFINED && !pSymbolTable->Type && 0){
+      else if (pSymbolTable->SectionNumber == IMAGE_SYM_UNDEFINED &&
+               !pSymbolTable->Type && 0) {
          /*
          *    The IMPORT global variable entry points
          */
@@ -271,9 +279,11 @@ DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout)
       pImageFileHeader->SizeOfOptionalHeader);
 
 
-   int haveExports = HaveExportedObjects(pImageFileHeader, PCOFFSectionHeaders);
+   int haveExports = HaveExportedObjects(pImageFileHeader,
+                                         PCOFFSectionHeaders);
    if (!haveExports)
-       DumpExternalsObjects(PCOFFSymbolTable, PCOFFSectionHeaders, fout, COFFSymbolCount);
+       DumpExternalsObjects(PCOFFSymbolTable, PCOFFSectionHeaders,
+                            fout, COFFSymbolCount);
 }
 
 /*
@@ -322,7 +332,8 @@ DumpFile(LPSTR filename, FILE *fout)
    }
    /* Does it look like a i386 COFF OBJ file??? */
    else if (
-           ((dosHeader->e_magic == IMAGE_FILE_MACHINE_I386) || (dosHeader->e_magic == IMAGE_FILE_MACHINE_AMD64))
+           ((dosHeader->e_magic == IMAGE_FILE_MACHINE_I386) ||
+            (dosHeader->e_magic == IMAGE_FILE_MACHINE_AMD64))
            && (dosHeader->e_sp == 0)
            ) {
       /*

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4ff09893232b26b5c2961fb1e2a31836cad00a35
commit 4ff09893232b26b5c2961fb1e2a31836cad00a35
Author:     Bill Hoffman <bill.hoffman at kitware.com>
AuthorDate: Fri Jun 19 16:12:43 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jul 6 11:11:00 2015 -0400

    bindexplib: Drop code that CMake does not need

diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index a86318f..33f8161 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -71,290 +71,12 @@
 *----------------------------------------------------------------------
 */
 
-static char sccsid[] = "@(#) winDumpExts.c 1.2 95/10/03 15:27:34";
-
 #include <windows.h>
 #include <stdio.h>
 #include <string>
 #include <fstream>
 
 /*
-*----------------------------------------------------------------------
-* GetArgcArgv --
-*
-*      Break up a line into argc argv
-*----------------------------------------------------------------------
-*/
-int
-GetArgcArgv(std::string &s, char **argv)
-{
-   int quote = 0;
-   int argc = 0;
-   std::string::iterator bp = s.begin();
-
-   while (1) {
-      while (isspace(*bp)) {
-         bp++;
-      }
-      if (*bp == '\n' || *bp == '\0') {
-         *bp = '\0';
-         return argc;
-      }
-      if (*bp == '\"') {
-         quote = 1;
-         bp++;
-      }
-      argv[argc++] = &(*bp);
-
-      while (*bp != '\0') {
-         if (quote) {
-            if (*bp == '\"') {
-               quote = 0;
-               *bp = '\0';
-               bp++;
-               break;
-            }
-            bp++;
-            continue;
-         }
-         if (isspace(*bp)) {
-            *bp = '\0';
-            bp++;
-            break;
-         }
-         bp++;
-      }
-   }
-}
-
-/*
-*  The names of the first group of possible symbol table storage classes
-*/
-char * SzStorageClass1[] = {
-   "NULL","AUTOMATIC","EXTERNAL","STATIC","REGISTER","EXTERNAL_DEF","LABEL",
-   "UNDEFINED_LABEL","MEMBER_OF_STRUCT","ARGUMENT","STRUCT_TAG",
-   "MEMBER_OF_UNION","UNION_TAG","TYPE_DEFINITION","UNDEFINED_STATIC",
-   "ENUM_TAG","MEMBER_OF_ENUM","REGISTER_PARAM","BIT_FIELD"
-};
-
-/*
-* The names of the second group of possible symbol table storage classes
-*/
-char * SzStorageClass2[] = {
-   "BLOCK","FUNCTION","END_OF_STRUCT","FILE","SECTION","WEAK_EXTERNAL"
-};
-
-/*
-*----------------------------------------------------------------------
-* GetSZStorageClass --
-*
-*      Given a symbol storage class value, return a descriptive
-*      ASCII string
-*----------------------------------------------------------------------
-*/
-PSTR
-GetSZStorageClass(BYTE storageClass)
-{
-   if ( storageClass <= IMAGE_SYM_CLASS_BIT_FIELD )
-      return SzStorageClass1[storageClass];
-   else if ( (storageClass >= IMAGE_SYM_CLASS_BLOCK)
-      && (storageClass <= IMAGE_SYM_CLASS_WEAK_EXTERNAL) )
-      return SzStorageClass2[storageClass-IMAGE_SYM_CLASS_BLOCK];
-   else
-      return "???";
-}
-
-void AddHex(std::string& buf, long val, bool caps=false)
-{
-   buf += "0x";
-   size_t len=buf.length();
-   while (val) {
-      char hex = (char)(val & 16);
-      val = val >> 4;
-      if (hex<10) hex+='0';
-      else if (caps) hex+='A'-10;
-      else hex+='a'-10;
-      buf.insert(len, hex, 1);
-   }
-}
-
-/*
-*----------------------------------------------------------------------
-* GetSectionName --
-*
-*      Used by DumpSymbolTable, it gives meaningful names to
-*      the non-normal section number.
-*
-* Results:
-*      A name is returned in buffer
-*----------------------------------------------------------------------
-*/
-void
-GetSectionName(PIMAGE_SYMBOL pSymbolTable, std::string& buffer)
-{
-   DWORD section;
-
-   section = pSymbolTable->SectionNumber;
-
-   switch ( (SHORT)section )
-   {
-   case IMAGE_SYM_UNDEFINED: if (pSymbolTable->Value) buffer += "COMM"; else buffer += "UNDEF"; break;
-   case IMAGE_SYM_ABSOLUTE:  buffer += "ABS  "; break;
-   case IMAGE_SYM_DEBUG:     buffer += "DEBUG"; break;
-   default: AddHex(buffer, section, true);
-   }
-}
-
-/*
-*----------------------------------------------------------------------
-* GetSectionCharacteristics --
-*
-*      Converts the Characteristics field of IMAGE_SECTION_HEADER
-*      to print.
-*
-*  Results:
-*       A definiton of the section symbol type
-*----------------------------------------------------------------------
-*/
-void
-GetSectionCharacteristics(PIMAGE_SECTION_HEADER pSectionHeaders, int nSectNum, std::string &buffer)
-{
-   DWORD SectChar;
-   std::string TempBuf;
-   buffer.clear();
-   if (nSectNum > 0) {
-      SectChar = pSectionHeaders[nSectNum-1].Characteristics;
-
-      buffer = " ";
-      AddHex(buffer, SectChar);
-      if       (SectChar & IMAGE_SCN_CNT_CODE)                buffer += " Code";
-      else if  (SectChar & IMAGE_SCN_CNT_INITIALIZED_DATA)    buffer += " Init. data";
-      else if  (SectChar & IMAGE_SCN_CNT_UNINITIALIZED_DATA ) buffer += " UnInit data";
-      else                                                    buffer += " Unknow type";
-
-      if   (SectChar & IMAGE_SCN_MEM_READ)  {
-         buffer += " Read";
-         if (SectChar & IMAGE_SCN_MEM_WRITE)
-            buffer += " and Write";
-         else buffer += " only";
-      }
-      else if (SectChar & IMAGE_SCN_MEM_WRITE)
-         buffer +=" Write only";
-
-   }
-}
-
-/*
-*----------------------------------------------------------------------
-* DumpSymbolTable --
-*
-*      Dumps a COFF symbol table from an EXE or OBJ.  We only use
-*      it to dump tables from OBJs.
-*----------------------------------------------------------------------
-*/
-void
-DumpSymbolTable(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionHeaders, FILE *fout, unsigned cSymbols)
-{
-   unsigned i;
-   PSTR stringTable;
-   std::string sectionName;
-   std::string sectionCharacter;
-   int iSectNum;
-
-   fprintf(fout, "Symbol Table - %X entries  (* = auxillary symbol)\n",
-      cSymbols);
-
-   fprintf(fout,
-      "Indx Name                 Value    Section    cAux  Type    Storage  Character\n"
-      "---- -------------------- -------- ---------- ----- ------- -------- ---------\n");
-
-   /*
-   * The string table apparently starts right after the symbol table
-   */
-   stringTable = (PSTR)&pSymbolTable[cSymbols];
-
-   for ( i=0; i < cSymbols; i++ ) {
-      fprintf(fout, "%04X ", i);
-      if ( pSymbolTable->N.Name.Short != 0 )
-         fprintf(fout, "%-20.8s", pSymbolTable->N.ShortName);
-      else
-         fprintf(fout, "%-20s", stringTable + pSymbolTable->N.Name.Long);
-
-      fprintf(fout, " %08X", pSymbolTable->Value);
-
-      iSectNum = pSymbolTable->SectionNumber;
-      GetSectionName(pSymbolTable, sectionName);
-      fprintf(fout, " sect:%s aux:%X type:%02X st:%s",
-         sectionName.c_str(),
-         pSymbolTable->NumberOfAuxSymbols,
-         pSymbolTable->Type,
-         GetSZStorageClass(pSymbolTable->StorageClass) );
-
-      GetSectionCharacteristics(pSectionHeaders,iSectNum,sectionCharacter);
-      fprintf(fout," hc: %s \n",sectionCharacter.c_str());
-#if 0
-      if ( pSymbolTable->NumberOfAuxSymbols )
-         DumpAuxSymbols(pSymbolTable);
-#endif
-
-      /*
-      * Take into account any aux symbols
-      */
-      i += pSymbolTable->NumberOfAuxSymbols;
-      pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
-      pSymbolTable++;
-   }
-}
-
-/*
-*----------------------------------------------------------------------
-* DumpExternals --
-*
-*      Dumps a COFF symbol table from an EXE or OBJ.  We only use
-*      it to dump tables from OBJs.
-*----------------------------------------------------------------------
-*/
-void
-DumpExternals(PIMAGE_SYMBOL pSymbolTable, FILE *fout, unsigned cSymbols)
-{
-   unsigned i;
-   PSTR stringTable;
-   std::string symbol;
-
-   /*
-   * The string table apparently starts right after the symbol table
-   */
-   stringTable = (PSTR)&pSymbolTable[cSymbols];
-
-   for ( i=0; i < cSymbols; i++ ) {
-      if (pSymbolTable->SectionNumber > 0 && pSymbolTable->Type == 0x20) {
-         if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
-            if (pSymbolTable->N.Name.Short != 0) {
-               symbol = "";
-               symbol.insert(0, (const char *)(pSymbolTable->N.ShortName), 8);
-            } else {
-               symbol = stringTable + pSymbolTable->N.Name.Long;
-            }
-            std::string::size_type posAt = symbol.find('@');
-            if (posAt != std::string::npos) symbol.erase(posAt);
-#ifndef _MSC_VER
-            fprintf(fout, "\t%s\n", symbol.c_str());
-#else
-            fprintf(fout, "\t%s\n", symbol.c_str()+1);
-#endif
-         }
-      }
-
-      /*
-      * Take into account any aux symbols
-      */
-      i += pSymbolTable->NumberOfAuxSymbols;
-      pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
-      pSymbolTable++;
-   }
-}
-
-/*
 + * Utility func, strstr with size
 + */
 const char* StrNStr(const char* start, const char* find, size_t &size) {
@@ -387,7 +109,7 @@ const char* StrNStr(const char* start, const char* find, size_t &size) {
  *----------------------------------------------------------------------
  */
 int
-HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader, PIMAGE_SECTION_HEADER pSectionHeaders, FILE *fout)
+HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader, PIMAGE_SECTION_HEADER pSectionHeaders)
 {
     static int fImportFlag = 0;  /*  The status is nor defined yet */
     WORD i;
@@ -443,7 +165,7 @@ HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader, PIMAGE_SECTION_HEADER p
 */
 void
 DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionHeaders,
-                     FILE *fout, unsigned cSymbols, int fort)
+                     FILE *fout, unsigned cSymbols)
 {
    unsigned i;
    PSTR stringTable;
@@ -470,13 +192,7 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionH
             }
 
             while (isspace(symbol[0])) symbol.erase(0,1);
-#ifdef _MSC_VER
             if (symbol[0] == '_') symbol.erase(0,1);
-            if (fort) {
-               std::string::size_type posAt = symbol.find('@');
-               if (posAt != std::string::npos) symbol.erase(posAt);
-            }
-#endif
             if (fImportFlag) {
                fImportFlag = 0;
                fprintf(fout,"EXPORTS \n");
@@ -485,11 +201,6 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionH
             Check whether it is "Scalar deleting destructor" and
             "Vector deleting destructor"
             */
-            /*
-            if (!strstr(s,"@@UAEPAXI at Z") && !strstr(s,"@@QAEPAXI at Z") &&
-            !strstr(s,"@AEPAXI at Z")   && !strstr(s,"AEPAXI at Z")    &&
-            !strstr(s,"real@"))
-            */
             const char *scalarPrefix = "??_G";
             const char *vectorPrefix = "??_E";
             if (symbol.compare(0, 4, scalarPrefix) &&
@@ -544,7 +255,7 @@ DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionH
 *----------------------------------------------------------------------
 */
 void
-DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout, int full, int fort)
+DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout)
 {
    PIMAGE_SYMBOL PCOFFSymbolTable;
    PIMAGE_SECTION_HEADER PCOFFSectionHeaders;
@@ -560,13 +271,9 @@ DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout, int full, int fort)
       pImageFileHeader->SizeOfOptionalHeader);
 
 
-   if (full) {
-      DumpSymbolTable(PCOFFSymbolTable, PCOFFSectionHeaders, fout, COFFSymbolCount);
-   } else {
-        int haveExports = HaveExportedObjects(pImageFileHeader, PCOFFSectionHeaders, fout);
-        if (!haveExports)
-            DumpExternalsObjects(PCOFFSymbolTable, PCOFFSectionHeaders, fout, COFFSymbolCount, fort);
-   }
+   int haveExports = HaveExportedObjects(pImageFileHeader, PCOFFSectionHeaders);
+   if (!haveExports)
+       DumpExternalsObjects(PCOFFSymbolTable, PCOFFSectionHeaders, fout, COFFSymbolCount);
 }
 
 /*
@@ -578,7 +285,7 @@ DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout, int full, int fort)
 *----------------------------------------------------------------------
 */
 void
-DumpFile(LPSTR filename, FILE *fout, int full, int fort)
+DumpFile(LPSTR filename, FILE *fout)
 {
    HANDLE hFile;
    HANDLE hFileMapping;
@@ -610,12 +317,8 @@ DumpFile(LPSTR filename, FILE *fout, int full, int fort)
 
    dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
    if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
-#if 0
-      DumpExeFile( dosHeader );
-#else
       fprintf(stderr, "File is an executable.  I don't dump those.\n");
       return;
-#endif
    }
    /* Does it look like a i386 COFF OBJ file??? */
    else if (
@@ -627,7 +330,7 @@ DumpFile(LPSTR filename, FILE *fout, int full, int fort)
       * really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C)
       * and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0;
       */
-      DumpObjFile((PIMAGE_FILE_HEADER) lpFileBase, fout, full, fort);
+      DumpObjFile((PIMAGE_FILE_HEADER) lpFileBase, fout);
    } else {
       printf("unrecognized file format\n");
    }
@@ -635,123 +338,3 @@ DumpFile(LPSTR filename, FILE *fout, int full, int fort)
    CloseHandle(hFileMapping);
    CloseHandle(hFile);
 }
-
-void
-main(int argc, char **argv)
-{
-   std::string cmdline;
-   int i, arg;
-   FILE *fout;
-   int full = 0;
-   int fort = 0;
-   char *dllname = "";
-   char *outfile = NULL;
-
-   if (argc < 3) {
-Usage:
-      fprintf(stderr, "Usage: %s ?-o outfile? ?-f(ull)? <dllname> <object filenames> ..\n", argv[0]);
-      exit(1);
-   }
-
-   arg = 1;
-   while (argv[arg][0] == '-') {
-      if (strcmp(argv[arg], "--") == 0) {
-         arg++;
-         break;
-      } else if (strcmp(argv[arg], "-f") == 0) {
-         full = 1;
-      } else if (strcmp(argv[arg], "-x") == 0) {
-         fort = 1;
-      } else if (strcmp(argv[arg], "-o") == 0) {
-         arg++;
-         if (arg == argc) {
-            goto Usage;
-         }
-         outfile = argv[arg];
-      }
-      arg++;
-   }
-   if (arg == argc) {
-      goto Usage;
-   }
-
-   if (outfile) {
-      fout = fopen(outfile, "w+");
-      if (fout == NULL) {
-         fprintf(stderr, "Unable to open \'%s\' for writing:\n",
-            argv[arg]);
-         perror("");
-         exit(1);
-      }
-   } else {
-      fout = stdout;
-   }
-
-   if (! full) {
-      dllname = argv[arg];
-      arg++;
-      if (arg == argc) {
-         goto Usage;
-      }
-      fprintf(fout, "LIBRARY    %s\n", dllname);
-#ifndef _X86_
-      fprintf(fout, "CODE PRELOAD MOVEABLE DISCARDABLE\n");
-      fprintf(fout, "DATA PRELOAD MOVEABLE MULTIPLE\n\n");
-#endif
-   }
-
-   for (; arg < argc; arg++) {
-      WIN32_FIND_DATA FindFileData;
-      HANDLE SearchFile;
-      if (argv[arg][0] == '@') {
-         std::ifstream fargs(&argv[arg][1]);
-         if (!fargs) {
-            fprintf(stderr, "Unable to open \'%s\' for reading:\n",
-               argv[arg]);
-            perror("");
-            exit(1);
-         }
-         char *fargv[1000];
-         for (i = 0; i < arg; i++) {
-            cmdline += argv[i];
-            fargv[i] = argv[i];
-         }
-         std::string line;
-         std::getline(fargs, line);
-         cmdline += line;
-         fprintf(stderr, "%s\n", line.c_str());
-         i += GetArgcArgv(line, &fargv[i]);
-         argc = i;
-         argv = fargv;
-      }
-      /*
-      *  Argument can contain the wildcard names
-      */
-      SearchFile = FindFirstFile(argv[arg],&FindFileData);
-      if (SearchFile == INVALID_HANDLE_VALUE){
-         fprintf(stderr, "Unable to find \'%s\' for reading:\n",
-            argv[arg]);
-         exit(1);
-      }
-      else  {
-         /*
-         *  Since WIN32_FIND_DATA has no path information one has to extract it himself.
-         */
-         TCHAR *filename = argv[arg];
-         TCHAR path[2048];
-         size_t i = strlen(filename);
-         i--;
-         while( filename[i] != '\\' && filename[i] != '/'  && i >=0) i--;
-         do
-         {
-            if (i >= 0) strncpy( path, filename, i+1); /* Generate the 'path' info */
-            path[i+1] = '\0';
-            DumpFile(strcat(path, FindFileData.cFileName), fout, full, fort);
-         } while (FindNextFile(SearchFile,&FindFileData));
-
-
-         FindClose(SearchFile);
-      }
-   }
-   exit(0);
-}

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7de8276ca92db0630009eeab865afc445a30e1b8
commit 7de8276ca92db0630009eeab865afc445a30e1b8
Author:     Bill Hoffman <bill.hoffman at kitware.com>
AuthorDate: Fri Jun 19 16:12:43 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jul 6 11:11:00 2015 -0400

    bindexplib: Add copyright/license notice block

diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index 6f9605c..a86318f 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -1,3 +1,21 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2015 Kitware, Inc.
+
+  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.
+============================================================================*/
+/*-------------------------------------------------------------------------
+  Portions of this source have been derived from the 'bindexplib' tool
+  provided by the CERN ROOT Data Analysis Framework project (root.cern.ch).
+  Permission has been granted by Pere Mato <pere.mato at cern.ch> to distribute
+  this derived work under the CMake license.
+-------------------------------------------------------------------------*/
+
 /*
 *----------------------------------------------------------------------
 * Program:  dumpexts.exe

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=65086ad778b5d8312e4168fc5ed670e545be7d4b
commit 65086ad778b5d8312e4168fc5ed670e545be7d4b
Author:     Bill Hoffman <bill.hoffman at kitware.com>
AuthorDate: Fri Jun 19 16:12:43 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jul 6 11:10:58 2015 -0400

    bindexplib: Import original implementation from CERN
    
    Download the original implementation provided by root.cern.ch with the
    following session:
    
    $ wget https://raw.githubusercontent.com/gordonwatts/root-vc-port/f0ee59af/build/win/bindexplib/bindexplib.cxx
    $ sha1sum bindexplib.cxx
    fa6efafb2c58a0644bd0f6a56fe02ee0d55c7fcd  bindexplib.cxx
    $ sed -i 's/ *$//;s/'$'\t''/        /' bindexplib.cxx

diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
new file mode 100644
index 0000000..6f9605c
--- /dev/null
+++ b/Source/bindexplib.cxx
@@ -0,0 +1,739 @@
+/*
+*----------------------------------------------------------------------
+* Program:  dumpexts.exe
+* Author:   Gordon Chaffee
+*
+* History:  The real functionality of this file was written by
+*           Matt Pietrek in 1993 in his pedump utility.  I've
+*           modified it to dump the externals in a bunch of object
+*           files to create a .def file.
+*
+* Notes:    Visual C++ puts an underscore before each exported symbol.
+*           This file removes them.  I don't know if this is a problem
+*           this other compilers.  If _MSC_VER is defined,
+*           the underscore is removed.  If not, it isn't.  To get a
+*           full dump of an object file, use the -f option.  This can
+*           help determine the something that may be different with a
+*           compiler other than Visual C++.
+*   ======================================
+* Corrections (Axel 2006-04-04):
+*   Conversion to C++. Mostly.
+*
+ * Extension (Axel 2006-03-15)
+ *    As soon as an object file contains an /EXPORT directive (which
+ *    is generated by the compiler when a symbol is declared as
+ *    declspec(dllexport)) no to-be-exported symbols are printed,
+ *    as the linker will see these directives, and if those directives
+ *    are present we only export selectively (i.e. we trust the
+ *    programmer).
+ *
+ *   ======================================
+*   ======================================
+* Corrections (Valery Fine 23/02/98):
+*
+*           The "(vector) deleting destructor" MUST not be exported
+*           To recognize it the following test are introduced:
+*  "@@UAEPAXI at Z"  scalar deleting dtor
+*  "@@QAEPAXI at Z"  vector deleting dtor
+*  "AEPAXI at Z"     vector deleting dtor with thunk adjustor
+*   ======================================
+* Corrections (Valery Fine 12/02/97):
+*
+*    It created a wrong EXPORTS for the global pointers and constants.
+*    The Section Header has been involved to discover the missing information
+*    Now the pointers are correctly supplied  supplied with "DATA" descriptor
+*        the constants  with no extra descriptor.
+*
+* Corrections (Valery Fine 16/09/96):
+*
+*     It didn't work for C++ code with global variables and class definitons
+*     The DumpExternalObject function has been introduced to generate .DEF file
+*
+* Author:   Valery Fine 16/09/96  (E-mail: fine at vxcern.cern.ch)
+*----------------------------------------------------------------------
+*/
+
+static char sccsid[] = "@(#) winDumpExts.c 1.2 95/10/03 15:27:34";
+
+#include <windows.h>
+#include <stdio.h>
+#include <string>
+#include <fstream>
+
+/*
+*----------------------------------------------------------------------
+* GetArgcArgv --
+*
+*      Break up a line into argc argv
+*----------------------------------------------------------------------
+*/
+int
+GetArgcArgv(std::string &s, char **argv)
+{
+   int quote = 0;
+   int argc = 0;
+   std::string::iterator bp = s.begin();
+
+   while (1) {
+      while (isspace(*bp)) {
+         bp++;
+      }
+      if (*bp == '\n' || *bp == '\0') {
+         *bp = '\0';
+         return argc;
+      }
+      if (*bp == '\"') {
+         quote = 1;
+         bp++;
+      }
+      argv[argc++] = &(*bp);
+
+      while (*bp != '\0') {
+         if (quote) {
+            if (*bp == '\"') {
+               quote = 0;
+               *bp = '\0';
+               bp++;
+               break;
+            }
+            bp++;
+            continue;
+         }
+         if (isspace(*bp)) {
+            *bp = '\0';
+            bp++;
+            break;
+         }
+         bp++;
+      }
+   }
+}
+
+/*
+*  The names of the first group of possible symbol table storage classes
+*/
+char * SzStorageClass1[] = {
+   "NULL","AUTOMATIC","EXTERNAL","STATIC","REGISTER","EXTERNAL_DEF","LABEL",
+   "UNDEFINED_LABEL","MEMBER_OF_STRUCT","ARGUMENT","STRUCT_TAG",
+   "MEMBER_OF_UNION","UNION_TAG","TYPE_DEFINITION","UNDEFINED_STATIC",
+   "ENUM_TAG","MEMBER_OF_ENUM","REGISTER_PARAM","BIT_FIELD"
+};
+
+/*
+* The names of the second group of possible symbol table storage classes
+*/
+char * SzStorageClass2[] = {
+   "BLOCK","FUNCTION","END_OF_STRUCT","FILE","SECTION","WEAK_EXTERNAL"
+};
+
+/*
+*----------------------------------------------------------------------
+* GetSZStorageClass --
+*
+*      Given a symbol storage class value, return a descriptive
+*      ASCII string
+*----------------------------------------------------------------------
+*/
+PSTR
+GetSZStorageClass(BYTE storageClass)
+{
+   if ( storageClass <= IMAGE_SYM_CLASS_BIT_FIELD )
+      return SzStorageClass1[storageClass];
+   else if ( (storageClass >= IMAGE_SYM_CLASS_BLOCK)
+      && (storageClass <= IMAGE_SYM_CLASS_WEAK_EXTERNAL) )
+      return SzStorageClass2[storageClass-IMAGE_SYM_CLASS_BLOCK];
+   else
+      return "???";
+}
+
+void AddHex(std::string& buf, long val, bool caps=false)
+{
+   buf += "0x";
+   size_t len=buf.length();
+   while (val) {
+      char hex = (char)(val & 16);
+      val = val >> 4;
+      if (hex<10) hex+='0';
+      else if (caps) hex+='A'-10;
+      else hex+='a'-10;
+      buf.insert(len, hex, 1);
+   }
+}
+
+/*
+*----------------------------------------------------------------------
+* GetSectionName --
+*
+*      Used by DumpSymbolTable, it gives meaningful names to
+*      the non-normal section number.
+*
+* Results:
+*      A name is returned in buffer
+*----------------------------------------------------------------------
+*/
+void
+GetSectionName(PIMAGE_SYMBOL pSymbolTable, std::string& buffer)
+{
+   DWORD section;
+
+   section = pSymbolTable->SectionNumber;
+
+   switch ( (SHORT)section )
+   {
+   case IMAGE_SYM_UNDEFINED: if (pSymbolTable->Value) buffer += "COMM"; else buffer += "UNDEF"; break;
+   case IMAGE_SYM_ABSOLUTE:  buffer += "ABS  "; break;
+   case IMAGE_SYM_DEBUG:     buffer += "DEBUG"; break;
+   default: AddHex(buffer, section, true);
+   }
+}
+
+/*
+*----------------------------------------------------------------------
+* GetSectionCharacteristics --
+*
+*      Converts the Characteristics field of IMAGE_SECTION_HEADER
+*      to print.
+*
+*  Results:
+*       A definiton of the section symbol type
+*----------------------------------------------------------------------
+*/
+void
+GetSectionCharacteristics(PIMAGE_SECTION_HEADER pSectionHeaders, int nSectNum, std::string &buffer)
+{
+   DWORD SectChar;
+   std::string TempBuf;
+   buffer.clear();
+   if (nSectNum > 0) {
+      SectChar = pSectionHeaders[nSectNum-1].Characteristics;
+
+      buffer = " ";
+      AddHex(buffer, SectChar);
+      if       (SectChar & IMAGE_SCN_CNT_CODE)                buffer += " Code";
+      else if  (SectChar & IMAGE_SCN_CNT_INITIALIZED_DATA)    buffer += " Init. data";
+      else if  (SectChar & IMAGE_SCN_CNT_UNINITIALIZED_DATA ) buffer += " UnInit data";
+      else                                                    buffer += " Unknow type";
+
+      if   (SectChar & IMAGE_SCN_MEM_READ)  {
+         buffer += " Read";
+         if (SectChar & IMAGE_SCN_MEM_WRITE)
+            buffer += " and Write";
+         else buffer += " only";
+      }
+      else if (SectChar & IMAGE_SCN_MEM_WRITE)
+         buffer +=" Write only";
+
+   }
+}
+
+/*
+*----------------------------------------------------------------------
+* DumpSymbolTable --
+*
+*      Dumps a COFF symbol table from an EXE or OBJ.  We only use
+*      it to dump tables from OBJs.
+*----------------------------------------------------------------------
+*/
+void
+DumpSymbolTable(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionHeaders, FILE *fout, unsigned cSymbols)
+{
+   unsigned i;
+   PSTR stringTable;
+   std::string sectionName;
+   std::string sectionCharacter;
+   int iSectNum;
+
+   fprintf(fout, "Symbol Table - %X entries  (* = auxillary symbol)\n",
+      cSymbols);
+
+   fprintf(fout,
+      "Indx Name                 Value    Section    cAux  Type    Storage  Character\n"
+      "---- -------------------- -------- ---------- ----- ------- -------- ---------\n");
+
+   /*
+   * The string table apparently starts right after the symbol table
+   */
+   stringTable = (PSTR)&pSymbolTable[cSymbols];
+
+   for ( i=0; i < cSymbols; i++ ) {
+      fprintf(fout, "%04X ", i);
+      if ( pSymbolTable->N.Name.Short != 0 )
+         fprintf(fout, "%-20.8s", pSymbolTable->N.ShortName);
+      else
+         fprintf(fout, "%-20s", stringTable + pSymbolTable->N.Name.Long);
+
+      fprintf(fout, " %08X", pSymbolTable->Value);
+
+      iSectNum = pSymbolTable->SectionNumber;
+      GetSectionName(pSymbolTable, sectionName);
+      fprintf(fout, " sect:%s aux:%X type:%02X st:%s",
+         sectionName.c_str(),
+         pSymbolTable->NumberOfAuxSymbols,
+         pSymbolTable->Type,
+         GetSZStorageClass(pSymbolTable->StorageClass) );
+
+      GetSectionCharacteristics(pSectionHeaders,iSectNum,sectionCharacter);
+      fprintf(fout," hc: %s \n",sectionCharacter.c_str());
+#if 0
+      if ( pSymbolTable->NumberOfAuxSymbols )
+         DumpAuxSymbols(pSymbolTable);
+#endif
+
+      /*
+      * Take into account any aux symbols
+      */
+      i += pSymbolTable->NumberOfAuxSymbols;
+      pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
+      pSymbolTable++;
+   }
+}
+
+/*
+*----------------------------------------------------------------------
+* DumpExternals --
+*
+*      Dumps a COFF symbol table from an EXE or OBJ.  We only use
+*      it to dump tables from OBJs.
+*----------------------------------------------------------------------
+*/
+void
+DumpExternals(PIMAGE_SYMBOL pSymbolTable, FILE *fout, unsigned cSymbols)
+{
+   unsigned i;
+   PSTR stringTable;
+   std::string symbol;
+
+   /*
+   * The string table apparently starts right after the symbol table
+   */
+   stringTable = (PSTR)&pSymbolTable[cSymbols];
+
+   for ( i=0; i < cSymbols; i++ ) {
+      if (pSymbolTable->SectionNumber > 0 && pSymbolTable->Type == 0x20) {
+         if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
+            if (pSymbolTable->N.Name.Short != 0) {
+               symbol = "";
+               symbol.insert(0, (const char *)(pSymbolTable->N.ShortName), 8);
+            } else {
+               symbol = stringTable + pSymbolTable->N.Name.Long;
+            }
+            std::string::size_type posAt = symbol.find('@');
+            if (posAt != std::string::npos) symbol.erase(posAt);
+#ifndef _MSC_VER
+            fprintf(fout, "\t%s\n", symbol.c_str());
+#else
+            fprintf(fout, "\t%s\n", symbol.c_str()+1);
+#endif
+         }
+      }
+
+      /*
+      * Take into account any aux symbols
+      */
+      i += pSymbolTable->NumberOfAuxSymbols;
+      pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
+      pSymbolTable++;
+   }
+}
+
+/*
++ * Utility func, strstr with size
++ */
+const char* StrNStr(const char* start, const char* find, size_t &size) {
+   size_t len;
+   const char* hint;
+
+   if (!start || !find || !size) {
+      size = 0;
+      return 0;
+   }
+   len = strlen(find);
+
+   while (hint = (const char*) memchr(start, find[0], size-len+1)) {
+      size -= (hint - start);
+      if (!strncmp(hint, find, len))
+         return hint;
+      start = hint + 1;
+   }
+
+   size = 0;
+   return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ * HaveExportedObjects --
+ *
+ *      Returns >0 if export directives (declspec(dllexport)) exist.
+ *
+ *----------------------------------------------------------------------
+ */
+int
+HaveExportedObjects(PIMAGE_FILE_HEADER pImageFileHeader, PIMAGE_SECTION_HEADER pSectionHeaders, FILE *fout)
+{
+    static int fImportFlag = 0;  /*  The status is nor defined yet */
+    WORD i;
+    size_t size;
+    char foundExports;
+    const char * rawdata;
+
+    PIMAGE_SECTION_HEADER pDirectivesSectionHeader;
+
+    if (fImportFlag) return 1;
+
+    i = 0;
+    foundExports = 0;
+    pDirectivesSectionHeader = 0;
+    for(i = 0; i < pImageFileHeader->NumberOfSections && !pDirectivesSectionHeader; i++)
+       if (!strncmp((const char*)&pSectionHeaders[i].Name[0], ".drectve",8))
+          pDirectivesSectionHeader = &pSectionHeaders[i];
+   if (!pDirectivesSectionHeader) return 0;
+
+    rawdata=(const char*)pImageFileHeader+pDirectivesSectionHeader->PointerToRawData;
+    if (!pDirectivesSectionHeader->PointerToRawData || !rawdata) return 0;
+
+    size = pDirectivesSectionHeader->SizeOfRawData;
+    const char* posImportFlag = rawdata;
+    while ((posImportFlag = StrNStr(posImportFlag, " /EXPORT:", size))) {
+       const char* lookingForDict = posImportFlag + 9;
+       if (!strncmp(lookingForDict, "_G__cpp_",8) ||
+           !strncmp(lookingForDict, "_G__set_cpp_",12)) {
+          posImportFlag = lookingForDict;
+          continue;
+       }
+
+       const char* lookingForDATA = posImportFlag + 9;
+       while (*(++lookingForDATA) && *lookingForDATA != ' ');
+       lookingForDATA -= 5;
+       // ignore DATA exports
+       if (strncmp(lookingForDATA, ",DATA", 5)) break;
+       posImportFlag = lookingForDATA + 5;
+    }
+    fImportFlag = (int)posImportFlag;
+    return fImportFlag;
+}
+
+
+
+/*
+ *----------------------------------------------------------------------
+* DumpExternalsObjects --
+*
+*      Dumps a COFF symbol table from an EXE or OBJ.  We only use
+*      it to dump tables from OBJs.
+*----------------------------------------------------------------------
+*/
+void
+DumpExternalsObjects(PIMAGE_SYMBOL pSymbolTable, PIMAGE_SECTION_HEADER pSectionHeaders,
+                     FILE *fout, unsigned cSymbols, int fort)
+{
+   unsigned i;
+   PSTR stringTable;
+   std::string symbol;
+   DWORD SectChar;
+   static int fImportFlag = -1;  /*  The status is nor defined yet */
+
+   /*
+   * The string table apparently starts right after the symbol table
+   */
+   stringTable = (PSTR)&pSymbolTable[cSymbols];
+
+   for ( i=0; i < cSymbols; i++ ) {
+      if (pSymbolTable->SectionNumber > 0 && ( pSymbolTable->Type == 0x20 || pSymbolTable->Type == 0x0)) {
+         if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
+            /*
+            *    The name of the Function entry points
+            */
+            if (pSymbolTable->N.Name.Short != 0) {
+               symbol = "";
+               symbol.insert(0, (const char *)pSymbolTable->N.ShortName, 8);
+            } else {
+               symbol = stringTable + pSymbolTable->N.Name.Long;
+            }
+
+            while (isspace(symbol[0])) symbol.erase(0,1);
+#ifdef _MSC_VER
+            if (symbol[0] == '_') symbol.erase(0,1);
+            if (fort) {
+               std::string::size_type posAt = symbol.find('@');
+               if (posAt != std::string::npos) symbol.erase(posAt);
+            }
+#endif
+            if (fImportFlag) {
+               fImportFlag = 0;
+               fprintf(fout,"EXPORTS \n");
+            }
+            /*
+            Check whether it is "Scalar deleting destructor" and
+            "Vector deleting destructor"
+            */
+            /*
+            if (!strstr(s,"@@UAEPAXI at Z") && !strstr(s,"@@QAEPAXI at Z") &&
+            !strstr(s,"@AEPAXI at Z")   && !strstr(s,"AEPAXI at Z")    &&
+            !strstr(s,"real@"))
+            */
+            const char *scalarPrefix = "??_G";
+            const char *vectorPrefix = "??_E";
+            if (symbol.compare(0, 4, scalarPrefix) &&
+               symbol.compare(0, 4, vectorPrefix) &&
+               symbol.find("real@") == std::string::npos)
+            {
+               SectChar = pSectionHeaders[pSymbolTable->SectionNumber-1].Characteristics;
+               if (!pSymbolTable->Type  && (SectChar & IMAGE_SCN_MEM_WRITE)) {
+                  // Read only (i.e. constants) must be excluded
+                  fprintf(fout, "\t%s \t DATA\n", symbol.c_str());
+               } else {
+                  if ( pSymbolTable->Type  || !(SectChar & IMAGE_SCN_MEM_READ)) {
+                     fprintf(fout, "\t%s\n", symbol.c_str());
+                  } else {
+                     //                    printf(" strange symbol: %s \n",s);
+                  }
+               }
+            }
+         }
+      }
+      else if (pSymbolTable->SectionNumber == IMAGE_SYM_UNDEFINED && !pSymbolTable->Type && 0){
+         /*
+         *    The IMPORT global variable entry points
+         */
+         if (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) {
+            symbol = stringTable + pSymbolTable->N.Name.Long;
+            while (isspace(symbol[0]))  symbol.erase(0,1);
+            if (symbol[0] == '_') symbol.erase(0,1);
+            if (!fImportFlag) {
+               fImportFlag = 1;
+               fprintf(fout,"IMPORTS \n");
+            }
+            fprintf(fout, "\t%s DATA \n", symbol.c_str()+1);
+         }
+      }
+
+      /*
+      * Take into account any aux symbols
+      */
+      i += pSymbolTable->NumberOfAuxSymbols;
+      pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
+      pSymbolTable++;
+   }
+}
+
+/*
+*----------------------------------------------------------------------
+* DumpObjFile --
+*
+*      Dump an object file--either a full listing or just the exported
+*      symbols.
+*----------------------------------------------------------------------
+*/
+void
+DumpObjFile(PIMAGE_FILE_HEADER pImageFileHeader, FILE *fout, int full, int fort)
+{
+   PIMAGE_SYMBOL PCOFFSymbolTable;
+   PIMAGE_SECTION_HEADER PCOFFSectionHeaders;
+   DWORD_PTR COFFSymbolCount;
+
+   PCOFFSymbolTable = (PIMAGE_SYMBOL)
+      ((DWORD_PTR)pImageFileHeader + pImageFileHeader->PointerToSymbolTable);
+   COFFSymbolCount = pImageFileHeader->NumberOfSymbols;
+
+   PCOFFSectionHeaders = (PIMAGE_SECTION_HEADER)
+      ((DWORD_PTR)pImageFileHeader          +
+      IMAGE_SIZEOF_FILE_HEADER +
+      pImageFileHeader->SizeOfOptionalHeader);
+
+
+   if (full) {
+      DumpSymbolTable(PCOFFSymbolTable, PCOFFSectionHeaders, fout, COFFSymbolCount);
+   } else {
+        int haveExports = HaveExportedObjects(pImageFileHeader, PCOFFSectionHeaders, fout);
+        if (!haveExports)
+            DumpExternalsObjects(PCOFFSymbolTable, PCOFFSectionHeaders, fout, COFFSymbolCount, fort);
+   }
+}
+
+/*
+*----------------------------------------------------------------------
+* DumpFile --
+*
+*      Open up a file, memory map it, and call the appropriate
+*      dumping routine
+*----------------------------------------------------------------------
+*/
+void
+DumpFile(LPSTR filename, FILE *fout, int full, int fort)
+{
+   HANDLE hFile;
+   HANDLE hFileMapping;
+   LPVOID lpFileBase;
+   PIMAGE_DOS_HEADER dosHeader;
+
+   hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
+      OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
+
+   if (hFile == INVALID_HANDLE_VALUE) {
+      fprintf(stderr, "Couldn't open file with CreateFile()\n");
+      return;
+   }
+
+   hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+   if (hFileMapping == 0) {
+      CloseHandle(hFile);
+      fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n");
+      return;
+   }
+
+   lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
+   if (lpFileBase == 0) {
+      CloseHandle(hFileMapping);
+      CloseHandle(hFile);
+      fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n");
+      return;
+   }
+
+   dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
+   if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
+#if 0
+      DumpExeFile( dosHeader );
+#else
+      fprintf(stderr, "File is an executable.  I don't dump those.\n");
+      return;
+#endif
+   }
+   /* Does it look like a i386 COFF OBJ file??? */
+   else if (
+           ((dosHeader->e_magic == IMAGE_FILE_MACHINE_I386) || (dosHeader->e_magic == IMAGE_FILE_MACHINE_AMD64))
+           && (dosHeader->e_sp == 0)
+           ) {
+      /*
+      * The two tests above aren't what they look like.  They're
+      * really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C)
+      * and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0;
+      */
+      DumpObjFile((PIMAGE_FILE_HEADER) lpFileBase, fout, full, fort);
+   } else {
+      printf("unrecognized file format\n");
+   }
+   UnmapViewOfFile(lpFileBase);
+   CloseHandle(hFileMapping);
+   CloseHandle(hFile);
+}
+
+void
+main(int argc, char **argv)
+{
+   std::string cmdline;
+   int i, arg;
+   FILE *fout;
+   int full = 0;
+   int fort = 0;
+   char *dllname = "";
+   char *outfile = NULL;
+
+   if (argc < 3) {
+Usage:
+      fprintf(stderr, "Usage: %s ?-o outfile? ?-f(ull)? <dllname> <object filenames> ..\n", argv[0]);
+      exit(1);
+   }
+
+   arg = 1;
+   while (argv[arg][0] == '-') {
+      if (strcmp(argv[arg], "--") == 0) {
+         arg++;
+         break;
+      } else if (strcmp(argv[arg], "-f") == 0) {
+         full = 1;
+      } else if (strcmp(argv[arg], "-x") == 0) {
+         fort = 1;
+      } else if (strcmp(argv[arg], "-o") == 0) {
+         arg++;
+         if (arg == argc) {
+            goto Usage;
+         }
+         outfile = argv[arg];
+      }
+      arg++;
+   }
+   if (arg == argc) {
+      goto Usage;
+   }
+
+   if (outfile) {
+      fout = fopen(outfile, "w+");
+      if (fout == NULL) {
+         fprintf(stderr, "Unable to open \'%s\' for writing:\n",
+            argv[arg]);
+         perror("");
+         exit(1);
+      }
+   } else {
+      fout = stdout;
+   }
+
+   if (! full) {
+      dllname = argv[arg];
+      arg++;
+      if (arg == argc) {
+         goto Usage;
+      }
+      fprintf(fout, "LIBRARY    %s\n", dllname);
+#ifndef _X86_
+      fprintf(fout, "CODE PRELOAD MOVEABLE DISCARDABLE\n");
+      fprintf(fout, "DATA PRELOAD MOVEABLE MULTIPLE\n\n");
+#endif
+   }
+
+   for (; arg < argc; arg++) {
+      WIN32_FIND_DATA FindFileData;
+      HANDLE SearchFile;
+      if (argv[arg][0] == '@') {
+         std::ifstream fargs(&argv[arg][1]);
+         if (!fargs) {
+            fprintf(stderr, "Unable to open \'%s\' for reading:\n",
+               argv[arg]);
+            perror("");
+            exit(1);
+         }
+         char *fargv[1000];
+         for (i = 0; i < arg; i++) {
+            cmdline += argv[i];
+            fargv[i] = argv[i];
+         }
+         std::string line;
+         std::getline(fargs, line);
+         cmdline += line;
+         fprintf(stderr, "%s\n", line.c_str());
+         i += GetArgcArgv(line, &fargv[i]);
+         argc = i;
+         argv = fargv;
+      }
+      /*
+      *  Argument can contain the wildcard names
+      */
+      SearchFile = FindFirstFile(argv[arg],&FindFileData);
+      if (SearchFile == INVALID_HANDLE_VALUE){
+         fprintf(stderr, "Unable to find \'%s\' for reading:\n",
+            argv[arg]);
+         exit(1);
+      }
+      else  {
+         /*
+         *  Since WIN32_FIND_DATA has no path information one has to extract it himself.
+         */
+         TCHAR *filename = argv[arg];
+         TCHAR path[2048];
+         size_t i = strlen(filename);
+         i--;
+         while( filename[i] != '\\' && filename[i] != '/'  && i >=0) i--;
+         do
+         {
+            if (i >= 0) strncpy( path, filename, i+1); /* Generate the 'path' info */
+            path[i+1] = '\0';
+            DumpFile(strcat(path, FindFileData.cFileName), fout, full, fort);
+         } while (FindNextFile(SearchFile,&FindFileData));
+
+
+         FindClose(SearchFile);
+      }
+   }
+   exit(0);
+}

-----------------------------------------------------------------------

Summary of changes:


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list