From 005f9e43db275a61e71b602800c65d653c44be45 Mon Sep 17 00:00:00 2001 From: vitoway Date: Sun, 1 Dec 2024 08:58:06 +0800 Subject: [PATCH] Update to make flutter 3.24.5 support win7 --- ...utter-engine-windows-x64-release-build.yml | 17 +- ...ding-Remove-Windows7-handling-of-unw.patch | 222 ++++++++++++++++++ 0001-revert-file_win.cc.patch | 123 ++++++++++ 3 files changed, 359 insertions(+), 3 deletions(-) create mode 100644 0001-Revert-win-unwinding-Remove-Windows7-handling-of-unw.patch create mode 100644 0001-revert-file_win.cc.patch diff --git a/.github/workflows/flutter-engine-windows-x64-release-build.yml b/.github/workflows/flutter-engine-windows-x64-release-build.yml index 00cb0cc8efe43..1dff94a50e78f 100644 --- a/.github/workflows/flutter-engine-windows-x64-release-build.yml +++ b/.github/workflows/flutter-engine-windows-x64-release-build.yml @@ -39,6 +39,16 @@ jobs: Invoke-WebRequest -Uri "https://dart-review.googlesource.com/changes/sdk~320620/revisions/2/patch?zip&path=runtime%2Fbin%2Fplatform_win.cc" -OutFile $filePath Expand-Archive -Path $filePath -DestinationPath "." git apply --directory="src/flutter/third_party/dart" 987dbe0.diff + + # fix https://github.com/dart-lang/sdk/commit/34213ba60578e46fc2455c5a56b09d9efabc532b#diff-8b21f02c32c6647079e2c07e7c6ddfff74ac69f81331f9ed67429125e9fe16aa + $filePath = "0001-Revert-win-unwinding-Remove-Windows7-handling-of-unw.patch" + Invoke-WebRequest -Uri "https://github.com/rustdesk/engine/raw/refs/heads/main/0001-Revert-win-unwinding-Remove-Windows7-handling-of-unw.patch" -OutFile $filePath + git apply --directory="src/flutter/third_party/dart" $filePath + + # fix https://dart-review.googlesource.com/c/sdk/+/335940/22/runtime/bin/file_win.cc#642 + $filePath = "0001-revert-file_win.cc.patch" + Invoke-WebRequest -Uri "https://github.com/rustdesk/engine/raw/refs/heads/main/0001-revert-file_win.cc.patch" -OutFile $filePath + git apply --directory="src/flutter/third_party/dart" $filePath # Compiling the Flutter engine cd src @@ -47,9 +57,10 @@ jobs: # Check and compress files $outputPath = "${{ github.workspace }}\windows-x64-release.zip" - $filesToCompress = Get-ChildItem -Path .\out\host_release\flutter_windows.dll* - if ($filesToCompress) { - Compress-Archive -Path $filesToCompress -DestinationPath $outputPath + $filesToCompress = Get-ChildItem -Path .\out\host_release\ | Where-Object { $_.Name -in @("flutter_windows.dll", "flutter_windows.dll.pdb", "flutter_windows.dll.exp", "flutter_windows.dll.lib", "flutter_windows.h", "flutter_export.h", "flutter_messenger.h", "flutter_plugin_registrar.h", "flutter_texture_registrar.h", "license.windows_flutter.md", "gen_snapshot.exe") } + $filesToCompressPaths = $filesToCompress.FullName + if ($filesToCompressPaths) { + Compress-Archive -Path $filesToCompressPaths -DestinationPath $outputPath } else { Write-Error "Build output files not found!" } diff --git a/0001-Revert-win-unwinding-Remove-Windows7-handling-of-unw.patch b/0001-Revert-win-unwinding-Remove-Windows7-handling-of-unw.patch new file mode 100644 index 0000000000000..9c5068450bcbb --- /dev/null +++ b/0001-Revert-win-unwinding-Remove-Windows7-handling-of-unw.patch @@ -0,0 +1,222 @@ +From 08a6dbe98c69f5e1d7ea9548474afd75df834a59 Mon Sep 17 00:00:00 2001 +From: vitoway +Date: Sat, 30 Nov 2024 11:53:52 +0800 +Subject: [PATCH] Revert "[win/unwinding] Remove Windows7 handling of unwinding + records API." + +This reverts commit 34213ba60578e46fc2455c5a56b09d9efabc532b. +--- + runtime/bin/elf_loader.cc | 2 + + runtime/platform/unwinding_records.cc | 2 + + runtime/platform/unwinding_records.h | 6 +++ + runtime/platform/unwinding_records_win.cc | 55 +++++++++++++++++++---- + runtime/vm/dart.cc | 2 + + runtime/vm/unwinding_records_win.cc | 12 ++++- + 6 files changed, 69 insertions(+), 10 deletions(-) + +diff --git a/runtime/bin/elf_loader.cc b/runtime/bin/elf_loader.cc +index 70baa9c142a..d3260a61162 100644 +--- a/runtime/bin/elf_loader.cc ++++ b/runtime/bin/elf_loader.cc +@@ -270,6 +270,7 @@ class LoadedElf { + } + + bool LoadedElf::Load() { ++ UnwindingRecordsPlatform::Init(); + VirtualMemory::Init(); + + if (error_ != nullptr) { +@@ -301,6 +302,7 @@ LoadedElf::~LoadedElf() { + UnwindingRecordsPlatform::UnregisterDynamicTable( + dynamic_runtime_function_tables_[i]); + } ++ UnwindingRecordsPlatform::Cleanup(); + #endif + + // Unmap the image. +diff --git a/runtime/platform/unwinding_records.cc b/runtime/platform/unwinding_records.cc +index e6e69d0ed0b..1b9c4f6f540 100644 +--- a/runtime/platform/unwinding_records.cc ++++ b/runtime/platform/unwinding_records.cc +@@ -19,6 +19,8 @@ intptr_t UnwindingRecordsPlatform::SizeInBytes() { + #if !defined(DART_HOST_OS_WINDOWS) || \ + (!defined(TARGET_ARCH_X64) && !defined(TARGET_ARCH_ARM64)) + ++void UnwindingRecordsPlatform::Init() {} ++void UnwindingRecordsPlatform::Cleanup() {} + void UnwindingRecordsPlatform::RegisterExecutableMemory( + void* start, + intptr_t size, +diff --git a/runtime/platform/unwinding_records.h b/runtime/platform/unwinding_records.h +index 83d242a4984..0207d20e536 100644 +--- a/runtime/platform/unwinding_records.h ++++ b/runtime/platform/unwinding_records.h +@@ -12,12 +12,18 @@ namespace dart { + + class UnwindingRecordsPlatform : public AllStatic { + public: ++ static void Init(); ++ static void Cleanup(); ++ + static intptr_t SizeInBytes(); + + static void RegisterExecutableMemory(void* start, + intptr_t size, + void** pp_dynamic_table); + static void UnregisterDynamicTable(void* p_dynamic_table); ++ ++ static void* GetAddGrowableFunctionTableFunc(); ++ static void* GetDeleteGrowableFunctionTableFunc(); + }; + + #if (defined(DART_TARGET_OS_WINDOWS) || defined(DART_HOST_OS_WINDOWS)) && \ +diff --git a/runtime/platform/unwinding_records_win.cc b/runtime/platform/unwinding_records_win.cc +index 937cd1d833e..ade1986eb3c 100644 +--- a/runtime/platform/unwinding_records_win.cc ++++ b/runtime/platform/unwinding_records_win.cc +@@ -27,10 +27,48 @@ intptr_t UnwindingRecordsPlatform::SizeInBytes() { + #if defined(DART_HOST_OS_WINDOWS) && \ + (defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM64)) + ++static HMODULE ntdll_module; ++static decltype(&::RtlAddGrowableFunctionTable) ++ add_growable_function_table_func_ = nullptr; ++static decltype(&::RtlDeleteGrowableFunctionTable) ++ delete_growable_function_table_func_ = nullptr; ++ ++void* UnwindingRecordsPlatform::GetAddGrowableFunctionTableFunc() { ++ return add_growable_function_table_func_; ++} ++ ++void* UnwindingRecordsPlatform::GetDeleteGrowableFunctionTableFunc() { ++ return delete_growable_function_table_func_; ++} ++ ++void UnwindingRecordsPlatform::Init() { ++ ntdll_module = ++ LoadLibraryEx(L"ntdll.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); ++ ASSERT(ntdll_module != nullptr); ++ // This pair of functions is not available on Windows 7. ++ add_growable_function_table_func_ = ++ reinterpret_cast( ++ ::GetProcAddress(ntdll_module, "RtlAddGrowableFunctionTable")); ++ delete_growable_function_table_func_ = ++ reinterpret_cast( ++ ::GetProcAddress(ntdll_module, "RtlDeleteGrowableFunctionTable")); ++ // Either both available, or both not available. ++ ASSERT((add_growable_function_table_func_ == nullptr) == ++ (delete_growable_function_table_func_ == nullptr)); ++} ++ ++void UnwindingRecordsPlatform::Cleanup() { ++ FreeLibrary(ntdll_module); ++} ++ + void UnwindingRecordsPlatform::RegisterExecutableMemory( + void* start, + intptr_t size, + void** pp_dynamic_table) { ++ auto func = add_growable_function_table_func_; ++ if (func == nullptr) { ++ return; ++ } + intptr_t unwinding_record_offset = size - kReservedUnwindingRecordsSizeBytes; + uint8_t* record_ptr = static_cast(start) + unwinding_record_offset; + CodeRangeUnwindingRecord* record = +@@ -38,20 +76,21 @@ void UnwindingRecordsPlatform::RegisterExecutableMemory( + RELEASE_ASSERT(record->magic == kUnwindingRecordMagic); + uword start_num = reinterpret_cast(start); + uword end_num = start_num + size; +- DWORD status = RtlAddGrowableFunctionTable( +- pp_dynamic_table, +- /*FunctionTable=*/record->runtime_function, +- /*EntryCount=*/record->runtime_function_count, +- /*MaximumEntryCount=*/record->runtime_function_count, +- /*RangeBase=*/start_num, +- /*RangeEnd=*/end_num); ++ DWORD status = func(pp_dynamic_table, ++ /*FunctionTable=*/record->runtime_function, ++ /*EntryCount=*/record->runtime_function_count, ++ /*MaximumEntryCount=*/record->runtime_function_count, ++ /*RangeBase=*/start_num, ++ /*RangeEnd=*/end_num); + if (status != 0) { + FATAL("Failed to add growable function table: 0x%x\n", status); + } + } + + void UnwindingRecordsPlatform::UnregisterDynamicTable(void* p_dynamic_table) { +- RtlDeleteGrowableFunctionTable(p_dynamic_table); ++ auto func = delete_growable_function_table_func_; ++ if (func == nullptr) return; ++ func(p_dynamic_table); + } + + #endif // defined(DART_HOST_OS_WINDOWS) +diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc +index 3c4502ba353..66e48cdb656 100644 +--- a/runtime/vm/dart.cc ++++ b/runtime/vm/dart.cc +@@ -342,6 +342,7 @@ char* Dart::DartInit(const Dart_InitializeParams* params) { + ForwardingCorpse::Init(); + Api::Init(); + NativeSymbolResolver::Init(); ++ UnwindingRecordsPlatform::Init(); + Page::Init(); + StoreBuffer::Init(); + MarkingStack::Init(); +@@ -757,6 +758,7 @@ char* Dart::Cleanup() { + StoreBuffer::Cleanup(); + Object::Cleanup(); + Page::Cleanup(); ++ UnwindingRecordsPlatform::Cleanup(); + StubCode::Cleanup(); + #if defined(SUPPORT_TIMELINE) + if (FLAG_trace_shutdown) { +diff --git a/runtime/vm/unwinding_records_win.cc b/runtime/vm/unwinding_records_win.cc +index a92c2931df5..84aebe36387 100644 +--- a/runtime/vm/unwinding_records_win.cc ++++ b/runtime/vm/unwinding_records_win.cc +@@ -109,6 +109,11 @@ const void* UnwindingRecords::GenerateRecordsInto(intptr_t offset, + // Special exception-unwinding records are put at the end of executable + // page on Windows for 64-bit applications. + void UnwindingRecords::RegisterExecutablePage(Page* page) { ++ // Won't set up unwinding records on Windows 7, so users won't be able ++ // to benefit from proper unhandled exceptions filtering. ++ auto function = static_cast( ++ UnwindingRecordsPlatform::GetAddGrowableFunctionTableFunc()); ++ if (function == nullptr) return; + ASSERT(page->is_executable()); + ASSERT(sizeof(CodeRangeUnwindingRecord) <= + UnwindingRecordsPlatform::SizeInBytes()); +@@ -120,7 +125,7 @@ void UnwindingRecords::RegisterExecutablePage(Page* page) { + unwinding_record_offset) CodeRangeUnwindingRecord(); + InitUnwindingRecord(unwinding_record_offset, record, page->memory_->size()); + RELEASE_ASSERT(record->magic == kUnwindingRecordMagic); +- DWORD status = RtlAddGrowableFunctionTable( ++ DWORD status = function( + /*DynamicTable=*/&record->dynamic_table, + /*FunctionTable=*/record->runtime_function, + /*EntryCount=*/record->runtime_function_count, +@@ -133,6 +138,9 @@ void UnwindingRecords::RegisterExecutablePage(Page* page) { + } + + void UnwindingRecords::UnregisterExecutablePage(Page* page) { ++ auto function = static_cast( ++ UnwindingRecordsPlatform::GetDeleteGrowableFunctionTableFunc()); ++ if (function == nullptr) return; + ASSERT(page->is_executable() && !page->is_image()); + intptr_t unwinding_record_offset = + page->memory_->size() - UnwindingRecordsPlatform::SizeInBytes(); +@@ -141,7 +149,7 @@ void UnwindingRecords::UnregisterExecutablePage(Page* page) { + reinterpret_cast(page->memory_->start()) + + unwinding_record_offset); + RELEASE_ASSERT(record->magic == kUnwindingRecordMagic); +- RtlDeleteGrowableFunctionTable(record->dynamic_table); ++ function(record->dynamic_table); + } + + #endif // defined(DART_HOST_OS_WINDOWS) +-- +2.47.0.windows.1 + diff --git a/0001-revert-file_win.cc.patch b/0001-revert-file_win.cc.patch new file mode 100644 index 0000000000000..b473ff33c8645 --- /dev/null +++ b/0001-revert-file_win.cc.patch @@ -0,0 +1,123 @@ +From 48874d5b15afd3704882af181d393888f24dde9e Mon Sep 17 00:00:00 2001 +From: vitoway +Date: Sat, 30 Nov 2024 12:02:38 +0800 +Subject: [PATCH] revert file_win.cc + +--- + runtime/bin/BUILD.gn | 2 +- + runtime/bin/file_win.cc | 71 ++++++----------------------------------- + 2 files changed, 11 insertions(+), 62 deletions(-) + +diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn +index be0893506f2..1b8f7fb088a 100644 +--- a/runtime/bin/BUILD.gn ++++ b/runtime/bin/BUILD.gn +@@ -64,7 +64,7 @@ template("build_libdart_builtin") { + public_deps = [ "$fuchsia_sdk/pkg/fdio" ] + } + if (is_win) { +- libs = [ "Pathcch.lib" ] ++ # libs = [ "Pathcch.lib" ] + } + include_dirs = [ ".." ] + sources = builtin_impl_sources +diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc +index 07e503ba19a..37627736fba 100644 +--- a/runtime/bin/file_win.cc ++++ b/runtime/bin/file_win.cc +@@ -13,7 +13,7 @@ + #include // NOLINT + #include // NOLINT + #include // NOLINT +-#include // NOLINT ++// #include // NOLINT + #include // NOLINT + #undef StrDup // defined in Shlwapi.h as StrDupW + #include // NOLINT +@@ -610,74 +610,23 @@ typedef struct _REPARSE_DATA_BUFFER { + }; + } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; + ++static constexpr int kReparseDataHeaderSize = ++ sizeof(ULONG) + 2 * sizeof(USHORT); ++static constexpr int kMountPointHeaderSize = 4 * sizeof(USHORT); ++ + bool File::CreateLink(Namespace* namespc, + const char* utf8_name, + const char* utf8_target) { + const auto name = ToWinAPIFilePath(utf8_name); +- +- std::unique_ptr target; +- bool target_is_directory; +- if (File::IsAbsolutePath(utf8_target)) { +- target = ToWinAPIFilePath(utf8_target); +- target_is_directory = +- File::GetType(target.get(), /*follow_links=*/true) == kIsDirectory; +- } else { +- // The path of `target` is relative to `name`. +- // +- // To determine if `target` is a file or directory, we need to calculate +- // either its absolute path or its path relative to the current working +- // directory. +- // +- // For example: +- // +- // name= C:\A\B\Link ..\..\Link ..\..\Link +- // target= MyFile MyFile ..\Dir\MyFile +- // -------------------------------------------------------------------- +- // target_path= C:\A\B\MyFile ..\..\MyFile ..\..\..\Dir\MyFile +- // +- // The transformation steps are: +- // 1. target_path := name ..\..\Link +- // 2. target_path := remove_file(target_path) ..\..\ +- // 3. target_path := combine(target_path, target) ..\..\..\Dir\MyFile +- target = Utf8ToWideChar(utf8_target); +- +- // 1. target_path := name +- intptr_t target_path_max_length = +- wcslen(name.get()) + wcslen(target.get()) + 2; +- auto target_path = std::make_unique(target_path_max_length); +- wcscpy_s(target_path.get(), target_path_max_length, name.get()); +- +- // 2. target_path := remove_file(target_path) +- HRESULT remove_result = +- PathCchRemoveFileSpec(target_path.get(), target_path_max_length); +- if (remove_result == S_FALSE) { +- // If the file component could not be removed, then `name` is +- // top-level, like "C:\" or "/". Attempts to create files at those paths +- // will fail with ERROR_ACCESS_DENIED. +- SetLastError(ERROR_ACCESS_DENIED); +- return false; +- } else if (remove_result != S_OK) { +- SetLastError(remove_result); +- return false; +- } +- +- // 3. target_path := combine(target_path, target) +- HRESULT combine_result = PathCchCombineEx( +- target_path.get(), target_path_max_length, target_path.get(), +- target.get(), PATHCCH_ALLOW_LONG_PATHS); +- if (combine_result != S_OK) { +- SetLastError(combine_result); +- return false; +- } +- +- target_is_directory = +- File::GetType(target_path.get(), /*follow_links=*/true) == kIsDirectory; +- } ++ std::unique_ptr target = ToWinAPIFilePath(utf8_target); + + DWORD flags = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE; +- if (target_is_directory) { ++ ++ File::Type type = File::GetType(namespc, utf8_target, true); ++ if (type == kIsDirectory) { + flags |= SYMBOLIC_LINK_FLAG_DIRECTORY; + } ++ + int create_status = CreateSymbolicLinkW(name.get(), target.get(), flags); + + // If running on a Windows 10 build older than 14972, an invalid parameter +-- +2.47.0.windows.1 +