aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/def_parser/def_parser.patch
diff options
context:
space:
mode:
authorGravatar Yun Peng <pcloudy@google.com>2017-08-25 09:59:14 +0200
committerGravatar Yun Peng <pcloudy@google.com>2017-08-28 09:37:47 +0200
commit66437a0173488ca4e77aab8c41d5454871c8c6a2 (patch)
tree3527d0aff2c40c5be751aa972d880b27e6eb6aa2 /third_party/def_parser/def_parser.patch
parent9e3a3e2f6a16288febc74a4a3c9086c995f6aa5a (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.patch328
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());
+ }