blob: 56679bf2348fe47a0165c812afcbe8da98eca970 [file] [log] [blame]
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