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 #include +#include +#include #include #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& symbols, - std::set& dataSymbols, bool isI386) + DumpSymbols(ObjectHeaderType* ih, std::set& symbols, + std::set& 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& Symbols; - std::set& DataSymbols; + private: + std::set& Symbols; + std::set& DataSymbols; DWORD_PTR SymbolCount; PIMAGE_SECTION_HEADER SectionHeaders; ObjectHeaderType* ObjectImageHeader; @@ -288,35 +286,56 @@ private: bool IsI386; }; -bool DumpFile(const char* filename, std::set& symbols, - std::set& 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& symbols, + std::set& 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& 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& 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::const_iterator i = this->DataSymbols.begin(); + for (std::set::const_iterator i = this->DataSymbols.begin(); i != this->DataSymbols.end(); ++i) { fprintf(file, "\t%s \t DATA\n", i->c_str()); } - for (std::set::const_iterator i = this->Symbols.begin(); + for (std::set::const_iterator i = this->Symbols.begin(); i != this->Symbols.end(); ++i) { fprintf(file, "\t%s\n", i->c_str()); }