diff --git a/src/coreclr/tools/superpmi/mcs/commandline.cpp b/src/coreclr/tools/superpmi/mcs/commandline.cpp index 86ce6023375d1f..8a2f10c2696778 100644 --- a/src/coreclr/tools/superpmi/mcs/commandline.cpp +++ b/src/coreclr/tools/superpmi/mcs/commandline.cpp @@ -335,7 +335,8 @@ bool CommandLine::Parse(int argc, char* argv[], /* OUT */ Options* o) i++; processMCL2: - bool isValidList = MCList::processArgAsMCL(argv[i], &o->indexCount, &o->indexes); + bool isValidList = MCList::processArgAsMCL(argv[i], o->indexes); + o->indexCount = (int)o->indexes.size(); if (!isValidList) i--; } diff --git a/src/coreclr/tools/superpmi/mcs/commandline.h b/src/coreclr/tools/superpmi/mcs/commandline.h index ea78f456f91a96..98e7112dac9e35 100644 --- a/src/coreclr/tools/superpmi/mcs/commandline.h +++ b/src/coreclr/tools/superpmi/mcs/commandline.h @@ -39,7 +39,6 @@ class CommandLine , nameOfFile2(nullptr) , nameOfFile3(nullptr) , indexCount(-1) - , indexes(nullptr) { } @@ -68,7 +67,7 @@ class CommandLine char* nameOfFile2; char* nameOfFile3; int indexCount; - int* indexes; + std::vector indexes; }; static bool Parse(int argc, char* argv[], /* OUT */ Options* o); diff --git a/src/coreclr/tools/superpmi/mcs/mcs.cpp b/src/coreclr/tools/superpmi/mcs/mcs.cpp index 2923a4f9186f31..313c98a43ec74b 100644 --- a/src/coreclr/tools/superpmi/mcs/mcs.cpp +++ b/src/coreclr/tools/superpmi/mcs/mcs.cpp @@ -43,7 +43,7 @@ int __cdecl main(int argc, char* argv[]) int exitCode = 0; if (o.actionASMDump) { - exitCode = verbASMDump::DoWork(o.nameOfFile1, o.nameOfFile2, o.indexCount, o.indexes); + exitCode = verbASMDump::DoWork(o.nameOfFile1, o.nameOfFile2, o.indexCount, o.indexes.data()); } if (o.actionConcat) { @@ -55,15 +55,15 @@ int __cdecl main(int argc, char* argv[]) } if (o.actionCopy) { - exitCode = verbStrip::DoWork(o.nameOfFile1, o.nameOfFile2, o.indexCount, o.indexes, false, o.stripCR); + exitCode = verbStrip::DoWork(o.nameOfFile1, o.nameOfFile2, o.indexCount, o.indexes.data(), false, o.stripCR); } if (o.actionDump) { - exitCode = verbDump::DoWork(o.nameOfFile1, o.indexCount, o.indexes, o.simple); + exitCode = verbDump::DoWork(o.nameOfFile1, o.indexCount, o.indexes.data(), o.simple); } if (o.actionFracture) { - exitCode = verbFracture::DoWork(o.nameOfFile1, o.nameOfFile2, o.indexCount, o.indexes, o.stripCR); + exitCode = verbFracture::DoWork(o.nameOfFile1, o.nameOfFile2, o.indexCount, o.indexes.data(), o.stripCR); } if (o.actionDumpMap) { @@ -75,7 +75,7 @@ int __cdecl main(int argc, char* argv[]) } if (o.actionILDump) { - exitCode = verbILDump::DoWork(o.nameOfFile1, o.indexCount, o.indexes); + exitCode = verbILDump::DoWork(o.nameOfFile1, o.indexCount, o.indexes.data()); } if (o.actionInteg) { @@ -87,11 +87,11 @@ int __cdecl main(int argc, char* argv[]) } if (o.actionStat) { - exitCode = verbStat::DoWork(o.nameOfFile1, o.nameOfFile2, o.indexCount, o.indexes); + exitCode = verbStat::DoWork(o.nameOfFile1, o.nameOfFile2, o.indexCount, o.indexes.data()); } if (o.actionStrip) { - exitCode = verbStrip::DoWork(o.nameOfFile1, o.nameOfFile2, o.indexCount, o.indexes, true, o.stripCR); + exitCode = verbStrip::DoWork(o.nameOfFile1, o.nameOfFile2, o.indexCount, o.indexes.data(), true, o.stripCR); } if (o.actionTOC) { diff --git a/src/coreclr/tools/superpmi/mcs/removedup.cpp b/src/coreclr/tools/superpmi/mcs/removedup.cpp index b2ba784e633f15..4c4f11ebd19306 100644 --- a/src/coreclr/tools/superpmi/mcs/removedup.cpp +++ b/src/coreclr/tools/superpmi/mcs/removedup.cpp @@ -118,7 +118,7 @@ bool RemoveDup::uniqueLegacy(MethodContext* mc) return true; } -bool RemoveDup::CopyAndRemoveDups(const char* nameOfInput, HANDLE hFileOut) +bool RemoveDup::CopyAndRemoveDups(const char* nameOfInput, FILE* fpOut) { MethodContextIterator mci(/* progressReport */ true); if (!mci.Initialize(nameOfInput)) @@ -138,7 +138,7 @@ bool RemoveDup::CopyAndRemoveDups(const char* nameOfInput, HANDLE hFileOut) { if (uniqueLegacy(mc)) { - mc->saveToFile(hFileOut); + mc->saveToFile(fpOut); savedCount++; // In this case, for the legacy comparer, it has placed the 'mc' in the 'm_inFileLegacy' table, so we @@ -153,7 +153,7 @@ bool RemoveDup::CopyAndRemoveDups(const char* nameOfInput, HANDLE hFileOut) { if (unique(mc)) { - mc->saveToFile(hFileOut); + mc->saveToFile(fpOut); savedCount++; } delete mc; // we no longer need this diff --git a/src/coreclr/tools/superpmi/mcs/removedup.h b/src/coreclr/tools/superpmi/mcs/removedup.h index ee14e636ef7fff..d52b955a6f1510 100644 --- a/src/coreclr/tools/superpmi/mcs/removedup.h +++ b/src/coreclr/tools/superpmi/mcs/removedup.h @@ -35,7 +35,7 @@ class RemoveDup ~RemoveDup(); - bool CopyAndRemoveDups(const char* nameOfInput, HANDLE hFileOut); + bool CopyAndRemoveDups(const char* nameOfInput, FILE* fpOut); private: diff --git a/src/coreclr/tools/superpmi/mcs/verbasmdump.cpp b/src/coreclr/tools/superpmi/mcs/verbasmdump.cpp index 6d70077b8c7a4e..8c98c1b438d97d 100644 --- a/src/coreclr/tools/superpmi/mcs/verbasmdump.cpp +++ b/src/coreclr/tools/superpmi/mcs/verbasmdump.cpp @@ -28,31 +28,25 @@ int verbASMDump::DoWork(const char* nameOfInput, const char* nameOfOutput, int i char buff[500]; sprintf_s(buff, 500, "%s-%d.asm", nameOfOutput, mci.MethodContextNumber()); - HANDLE hFileOut = CreateFileA(buff, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (hFileOut == INVALID_HANDLE_VALUE) + FILE* fpOut = fopen(buff, "w"); + if (fpOut == NULL) { - LogError("Failed to open output '%s'. GetLastError()=%u", buff, GetLastError()); + LogError("Failed to open output '%s'. errno=%d", buff, errno); return -1; } if (mc->cr->IsEmpty()) { - const size_t bufflen = 4096; - DWORD bytesWritten; - char buff[bufflen]; - ZeroMemory(buff, bufflen * sizeof(char)); - int buff_offset = sprintf_s(buff, bufflen, ";;Method context has no compile result"); - WriteFile(hFileOut, buff, buff_offset * sizeof(char), &bytesWritten, nullptr); + fprintf(fpOut, ";;Method context has no compile result"); } else { - ASMDumper::DumpToFile(hFileOut, mc, mc->cr); + ASMDumper::DumpToFile(fpOut, mc, mc->cr); } - if (!CloseHandle(hFileOut)) + if (fclose(fpOut) != 0) { - LogError("CloseHandle failed. GetLastError()=%u", GetLastError()); + LogError("fclose failed. errno=%d", errno); return -1; } savedCount++; diff --git a/src/coreclr/tools/superpmi/mcs/verbconcat.cpp b/src/coreclr/tools/superpmi/mcs/verbconcat.cpp index 9d6f7b39c0e291..aacc7c9b1a5860 100644 --- a/src/coreclr/tools/superpmi/mcs/verbconcat.cpp +++ b/src/coreclr/tools/superpmi/mcs/verbconcat.cpp @@ -14,61 +14,37 @@ int verbConcat::DoWork(const char* nameOfFile1, const char* nameOfFile2) LogVerbose("Concatenating '%s'+'%s' into %s", nameOfFile1, nameOfFile2, nameOfFile1); - LARGE_INTEGER DataTemp1; - LARGE_INTEGER DataTemp2; - - HANDLE hFileIn1 = CreateFileA(nameOfFile1, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (hFileIn1 == INVALID_HANDLE_VALUE) - { - LogError("Failed to open input 1 '%s'. GetLastError()=%u", nameOfFile1, GetLastError()); - return -1; - } - if (GetFileSizeEx(hFileIn1, &DataTemp1) == 0) + FILE* fp1 = fopen(nameOfFile1, "ab+"); + if (fp1 == NULL) { - LogError("GetFileSizeEx failed. GetLastError()=%u", GetLastError()); + LogError("Failed to open input 1 '%s'. errno=%d", nameOfFile1, errno); return -1; } - LONG highDWORD = 0; - DWORD dwPtr = SetFilePointer(hFileIn1, 0, &highDWORD, FILE_END); - if (dwPtr == INVALID_SET_FILE_POINTER) - { - LogError("Failed to SetFilePointer on input 1 '%s'. GetLastError()=%u", nameOfFile1, GetLastError()); - return -1; - } - - HANDLE hFileIn2 = CreateFileA(nameOfFile2, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (hFileIn2 == INVALID_HANDLE_VALUE) - { - LogError("Failed to open input 2 '%s'. GetLastError()=%u", nameOfFile2, GetLastError()); - return -1; - } - if (GetFileSizeEx(hFileIn2, &DataTemp2) == 0) + FILE* fp2 = fopen(nameOfFile2, "rb"); + if (fp2 == NULL) { - LogError("2nd GetFileSizeEx failed. GetLastError()=%u", GetLastError()); + LogError("Failed to open input 2 '%s'. errno=%d", nameOfFile2, errno); return -1; } unsigned char* buffer = new unsigned char[BUFFER_SIZE]; + int64_t offset = 0; st1.Start(); - for (LONGLONG offset = 0; offset < DataTemp2.QuadPart; offset += BUFFER_SIZE) + while (!feof(fp2)) { - DWORD bytesRead = -1; - BOOL res = ReadFile(hFileIn2, buffer, BUFFER_SIZE, &bytesRead, nullptr); - if (res == 0) + size_t bytesRead = fread(buffer, 1, BUFFER_SIZE, fp2); + if (bytesRead <= 0) { - LogError("Failed to read '%s' from offset %lld. GetLastError()=%u", nameOfFile2, offset, GetLastError()); + LogError("Failed to read '%s' from offset %lld. errno=%d", nameOfFile2, offset, errno); delete[] buffer; return -1; } - DWORD bytesWritten = -1; - BOOL res2 = WriteFile(hFileIn1, buffer, bytesRead, &bytesWritten, nullptr); - if (res2 == 0) + size_t bytesWritten = fwrite(buffer, 1, bytesRead, fp1); + if (bytesWritten <= 0) { - LogError("Failed to write '%s' at offset %lld. GetLastError()=%u", nameOfFile1, offset, GetLastError()); + LogError("Failed to write '%s' at offset %lld. errno=%d", nameOfFile1, offset, errno); delete[] buffer; return -1; } @@ -78,24 +54,25 @@ int verbConcat::DoWork(const char* nameOfFile1, const char* nameOfFile2) delete[] buffer; return -1; } + offset += bytesRead; } st1.Stop(); delete[] buffer; - if (CloseHandle(hFileIn1) == 0) + if (fclose(fp1) != 0) { - LogError("CloseHandle failed. GetLastError()=%u", GetLastError()); + LogError("CloseHandle failed. errno=%d", errno); return -1; } - if (CloseHandle(hFileIn2) == 0) + if (fclose(fp2) != 0) { - LogError("2nd CloseHandle failed. GetLastError()=%u", GetLastError()); + LogError("2nd CloseHandle failed. errno=%d", errno); return -1; } - LogInfo("Read/Wrote %lld MB @ %4.2f MB/s.\n", DataTemp2.QuadPart / (1000 * 1000), - (((double)DataTemp2.QuadPart) / (1000 * 1000)) / + LogInfo("Read/Wrote %lld MB @ %4.2f MB/s.\n", offset / (1000 * 1000), + (((double)offset) / (1000 * 1000)) / st1.GetSeconds()); // yes yes.. http://en.wikipedia.org/wiki/Megabyte_per_second#Megabyte_per_second return 0; diff --git a/src/coreclr/tools/superpmi/mcs/verbfracture.cpp b/src/coreclr/tools/superpmi/mcs/verbfracture.cpp index 549e4ed9322149..a9295481a4b786 100644 --- a/src/coreclr/tools/superpmi/mcs/verbfracture.cpp +++ b/src/coreclr/tools/superpmi/mcs/verbfracture.cpp @@ -24,28 +24,27 @@ int verbFracture::DoWork( int fileCount = 0; char fileName[512]; - HANDLE hFileOut = INVALID_HANDLE_VALUE; + FILE* fpOut = NULL; while (mci.MoveNext()) { MethodContext* mc = mci.Current(); - if ((hFileOut == INVALID_HANDLE_VALUE) || (((mci.MethodContextNumber() - 1) % rangeSize) == 0)) + if ((fpOut == NULL) || (((mci.MethodContextNumber() - 1) % rangeSize) == 0)) { - if (hFileOut != INVALID_HANDLE_VALUE) + if (fpOut != NULL) { - if (!CloseHandle(hFileOut)) + if (fclose(fpOut) != 0) { - LogError("1st CloseHandle failed. GetLastError()=%u", GetLastError()); + LogError("1st CloseHandle failed. errno=%d", errno); return -1; } - hFileOut = INVALID_HANDLE_VALUE; + fpOut = NULL; } sprintf_s(fileName, 512, "%s-%0*d.mch", nameOfOutput, 5, fileCount++); - hFileOut = CreateFileA(fileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (hFileOut == INVALID_HANDLE_VALUE) + fpOut = fopen(fileName, "wb"); + if (fpOut == NULL) { - LogError("Failed to open output file '%s'. GetLastError()=%u", fileName, GetLastError()); + LogError("Failed to open output file '%s'. errno=%d", fileName, errno); return -1; } } @@ -54,14 +53,14 @@ int verbFracture::DoWork( delete mc->cr; mc->cr = new CompileResult(); } - mc->saveToFile(hFileOut); + mc->saveToFile(fpOut); } - if (hFileOut != INVALID_HANDLE_VALUE) + if (fpOut != NULL) { - if (!CloseHandle(hFileOut)) + if (fclose(fpOut) != 0) { - LogError("2nd CloseHandle failed. GetLastError()=%u", GetLastError()); + LogError("2nd CloseHandle failed. errno=%d", errno); return -1; } } diff --git a/src/coreclr/tools/superpmi/mcs/verbmerge.cpp b/src/coreclr/tools/superpmi/mcs/verbmerge.cpp index 35b7263d4a68b7..ffefe531586fde 100644 --- a/src/coreclr/tools/superpmi/mcs/verbmerge.cpp +++ b/src/coreclr/tools/superpmi/mcs/verbmerge.cpp @@ -69,46 +69,36 @@ WCHAR* verbMerge::ConvertMultiByteToWideChar(LPCSTR str) // 'buffer' is memory that can be used to do reading/buffering. // // static -int verbMerge::AppendFileRaw(HANDLE hFileOut, LPCWSTR fileFullPath, unsigned char* buffer, size_t bufferSize) +int verbMerge::AppendFileRaw(FILE* fpOut, LPCWSTR fileFullPath, unsigned char* buffer, size_t bufferSize) { int result = 0; // default to zero == success char* fileNameAsChar = ConvertWideCharToMultiByte(fileFullPath); LogInfo("Appending file '%s'", fileNameAsChar); - HANDLE hFileIn = CreateFileW(fileFullPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (hFileIn == INVALID_HANDLE_VALUE) + FILE* fpIn = fopen(fileNameAsChar, "rb"); + if (fpIn == NULL) { // If you use a relative path, you can get GetLastError()==3, if the absolute path is longer // than MAX_PATH. - LogError("Failed to open input file '%s'. GetLastError()=%u", fileNameAsChar, GetLastError()); + LogError("Failed to open input file '%s'. errno=%d", fileNameAsChar, errno); return -1; } - LARGE_INTEGER fileSize; - if (GetFileSizeEx(hFileIn, &fileSize) == 0) + int64_t offset = 0; + while (!feof(fpIn)) { - LogError("GetFileSizeEx on '%s' failed. GetLastError()=%u", fileNameAsChar, GetLastError()); - result = -1; - goto CLEAN_UP; - } - - for (LONGLONG offset = 0; offset < fileSize.QuadPart; offset += bufferSize) - { - DWORD bytesRead = -1; - BOOL res = ReadFile(hFileIn, buffer, (DWORD)bufferSize, &bytesRead, nullptr); - if (!res) + size_t bytesRead = fread(buffer, 1, bufferSize, fpIn); + if (bytesRead <= 0) { - LogError("Failed to read '%s' from offset %lld. GetLastError()=%u", fileNameAsChar, offset, GetLastError()); + LogError("Failed to read '%s' from offset %lld. errno=%d", fileNameAsChar, offset, errno); result = -1; goto CLEAN_UP; } - DWORD bytesWritten = -1; - BOOL res2 = WriteFile(hFileOut, buffer, bytesRead, &bytesWritten, nullptr); - if (!res2) + size_t bytesWritten = fwrite(buffer, 1, bytesRead, fpOut); + if (bytesWritten <= 0) { - LogError("Failed to write output file at offset %lld. GetLastError()=%u", offset, GetLastError()); + LogError("Failed to write output file at offset %lld. errno=%d", offset, errno); result = -1; goto CLEAN_UP; } @@ -124,22 +114,22 @@ int verbMerge::AppendFileRaw(HANDLE hFileOut, LPCWSTR fileFullPath, unsigned cha delete[] fileNameAsChar; - if (CloseHandle(hFileIn) == 0) + if (fclose(fpIn) != 0) { - LogError("CloseHandle failed. GetLastError()=%u", GetLastError()); + LogError("CloseHandle failed. errno=%d", errno); result = -1; } return result; } -// AppendFile: append the file named by 'fileFullPath' to the output file referred to by 'hFileOut'. The 'hFileOut' +// AppendFile: append the file named by 'fileFullPath' to the output file referred to by 'fpOut'. The 'fpOut' // handle is assumed to be open, and the file position is assumed to be at the correct spot for writing, to append. // // 'buffer' is memory that can be used to do reading/buffering. // // static -int verbMerge::AppendFile(HANDLE hFileOut, LPCWSTR fileFullPath, bool dedup, unsigned char* buffer, size_t bufferSize) +int verbMerge::AppendFile(FILE* fpOut, LPCWSTR fileFullPath, bool dedup, unsigned char* buffer, size_t bufferSize) { int result = 0; // default to zero == success @@ -148,7 +138,7 @@ int verbMerge::AppendFile(HANDLE hFileOut, LPCWSTR fileFullPath, bool dedup, uns // Need to conver the fileFullPath to non-Unicode. char* fileFullPathAsChar = ConvertWideCharToMultiByte(fileFullPath); LogInfo("Appending file '%s'", fileFullPathAsChar); - bool ok = m_removeDups.CopyAndRemoveDups(fileFullPathAsChar, hFileOut); + bool ok = m_removeDups.CopyAndRemoveDups(fileFullPathAsChar, fpOut); delete[] fileFullPathAsChar; if (!ok) { @@ -158,7 +148,7 @@ int verbMerge::AppendFile(HANDLE hFileOut, LPCWSTR fileFullPath, bool dedup, uns } else { - result = AppendFileRaw(hFileOut, fileFullPath, buffer, bufferSize); + result = AppendFileRaw(fpOut, fileFullPath, buffer, bufferSize); } return result; @@ -454,7 +444,7 @@ int verbMerge::FilterDirectory(LPCWSTR dir, // Append all files in the given directory matching the file pattern. // // static -int verbMerge::AppendAllInDir(HANDLE hFileOut, +int verbMerge::AppendAllInDir(FILE* fpOut, LPCWSTR dir, LPCWSTR file, unsigned char* buffer, @@ -536,7 +526,7 @@ int verbMerge::AppendAllInDir(HANDLE hFileOut, } else { - result = AppendFile(hFileOut, fileFullPath, dedup, buffer, bufferSize); + result = AppendFile(fpOut, fileFullPath, dedup, buffer, bufferSize); if (result != 0) { // Error was already logged. @@ -567,7 +557,7 @@ int verbMerge::AppendAllInDir(HANDLE hFileOut, { const FindData& findData = fileArray[i]; LPWSTR subDir = MergePathStrings(dir, findData.cFileName); - result = AppendAllInDir(hFileOut, subDir, file, buffer, bufferSize, recursive, dedup, &dirSize); + result = AppendAllInDir(fpOut, subDir, file, buffer, bufferSize, recursive, dedup, &dirSize); delete [] subDir; if (result != 0) @@ -623,19 +613,14 @@ int verbMerge::DoWork(const char* nameOfOutputFile, const char* pattern, bool re } } - int nameLength = (int)strlen(nameOfOutputFile) + 1; - LPWSTR nameOfOutputFileAsWchar = new WCHAR[nameLength]; - MultiByteToWideChar(CP_ACP, 0, nameOfOutputFile, -1, nameOfOutputFileAsWchar, nameLength); - int patternLength = (int)strlen(pattern) + 1; LPWSTR patternAsWchar = new WCHAR[patternLength]; MultiByteToWideChar(CP_ACP, 0, pattern, -1, patternAsWchar, patternLength); - HANDLE hFileOut = CreateFileW(nameOfOutputFileAsWchar, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (hFileOut == INVALID_HANDLE_VALUE) + FILE* fpOut = fopen(nameOfOutputFile, "wb"); + if (fpOut == NULL) { - LogError("Failed to open output file '%s'. GetLastError()=%u", nameOfOutputFile, GetLastError()); + LogError("Failed to open output file '%s'. errno=%d", nameOfOutputFile, errno); return -1; } @@ -690,7 +675,7 @@ int verbMerge::DoWork(const char* nameOfOutputFile, const char* pattern, bool re st1.Start(); - result = AppendAllInDir(hFileOut, dir, file, buffer, BUFFER_SIZE, recursive, dedup, &dirSize); + result = AppendAllInDir(fpOut, dir, file, buffer, BUFFER_SIZE, recursive, dedup, &dirSize); if (result != 0) { goto CLEAN_UP; @@ -708,9 +693,9 @@ int verbMerge::DoWork(const char* nameOfOutputFile, const char* pattern, bool re delete[] patternAsWchar; delete[] buffer; - if (CloseHandle(hFileOut) == 0) + if (fclose(fpOut) != 0) { - LogError("CloseHandle failed. GetLastError()=%u", GetLastError()); + LogError("fclose failed. errno=%d", errno); result = -1; } @@ -720,7 +705,7 @@ int verbMerge::DoWork(const char* nameOfOutputFile, const char* pattern, bool re int st = remove(nameOfOutputFile); if (st != 0) { - LogError("Failed to delete file after MCS /merge failed. GetLastError()=%u", GetLastError()); + LogError("Failed to delete file after MCS /merge failed. errno=%d", errno); } } else @@ -734,7 +719,5 @@ int verbMerge::DoWork(const char* nameOfOutputFile, const char* pattern, bool re } } - delete[] nameOfOutputFileAsWchar; - return result; } diff --git a/src/coreclr/tools/superpmi/mcs/verbmerge.h b/src/coreclr/tools/superpmi/mcs/verbmerge.h index ce1eee96b7c522..7106570d44bf62 100644 --- a/src/coreclr/tools/superpmi/mcs/verbmerge.h +++ b/src/coreclr/tools/superpmi/mcs/verbmerge.h @@ -83,9 +83,9 @@ class verbMerge static char* ConvertWideCharToMultiByte(LPCWSTR wstr); static WCHAR* ConvertMultiByteToWideChar(LPCSTR str); - static int AppendFileRaw(HANDLE hFileOut, LPCWSTR fileFullPath, unsigned char* buffer, size_t bufferSize); - static int AppendFile(HANDLE hFileOut, LPCWSTR fileFullPath, bool dedup, unsigned char* buffer, size_t bufferSize); - static int AppendAllInDir(HANDLE hFileOut, + static int AppendFileRaw(FILE* fpOut, LPCWSTR fileFullPath, unsigned char* buffer, size_t bufferSize); + static int AppendFile(FILE* fpOut, LPCWSTR fileFullPath, bool dedup, unsigned char* buffer, size_t bufferSize); + static int AppendAllInDir(FILE* fpOut, LPCWSTR dir, LPCWSTR file, unsigned char* buffer, diff --git a/src/coreclr/tools/superpmi/mcs/verbremovedup.cpp b/src/coreclr/tools/superpmi/mcs/verbremovedup.cpp index a67f7f8debc400..ef4fde2d59d082 100644 --- a/src/coreclr/tools/superpmi/mcs/verbremovedup.cpp +++ b/src/coreclr/tools/superpmi/mcs/verbremovedup.cpp @@ -9,25 +9,24 @@ int verbRemoveDup::DoWork(const char* nameOfInput, const char* nameOfOutput, boo { LogVerbose("Removing duplicates from '%s', writing to '%s'", nameOfInput, nameOfOutput); - HANDLE hFileOut = CreateFileA(nameOfOutput, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (hFileOut == INVALID_HANDLE_VALUE) + FILE* fpOut = fopen(nameOfOutput, "wb"); + if (fpOut == NULL) { - LogError("Failed to open output '%s'. GetLastError()=%u", nameOfOutput, GetLastError()); + LogError("Failed to open output '%s'. errno=%d", nameOfOutput, errno); return -1; } RemoveDup removeDups; if (!removeDups.Initialize(stripCR, legacyCompare, /* cleanup */ false) - || !removeDups.CopyAndRemoveDups(nameOfInput, hFileOut)) + || !removeDups.CopyAndRemoveDups(nameOfInput, fpOut)) { LogError("Failed to remove dups"); return -1; } - if (CloseHandle(hFileOut) == 0) + if (fclose(fpOut) != 0) { - LogError("CloseHandle failed. GetLastError()=%u", GetLastError()); + LogError("CloseHandle failed. errno=%d", errno); return -1; } diff --git a/src/coreclr/tools/superpmi/mcs/verbstat.cpp b/src/coreclr/tools/superpmi/mcs/verbstat.cpp index e3cc44de1a0317..b8c9e28cbdf211 100644 --- a/src/coreclr/tools/superpmi/mcs/verbstat.cpp +++ b/src/coreclr/tools/superpmi/mcs/verbstat.cpp @@ -18,24 +18,20 @@ int verbStat::DoWork(const char* nameOfInput, const char* nameOfOutput, int inde int savedCount = 0; - HANDLE hFileOut = CreateFileA(nameOfOutput, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (hFileOut == INVALID_HANDLE_VALUE) + FILE* fpOut = fopen(nameOfOutput, "w"); + if (fpOut == NULL) { - LogError("Failed to open input 1 '%s'. GetLastError()=%u", nameOfOutput, GetLastError()); + LogError("Failed to open input 1 '%s'. errno=%d", nameOfOutput, errno); return -1; } #define bufflen 50000 - DWORD bytesWritten; char buff[bufflen]; int offset = 0; ZeroMemory(&buff[0], bufflen); offset += sprintf_s(buff, bufflen, "Title,MC#,"); offset += MethodContext::dumpStatTitleToBuffer(&buff[offset], bufflen - offset); - buff[offset++] = 0x0d; - buff[offset++] = 0x0a; - WriteFile(hFileOut, &buff[0], offset, &bytesWritten, nullptr); + fprintf(fpOut, "%s\n", buff); while (mci.MoveNext()) { @@ -52,15 +48,13 @@ int verbStat::DoWork(const char* nameOfInput, const char* nameOfOutput, int inde buff[offset++] = ','; offset += sprintf_s(&buff[offset], bufflen - offset, "%d,", mci.MethodContextNumber()); offset += mc->dumpStatToBuffer(&buff[offset], bufflen - offset); - buff[offset++] = 0x0d; - buff[offset++] = 0x0a; - WriteFile(hFileOut, &buff[0], offset, &bytesWritten, nullptr); + fprintf(fpOut, "%s\n", buff); savedCount++; } - if (!CloseHandle(hFileOut)) + if (fclose(fpOut) != 0) { - LogError("2nd CloseHandle failed. GetLastError()=%u", GetLastError()); + LogError("fclose failed. errno=%d", errno); return -1; } diff --git a/src/coreclr/tools/superpmi/mcs/verbstrip.cpp b/src/coreclr/tools/superpmi/mcs/verbstrip.cpp index a9fe50114c8e44..ad37165c82a339 100644 --- a/src/coreclr/tools/superpmi/mcs/verbstrip.cpp +++ b/src/coreclr/tools/superpmi/mcs/verbstrip.cpp @@ -33,11 +33,10 @@ int verbStrip::DoWork( return -1; } - HANDLE hFileOut = CreateFileA(nameOfOutput, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (hFileOut == INVALID_HANDLE_VALUE) + FILE* fpOut = fopen(nameOfOutput, "wb"); + if (fpOut == NULL) { - LogError("Failed to open input 1 '%s'. GetLastError()=%u", nameOfOutput, GetLastError()); + LogError("Failed to open input 1 '%s'. errno=%d", nameOfOutput, errno); return -1; } @@ -72,13 +71,13 @@ int verbStrip::DoWork( delete mc->cr; mc->cr = new CompileResult(); } - mc->saveToFile(hFileOut); + mc->saveToFile(fpOut); savedCount++; delete mc; } - if (CloseHandle(hFileOut) == 0) + if (fclose(fpOut) != 0) { - LogError("2nd CloseHandle failed. GetLastError()=%u", GetLastError()); + LogError("fclose failed. errno=%d", errno); return -1; } LogInfo("Loaded %d, Saved %d", loadedCount, savedCount); @@ -100,11 +99,10 @@ int verbStrip::DoWorkTheOldWay( bool write; int index = 0; // Can't use MethodContextIterator indexing, since we want the opposite of that. - HANDLE hFileOut = CreateFileA(nameOfOutput, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (hFileOut == INVALID_HANDLE_VALUE) + FILE* fpOut = fopen(nameOfOutput, "wb"); + if (fpOut == NULL) { - LogError("Failed to open input 1 '%s'. GetLastError()=%u", nameOfOutput, GetLastError()); + LogError("Failed to open input 1 '%s'. errno=%d", nameOfOutput, errno); return -1; } @@ -129,14 +127,14 @@ int verbStrip::DoWorkTheOldWay( delete mc->cr; mc->cr = new CompileResult(); } - mc->saveToFile(hFileOut); + mc->saveToFile(fpOut); savedCount++; } } - if (CloseHandle(hFileOut) == 0) + if (fclose(fpOut) != 0) { - LogError("2nd CloseHandle failed. GetLastError()=%u", GetLastError()); + LogError("fclose failed. errno=%d", errno); return -1; } diff --git a/src/coreclr/tools/superpmi/mcs/verbtoc.cpp b/src/coreclr/tools/superpmi/mcs/verbtoc.cpp index d2a384388c12fd..cb45976b0e7e32 100644 --- a/src/coreclr/tools/superpmi/mcs/verbtoc.cpp +++ b/src/coreclr/tools/superpmi/mcs/verbtoc.cpp @@ -14,9 +14,7 @@ class TOCElementNode TOCElementNode* Next; TOCElement tocElement; - TOCElementNode(int number, int64_t offset) : Next(nullptr), tocElement(number, offset) - { - } + TOCElementNode(int number, int64_t offset) : Next(nullptr), tocElement(number, offset) {} }; int verbTOC::DoWork(const char* nameOfInput) @@ -55,48 +53,50 @@ int verbTOC::DoWork(const char* nameOfInput) char* nameOfOutput = (char*)_alloca(maxLen); strcpy_s(nameOfOutput, maxLen, nameOfInput); strcat_s(nameOfOutput, maxLen, ".mct"); - HANDLE hFileOut = - CreateFileA(nameOfOutput, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFileOut == INVALID_HANDLE_VALUE) + FILE* fpOut = fopen(nameOfOutput, "wb"); + if (fpOut == NULL) { - LogError("Failed to open input 1 '%s'. GetLastError()=%u", nameOfOutput, GetLastError()); + LogError("Failed to open input 1 '%s'. errno=%d", nameOfOutput, errno); return -1; } - DWORD written; + size_t written; // Write out the signature "INDX" and then the element count - LARGE_INTEGER token; - token.u.LowPart = *(const int*)"INDX"; // cuz Type Safety is for languages that have good IO facilities - token.u.HighPart = savedCount; - if (!WriteFile(hFileOut, &token, sizeof(token), &written, nullptr) || written != sizeof(token)) + struct + { + uint32_t sig; + uint32_t count; + } token; + token.sig = *(const int*)"INDX"; // cuz Type Safety is for languages that have good IO facilities + token.count = savedCount; + if ((written = fwrite(&token, sizeof(token), 1, fpOut)) <= 0 || written != sizeof(token)) { - LogError("Failed to write index header. GetLastError()=%u", GetLastError()); + LogError("Failed to write index header. errno=%d", errno); } // Now just dump sizeof(TOCElement) byte chunks into the file. // I could probably do this more efficiently, but I don't think it matters - DWORD chunkSize = sizeof(TOCElement); for (curElem = head; curElem != nullptr; curElem = curElem->Next) { - if (!WriteFile(hFileOut, &curElem->tocElement, chunkSize, &written, nullptr) || written != chunkSize) + if ((written = fwrite(&curElem->tocElement, sizeof(TOCElement), 1, fpOut)) <= 0 || written != sizeof(TOCElement)) { - LogError("Failed to write index element '%d'. GetLastError()=%u", curElem->tocElement.Number, - GetLastError()); + LogError("Failed to write index element '%d'. errno=%d", curElem->tocElement.Number, + errno); return -1; } } // Now write out a final "INDX" to flag the end of the file... - if (!WriteFile(hFileOut, &token.u.LowPart, sizeof(token.u.LowPart), &written, nullptr) || - (written != sizeof(token.u.LowPart))) + if ((written = fwrite(&token.sig, sizeof(token.sig), 1, fpOut)) <= 0 || + (written != sizeof(token.sig))) { - LogError("Failed to write index terminal. GetLastError()=%u", GetLastError()); + LogError("Failed to write index terminal. errno=%d", errno); } LogInfo("Loaded %d, added %d to Table of Contents", mci.MethodContextNumber(), savedCount); - if (CloseHandle(hFileOut) == 0) + if (fclose(fpOut) != 0) { - LogError("CloseHandle failed. GetLastError()=%u", GetLastError()); + LogError("fclose failed. errno=%d", errno); return -1; } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.cpp b/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.cpp index 24f355ac895bd9..afe87709591c7a 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.cpp @@ -4,25 +4,16 @@ #include "standardpch.h" #include "asmdumper.h" -void ASMDumper::DumpToFile(HANDLE hFile, MethodContext* mc, CompileResult* cr) +void ASMDumper::DumpToFile(FILE* fp, MethodContext* mc, CompileResult* cr) { CORINFO_METHOD_INFO info; unsigned flags = 0; CORINFO_OS os = CORINFO_WINNT; mc->repCompileMethod(&info, &flags, &os); -#define bufflen 4096 - DWORD bytesWritten; - char buff[bufflen]; + fprintf(fp, ";;Generated from SuperPMI on original input '%s'", cr->repProcessName()); - int buff_offset = 0; - ZeroMemory(buff, bufflen * sizeof(char)); - buff_offset += sprintf_s(&buff[buff_offset], bufflen - buff_offset, - ";;Generated from SuperPMI on original input '%s'", cr->repProcessName()); - - buff_offset += sprintf_s(&buff[buff_offset], bufflen - buff_offset, "\r\n Method Name \"%s\"", - getMethodName(mc, info.ftn).c_str()); - WriteFile(hFile, buff, buff_offset * sizeof(char), &bytesWritten, nullptr); + fprintf(fp, "\n Method Name \"%s\"", getMethodName(mc, info.ftn).c_str()); ULONG hotCodeSize; ULONG coldCodeSize; @@ -56,53 +47,7 @@ void ASMDumper::DumpToFile(HANDLE hFile, MethodContext* mc, CompileResult* cr) cr->applyRelocs(&rc, coldCodeBlock, coldCodeSize, orig_coldCodeBlock); cr->applyRelocs(&rc, roDataBlock, roDataSize, orig_roDataBlock); -#ifdef USE_MSVCDIS - -#ifdef TARGET_AMD64 - DIS* disasm = DIS::PdisNew(DIS::distX8664); -#elif TARGET_X86 - DIS* disasm = DIS::PdisNew(DIS::distX86); -#endif - size_t offset = 0; - while (offset < hotCodeSize) - { - buff_offset = 0; - ZeroMemory(buff, bufflen * sizeof(char)); - - DIS::INSTRUCTION instr; - DIS::OPERAND ops[3]; - - size_t instrSize = disasm->CbDisassemble(0, (void*)(hotCodeBlock + offset), 15); - if (instrSize == 0) - { - LogWarning("Zero sized instruction"); - break; - } - disasm->FDecode(&instr, ops, 3); - - WCHAR instrMnemonic[64]; // I never know how much to allocate... - disasm->CchFormatInstr(instrMnemonic, 64); - std::string instrMnemonicUtf8 = ConvertToUtf8(instrMnemonic); - buff_offset += sprintf_s(&buff[buff_offset], bufflen - buff_offset, "\r\n%p %s", - (void*)((size_t)orig_hotCodeBlock + offset), instrMnemonicUtf8.c_str()); - buff_offset += sprintf_s(&buff[buff_offset], bufflen - buff_offset, " ; "); - for (unsigned int i = 0; i < instrSize; i++) - buff_offset += - sprintf_s(&buff[buff_offset], bufflen - buff_offset, "%02x ", *((BYTE*)(hotCodeBlock + offset + i))); - WriteFile(hFile, buff, buff_offset * sizeof(char), &bytesWritten, nullptr); - offset += instrSize; - } - - delete disasm; - -#else // !USE_MSVCDIS - - buff_offset = 0; - ZeroMemory(buff, bufflen * sizeof(char)); - buff_offset += sprintf_s(&buff[buff_offset], bufflen - buff_offset, ";; No disassembler available"); - WriteFile(hFile, buff, buff_offset * sizeof(char), &bytesWritten, nullptr); - -#endif // !USE_MSVCDIS + fprintf(fp, ";; No disassembler available"); - FlushFileBuffers(hFile); + fflush(fp); } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.h b/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.h index 90af3ef16febfc..be4987b547c773 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/asmdumper.h @@ -11,7 +11,7 @@ class ASMDumper { public: - static void DumpToFile(HANDLE hFile, MethodContext* mc, CompileResult* cr); + static void DumpToFile(FILE* fp, MethodContext* mc, CompileResult* cr); }; #endif diff --git a/src/coreclr/tools/superpmi/superpmi-shared/logging.cpp b/src/coreclr/tools/superpmi/superpmi-shared/logging.cpp index a0de0cda60d122..4236d274771920 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/logging.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/logging.cpp @@ -18,7 +18,7 @@ bool Logger::s_initialized = false; UINT32 Logger::s_logLevel = LOGMASK_DEFAULT; -HANDLE Logger::s_logFile = INVALID_HANDLE_VALUE; +FILE* Logger::s_logFile = NULL; char* Logger::s_logFilePath = nullptr; minipal_mutex Logger::s_critSec; @@ -55,12 +55,11 @@ void Logger::Shutdown() /* static */ void Logger::OpenLogFile(const char* logFilePath) { - if (s_logFile == INVALID_HANDLE_VALUE && logFilePath != nullptr) + if (s_logFile == NULL && logFilePath != nullptr) { - s_logFile = CreateFileA(logFilePath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); + s_logFile = fopen(logFilePath, "w"); - if (s_logFile != INVALID_HANDLE_VALUE) + if (s_logFile != NULL) { // We may need the file path later in order to delete the log file s_logFilePath = _strdup(logFilePath); @@ -79,22 +78,22 @@ void Logger::OpenLogFile(const char* logFilePath) /* static */ void Logger::CloseLogFile() { - if (s_logFile != INVALID_HANDLE_VALUE) + if (s_logFile != NULL) { // Avoid polluting the file system with empty log files - if (GetFileSize(s_logFile, nullptr) == 0 && s_logFilePath != nullptr) + if (ftell(s_logFile) == 0 && s_logFilePath != nullptr) { // We can call this before closing the handle because remove just marks the file // for deletion, i.e. it does not actually get deleted until its last handle is closed. if (remove(s_logFilePath) == -1) - fprintf(stderr, "WARNING: [Logger::CloseLogFile] remove failed. GetLastError()=%u\n", - GetLastError()); + fprintf(stderr, "WARNING: [Logger::CloseLogFile] remove failed. errno=%d\n", + errno); } - if (!CloseHandle(s_logFile)) - fprintf(stderr, "WARNING: [Logger::CloseLogFile] CloseHandle failed. GetLastError()=%u\n", GetLastError()); + if (fclose(s_logFile) != 0) + fprintf(stderr, "WARNING: [Logger::CloseLogFile] CloseHandle failed. errno=%d\n", errno); - s_logFile = INVALID_HANDLE_VALUE; + s_logFile = NULL; free(s_logFilePath); s_logFilePath = nullptr; @@ -251,7 +250,7 @@ void Logger::LogVprintf( fprintf(dest, "%s\n", fullMsg); - if (s_logFile != INVALID_HANDLE_VALUE) + if (s_logFile != NULL) { #ifndef TARGET_UNIX // TODO: no localtime_s() or strftime() in PAL tm timeInfo; @@ -276,25 +275,13 @@ void Logger::LogVprintf( const char* timeStr = ""; #endif // TARGET_UNIX - const char logEntryFmtStr[] = "%s - %s [%s:%d] - %s - %s\r\n"; - size_t logEntryBuffSize = sizeof(logEntryFmtStr) + strlen(timeStr) + strlen(function) + strlen(file) + /* line number */ 10 + - strlen(logLevelStr) + strlen(fullMsg); + if (fprintf(s_logFile, "%s - %s [%s:%d] - %s - %s\r\n", timeStr, function, file, line, logLevelStr, fullMsg) <= 0) + fprintf(stderr, "WARNING: [Logger::LogVprintf] Failed to write to log file. errno=%d\n", + errno); - char* logEntry = new char[logEntryBuffSize]; - sprintf_s(logEntry, logEntryBuffSize, logEntryFmtStr, timeStr, function, file, line, logLevelStr, fullMsg); - size_t logEntryLen = strlen(logEntry); - - DWORD bytesWritten; - - if (!WriteFile(s_logFile, logEntry, (DWORD)logEntryLen, &bytesWritten, nullptr)) - fprintf(stderr, "WARNING: [Logger::LogVprintf] Failed to write to log file. GetLastError()=%u\n", - GetLastError()); - - if (!FlushFileBuffers(s_logFile)) - fprintf(stderr, "WARNING: [Logger::LogVprintf] Failed to flush log file. GetLastError()=%u\n", - GetLastError()); - - delete[] logEntry; + if (fflush(s_logFile) != 0) + fprintf(stderr, "WARNING: [Logger::LogVprintf] Failed to flush log file. errno=%d\n", + errno); #ifndef TARGET_UNIX free((void*)timeStr); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/logging.h b/src/coreclr/tools/superpmi/superpmi-shared/logging.h index 83559df9befdbf..57685260cee097 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/logging.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/logging.h @@ -65,7 +65,7 @@ class Logger private: static bool s_initialized; static UINT32 s_logLevel; - static HANDLE s_logFile; + static FILE* s_logFile; static char* s_logFilePath; static minipal_mutex s_critSec; diff --git a/src/coreclr/tools/superpmi/superpmi-shared/mclist.cpp b/src/coreclr/tools/superpmi/superpmi-shared/mclist.cpp index 79dca0cdc766ae..ac19c719474999 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/mclist.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/mclist.cpp @@ -9,7 +9,7 @@ #include "mclist.h" #include "logging.h" -bool MCList::processArgAsMCL(char* input, int* count, int** list) +bool MCList::processArgAsMCL(char* input, std::vector& list) { // If it contains only '0-9', '-', ',' try to see it as a range list, else try to load as a file bool isRangeList = true; @@ -25,7 +25,6 @@ bool MCList::processArgAsMCL(char* input, int* count, int** list) if (isRangeList) { // Count items - *count = 0; unsigned rangeStart = 0; bool inRange = false; unsigned scratch = 0; @@ -33,52 +32,9 @@ bool MCList::processArgAsMCL(char* input, int* count, int** list) char* tail = input + len; - for (char* head = input; head <= tail; head++) - { - scratch = 0; - foundDigit = false; - while ((head <= tail) && (isdigit((unsigned char)*head))) - { - scratch = (scratch * 10) + ((*head) - '0'); - foundDigit = true; - head++; - } - if (foundDigit) - { - if (inRange) - { - inRange = false; - if (rangeStart >= scratch) - { - LogError("Invalid range in '%s'", input); - return false; - } - (*count) += scratch - rangeStart; - } - else - { - rangeStart = scratch; - (*count)++; - } - } - if (*head == '-') - inRange = true; - } - - if (*count == 0) - { - LogError("Didn't find a list!"); - return false; - } - inRange = false; rangeStart = 0; - int* ll = new int[*count]; - *list = ll; - int index = 0; - ll[index] = 0; - for (char* head = input; head <= tail; head++) { scratch = 0; @@ -95,12 +51,12 @@ bool MCList::processArgAsMCL(char* input, int* count, int** list) { inRange = false; for (unsigned int i = rangeStart + 1; i <= scratch; i++) - ll[index++] = i; + list.push_back(i); } else { - rangeStart = scratch; - ll[index++] = scratch; + rangeStart = scratch; + list.push_back(scratch); } } if (*head == '-') @@ -111,6 +67,13 @@ bool MCList::processArgAsMCL(char* input, int* count, int** list) LogError("Found invalid external range in '%s'", input); return false; } + + if (list.empty()) + { + LogError("Didn't find a list!"); + return false; + } + goto checkMCL; } else @@ -119,26 +82,25 @@ bool MCList::processArgAsMCL(char* input, int* count, int** list) if (lastdot != nullptr && _stricmp(lastdot, ".mcl") == 0) { // Read MCLFile - if (!getLineData(input, count, list)) + if (!getLineData(input, list)) return false; - if (*count >= 0) + if (list.size() >= 0) goto checkMCL; } return false; } checkMCL: // check that mcl list is increasing only - int* ll = (*list); - if (ll[0] == 0) + if (list[0] != 1) { LogError("MCL list needs to start from 1!"); return false; } - for (int i = 1; i < *count; i++) + for (size_t i = 1; i < list.size(); i++) { - if (ll[i - 1] >= ll[i]) + if (list[i - 1] >= list[i]) { - LogError("MCL list must be increasing.. found %d -> %d", ll[i - 1], ll[i]); + LogError("MCL list must be increasing.. found %d -> %d", list[i - 1], list[i]); return false; } } @@ -146,112 +108,60 @@ bool MCList::processArgAsMCL(char* input, int* count, int** list) } // Returns true on success, false on failure. -// On success, sets *pIndexCount to the number of indices read, and *pIndexes to a new array with all the indices read. -// The caller must free the memory with delete[]. /* static */ -bool MCList::getLineData(const char* nameOfInput, /* OUT */ int* pIndexCount, /* OUT */ int** pIndexes) +bool MCList::getLineData(const char* nameOfInput, std::vector& indexes) { - HANDLE hFile = CreateFileA(nameOfInput, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (hFile == INVALID_HANDLE_VALUE) + FILE* fp = fopen(nameOfInput, "r"); + if (fp == NULL) { - LogError("Unable to open '%s'. GetLastError()=%u", nameOfInput, GetLastError()); - return false; - } - LARGE_INTEGER DataTemp; - if (!GetFileSizeEx(hFile, &DataTemp)) - { - LogError("GetFileSizeEx failed. GetLastError()=%u", GetLastError()); + LogError("Unable to open '%s'. errno=%d", nameOfInput, errno); return false; } - if (DataTemp.QuadPart > MAXMCLFILESIZE) + int value; + while (fscanf(fp, "%d", &value) > 0) { - LogError("Size %d exceeds max size of %d", DataTemp.QuadPart, MAXMCLFILESIZE); - return false; + indexes.push_back(value); } - int sz = DataTemp.u.LowPart; - char* buff = new char[sz]; - DWORD bytesRead; - if (ReadFile(hFile, buff, sz, &bytesRead, nullptr) == 0) + if (fclose(fp) != 0) { - LogError("ReadFile failed. GetLastError()=%u", GetLastError()); - delete[] buff; + LogError("fclose failed. errno=%d", errno); return false; } - if (!CloseHandle(hFile)) - { - LogError("CloseHandle failed. GetLastError()=%u", GetLastError()); - delete[] buff; - return false; - } - - // Count the lines. Note that the last line better be terminated by a newline. - int lineCount = 0; - for (int i = 0; i < sz; i++) - { - if (buff[i] == '\n') - { - lineCount++; - } - } - - int* indexes = new int[lineCount]; - int indexCount = 0; - int i = 0; - while (i < sz) - { - // seek the first number on the line. This will skip empty lines and lines with no digits. - while (!isdigit((unsigned char)buff[i])) - i++; - // read in the number - indexes[indexCount++] = atoi(&buff[i]); - // seek to the start of next line - while ((i < sz) && (buff[i] != '\n')) - i++; - i++; - } - delete[] buff; - *pIndexCount = indexCount; - *pIndexes = indexes; return true; } void MCList::InitializeMCL(char* filename) { - hMCLFile = CreateFileA(filename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (hMCLFile == INVALID_HANDLE_VALUE) + fpMCLFile = fopen(filename, "w"); + if (fpMCLFile == NULL) { - LogError("Failed to open output file '%s'. GetLastError()=%u", filename, GetLastError()); + LogError("Failed to open output file '%s'. errno=%d", filename, errno); } } void MCList::AddMethodToMCL(int methodIndex) { - if (hMCLFile != INVALID_HANDLE_VALUE) + if (fpMCLFile != NULL) { - char strMethodIndex[12]; - DWORD charCount = 0; - DWORD bytesWritten = 0; - - charCount = sprintf_s(strMethodIndex, sizeof(strMethodIndex), "%d\r\n", methodIndex); - - if (!WriteFile(hMCLFile, strMethodIndex, charCount, &bytesWritten, nullptr) || bytesWritten != charCount) + if (fprintf(fpMCLFile, "%d\n", methodIndex) != 0) { - LogError("Failed to write method index '%d'. GetLastError()=%u", strMethodIndex, GetLastError()); + LogError("Failed to write method index '%d'. errno=%d", methodIndex, errno); } } } void MCList::CloseMCL() { - if (hMCLFile != INVALID_HANDLE_VALUE) + if (fpMCLFile != NULL) { - if (CloseHandle(hMCLFile) == 0) + if (fclose(fpMCLFile) == 0) { - LogError("CloseHandle failed. GetLastError()=%u", GetLastError()); + LogError("fclose failed. errno=%d", errno); } } + + fpMCLFile = NULL; } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/mclist.h b/src/coreclr/tools/superpmi/superpmi-shared/mclist.h index 44291f0600a0e0..9810846e78754a 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/mclist.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/mclist.h @@ -11,12 +11,12 @@ class MCList { public: - static bool processArgAsMCL(char* input, int* count, int** list); + static bool processArgAsMCL(char* input, std::vector& list); MCList() { // Initialize the static file handle - hMCLFile = INVALID_HANDLE_VALUE; + fpMCLFile = NULL; } // Methods to create an MCL file @@ -25,9 +25,9 @@ class MCList void CloseMCL(); private: - static bool getLineData(const char* nameOfInput, /* OUT */ int* pIndexCount, /* OUT */ int** pIndexes); + static bool getLineData(const char* nameOfInput, std::vector& indexes); // File handle for MCL file - HANDLE hMCLFile; + FILE* fpMCLFile; }; #endif diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index 5202cd73661c44..ecc3ef0f412390 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -138,7 +138,7 @@ unsigned int MethodContext::calculateRawFileSize() 2 /* end canary '4', '2' */; } -unsigned int MethodContext::saveToFile(HANDLE hFile) +unsigned int MethodContext::saveToFile(FILE* fp) { unsigned int totalLen = calculateFileSize(); unsigned int totalFileSize = @@ -165,7 +165,7 @@ unsigned int MethodContext::saveToFile(HANDLE hFile) Assert(buffIndex == totalFileSize); - WriteFile(hFile, buff2, totalFileSize, &bytesWritten, NULL); + bytesWritten = (DWORD)fwrite(buff2, 1, totalFileSize, fp); delete[] buff2; return bytesWritten; } @@ -183,12 +183,12 @@ bool MethodContext::Initialize(int mcIndex, unsigned char* buff, DWORD size, /* } // static -bool MethodContext::Initialize(int mcIndex, HANDLE hFile, /* OUT */ MethodContext** ppmc) +bool MethodContext::Initialize(int mcIndex, FILE* fp, /* OUT */ MethodContext** ppmc) { MethodContext* mc = new MethodContext(); mc->index = mcIndex; *ppmc = mc; - return mc->Initialize(mcIndex, hFile); + return mc->Initialize(mcIndex, fp); } bool MethodContext::Initialize(int mcIndex, unsigned char* buff, DWORD size) @@ -219,21 +219,21 @@ bool MethodContext::Initialize(int mcIndex, unsigned char* buff, DWORD size) return result; } -bool MethodContext::Initialize(int mcIndex, HANDLE hFile) +bool MethodContext::Initialize(int mcIndex, FILE* fp) { bool result = true; struct Param { - HANDLE hFile; + FILE* fp; MethodContext* pThis; } param; - param.hFile = hFile; + param.fp = fp; param.pThis = this; PAL_TRY(Param*, pParam, ¶m) { - pParam->pThis->MethodInitHelperFile(pParam->hFile); + pParam->pThis->MethodInitHelperFile(pParam->fp); } PAL_EXCEPT_FILTER(FilterSuperPMIExceptions_CatchMC) { @@ -245,18 +245,17 @@ bool MethodContext::Initialize(int mcIndex, HANDLE hFile) return result; } -void MethodContext::MethodInitHelperFile(HANDLE hFile) +void MethodContext::MethodInitHelperFile(FILE* fp) { - DWORD bytesRead; char buff[512]; unsigned int totalLen = 0; - AssertCode(ReadFile(hFile, buff, 2 + sizeof(unsigned int), &bytesRead, NULL) == TRUE, + AssertCode(fread(buff, 1, 2 + sizeof(unsigned int), fp) == 2 + sizeof(unsigned int), EXCEPTIONCODE_MC); // Read Magic number and totalLen AssertCodeMsg((buff[0] == 'm') && (buff[1] == 'c'), EXCEPTIONCODE_MC, "Didn't find magic number"); memcpy(&totalLen, &buff[2], sizeof(unsigned int)); unsigned char* buff2 = new unsigned char[totalLen + 2]; // total + End Canary - AssertCode(ReadFile(hFile, buff2, totalLen + 2, &bytesRead, NULL) == TRUE, EXCEPTIONCODE_MC); + AssertCode(fread(buff2, 1, totalLen + 2, fp) == totalLen + 2, EXCEPTIONCODE_MC); AssertCodeMsg((buff2[totalLen] == '4') && (buff2[totalLen + 1] == '2'), EXCEPTIONCODE_MC, "Didn't find end canary"); MethodInitHelper(buff2, totalLen); } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index bf853790fb9d8d..d2ee22207a217e 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -68,16 +68,16 @@ class MethodContext private: void MethodInitHelper(unsigned char* buff, unsigned int totalLen); - void MethodInitHelperFile(HANDLE hFile); + void MethodInitHelperFile(FILE* fp); bool Initialize(int mcIndex, unsigned char* buff, DWORD size); - bool Initialize(int mcIndex, HANDLE hFile); + bool Initialize(int mcIndex, FILE* fp); int dumpHashToBuffer(BYTE* pBuffer, int bufLen, char* buff, int len); public: static bool Initialize(int mcIndex, unsigned char* buff, DWORD size, /* OUT */ MethodContext** ppmc); - static bool Initialize(int mcIndex, HANDLE hFile, /* OUT */ MethodContext** ppmc); + static bool Initialize(int mcIndex, FILE* fp, /* OUT */ MethodContext** ppmc); ~MethodContext(); void Destroy(); @@ -87,7 +87,7 @@ class MethodContext } bool Equal(MethodContext* other); - unsigned int saveToFile(HANDLE hFile); + unsigned int saveToFile(FILE* fp); unsigned int calculateFileSize(); unsigned int calculateRawFileSize(); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontextiterator.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontextiterator.cpp index 0f9271b142e8ee..e8c460ce316858 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontextiterator.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontextiterator.cpp @@ -7,24 +7,20 @@ bool MethodContextIterator::Initialize(const char* fileName) { - m_hFile = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (m_hFile == INVALID_HANDLE_VALUE) + m_fp = fopen(fileName, "rb"); + if (m_fp == NULL) { LogError("Failed to open file '%s'. GetLastError()=%u", fileName, GetLastError()); return false; } - LARGE_INTEGER DataTemp; - if (GetFileSizeEx(m_hFile, &DataTemp) == 0) - { - LogError("GetFileSizeEx failed. GetLastError()=%u", GetLastError()); - CloseHandle(m_hFile); - m_hFile = INVALID_HANDLE_VALUE; - return false; - } - - m_fileSize = DataTemp.QuadPart; + fseek(m_fp, 0, SEEK_END); +#ifdef TARGET_WINDOWS + m_fileSize = _ftelli64(m_fp); +#else + m_fileSize = ftell(m_fp); +#endif + fseek(m_fp, 0, SEEK_SET); if (m_progressReport) { @@ -37,14 +33,14 @@ bool MethodContextIterator::Initialize(const char* fileName) bool MethodContextIterator::Destroy() { bool ret = true; // assume success - if (m_hFile != INVALID_HANDLE_VALUE) + if (m_fp != NULL) { - if (!CloseHandle(m_hFile)) + if (fclose(m_fp) != 0) { - LogError("CloseHandle failed. GetLastError()=%u", GetLastError()); + LogError("fclose failed. errno=%d", errno); ret = false; } - m_hFile = INVALID_HANDLE_VALUE; + m_fp = NULL; } delete m_mc; m_mc = nullptr; @@ -72,19 +68,11 @@ bool MethodContextIterator::MoveNext() while (true) { // Figure out where the pointer is currently. - LARGE_INTEGER pos; - pos.QuadPart = 0; - if (SetFilePointerEx(m_hFile, pos, &m_pos, FILE_CURRENT) == 0) - { - LogError("SetFilePointerEx failed. GetLastError()=%u", GetLastError()); - return false; // any failure causes us to bail out. - } - - if (m_pos.QuadPart >= m_fileSize) - { - return false; - } - +#ifdef TARGET_WINDOWS + m_pos = _ftelli64(m_fp); +#else + m_pos = ftell(m_fp); +#endif // Load the current method context. m_methodContextNumber++; @@ -99,7 +87,7 @@ bool MethodContextIterator::MoveNext() } } - if (!MethodContext::Initialize(m_methodContextNumber, m_hFile, &m_mc)) + if (!MethodContext::Initialize(m_methodContextNumber, m_fp, &m_mc)) return false; // If we have an array of indexes, skip the loaded indexes that have not been specified. diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontextiterator.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontextiterator.h index f45e85ea6e3954..ebda6c450efe2c 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontextiterator.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontextiterator.h @@ -9,10 +9,11 @@ class MethodContextIterator { public: MethodContextIterator(bool progressReport = false) - : m_hFile(INVALID_HANDLE_VALUE) + : m_fp(nullptr) , m_fileSize(0) , m_methodContextNumber(0) , m_mc(nullptr) + , m_pos(0) , m_indexCount(-1) , m_index(0) , m_indexes(nullptr) @@ -27,10 +28,11 @@ class MethodContextIterator } MethodContextIterator(const int indexCount, const int* indexes, bool progressReport = false) - : m_hFile(INVALID_HANDLE_VALUE) + : m_fp(nullptr) , m_fileSize(0) , m_methodContextNumber(0) , m_mc(nullptr) + , m_pos(0) , m_indexCount(indexCount) , m_index(0) , m_indexes(indexes) @@ -73,7 +75,7 @@ class MethodContextIterator // Return the file position offset of the current method context. int64_t CurrentPos() { - return m_pos.QuadPart; + return m_pos; } int MethodContextNumber() @@ -82,11 +84,11 @@ class MethodContextIterator } private: - HANDLE m_hFile; + FILE* m_fp; int64_t m_fileSize; int m_methodContextNumber; MethodContext* m_mc; - LARGE_INTEGER m_pos; + int64_t m_pos; // If m_indexCount==-1, use all method contexts. Otherwise, m_indexCount is the number of elements in the // m_indexes array, which contains a sorted set of method context indexes to return. In this case, m_index diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp b/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp index 3165ac8ab73436..00550f54a92289 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp @@ -18,15 +18,14 @@ #endif // TARGET_UNIX // Just a helper... -HANDLE MethodContextReader::OpenFile(const char* inputFile, DWORD flags) +FILE* MethodContextReader::OpenFile(const char* inputFile) { - HANDLE fileHandle = - CreateFileA(inputFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | flags, NULL); - if (fileHandle == INVALID_HANDLE_VALUE) + FILE* fp = fopen(inputFile, "rb"); + if (fp == NULL) { - LogError("Failed to open file '%s'. GetLastError()=%u", inputFile, GetLastError()); + LogError("Failed to open file '%s'. errno=%d", inputFile, errno); } - return fileHandle; + return fp; } static std::string to_lower(const std::string& input) @@ -83,7 +82,7 @@ std::string MethodContextReader::CheckForPairedFile(const std::string& fileName, MethodContextReader::MethodContextReader( const char* inputFileName, const int* indexes, int indexCount, char* hash, int offset, int increment) - : fileHandle(INVALID_HANDLE_VALUE) + : fp(NULL) , fileSize(0) , curMCIndex(0) , Indexes(indexes) @@ -123,11 +122,16 @@ MethodContextReader::MethodContextReader( this->tocFile.LoadToc(tocFileName.c_str()); // we'll get here even if we don't have a valid index file - this->fileHandle = OpenFile(mchFileName.c_str(), (this->hasTOC() && this->hasIndex()) ? FILE_ATTRIBUTE_NORMAL - : FILE_FLAG_SEQUENTIAL_SCAN); - if (this->fileHandle != INVALID_HANDLE_VALUE) + this->fp = fopen(mchFileName.c_str(), "rb"); + if (this->fp != NULL) { - GetFileSizeEx(this->fileHandle, (PLARGE_INTEGER) & this->fileSize); + fseek(this->fp, 0, SEEK_END); +#ifdef TARGET_WINDOWS + this->fileSize = _ftelli64(this->fp); +#else + this->fileSize = ftell(this->fp); +#endif + fseek(this->fp, 0, SEEK_SET); } ReadExcludedMethods(mchFileName); @@ -135,9 +139,9 @@ MethodContextReader::MethodContextReader( MethodContextReader::~MethodContextReader() { - if (fileHandle != INVALID_HANDLE_VALUE) + if (fp != NULL) { - CloseHandle(this->fileHandle); + fclose(fp); } minipal_mutex_destroy(&this->mutex); @@ -155,32 +159,25 @@ void MethodContextReader::ReleaseLock() minipal_mutex_leave(&this->mutex); } -bool MethodContextReader::atEof() -{ - int64_t pos = 0; - SetFilePointerEx(this->fileHandle, *(PLARGE_INTEGER)&pos, (PLARGE_INTEGER)&pos, - FILE_CURRENT); // LARGE_INTEGER is a crime against humanity - return pos == this->fileSize; -} - MethodContextBuffer MethodContextReader::ReadMethodContextNoLock(bool justSkip) { - DWORD bytesRead; char buff[512]; unsigned int totalLen = 0; - if (atEof()) + + size_t bytesRead = fread(buff, 1, 2 + sizeof(unsigned int), this->fp); + if (bytesRead == 0) { return MethodContextBuffer(); } - Assert(ReadFile(this->fileHandle, buff, 2 + sizeof(unsigned int), &bytesRead, NULL) == TRUE); + Assert(bytesRead == 2 + sizeof(unsigned int)); AssertMsg((buff[0] == 'm') && (buff[1] == 'c'), "Didn't find magic number"); memcpy(&totalLen, &buff[2], sizeof(unsigned int)); if (justSkip) { int64_t pos = totalLen + 2; // Just move the file pointer ahead the correct number of bytes - AssertMsg(SetFilePointerEx(this->fileHandle, *(PLARGE_INTEGER)&pos, (PLARGE_INTEGER)&pos, FILE_CURRENT) == TRUE, - "SetFilePointerEx failed (Error %X)", GetLastError()); + AssertMsg(fseek(this->fp, totalLen + 2, SEEK_CUR) == 0, + "fseek failed (Error %d)", errno); // Increment curMCIndex as we advanced the file pointer by another MC ++curMCIndex; @@ -190,7 +187,7 @@ MethodContextBuffer MethodContextReader::ReadMethodContextNoLock(bool justSkip) else { unsigned char* buff2 = new unsigned char[totalLen + 2]; // total + End Canary - Assert(ReadFile(this->fileHandle, buff2, totalLen + 2, &bytesRead, NULL) == TRUE); + Assert(fread(buff2, 1, totalLen + 2, this->fp) == totalLen + 2); // Increment curMCIndex as we read another MC ++curMCIndex; @@ -417,7 +414,7 @@ bool MethodContextReader::hasTOC() bool MethodContextReader::isValid() { - return this->fileHandle != INVALID_HANDLE_VALUE; + return this->fp != NULL; } // Return a measure of "progress" through the method contexts, as follows: @@ -438,8 +435,11 @@ double MethodContextReader::Progress() else { this->AcquireLock(); - int64_t pos = 0; - SetFilePointerEx(this->fileHandle, *(PLARGE_INTEGER)&pos, (PLARGE_INTEGER)&pos, FILE_CURRENT); +#ifdef TARGET_WINDOWS + int64_t pos = _ftelli64(this->fp); +#else + int64_t pos = ftell(this->fp); +#endif this->ReleaseLock(); return (double)pos; } @@ -512,7 +512,7 @@ MethodContextBuffer MethodContextReader::GetSpecificMethodContext(unsigned int m { return MethodContextBuffer(-2); } - if (SetFilePointerEx(this->fileHandle, *(PLARGE_INTEGER)&pos, (PLARGE_INTEGER)&pos, FILE_BEGIN)) + if (fseek(this->fp, (long)pos, SEEK_SET) == 0) { // ReadMethodContext will release the lock, but we already acquired it MethodContextBuffer mcb = this->ReadMethodContext(false); @@ -534,7 +534,7 @@ MethodContextBuffer MethodContextReader::GetSpecificMethodContext(unsigned int m // Read the file with excluded methods hashes and save them. void MethodContextReader::ReadExcludedMethods(std::string mchFileName) { - excludedMethodsList = nullptr; + excludedMethodsList.clear(); size_t suffix_offset = mchFileName.find_last_of('.'); if (suffix_offset == std::string::npos) @@ -549,83 +549,46 @@ void MethodContextReader::ReadExcludedMethods(std::string mchFileName) { return; } - HANDLE excludeFileHandle = OpenFile(excludeFileName.c_str()); - if (excludeFileHandle != INVALID_HANDLE_VALUE) + FILE* fpExclude = OpenFile(excludeFileName.c_str()); + if (fpExclude != NULL) { - int64_t excludeFileSizeLong; - GetFileSizeEx(excludeFileHandle, (PLARGE_INTEGER)&excludeFileSizeLong); - unsigned excludeFileSize = (unsigned)excludeFileSizeLong; - - char* buffer = new char[excludeFileSize + 1]; - DWORD bytesRead; - bool success = (ReadFile(excludeFileHandle, buffer, excludeFileSize, &bytesRead, NULL) == TRUE); - CloseHandle(excludeFileHandle); - - if (!success || excludeFileSize != bytesRead) - { - LogError("Failed to read the exclude file."); - delete[] buffer; - return; - } + char buffer[512]; + memset(buffer, 0, sizeof(buffer)); - buffer[excludeFileSize] = 0; - - int counter = 0; - - char* curr = buffer; - while (*curr != 0) + while (fscanf(fpExclude, "%511s", buffer) > 0) { - while (isspace(*curr)) - { - curr++; - } - - std::string hash; - while (*curr != 0 && !isspace(*curr)) - { - hash += *curr; - curr++; - } + std::string hash(buffer); if (hash.length() == MM3_HASH_BUFFER_SIZE - 1) { - StringList* node = new StringList(); - node->hash = hash; - node->next = excludedMethodsList; - excludedMethodsList = node; - counter++; + excludedMethodsList.push_back(std::move(hash)); } else { LogInfo("The exclude file contains wrong values: %s.", hash.c_str()); } } - delete[] buffer; - LogInfo("Exclude file %s contains %d methods.", excludeFileName.c_str(), counter); + + LogInfo("Exclude file %s contains %d methods.", excludeFileName.c_str(), (int)excludedMethodsList.size()); } } // Free memory used for excluded methods. void MethodContextReader::CleanExcludedMethods() { - while (excludedMethodsList != nullptr) - { - StringList* next = excludedMethodsList->next; - delete excludedMethodsList; - excludedMethodsList = next; - } + excludedMethodsList.clear(); } // Return should this method context be excluded from the replay or not. bool MethodContextReader::IsMethodExcluded(MethodContext* mc) { - if (excludedMethodsList != nullptr) + if (!excludedMethodsList.empty()) { char md5HashBuf[MM3_HASH_BUFFER_SIZE] = {0}; mc->dumpMethodHashToBuffer(md5HashBuf, MM3_HASH_BUFFER_SIZE); - for (StringList* node = excludedMethodsList; node != nullptr; node = node->next) + for (const std::string& hash : excludedMethodsList) { - if (strcmp(node->hash.c_str(), md5HashBuf) == 0) + if (strcmp(hash.c_str(), md5HashBuf) == 0) { return true; } @@ -636,9 +599,7 @@ bool MethodContextReader::IsMethodExcluded(MethodContext* mc) void MethodContextReader::Reset(const int* newIndexes, int newIndexCount) { - int64_t pos = 0; - BOOL result = SetFilePointerEx(fileHandle, *(PLARGE_INTEGER)&pos, NULL, FILE_BEGIN); - assert(result); + fseek(fp, 0, SEEK_SET); Indexes = newIndexes; IndexCount = newIndexCount; diff --git a/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.h b/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.h index f5ef48009b8370..0996ab56a6c3c7 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.h @@ -48,7 +48,7 @@ class MethodContextReader { private: // The MC/MCH file - HANDLE fileHandle; + FILE* fp; // The size of the MC/MCH file int64_t fileSize; @@ -82,19 +82,14 @@ class MethodContextReader int Offset; int Increment; - struct StringList - { - StringList* next; - std::string hash; - }; - StringList* excludedMethodsList; + std::vector excludedMethodsList; // Binary search to get this method number from the index // Returns -1 for not found, or -2 for not indexed int64_t GetOffset(unsigned int methodNumber); // Just a helper... - static HANDLE OpenFile(const char* inputFile, DWORD flags = FILE_ATTRIBUTE_NORMAL); + static FILE* OpenFile(const char* inputFile); MethodContextBuffer ReadMethodContextNoLock(bool justSkip = false); MethodContextBuffer ReadMethodContext(bool acquireLock, bool justSkip = false); @@ -111,9 +106,6 @@ class MethodContextReader const std::string& origSuffix, const std::string& newSuffix); - // are we're at the end of the file... - bool atEof(); - // Do we have a valid TOC? bool hasTOC(); diff --git a/src/coreclr/tools/superpmi/superpmi-shared/tocfile.cpp b/src/coreclr/tools/superpmi/superpmi-shared/tocfile.cpp index 4898c6d8b9a161..e7e6df7bd12cc9 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/tocfile.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/tocfile.cpp @@ -12,48 +12,51 @@ // Tries to load a Table of Contents void TOCFile::LoadToc(const char* inputFileName, bool validate) { - HANDLE hIndex = CreateFileA(inputFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (hIndex == INVALID_HANDLE_VALUE) + FILE* fpIndex = fopen(inputFileName, "rb"); + if (fpIndex == NULL) { - LogError("Failed to open file '%s'. GetLastError()=%u", inputFileName, GetLastError()); + LogError("Failed to open file '%s'. errno=%d", inputFileName, errno); return; } // Now read the index file - LARGE_INTEGER val; // I'm abusing LARGE_INTEGER here... - DWORD read; - if (!ReadFile(hIndex, &val, sizeof(val), &read, nullptr) || (val.u.LowPart != *(DWORD*)("INDX"))) + struct { - CloseHandle(hIndex); + uint32_t sig; + uint32_t count; + } header; + if (fread(&header, sizeof(header), 1, fpIndex) != 0 || (header.sig != *(uint32_t*)("INDX"))) + { + fclose(fpIndex); LogWarning("The index file %s is invalid: it seems to be missing the starting sentinel/length", inputFileName); return; } - this->m_tocCount = val.u.HighPart; + this->m_tocCount = header.count; this->m_tocArray = new TOCElement[this->m_tocCount]; // Read the whole array - if (!ReadFile(hIndex, &this->m_tocArray[0], (DWORD)(this->m_tocCount * sizeof(TOCElement)), &read, nullptr) || - (read != (DWORD)(this->m_tocCount * sizeof(TOCElement)))) + size_t read = fread(&this->m_tocArray[0], sizeof(TOCElement), this->m_tocCount, fpIndex); + if (read != this->m_tocCount * sizeof(TOCElement)) { - CloseHandle(hIndex); + fclose(fpIndex); this->Clear(); LogWarning("The index file %s is invalid: it appears to be truncated.", inputFileName); return; } - // Get the last 4 byte token (more abuse of LARGE_INTEGER) - if (!ReadFile(hIndex, &val.u.HighPart, sizeof(DWORD), &read, nullptr) || (read != sizeof(DWORD)) || - (val.u.LowPart != (DWORD)val.u.HighPart)) + // Get the last 4 byte token + uint32_t sentinal; + read = fread(&sentinal, sizeof(sentinal), 1, fpIndex); + if ((read != sizeof(sentinal)) || (sentinal != header.sig)) { - CloseHandle(hIndex); + fclose(fpIndex); this->Clear(); LogWarning("The index file %s is invalid: it appears to be missing the ending sentinel.", inputFileName); return; } - CloseHandle(hIndex); + fclose(fpIndex); if (validate) { diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitcompiler.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitcompiler.cpp index d7f15ea6cd1fc3..412eaf08ad39a1 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitcompiler.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitcompiler.cpp @@ -26,7 +26,7 @@ void interceptor_ICJC::finalizeAndCommitCollection(MethodContext* mc, CorJitResu mc->cr->recAllocGCInfoCapture(); } - mc->saveToFile(hFile); + mc->saveToFile(fp); } template diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitcompiler.h b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitcompiler.h index 56e82ca744237c..8c00074cd3faaf 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitcompiler.h +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitcompiler.h @@ -16,7 +16,7 @@ class interceptor_ICJC : public ICorJitCompiler public: // Added to help us track the original icjc and be able to easily indirect to it. ICorJitCompiler* original_ICorJitCompiler; - HANDLE hFile; + FILE* fp; CORINFO_OS currentOs; void finalizeAndCommitCollection(MethodContext* mc, CorJitResult result, uint8_t* nativeEntry, uint32_t nativeSizeOfCode); diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/superpmi-shim-collector.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/superpmi-shim-collector.cpp index f3ff4af0e6f9db..d185eed6d6de58 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/superpmi-shim-collector.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/superpmi-shim-collector.cpp @@ -215,11 +215,10 @@ extern "C" DLLEXPORT ICorJitCompiler* getJit() #endif // create our datafile - pJitInstance->hFile = CreateFileA(g_dataFileName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, - CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (pJitInstance->hFile == INVALID_HANDLE_VALUE) + pJitInstance->fp = fopen(g_dataFileName.c_str(), "wb+"); + if (pJitInstance->fp == NULL) { - LogError("Couldn't open file '%s': error %d", g_dataFileName.c_str(), GetLastError()); + LogError("Couldn't open file '%s': error %d", g_dataFileName.c_str(), errno); } return pJitInstance; diff --git a/src/coreclr/tools/superpmi/superpmi/commandline.cpp b/src/coreclr/tools/superpmi/superpmi/commandline.cpp index 6fd0acfcae6922..4dd70fd155077e 100644 --- a/src/coreclr/tools/superpmi/superpmi/commandline.cpp +++ b/src/coreclr/tools/superpmi/superpmi/commandline.cpp @@ -419,7 +419,8 @@ bool CommandLine::Parse(int argc, char* argv[], /* OUT */ Options* o) return false; } - bool isValidList = MCList::processArgAsMCL(argv[i], &o->indexCount, &o->indexes); + bool isValidList = MCList::processArgAsMCL(argv[i], o->indexes); + o->indexCount = (int)o->indexes.size(); if (!isValidList) { LogError("Arg '%s' is invalid, needed method context list.", argv[i]); diff --git a/src/coreclr/tools/superpmi/superpmi/commandline.h b/src/coreclr/tools/superpmi/superpmi/commandline.h index 02a9ef4ee38466..749fdcb64d1f33 100644 --- a/src/coreclr/tools/superpmi/superpmi/commandline.h +++ b/src/coreclr/tools/superpmi/superpmi/commandline.h @@ -36,7 +36,7 @@ class CommandLine int indexCount = -1; // If indexCount is -1 and hash points to nullptr it means compile all. int failureLimit = -1; // Number of failures after which bail out the replay/asmdiffs. int repeatCount = 1; // Number of times given methods should be compiled. - int* indexes = nullptr; + std::vector indexes; char* hash = nullptr; char* methodStatsTypes = nullptr; char* details = nullptr; diff --git a/src/coreclr/tools/superpmi/superpmi/fileio.cpp b/src/coreclr/tools/superpmi/superpmi/fileio.cpp index eaa53fb0c9189e..f538bb479f9ad4 100644 --- a/src/coreclr/tools/superpmi/superpmi/fileio.cpp +++ b/src/coreclr/tools/superpmi/superpmi/fileio.cpp @@ -124,17 +124,15 @@ bool FileWriter::Flush() if (m_bufferIndex <= 0) return true; - DWORD numWritten; - bool result = - WriteFile(m_file.Get(), m_buffer.data(), static_cast(m_bufferIndex), &numWritten, nullptr) && - (numWritten == static_cast(m_bufferIndex)); + size_t numWritten = fwrite(m_buffer.data(), 1, m_bufferIndex, m_file.Get()); + bool result = (numWritten == m_bufferIndex); m_bufferIndex = 0; return result; } bool FileWriter::CreateNew(const char* path, FileWriter* fw) { - FileHandle handle(CreateFile(path, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr)); + FILEHandle handle(fopen(path, "wb")); if (!handle.IsValid()) { return false; @@ -143,64 +141,3 @@ bool FileWriter::CreateNew(const char* path, FileWriter* fw) *fw = FileWriter(std::move(handle)); return true; } - -bool FileLineReader::Open(const char* path, FileLineReader* fr) -{ - FileHandle file(CreateFile(path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr)); - if (!file.IsValid()) - { - return false; - } - - LARGE_INTEGER size; - if (!GetFileSizeEx(file.Get(), &size)) - { - return false; - } - - if (static_cast(size.QuadPart) > SIZE_MAX) - { - return false; - } - - FileMappingHandle mapping(CreateFileMapping(file.Get(), nullptr, PAGE_READONLY, size.u.HighPart, size.u.LowPart, nullptr)); - if (!mapping.IsValid()) - { - return false; - } - - FileViewHandle view(MapViewOfFile(mapping.Get(), FILE_MAP_READ, 0, 0, 0)); - if (!view.IsValid()) - { - return false; - } - - *fr = FileLineReader(std::move(file), std::move(mapping), std::move(view), static_cast(size.QuadPart)); - return true; -} - -bool FileLineReader::AdvanceLine() -{ - if (m_cur >= m_end) - { - return false; - } - - char* end = m_cur; - while (end < m_end && *end != '\r' && *end != '\n') - { - end++; - } - - m_currentLine.resize(end - m_cur + 1); - memcpy(m_currentLine.data(), m_cur, end - m_cur); - m_currentLine[end - m_cur] = '\0'; - - m_cur = end; - if (m_cur < m_end && *m_cur == '\r') - m_cur++; - if (m_cur < m_end && *m_cur == '\n') - m_cur++; - - return true; -} diff --git a/src/coreclr/tools/superpmi/superpmi/fileio.h b/src/coreclr/tools/superpmi/superpmi/fileio.h index 8c721c2545008e..b519ad0cea3587 100644 --- a/src/coreclr/tools/superpmi/superpmi/fileio.h +++ b/src/coreclr/tools/superpmi/superpmi/fileio.h @@ -4,6 +4,8 @@ #ifndef _FileIO #define _FileIO +#include + template struct HandleWrapper { @@ -54,38 +56,22 @@ struct HandleWrapper HandleType m_handle; }; -struct FileHandleSpec -{ - using Type = HANDLE; - static HANDLE Invalid() { return INVALID_HANDLE_VALUE; } - static void Close(HANDLE h) { CloseHandle(h); } -}; - -struct FileMappingHandleSpec +struct FILEPtrSpec { - using Type = HANDLE; - static HANDLE Invalid() { return nullptr; } - static void Close(HANDLE h) { CloseHandle(h); } + using Type = FILE*; + static FILE* Invalid() { return NULL; } + static void Close(FILE* fp) { fclose(fp); } }; -struct FileViewHandleSpec -{ - using Type = LPVOID; - static LPVOID Invalid() { return nullptr; } - static void Close(LPVOID p) { UnmapViewOfFile(p); } -}; - -typedef HandleWrapper FileHandle; -typedef HandleWrapper FileMappingHandle; -typedef HandleWrapper FileViewHandle; +typedef HandleWrapper FILEHandle; class FileWriter { - FileHandle m_file; + FILEHandle m_file; std::vector m_buffer; size_t m_bufferIndex = 0; - explicit FileWriter(FileHandle file) + explicit FileWriter(FILEHandle file) : m_file(std::move(file)) , m_buffer(8192) { @@ -130,36 +116,4 @@ class FileWriter static bool CreateNew(const char* path, FileWriter* fw); }; -class FileLineReader -{ - FileHandle m_file; - FileMappingHandle m_fileMapping; - FileViewHandle m_view; - - char* m_cur; - char* m_end; - std::vector m_currentLine; - - FileLineReader(FileHandle file, FileMappingHandle fileMapping, FileViewHandle view, size_t size) - : m_file(std::move(file)) - , m_fileMapping(std::move(fileMapping)) - , m_view(std::move(view)) - , m_cur(static_cast(m_view.Get())) - , m_end(static_cast(m_view.Get()) + size) - { - } - -public: - FileLineReader() - : m_cur(nullptr) - , m_end(nullptr) - { - } - - bool AdvanceLine(); - const char* GetCurrentLine() { return m_currentLine.data(); } - - static bool Open(const char* path, FileLineReader* fr); -}; - #endif diff --git a/src/coreclr/tools/superpmi/superpmi/methodstatsemitter.cpp b/src/coreclr/tools/superpmi/superpmi/methodstatsemitter.cpp index 36cee7c6ccdb2d..ed405965e48c94 100644 --- a/src/coreclr/tools/superpmi/superpmi/methodstatsemitter.cpp +++ b/src/coreclr/tools/superpmi/superpmi/methodstatsemitter.cpp @@ -14,34 +14,28 @@ MethodStatsEmitter::MethodStatsEmitter(char* nameOfInput) char filename[MAX_PATH + 1]; sprintf_s(filename, MAX_PATH + 1, "%s.stats", nameOfInput); - hStatsFile = - CreateFileA(filename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (hStatsFile == INVALID_HANDLE_VALUE) + fpStatsFile = fopen(filename, "w"); + if (fpStatsFile == NULL) { - LogError("Failed to open output file '%s'. GetLastError()=%u", filename, GetLastError()); + LogError("Failed to open output file '%s'. errno=%d", filename, errno); } } MethodStatsEmitter::~MethodStatsEmitter() { - if (hStatsFile != INVALID_HANDLE_VALUE) + if (fpStatsFile != NULL) { - if (CloseHandle(hStatsFile) == 0) + if (fclose(fpStatsFile) != 0) { - LogError("CloseHandle failed. GetLastError()=%u", GetLastError()); + LogError("fclose failed. errno=%d", errno); } } } void MethodStatsEmitter::Emit(int methodNumber, MethodContext* mc, ULONGLONG firstTime, ULONGLONG secondTime) { - if (hStatsFile != INVALID_HANDLE_VALUE) + if (fpStatsFile != NULL) { - // Print the CSV header row - char rowData[2048]; - DWORD charCount = 0; - DWORD bytesWritten = 0; - if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 'h') != NULL || strchr(statsTypes, 'H') != NULL) { // Obtain the method Hash @@ -49,11 +43,11 @@ void MethodStatsEmitter::Emit(int methodNumber, MethodContext* mc, ULONGLONG fir if (mc->dumpMethodHashToBuffer(md5Hash, MM3_HASH_BUFFER_SIZE) != MM3_HASH_BUFFER_SIZE) md5Hash[0] = 0; - charCount += sprintf_s(rowData + charCount, ARRAY_SIZE(rowData) - charCount, "%s,", md5Hash); + fprintf(fpStatsFile, "%s,", md5Hash); } if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 'n') != NULL || strchr(statsTypes, 'N') != NULL) { - charCount += sprintf_s(rowData + charCount, ARRAY_SIZE(rowData) - charCount, "%d,", methodNumber); + fprintf(fpStatsFile, "%d,", methodNumber); } if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 'i') != NULL || strchr(statsTypes, 'I') != NULL) { @@ -63,7 +57,7 @@ void MethodStatsEmitter::Emit(int methodNumber, MethodContext* mc, ULONGLONG fir CORINFO_OS os = CORINFO_WINNT; mc->repCompileMethod(&info, &flags, &os); - charCount += sprintf_s(rowData + charCount, ARRAY_SIZE(rowData) - charCount, "%d,", info.ILCodeSize); + fprintf(fpStatsFile, "%d,", info.ILCodeSize); } if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 'a') != NULL || strchr(statsTypes, 'A') != NULL) { @@ -76,21 +70,14 @@ void MethodStatsEmitter::Emit(int methodNumber, MethodContext* mc, ULONGLONG fir else codeSize = 0; // this is likely a thin mc - charCount += sprintf_s(rowData + charCount, ARRAY_SIZE(rowData) - charCount, "%d,", codeSize); + fprintf(fpStatsFile, "%d,", codeSize); } if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 't') != NULL || strchr(statsTypes, 'T') != NULL) { - charCount += - sprintf_s(rowData + charCount, ARRAY_SIZE(rowData) - charCount, "%llu,%llu,", firstTime, secondTime); + fprintf(fpStatsFile, "%llu,%llu,", (unsigned long long)firstTime, (unsigned long long)secondTime); } - // get rid of the final ',' and replace it with a '\n' - rowData[charCount - 1] = '\n'; - - if (!WriteFile(hStatsFile, rowData, charCount, &bytesWritten, nullptr) || bytesWritten != charCount) - { - LogError("Failed to write row header '%s'. GetLastError()=%u", rowData, GetLastError()); - } + fprintf(fpStatsFile, "\n"); } } @@ -98,30 +85,19 @@ void MethodStatsEmitter::SetStatsTypes(char* types) { statsTypes = types; - if (hStatsFile != INVALID_HANDLE_VALUE) + if (fpStatsFile != INVALID_HANDLE_VALUE) { - // Print the CSV header row - char rowHeader[1024]; - DWORD charCount = 0; - DWORD bytesWritten = 0; - if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 'h') != NULL || strchr(statsTypes, 'H') != NULL) - charCount += sprintf_s(rowHeader + charCount, ARRAY_SIZE(rowHeader) - charCount, "HASH,"); + fprintf(fpStatsFile, "HASH,"); if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 'n') != NULL || strchr(statsTypes, 'N') != NULL) - charCount += sprintf_s(rowHeader + charCount, ARRAY_SIZE(rowHeader) - charCount, "METHOD_NUMBER,"); + fprintf(fpStatsFile, "METHOD_NUMBER,"); if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 'i') != NULL || strchr(statsTypes, 'I') != NULL) - charCount += sprintf_s(rowHeader + charCount, ARRAY_SIZE(rowHeader) - charCount, "IL_CODE_SIZE,"); + fprintf(fpStatsFile, "IL_CODE_SIZE,"); if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 'a') != NULL || strchr(statsTypes, 'A') != NULL) - charCount += sprintf_s(rowHeader + charCount, ARRAY_SIZE(rowHeader) - charCount, "ASM_CODE_SIZE,"); + fprintf(fpStatsFile, "ASM_CODE_SIZE,"); if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 't') != NULL || strchr(statsTypes, 'T') != NULL) - charCount += sprintf_s(rowHeader + charCount, ARRAY_SIZE(rowHeader) - charCount, "Time1,Time2,"); - - // get rid of the final ',' and replace it with a '\n' - rowHeader[charCount - 1] = '\n'; + fprintf(fpStatsFile, "Time1,Time2,"); - if (!WriteFile(hStatsFile, rowHeader, charCount, &bytesWritten, nullptr) || bytesWritten != charCount) - { - LogError("Failed to write row header '%s'. GetLastError()=%u", rowHeader, GetLastError()); - } + fprintf(fpStatsFile, "\n"); } } diff --git a/src/coreclr/tools/superpmi/superpmi/methodstatsemitter.h b/src/coreclr/tools/superpmi/superpmi/methodstatsemitter.h index 40d38698b3d446..c35d134e346f65 100644 --- a/src/coreclr/tools/superpmi/superpmi/methodstatsemitter.h +++ b/src/coreclr/tools/superpmi/superpmi/methodstatsemitter.h @@ -14,8 +14,8 @@ class MethodStatsEmitter { private: - char* statsTypes; - HANDLE hStatsFile; + char* statsTypes; + FILE* fpStatsFile; public: MethodStatsEmitter(char* nameOfInput); diff --git a/src/coreclr/tools/superpmi/superpmi/parallelsuperpmi.cpp b/src/coreclr/tools/superpmi/superpmi/parallelsuperpmi.cpp index 07b3cd5805bcb9..b21a6384a9cc9d 100644 --- a/src/coreclr/tools/superpmi/superpmi/parallelsuperpmi.cpp +++ b/src/coreclr/tools/superpmi/superpmi/parallelsuperpmi.cpp @@ -72,108 +72,67 @@ bool StartProcess(char* commandLine, HANDLE hStdOutput, HANDLE hStdError, HANDLE return true; } -void ReadMCLToArray(char* mclFilename, int** arr, int* count) +void ReadMCLToArray(char* mclFilename, std::vector& MCL) { - *count = 0; - *arr = nullptr; - char* buff = nullptr; + FILE* fp = fopen(mclFilename, "r"); + int64_t size; - HANDLE hFile = CreateFileA(mclFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - - if (hFile == INVALID_HANDLE_VALUE) - { - LogError("Unable to open '%s'. GetLastError()=%u", mclFilename, GetLastError()); - goto Cleanup; - } - - LARGE_INTEGER DataTemp; - if (GetFileSizeEx(hFile, &DataTemp) == 0) - { - LogError("GetFileSizeEx failed. GetLastError()=%u", GetLastError()); - goto Cleanup; - } - - if (DataTemp.QuadPart > MAXMCLFILESIZE) + if (fp == NULL) { - LogError("Size %d exceeds max size of %d", DataTemp.QuadPart, MAXMCLFILESIZE); + LogError("Unable to open '%s'. errno=%d", mclFilename, errno); goto Cleanup; } - int sz; - sz = (int)(DataTemp.QuadPart); + fseek(fp, 0, SEEK_END); +#ifdef TARGET_WINDOWS + size = _ftelli64(fp); +#else + size = ftell(fp); +#endif + fseek(fp, 0, SEEK_SET); - buff = new char[sz]; - DWORD bytesRead; - if (ReadFile(hFile, buff, sz, &bytesRead, nullptr) == 0) + if (size > MAXMCLFILESIZE) { - LogError("ReadFile failed. GetLastError()=%u", GetLastError()); + LogError("Size %lld exceeds max size of %d", size, MAXMCLFILESIZE); goto Cleanup; } - for (int i = 0; i < sz; i++) - { - if (buff[i] == 0x0d) - (*count)++; - } - - if (*count <= 0) - return; - - *arr = new int[*count]; - for (int j = 0, arrIndex = 0; j < sz;) + int value; + while (fscanf(fp, "%d", &value) > 0) { - // seek the first number on the line - while (!isdigit((unsigned char)buff[j])) - j++; - // read in the number - (*arr)[arrIndex++] = atoi(&buff[j]); - // seek to the start of next line - while ((j < sz) && (buff[j] != 0x0a)) - j++; - j++; + MCL.push_back(value); } Cleanup: - if (buff != nullptr) - delete[] buff; - - if (hFile != INVALID_HANDLE_VALUE) - CloseHandle(hFile); + if (fp != NULL) + fclose(fp); } -bool WriteArrayToMCL(char* mclFilename, int* arr, int count) +bool WriteArrayToMCL(char* mclFilename, std::vector& MCL) { - HANDLE hMCLFile = - CreateFileA(mclFilename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + FILE* fpMCLFile = fopen(mclFilename, "w"); bool result = true; - if (hMCLFile == INVALID_HANDLE_VALUE) + if (fpMCLFile == NULL) { - LogError("Failed to open output file '%s'. GetLastError()=%u", mclFilename, GetLastError()); + LogError("Failed to open output file '%s'. errno=%d", mclFilename, errno); result = false; goto Cleanup; } - for (int i = 0; i < count; i++) + for (int val : MCL) { - char strMethodIndex[12]; - DWORD charCount = 0; - DWORD bytesWritten = 0; - - charCount = sprintf_s(strMethodIndex, sizeof(strMethodIndex), "%d\r\n", arr[i]); - - if (!WriteFile(hMCLFile, strMethodIndex, charCount, &bytesWritten, nullptr) || (bytesWritten != charCount)) + if (fprintf(fpMCLFile, "%d\r\n", val) <= 0) { - LogError("Failed to write method index '%d'. GetLastError()=%u", strMethodIndex, GetLastError()); + LogError("Failed to write method index '%d'. errno=%d", val, errno); result = false; goto Cleanup; } } Cleanup: - if (hMCLFile != INVALID_HANDLE_VALUE) - CloseHandle(hMCLFile); + if (fpMCLFile != NULL) + fclose(fpMCLFile); return result; } @@ -295,11 +254,6 @@ BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) } #endif // !TARGET_UNIX -int __cdecl compareInt(const void* arg1, const void* arg2) -{ - return (*(const int*)arg1) - (*(const int*)arg2); -} - struct PerWorkerData { HANDLE hStdOutput = INVALID_HANDLE_VALUE; @@ -314,40 +268,25 @@ struct PerWorkerData static void MergeWorkerMCLs(char* mclFilename, PerWorkerData* workerData, int workerCount, char* PerWorkerData::*mclPath) { - int **MCL = new int *[workerCount], *MCLCount = new int[workerCount], totalCount = 0; + std::vector MCL; for (int i = 0; i < workerCount; i++) { // Read the next partial MCL file - ReadMCLToArray(workerData[i].*mclPath, &MCL[i], &MCLCount[i]); - - totalCount += MCLCount[i]; + ReadMCLToArray(workerData[i].*mclPath, MCL); } - int* mergedMCL = new int[totalCount]; - int index = 0; - - for (int i = 0; i < workerCount; i++) - { - for (int j = 0; j < MCLCount[i]; j++) - mergedMCL[index++] = MCL[i][j]; - } - - qsort(mergedMCL, totalCount, sizeof(int), compareInt); + std::sort(MCL.begin(), MCL.end()); // Write the merged MCL array back to disk - if (!WriteArrayToMCL(mclFilename, mergedMCL, totalCount)) + if (!WriteArrayToMCL(mclFilename, MCL)) LogError("Unable to write to MCL file %s.", mclFilename); - - delete[] MCL; - delete[] MCLCount; - delete[] mergedMCL; } static void MergeWorkerCsvs(char* csvFilename, PerWorkerData* workerData, int workerCount, char* PerWorkerData::* csvPath) { - FileWriter fw; - if (!FileWriter::CreateNew(csvFilename, &fw)) + FILE* fpWriter = fopen(csvFilename, "w"); + if (fpWriter == NULL) { LogError("Could not create file %s", csvFilename); return; @@ -369,24 +308,29 @@ static void MergeWorkerCsvs(char* csvFilename, PerWorkerData* workerData, int wo continue; } - FileLineReader reader; - if (!FileLineReader::Open(workerData[i].*csvPath, &reader)) + FILE* fpReader = fopen(workerData[i].*csvPath, "r"); + + if (fpReader == NULL) { LogError("Could not open child CSV file %s", workerData[i].*csvPath); continue; } - if (hasHeader && !reader.AdvanceLine()) + char buffer[512]; + if (hasHeader) { - continue; + // Skip the title line + fgets(buffer, 511, fpReader); } - while (reader.AdvanceLine()) + while (!feof(fpReader)) { - fw.Printf("%s\n", reader.GetCurrentLine()); + fgets(buffer, 511, fpReader); + fputs(buffer, fpReader); } hasHeader = true; + fclose(fpReader); } } diff --git a/src/coreclr/tools/superpmi/superpmi/streamingsuperpmi.cpp b/src/coreclr/tools/superpmi/superpmi/streamingsuperpmi.cpp index 79a08bb4f37ef5..5d6788ed20cca5 100644 --- a/src/coreclr/tools/superpmi/superpmi/streamingsuperpmi.cpp +++ b/src/coreclr/tools/superpmi/superpmi/streamingsuperpmi.cpp @@ -154,7 +154,7 @@ int doStreamingSuperPMI(CommandLine::Options& o) // Just one worker for now... all method selection done via stream file // o.workerCount = 1; - o.indexes = nullptr; + o.indexes.clear(); o.indexCount = -1; o.hash = nullptr; o.offset = -1; @@ -163,7 +163,7 @@ int doStreamingSuperPMI(CommandLine::Options& o) // The method context reader handles skipping any unrequested method contexts // Used in conjunction with an MCI file, it does a lot less work... MethodContextReader* reader = - new MethodContextReader(o.nameOfInputMethodContextFile, o.indexes, o.indexCount, o.hash, o.offset, o.increment); + new MethodContextReader(o.nameOfInputMethodContextFile, nullptr, o.indexCount, o.hash, o.offset, o.increment); if (!reader->isValid()) { return (int)SpmiResult::GeneralFailure; diff --git a/src/coreclr/tools/superpmi/superpmi/superpmi.cpp b/src/coreclr/tools/superpmi/superpmi/superpmi.cpp index e7b62be6585330..52f403819634b1 100644 --- a/src/coreclr/tools/superpmi/superpmi/superpmi.cpp +++ b/src/coreclr/tools/superpmi/superpmi/superpmi.cpp @@ -335,8 +335,8 @@ int __cdecl main(int argc, char* argv[]) // The method context reader handles skipping any unrequested method contexts // Used in conjunction with an MCI file, it does a lot less work... - MethodContextReader* reader = - new MethodContextReader(o.nameOfInputMethodContextFile, o.indexes, o.indexCount, o.hash, o.offset, o.increment); + MethodContextReader* reader = new MethodContextReader(o.nameOfInputMethodContextFile, o.indexes.data(), + o.indexCount, o.hash, o.offset, o.increment); if (!reader->isValid()) { return (int)SpmiResult::GeneralFailure; @@ -495,17 +495,16 @@ int __cdecl main(int argc, char* argv[]) { char buff[500]; sprintf_s(buff, 500, "%s-%d.mc", o.reproName, reader->GetMethodContextIndex()); - HANDLE hFileOut = CreateFileA(buff, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (hFileOut == INVALID_HANDLE_VALUE) + FILE* fpOut = fopen(buff, "wb"); + if (fpOut == NULL) { - LogError("Failed to open output '%s'. GetLastError()=%u", buff, GetLastError()); + LogError("Failed to open output '%s'. errno=%d", buff, errno); return (int)SpmiResult::GeneralFailure; } - mc->saveToFile(hFileOut); - if (CloseHandle(hFileOut) == 0) + mc->saveToFile(fpOut); + if (fclose(fpOut) != 0) { - LogError("CloseHandle for output file failed. GetLastError()=%u", GetLastError()); + LogError("CloseHandle for output file failed. errno=%d", errno); return (int)SpmiResult::GeneralFailure; } LogInfo("Wrote out repro to '%s'", buff);