| diff --git a/third_party/def_parser/def_parser.cc b/third_party/def_parser/def_parser.cc |
| index 8f78744312..890f33a1ba 100644 |
| --- a/third_party/def_parser/def_parser.cc |
| +++ b/third_party/def_parser/def_parser.cc |
| @@ -62,21 +62,14 @@ |
| * Author: Valery Fine 16/09/96 (E-mail: fine@vxcern.cern.ch) |
| *---------------------------------------------------------------------- |
| */ |
| -#include "bindexplib.h" |
| +#include "third_party/def_parser/def_parser.h" |
| |
| -#include <cstddef> // IWYU pragma: keep |
| +#include <algorithm> |
| +#include <iostream> |
| +#include <fstream> |
| +#include <memory> // unique_ptr |
| #include <sstream> |
| -#include <vector> |
| - |
| -#ifdef _WIN32 |
| -# include <windows.h> |
| - |
| -# include "cmsys/Encoding.hxx" |
| -#endif |
| - |
| -#include "cmsys/FStream.hxx" |
| - |
| -#include "cmSystemTools.h" |
| +#include <windows.h> |
| |
| #ifdef _WIN32 |
| # ifndef IMAGE_FILE_MACHINE_ARM |
| @@ -99,6 +92,11 @@ |
| # define IMAGE_FILE_MACHINE_ARM64EC 0xa641 // ARM64EC Little-Endian |
| # endif |
| |
| +using std::string; |
| +using std::wstring; |
| +using std::stringstream; |
| +using std::unique_ptr; |
| + |
| typedef struct cmANON_OBJECT_HEADER_BIGOBJ |
| { |
| /* same as ANON_OBJECT_HEADER_V2 */ |
| @@ -341,77 +339,69 @@ private: |
| }; |
| #endif |
| |
| -static bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename, |
| - std::set<std::string>& symbols, |
| - std::set<std::string>& dataSymbols) |
| -{ |
| - std::string output; |
| - // break up command line into a vector |
| - std::vector<std::string> command; |
| - command.push_back(nmPath); |
| - command.emplace_back("--no-weak"); |
| - command.emplace_back("--defined-only"); |
| - command.emplace_back("--format=posix"); |
| - command.emplace_back(filename); |
| - |
| - // run the command |
| - int exit_code = 0; |
| - cmSystemTools::RunSingleCommand(command, &output, &output, &exit_code, |
| - nullptr, cmSystemTools::OUTPUT_NONE); |
| - |
| - if (exit_code != 0) { |
| - fprintf(stderr, "llvm-nm returned an error: %s\n", output.c_str()); |
| - return false; |
| +void PrintLastError() { |
| + DWORD last_error = GetLastError(); |
| + if (last_error == 0) { |
| + return; |
| } |
| |
| - std::istringstream ss(output); |
| - std::string line; |
| - while (std::getline(ss, line)) { |
| - if (line.empty()) { // last line |
| - continue; |
| - } |
| - size_t sym_end = line.find(' '); |
| - if (sym_end == std::string::npos) { |
| - fprintf(stderr, "Couldn't parse llvm-nm output line: %s\n", |
| - line.c_str()); |
| - return false; |
| - } |
| - if (line.size() < sym_end + 1) { |
| - fprintf(stderr, "Couldn't parse llvm-nm output line: %s\n", |
| - line.c_str()); |
| - return false; |
| - } |
| - const char sym_type = line[sym_end + 1]; |
| - line.resize(sym_end); |
| - switch (sym_type) { |
| - case 'D': |
| - dataSymbols.insert(line); |
| - break; |
| - case 'T': |
| - symbols.insert(line); |
| - break; |
| - } |
| + 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); |
| +} |
| + |
| +wstring StringToWString(const string& s) { |
| + SetLastError(ERROR_SUCCESS); |
| + DWORD len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, NULL, 0); |
| + if (len == 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { |
| + PrintLastError(); |
| + return L""; |
| } |
| + unique_ptr<WCHAR[]> wstr(new WCHAR[len]); |
| + MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, wstr.get(), len); |
| + return wstring(wstr.get()); |
| +} |
| |
| - return true; |
| +wstring AsAbsoluteWindowsPath(const string& path) { |
| + wstring wpath = StringToWString(path); |
| + // Get the buffer length we need for the full path. |
| + SetLastError(ERROR_SUCCESS); |
| + DWORD len = GetFullPathNameW(wpath.c_str(), 0, NULL, NULL); |
| + if (len == 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { |
| + PrintLastError(); |
| + return L""; |
| + } |
| + SetLastError(ERROR_SUCCESS); |
| + unique_ptr<WCHAR[]> buffer(new WCHAR[len]); |
| + GetFullPathNameW(wpath.c_str(), len, buffer.get(), NULL); |
| + if (GetLastError() != ERROR_SUCCESS) { |
| + PrintLastError(); |
| + return L""; |
| + } |
| + return wstring(L"\\\\?\\") + wstring(buffer.get()); |
| } |
| |
| -static bool DumpFile(std::string const& nmPath, const char* filename, |
| +static bool DumpFile(const char* filename, |
| std::set<std::string>& symbols, |
| std::set<std::string>& dataSymbols) |
| { |
| -#ifndef _WIN32 |
| - return DumpFileWithLlvmNm(nmPath, filename, symbols, dataSymbols); |
| -#else |
| HANDLE hFile; |
| HANDLE hFileMapping; |
| LPVOID lpFileBase; |
| |
| - hFile = CreateFileW(cmsys::Encoding::ToWide(filename).c_str(), GENERIC_READ, |
| + wstring filenameW = AsAbsoluteWindowsPath(filename); |
| + hFile = CreateFileW(filenameW.c_str(), GENERIC_READ, |
| FILE_SHARE_READ, nullptr, 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; |
| } |
| @@ -419,16 +409,18 @@ static bool DumpFile(std::string const& nmPath, const char* filename, |
| hFileMapping = |
| CreateFileMapping(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr); |
| 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; |
| } |
| |
| @@ -474,14 +466,6 @@ static bool DumpFile(std::string const& nmPath, const char* filename, |
| : (h->Machine == IMAGE_FILE_MACHINE_ARM64EC ? Arch::ARM64EC |
| : Arch::Generic))); |
| symbolDumper.DumpObjFile(); |
| - } else if ( |
| - // BCexCODE - llvm bitcode |
| - (h->Sig1 == 0x4342 && h->Sig2 == 0xDEC0) || |
| - // 0x0B17C0DE - llvm bitcode BC wrapper |
| - (h->Sig1 == 0x0B17 && h->Sig2 == 0xC0DE)) { |
| - |
| - return DumpFileWithLlvmNm(nmPath, filename, symbols, dataSymbols); |
| - |
| } else { |
| printf("unrecognized file format in '%s, %u'\n", filename, |
| imageHeader->Machine); |
| @@ -493,18 +477,22 @@ static bool DumpFile(std::string const& nmPath, const char* filename, |
| CloseHandle(hFileMapping); |
| CloseHandle(hFile); |
| return true; |
| -#endif |
| } |
| |
| -bool bindexplib::AddObjectFile(const char* filename) |
| +void DefParser::SetDLLName(const string& dllname) { |
| + this->DLLName = dllname; |
| +} |
| + |
| +bool DefParser::AddObjectFile(const char* filename) |
| { |
| - return DumpFile(this->NmPath, filename, this->Symbols, this->DataSymbols); |
| + return DumpFile(filename, this->Symbols, this->DataSymbols); |
| } |
| |
| -bool bindexplib::AddDefinitionFile(const char* filename) |
| +bool DefParser::AddDefinitionFile(const char* filename) |
| { |
| - cmsys::ifstream infile(filename); |
| + std::ifstream infile(filename); |
| if (!infile) { |
| + PrintLastError(); |
| fprintf(stderr, "Couldn't open definition file '%s'\n", filename); |
| return false; |
| } |
| @@ -529,8 +517,31 @@ 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::string const& ds : this->DataSymbols) { |
| fprintf(file, "\t%s \t DATA\n", ds.c_str()); |
| @@ -539,8 +550,3 @@ void bindexplib::WriteFile(FILE* file) |
| fprintf(file, "\t%s\n", s.c_str()); |
| } |
| } |
| - |
| -void bindexplib::SetNmPath(std::string const& nm) |
| -{ |
| - this->NmPath = nm; |
| -} |
| \ No newline at end of file |