⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mergesym.cxx

📁 pwlib源码库
💻 CXX
字号:
/* * MergeSym.cxx * * Symbol merging utility for Windows DLL's. * * Portable Windows Library * * Copyright (c) 1993-1998 Equivalence Pty. Ltd. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Contributor(s): ______________________________________. * * $Log: MergeSym.cxx,v $ * Revision 1.16  2005/04/20 07:02:11  csoutheren * Changed handle "," in include paths * * Revision 1.15  2004/06/05 04:55:29  rjongbloed * Removed the unmangled versions of symbols to eliminate problems withthe line length *   exceeding MSVC linkers internal limits. Has added benefit of making files half the size. * * Revision 1.14  2004/05/22 07:41:32  rjongbloed * Added ability to specify command line override of the "dumpbin" program run *   to get library symbols, very useful for debugging. * * Revision 1.13  2004/04/09 07:03:23  rjongbloed * Added ability to get the output to DUMPBIN sent to a file. * * Revision 1.12  2004/04/03 06:54:32  rjongbloed * Many and various changes to support new Visual C++ 2003 * * Revision 1.11  2003/10/30 11:27:12  rjongbloed * Fixed ability to specify partial path for -x parameter. * * Revision 1.10  2003/02/11 07:00:17  robertj * Added copying def file to a backup version before alteration from read only. * * Revision 1.9  2002/06/13 05:51:01  robertj * Added ignore of some inherently private symbols exported by libraru eg debug *   line number info and real number constants. * * Revision 1.8  2000/12/18 07:31:10  robertj * Fixed minor irritation with DEF file being reordered when symbol added. * * Revision 1.7  2000/04/29 05:48:22  robertj * Added error and progress reporting in searching path for external DEF files. * * Revision 1.6  2000/04/29 05:01:49  robertj * Added multiple external DEF file capability (-x flag). * Added directory search path argument for external DEF files. * Fixed bug for symbols in external DEF file actively removed from merged DEF file. * Added copyright notice. * */#include <ptlib.h>#include <ptlib/pipechan.h>PDECLARE_CLASS(Symbol, PCaselessString)  public:    Symbol(const PString & sym, const PString & cpp, PINDEX ord = 0, BOOL ext = FALSE)      : PCaselessString(sym), unmangled(cpp) { ordinal = ord; external = ext; }    void SetOrdinal(PINDEX ord) { ordinal = ord; }    BOOL IsExternal() const { return external; }    void PrintOn(ostream & s) const    { s << "    " << theArray << " @" << ordinal << " NONAME\n"; }  private:    PString unmangled;    PINDEX ordinal;    BOOL external;};PSORTED_LIST(SortedSymbolList, Symbol);PDECLARE_CLASS(MergeSym, PProcess)  public:    MergeSym();    void Main();};PCREATE_PROCESS(MergeSym);MergeSym::MergeSym()  : PProcess("Equivalence", "MergeSym", 1, 4, ReleaseCode, 0){}void MergeSym::Main(){  cout << GetName() << " version " << GetVersion(TRUE)       << " on " << GetOSClass() << ' ' << GetOSName()       << " by " << GetManufacturer() << endl;  PArgList & args = GetArguments();  args.Parse("vsd:x:I:");  PFilePath lib_filename, def_filename;  switch (args.GetCount()) {    case 2 :      def_filename = args[1];      lib_filename = args[0];      break;    case 1 :      lib_filename = def_filename = args[0];      def_filename.SetType(".def");      break;    default :      PError << "usage: MergeSym [ -v ] [ -s ] [ -d dumpbin ] [ -x deffile[.def] ] [-I deffilepath ] libfile[.lib] [ deffile[.def] ]";      SetTerminationValue(1);      return;  }  if (lib_filename.GetType().IsEmpty())    lib_filename.SetType(".lib");  if (!PFile::Exists(lib_filename)) {    PError << "MergeSym: library file " << lib_filename << " does not exist.\n";    SetTerminationValue(1);    return;  }  if (def_filename.GetType().IsEmpty())    def_filename.SetType(".def");  SortedSymbolList def_symbols;  if (args.HasOption('x')) {    PStringArray include_path;    if (args.HasOption('I')) {      PString includes = args.GetOptionString('I');      if (includes.Find(';') == P_MAX_INDEX)        include_path = includes.Tokenise(',', FALSE);      else        include_path = includes.Tokenise(';', FALSE);    }    include_path.InsertAt(0, new PString());    PStringArray file_list = args.GetOptionString('x').Lines();    for (PINDEX ext_index = 0; ext_index < file_list.GetSize(); ext_index++) {      PString base_ext_filename = file_list[ext_index];      PString ext_filename = base_ext_filename;      if (PFilePath(ext_filename).GetType().IsEmpty())        ext_filename += ".def";      PINDEX previous_def_symbols_size = def_symbols.GetSize();      for (PINDEX inc_index = 0; inc_index < include_path.GetSize(); inc_index++) {        PString trial_filename = PDirectory(include_path[inc_index]) + ext_filename;        if (args.HasOption('v'))          cout << "\nTrying " << trial_filename << " ..." << flush;        PTextFile ext;        if (ext.Open(trial_filename, PFile::ReadOnly)) {          if (args.HasOption('v'))            cout << "\nReading external symbols from " << ext.GetFilePath() << " ..." << flush;          BOOL prefix = TRUE;          while (!ext.eof()) {            PCaselessString line;            ext >> line;            if (prefix)              prefix = line.Find("EXPORTS") == P_MAX_INDEX;            else {              PINDEX start = 0;              while (isspace(line[start]))                start++;              PINDEX end = start;              while (line[end] != '\0' && !isspace(line[end]))                end++;              def_symbols.Append(new Symbol(line(start, end-1), "", 0, TRUE));              if (args.HasOption('v') && def_symbols.GetSize()%100 == 0)                cout << '.' << flush;            }          }          break;        }      }      if (inc_index >= include_path.GetSize())        PError << "MergeSym: external symbol file \"" << base_ext_filename << "\" not found.\n";      if (args.HasOption('v'))        cout << '\n' << (def_symbols.GetSize() - previous_def_symbols_size)             << " symbols read." << endl;    }  }  PStringList def_file_lines;  PINDEX max_ordinal = 0;  PINDEX removed = 0;  PTextFile def;  if (def.Open(def_filename, PFile::ReadOnly)) {    if (args.HasOption('v'))      cout << "Reading existing ordinals..." << flush;    BOOL prefix = TRUE;    while (!def.eof()) {      PCaselessString line;      def >> line;      if (prefix) {        def_file_lines.AppendString(line);        if (line.Find("EXPORTS") != P_MAX_INDEX)          prefix = FALSE;      }      else {        PINDEX start = 0;        while (isspace(line[start]))          start++;        PINDEX end = start;        while (line[end] != '\0' && !isspace(line[end]))          end++;        PINDEX ordpos = line.Find('@', end);        if (ordpos != P_MAX_INDEX) {          PINDEX ordinal = line.Mid(ordpos+1).AsInteger();          if (ordinal > max_ordinal)            max_ordinal = ordinal;          PINDEX unmanglepos = line.Find(';', ordpos);          if (unmanglepos != P_MAX_INDEX)            unmanglepos++;          Symbol sym(line(start, end-1), line.Mid(unmanglepos), ordinal);          if (def_symbols.GetValuesIndex(sym) == P_MAX_INDEX)            def_symbols.Append(new Symbol(sym));          removed++;          if (args.HasOption('v') && def_symbols.GetSize()%100 == 0)            cout << '.' << flush;        }      }    }    def.Close();    if (args.HasOption('v'))      cout << '\n' << removed << " symbols read." << endl;  }  else {    def_file_lines.AppendString("LIBRARY " + def_filename.GetTitle());    def_file_lines.AppendString("EXPORTS");  }  if (args.HasOption('v'))    cout << "Reading library symbols..." << flush;  PINDEX linecount = 0;  SortedSymbolList lib_symbols;  PString dumpbin = args.GetOptionString('d', "dumpbin");  PPipeChannel pipe(dumpbin + " /symbols '" + lib_filename + "'", PPipeChannel::ReadOnly);  if (!pipe.IsOpen()) {    PError << "\nMergeSym: could not run \"" << dumpbin << "\".\n";    SetTerminationValue(2);    return;  }  PTextFile symfile;  if (args.HasOption('s')) {    PFilePath sym_filename = def_filename;    sym_filename.SetType(".sym");    if (!symfile.Open(sym_filename, PFile::WriteOnly))      cerr << "Could not open symbol file " << sym_filename << endl;  }  while (!pipe.eof()) {    PString line;    pipe >> line;    symfile << line;    char * namepos = strchr(line, '|');    if (namepos != NULL) {      *namepos = '\0';      while (*++namepos == ' ');      if (strstr(line, " UNDEF ") == NULL &&          strstr(line, " External ") != NULL &&          strstr(namepos, "deleting destructor") == NULL) {        int namelen = strcspn(namepos, "\r\n\t ");        PString name(namepos, namelen);        if (strncmp(name, "??_C@_", 6) != 0 &&            strncmp(name, "__real@", 7) != 0 &&            strncmp(name, "?__LINE__Var@", 13) != 0 &&            lib_symbols.GetValuesIndex(name) == P_MAX_INDEX) {          const char * unmangled = strchr(namepos+namelen, '(');          if (unmangled == NULL)            unmangled = name;          else {            unmangled++;            char * endunmangle = strrchr(unmangled, ')');            if (endunmangle != NULL)              *endunmangle = '\0';          }          lib_symbols.Append(new Symbol(name, unmangled));        }      }    }    if (args.HasOption('v') && linecount%500 == 0)      cout << '.' << flush;    linecount++;  }  if (args.HasOption('v'))    cout << '\n' << lib_symbols.GetSize() << " symbols read.\n"            "Sorting symbols... " << flush;  PINDEX i;  for (i = 0; i < def_symbols.GetSize(); i++) {    if (lib_symbols.GetValuesIndex(def_symbols[i]) != P_MAX_INDEX &&        !def_symbols[i].IsExternal())      removed--;  }  PINDEX added = 0;  for (i = 0; i < lib_symbols.GetSize(); i++) {    if (def_symbols.GetValuesIndex(lib_symbols[i]) == P_MAX_INDEX) {      lib_symbols[i].SetOrdinal(++max_ordinal);      added++;    }  }  if (added == 0 && removed == 0)    cout << "\nNo changes to symbols.\n";  else {    if (args.HasOption('v'))      cout << "Writing .DEF file..." << flush;    // If file is read/only, set it to read/write    PFileInfo info;    if (PFile::GetInfo(def_filename, info)) {      if ((info.permissions&PFileInfo::UserWrite) == 0) {        PFile::SetPermissions(def_filename, info.permissions|PFileInfo::UserWrite);        cout << "Setting \"" << def_filename << "\" to read/write mode." << flush;        PFile::Copy(def_filename, def_filename+".original");      }    }    if (def.Open(def_filename, PFile::WriteOnly)) {      SortedSymbolList merged_symbols;      merged_symbols.DisallowDeleteObjects();      for (i = 0; i < def_symbols.GetSize(); i++) {        if (lib_symbols.GetValuesIndex(def_symbols[i]) != P_MAX_INDEX &&            !def_symbols[i].IsExternal()) {          merged_symbols.Append(&def_symbols[i]);        }        if (args.HasOption('v') && i%100 == 0)          cout << '.' << flush;      }      for (i = 0; i < lib_symbols.GetSize(); i++) {        if (def_symbols.GetValuesIndex(lib_symbols[i]) == P_MAX_INDEX)          merged_symbols.Append(&lib_symbols[i]);        if (args.HasOption('v') && i%100 == 0)          cout << '.' << flush;      }      cout << "\nSymbols merged: " << added << " added, " << removed << " removed.\n";      for (i = 0; i < def_file_lines.GetSize(); i++)        def << def_file_lines[i] << '\n';      for (i = 0; i < merged_symbols.GetSize(); i++)        def << merged_symbols[i];      if (args.HasOption('v'))        cout << merged_symbols.GetSize() << " symbols written." << endl;    }    else {      PError << "Could not create file " << def_filename << ':' << def.GetErrorText() << endl;      SetTerminationValue(1);    }  }}// End MergeSym.cxx

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -