diff options
author | Yun Peng <pcloudy@google.com> | 2017-08-25 09:59:14 +0200 |
---|---|---|
committer | Yun Peng <pcloudy@google.com> | 2017-08-28 09:37:47 +0200 |
commit | 66437a0173488ca4e77aab8c41d5454871c8c6a2 (patch) | |
tree | 3527d0aff2c40c5be751aa972d880b27e6eb6aa2 /third_party/def_parser/def_parser.patch | |
parent | 9e3a3e2f6a16288febc74a4a3c9086c995f6aa5a (diff) |
Windows: Implementing C++ DEF parser
C++ DEF parser can generating a DEF file from a object file, which can
be used to export symbols during linking DLL on Windows.
This parser is based on an implementation in CMake
See https://github.com/Kitware/CMake/blob/master/Source/bindexplib.cxx
A few changes has been made to make it work better.
Usage: output_deffile dllname [objfile ...] [input_deffile ...] [@paramfile ...]
output_deffile: the output DEF file
dllname: the DLL name this DEF file is used for, if dllname is not empty
string (eg. ""), def_parser writes an 'LIBRARY <dllname>' entry
into DEF file.
objfile: a object file, def_parser parses this file to find symbols,
then merges them into final result.
Can apppear multiple times.
input_deffile: an existing def file, def_parser merges all symbols in this file.
Can appear multiple times.
@paramfile: a parameter file that can contain objfile and input_deffile
Can appear multiple time.
Change-Id: I0ee65fa3119ecae2ea195b707af5690e4bc6a6c2
Diffstat (limited to 'third_party/def_parser/def_parser.patch')
-rw-r--r-- | third_party/def_parser/def_parser.patch | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/third_party/def_parser/def_parser.patch b/third_party/def_parser/def_parser.patch new file mode 100644 index 0000000000..78cb64872c --- /dev/null +++ b/third_party/def_parser/def_parser.patch @@ -0,0 +1,328 @@ +diff --git a/third_party/def_parser/def_parser.cc b/third_party/def_parser/def_parser.cc +index e96226a4b..07cb727b7 100644 +--- a/third_party/def_parser/def_parser.cc ++++ b/third_party/def_parser/def_parser.cc +@@ -61,19 +61,24 @@ + * Author: Valery Fine 16/09/96 (E-mail: fine@vxcern.cern.ch) + *---------------------------------------------------------------------- + */ +-#include "bindexplib.h" ++#include "src/main/cpp/util/file_platform.h" ++#include "third_party/def_parser/def_parser.h" + +-#include "cmsys/Encoding.hxx" +-#include "cmsys/FStream.hxx" ++#include <algorithm> + #include <iostream> ++#include <fstream> ++#include <sstream> + #include <windows.h> + + #ifndef IMAGE_FILE_MACHINE_ARMNT + #define IMAGE_FILE_MACHINE_ARMNT 0x01c4 + #endif + +-typedef struct cmANON_OBJECT_HEADER_BIGOBJ +-{ ++using std::string; ++using std::wstring; ++using std::stringstream; ++ ++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 +@@ -92,13 +97,10 @@ typedef struct cmANON_OBJECT_HEADER_BIGOBJ + DWORD NumberOfSymbols; + } cmANON_OBJECT_HEADER_BIGOBJ; + +-typedef struct _cmIMAGE_SYMBOL_EX +-{ +- union +- { ++typedef struct _cmIMAGE_SYMBOL_EX { ++ union { + BYTE ShortName[8]; +- struct +- { ++ struct { + DWORD Short; // if 0, use LongName + DWORD Long; // offset into string table + } Name; +@@ -113,16 +115,14 @@ typedef struct _cmIMAGE_SYMBOL_EX + typedef cmIMAGE_SYMBOL_EX UNALIGNED* cmPIMAGE_SYMBOL_EX; + + PIMAGE_SECTION_HEADER GetSectionHeaderOffset( +- PIMAGE_FILE_HEADER pImageFileHeader) +-{ ++ 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) +-{ ++ cmANON_OBJECT_HEADER_BIGOBJ* pImageFileHeader) { + return (PIMAGE_SECTION_HEADER)((DWORD_PTR)pImageFileHeader + + sizeof(cmANON_OBJECT_HEADER_BIGOBJ)); + } +@@ -130,8 +130,7 @@ PIMAGE_SECTION_HEADER GetSectionHeaderOffset( + /* + + * Utility func, strstr with size + + */ +-const char* StrNStr(const char* start, const char* find, size_t& size) +-{ ++const char* StrNStr(const char* start, const char* find, size_t& size) { + size_t len; + const char* hint; + +@@ -157,9 +156,8 @@ template < + class ObjectHeaderType, + // cmPIMAGE_SYMBOL_EX or PIMAGE_SYMBOL + class SymbolTableType> +-class DumpSymbols +-{ +-public: ++class DumpSymbols { ++ public: + /* + *---------------------------------------------------------------------- + * Constructor -- +@@ -169,11 +167,10 @@ public: + *---------------------------------------------------------------------- + */ + +- DumpSymbols(ObjectHeaderType* ih, std::set<std::string>& symbols, +- std::set<std::string>& dataSymbols, bool isI386) ++ DumpSymbols(ObjectHeaderType* ih, std::set<string>& symbols, ++ std::set<string>& dataSymbols, bool isI386) + : Symbols(symbols) +- , DataSymbols(dataSymbols) +- { ++ , DataSymbols(dataSymbols) { + this->ObjectImageHeader = ih; + this->SymbolTable = + (SymbolTableType*)((DWORD_PTR) this->ObjectImageHeader + +@@ -190,7 +187,9 @@ public: + * Dump an object file's exported symbols. + *---------------------------------------------------------------------- + */ +- void DumpObjFile() { this->DumpExternalsObjects(); } ++ void DumpObjFile() { ++ this->DumpExternalsObjects(); ++ } + + /* + *---------------------------------------------------------------------- +@@ -199,11 +198,10 @@ public: + * Dumps a COFF symbol table from an OBJ. + *---------------------------------------------------------------------- + */ +- void DumpExternalsObjects() +- { ++ void DumpExternalsObjects() { + unsigned i; + PSTR stringTable; +- std::string symbol; ++ string symbol; + DWORD SectChar; + /* + * The string table apparently starts right after the symbol table +@@ -230,8 +228,8 @@ public: + // 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) { ++ string::size_type posAt = symbol.find('@'); ++ if (posAt != string::npos) { + symbol.erase(posAt); + } + } +@@ -247,14 +245,14 @@ public: + const char* scalarPrefix = "??_G"; + const char* vectorPrefix = "??_E"; + // The original code had a check for +- // symbol.find("real@") == std::string::npos) ++ // symbol.find("real@") == string::npos) + // but this disallows member functions with the name "real". + if (symbol.compare(0, 4, scalarPrefix) && + symbol.compare(0, 4, vectorPrefix)) { + SectChar = this->SectionHeaders[pSymbolTable->SectionNumber - 1] + .Characteristics; + // skip symbols containing a dot +- if (symbol.find('.') == std::string::npos) { ++ if (symbol.find('.') == string::npos) { + if (!pSymbolTable->Type && (SectChar & IMAGE_SCN_MEM_WRITE)) { + // Read only (i.e. constants) must be excluded + this->DataSymbols.insert(symbol); +@@ -278,9 +276,9 @@ public: + } + } + +-private: +- std::set<std::string>& Symbols; +- std::set<std::string>& DataSymbols; ++ private: ++ std::set<string>& Symbols; ++ std::set<string>& DataSymbols; + DWORD_PTR SymbolCount; + PIMAGE_SECTION_HEADER SectionHeaders; + ObjectHeaderType* ObjectImageHeader; +@@ -288,35 +286,56 @@ private: + bool IsI386; + }; + +-bool DumpFile(const char* filename, std::set<std::string>& symbols, +- std::set<std::string>& dataSymbols) +-{ ++void PrintLastError() { ++ DWORD last_error = GetLastError(); ++ if (last_error == 0) { ++ return; ++ } ++ ++ char* message_buffer; ++ size_t size = FormatMessageA( ++ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | ++ FORMAT_MESSAGE_IGNORE_INSERTS, ++ NULL, last_error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), ++ (LPSTR)&message_buffer, 0, NULL); ++ ++ std::cerr << "(error: " << last_error << "): " << message_buffer; ++ LocalFree(message_buffer); ++} ++ ++bool DumpFile(const char* filename, std::set<string>& symbols, ++ std::set<string>& dataSymbols) { + HANDLE hFile; + HANDLE hFileMapping; + LPVOID lpFileBase; + PIMAGE_DOS_HEADER dosHeader; + +- hFile = CreateFileW(cmsys::Encoding::ToWide(filename).c_str(), GENERIC_READ, ++ wstring filenameW; ++ blaze_util::AsAbsoluteWindowsPath(filename, &filenameW); ++ hFile = CreateFileW(filenameW.c_str(), GENERIC_READ, + FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, 0); + + if (hFile == INVALID_HANDLE_VALUE) { ++ PrintLastError(); + 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); ++ PrintLastError(); + fprintf(stderr, "Couldn't open file mapping with CreateFileMapping()\n"); ++ CloseHandle(hFile); + return false; + } + + lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0); + if (lpFileBase == 0) { ++ PrintLastError(); ++ fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n"); + CloseHandle(hFileMapping); + CloseHandle(hFile); +- fprintf(stderr, "Couldn't map view of file with MapViewOfFile()\n"); + return false; + } + +@@ -348,7 +367,7 @@ bool DumpFile(const char* filename, std::set<std::string>& symbols, + (h->Machine == IMAGE_FILE_MACHINE_I386)); + symbolDumper.DumpObjFile(); + } else { +- printf("unrecognized file format in '%s'\n", filename); ++ printf("Unrecognized file format in '%s'\n", filename); + return false; + } + } +@@ -358,19 +377,23 @@ bool DumpFile(const char* filename, std::set<std::string>& symbols, + return true; + } + +-bool bindexplib::AddObjectFile(const char* filename) +-{ ++ ++void DefParser::SetDLLName(const string& dllname) { ++ this->DLLName = dllname; ++} ++ ++bool DefParser::AddObjectFile(const char* filename) { + return DumpFile(filename, this->Symbols, this->DataSymbols); + } + +-bool bindexplib::AddDefinitionFile(const char* filename) +-{ +- cmsys::ifstream infile(filename); ++bool DefParser::AddDefinitionFile(const char* filename) { ++ std::ifstream infile(filename); + if (!infile) { ++ PrintLastError(); + fprintf(stderr, "Couldn't open definition file '%s'\n", filename); + return false; + } +- std::string str; ++ string str; + while (std::getline(infile, str)) { + // skip the LIBRAY and EXPORTS lines (if any) + if ((str.compare(0, 7, "LIBRARY") == 0) || +@@ -380,8 +403,8 @@ bool bindexplib::AddDefinitionFile(const char* filename) + // remove leading tabs & spaces + str.erase(0, str.find_first_not_of(" \t")); + std::size_t found = str.find(" \t DATA"); +- if (found != std::string::npos) { +- str.erase(found, std::string::npos); ++ if (found != string::npos) { ++ str.erase(found, string::npos); + this->DataSymbols.insert(str); + } else { + this->Symbols.insert(str); +@@ -391,14 +414,37 @@ bool bindexplib::AddDefinitionFile(const char* filename) + return true; + } + +-void bindexplib::WriteFile(FILE* file) +-{ ++bool DefParser::IsDefFile(const string& file) { ++ // Get file extension and convert it to lower case. ++ string ext = file.substr(file.find_last_of(".") + 1); ++ std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); ++ return ext == "def"; ++} ++ ++bool DefParser::AddFile(const string& file) { ++ if (IsDefFile(file)) { ++ if (!this->AddDefinitionFile(file.c_str())) { ++ return false; ++ } ++ } else { ++ if (!this->AddObjectFile(file.c_str())) { ++ return false; ++ } ++ } ++ return true; ++} ++ ++void DefParser::WriteFile(FILE* file) { ++ if (!this->DLLName.empty()) { ++ fprintf(file, "LIBRARY %s\n", this->DLLName.c_str()); ++ } ++ + fprintf(file, "EXPORTS \n"); +- for (std::set<std::string>::const_iterator i = this->DataSymbols.begin(); ++ for (std::set<string>::const_iterator i = this->DataSymbols.begin(); + i != this->DataSymbols.end(); ++i) { + fprintf(file, "\t%s \t DATA\n", i->c_str()); + } +- for (std::set<std::string>::const_iterator i = this->Symbols.begin(); ++ for (std::set<string>::const_iterator i = this->Symbols.begin(); + i != this->Symbols.end(); ++i) { + fprintf(file, "\t%s\n", i->c_str()); + } |